; Phase 1 — dag model + structural content addressing. ; ---- content-id determinism ---- (artdag-test "same spec -> same id" (equal? (artdag/content-id (artdag/node "blur" (list "i1") {:r 3})) (artdag/content-id (artdag/node "blur" (list "i1") {:r 3}))) true) (artdag-test "op affects id" (equal? (artdag/content-id (artdag/node "blur" (list "i1") {})) (artdag/content-id (artdag/node "sharpen" (list "i1") {}))) false) (artdag-test "params affect id" (equal? (artdag/content-id (artdag/node "blur" (list "i1") {:r 3})) (artdag/content-id (artdag/node "blur" (list "i1") {:r 5}))) false) (artdag-test "inputs affect id" (equal? (artdag/content-id (artdag/node "add" (list "i1") {})) (artdag/content-id (artdag/node "add" (list "i2") {}))) false) (artdag-test "param key order does not affect id" (equal? (artdag/content-id (artdag/node "op" (list) {:a 1 :b 2})) (artdag/content-id (artdag/node "op" (list) {:a 1 :b 2}))) true) ; ---- commutativity ---- (artdag-test "commutative op: input order ignored" (equal? (artdag/content-id (artdag/cnode "add" (list "i1" "i2") {})) (artdag/content-id (artdag/cnode "add" (list "i2" "i1") {}))) true) (artdag-test "non-commutative op: input order matters" (equal? (artdag/content-id (artdag/node "sub" (list "i1" "i2") {})) (artdag/content-id (artdag/node "sub" (list "i2" "i1") {}))) false) ; ---- build: success ---- (artdag-test "build ok for valid dag" (get (artdag/build (list (list "a" "load" (list) {}) (list "b" "load" (list) {:s 1}) (list "c" "add" (list "a" "b") {}))) :ok) true) (artdag-test "node-count counts distinct nodes" (artdag/node-count (artdag/build (list (list "a" "load" (list) {}) (list "b" "load" (list) {:s 1}) (list "c" "add" (list "a" "b") {})))) 3) ; ---- subgraph sharing ---- (artdag-test "identical leaves dedup to one node" (artdag/node-count (artdag/build (list (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 1}) (list "c" "add" (list "a" "b") {})))) 2) (artdag-test "duplicate names map to same id" (let ((d (artdag/build (list (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 1}))))) (equal? (artdag/dag-id d "a") (artdag/dag-id d "b"))) true) (artdag-test "identical subgraph shares id across dags" (let ((d1 (artdag/build (list (list "x" "load" (list) {:s 7}) (list "y" "neg" (list "x") {})))) (d2 (artdag/build (list (list "p" "load" (list) {:s 7}) (list "q" "neg" (list "p") {}))))) (equal? (artdag/dag-id d1 "y") (artdag/dag-id d2 "q"))) true) ; ---- validation ---- (artdag-test "cycle rejected" (get (artdag/build (list (list "a" "f" (list "b") {}) (list "b" "g" (list "a") {}))) :error) "cycle") (artdag-test "self-cycle rejected" (get (artdag/build (list (list "a" "f" (list "a") {}))) :error) "cycle") (artdag-test "dangling input rejected" (get (artdag/build (list (list "a" "f" (list "ghost") {}))) :error) "dangling") (artdag-test "dangling refs reported" (get (artdag/build (list (list "a" "f" (list "ghost") {}))) :refs) (list "ghost")) ; ---- topological order ---- (artdag-test "topo order: deps before dependents" (let ((d (artdag/build (list (list "c" "add" (list "a" "b") {}) (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 2}))))) (artdag/dag-order d)) (let ((d (artdag/build (list (list "c" "add" (list "a" "b") {}) (list "a" "load" (list) {:s 1}) (list "b" "load" (list) {:s 2}))))) (list (artdag/dag-id d "a") (artdag/dag-id d "b") (artdag/dag-id d "c")))) (artdag-test "topo order: deep chain" (let ((d (artdag/build (list (list "d" "f" (list "c") {}) (list "c" "f" (list "b") {}) (list "b" "f" (list "a") {}) (list "a" "load" (list) {}))))) (artdag/dag-order d)) (let ((d (artdag/build (list (list "d" "f" (list "c") {}) (list "c" "f" (list "b") {}) (list "b" "f" (list "a") {}) (list "a" "load" (list) {}))))) (list (artdag/dag-id d "a") (artdag/dag-id d "b") (artdag/dag-id d "c") (artdag/dag-id d "d")))) ; ---- accessors ---- (artdag-test "dag-node-by-name returns node spec" (artdag/node-op (artdag/dag-node-by-name (artdag/build (list (list "a" "load" (list) {}))) "a")) "load") (artdag-test "resolved inputs are content-ids" (let ((d (artdag/build (list (list "a" "load" (list) {}) (list "b" "neg" (list "a") {}))))) (artdag/node-inputs (artdag/dag-node-by-name d "b"))) (let ((d (artdag/build (list (list "a" "load" (list) {}) (list "b" "neg" (list "a") {}))))) (list (artdag/dag-id d "a"))))