Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 57s
analyze.sx projects DAG edges to (edge in out) facts and runs recursive reachable rules for deps-of/dependents-of/reachable-from/ancestors-of, plus dirty-closure (dirty(Y):-edge(X,Y),dirty(X)) for incremental recompute. Keystone: changing a mid node dirties only it + downstream. analyze 16/16, total 36/36. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
89 lines
2.5 KiB
Plaintext
89 lines
2.5 KiB
Plaintext
; 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))))
|