Open fstamour opened 2 years ago
Should be possible to perform this "what do we copy?" algorithm in O(n) time with two walks in total.
At the end of this algorithm:
I do not yet know if that algorithm is correct.
@marcoheisig comes to help! Thanks.
(defun supersubst (graph substitutions)
(declare (hash-table substitutions))
(let ((parent-table (make-hash-table))
(color-table (make-hash-table)))
(macrolet ((parents (node) `(gethash ,node parent-table '()))
(color (node) `(gethash ,node color-table :white)))
;; Determine the parents of each node.
(do-graph-nodes (node graph)
(do-node-children (child node)
(push node (parents child))))
;; Mark nodes that must be copied as black.
(maphash
(lambda (old new)
(let ((worklist (list old)))
(loop until (null worklist) for node = (pop worklist) do
(unless (eq (color node) :black)
(setf (color node) :black)
(dolist (parent (parents node))
(push parent worklist))))))
substitutions)
;; TODO Actually copy the graph.
)))
TODO: old
in the hash table should be a function of some sort, because we cannot locate nodes just by eq
. Something along these lines, bla bla structure sharing. I need to concretify it later.
this algorithm needs a bit more more information! and I think I'll figure it out let's consider our favorite diamond, A → B → D, A → C → D and I'd like to only modify the node that B points to so this becomes a non-diamond, A' → B' → D', A' → C → D but I can't simply mark D as black because that would unnecessarily copy C so I can't really use eq for nodes, I think need to use parent+edge combo to identify which nodes to copy and that's doable
From discord (discord link):
From @phoe on discord (html link discord link) - Heavily paraphrased: