; lib/artdag/analyze.sx — Phase 2: Analyze on Datalog. ; Project the DAG's edges into a Datalog db and answer dependency questions ; (deps, dependents, transitive reachability) plus dirty-closure propagation ; as recursive Datalog — the acl/relations reachability shape. Depends on ; lib/artdag/dag.sx and the lib/datalog/ public API. ; edge(input-id, node-id): data flows input -> node (input is a dependency). (define artdag/edge-facts (fn (dag) (reduce (fn (acc id) (concat acc (map (fn (in) (list (quote edge) in id)) (artdag/node-inputs (artdag/dag-get dag id))))) (list) (keys (artdag/dag-nodes dag))))) ; reachable(X,Y): Y is a transitive dependent of X (forward, downstream). (define artdag/reach-rules (quote ((reachable X Y <- (edge X Y)) (reachable X Z <- (edge X Y) (reachable Y Z))))) (define artdag/analyze (fn (dag) (dl-program-data (artdag/edge-facts dag) artdag/reach-rules))) ; pull a single variable's bindings out of a subst list, sorted for determinism. (define artdag/-bindings (fn (substs var) (artdag/sort-strings (map (fn (s) (get s var)) substs)))) ; direct dependencies (inputs) of a node. (define artdag/deps-of (fn (db id) (artdag/-bindings (dl-query db (list (quote edge) (quote X) id)) :X))) ; direct dependents of a node. (define artdag/dependents-of (fn (db id) (artdag/-bindings (dl-query db (list (quote edge) id (quote Y))) :Y))) ; transitive dependents (everything downstream of a node). (define artdag/reachable-from (fn (db id) (artdag/-bindings (dl-query db (list (quote reachable) id (quote Y))) :Y))) ; transitive dependencies (everything upstream of a node). (define artdag/ancestors-of (fn (db id) (artdag/-bindings (dl-query db (list (quote reachable) (quote X) id)) :X))) ; dirty propagation: dirty(Y) :- edge(X,Y), dirty(X). Seeds are changed nodes. (define artdag/dirty-rules (quote ((dirty Y <- (edge X Y) (dirty X))))) (define artdag/dirty-seeds (fn (changed) (map (fn (c) (list (quote dirty) c)) changed))) ; transitive dirty closure of a set of changed node-ids: the changed nodes plus ; every transitive dependent that must recompute. Sorted, deduplicated. (define artdag/dirty-closure (fn (dag changed) (let ((db (dl-program-data (concat (artdag/edge-facts dag) (artdag/dirty-seeds changed)) artdag/dirty-rules))) (artdag/-bindings (dl-query db (list (quote dirty) (quote X))) :X))))