; Phase 2 — Analyze on Datalog: deps/dependents/reachability + dirty closure.

; diamond:  a -> b, a -> c, (b,c) -> d
(define
  an-D
  (artdag/build
    (list
      (list "a" "load" (list) {})
      (list "b" "f" (list "a") {})
      (list "c" "g" (list "a") {})
      (list "d" "add" (list "b" "c") {} true))))
(define an-db (artdag/analyze an-D))
(define an-a (artdag/dag-id an-D "a"))
(define an-b (artdag/dag-id an-D "b"))
(define an-c (artdag/dag-id an-D "c"))
(define an-d (artdag/dag-id an-D "d"))

; ---- direct deps / dependents ----

(artdag-test
  "deps-of: direct inputs"
  (artdag/deps-of an-db an-d)
  (artdag/sort-strings (list an-b an-c)))

(artdag-test "deps-of: leaf has none" (artdag/deps-of an-db an-a) (list))

(artdag-test
  "dependents-of: direct consumers"
  (artdag/dependents-of an-db an-a)
  (artdag/sort-strings (list an-b an-c)))

(artdag-test
  "dependents-of: output has none"
  (artdag/dependents-of an-db an-d)
  (list))

; ---- transitive reachability ----

(artdag-test
  "reachable-from: all downstream"
  (artdag/reachable-from an-db an-a)
  (artdag/sort-strings (list an-b an-c an-d)))

(artdag-test
  "reachable-from: mid node reaches output"
  (artdag/reachable-from an-db an-b)
  (list an-d))

(artdag-test
  "ancestors-of: all upstream"
  (artdag/ancestors-of an-db an-d)
  (artdag/sort-strings (list an-a an-b an-c)))

(artdag-test
  "ancestors-of: leaf has none"
  (artdag/ancestors-of an-db an-a)
  (list))

; ---- deep chain ----

(define
  ch-D
  (artdag/build
    (list
      (list "a" "load" (list) {})
      (list "b" "f" (list "a") {})
      (list "c" "f" (list "b") {})
      (list "d" "f" (list "c") {}))))
(define ch-db (artdag/analyze ch-D))

(artdag-test
  "deep chain: reachable-from leaf"
  (artdag/reachable-from ch-db (artdag/dag-id ch-D "a"))
  (artdag/sort-strings
    (list
      (artdag/dag-id ch-D "b")
      (artdag/dag-id ch-D "c")
      (artdag/dag-id ch-D "d"))))

(artdag-test
  "deep chain: ancestors of tip"
  (artdag/ancestors-of ch-db (artdag/dag-id ch-D "d"))
  (artdag/sort-strings
    (list
      (artdag/dag-id ch-D "a")
      (artdag/dag-id ch-D "b")
      (artdag/dag-id ch-D "c"))))

; ---- dirty closure ----

(artdag-test
  "dirty closure: change leaf dirties all"
  (artdag/dirty-closure an-D (list an-a))
  (artdag/sort-strings (list an-a an-b an-c an-d)))

(artdag-test
  "dirty closure: change mid touches only downstream"
  (artdag/dirty-closure an-D (list an-b))
  (artdag/sort-strings (list an-b an-d)))

(artdag-test
  "dirty closure: unaffected stay clean (count)"
  (len (artdag/dirty-closure an-D (list an-b)))
  2)

(artdag-test
  "dirty closure: change output dirties only itself"
  (artdag/dirty-closure an-D (list an-d))
  (list an-d))

(artdag-test
  "dirty closure: multiple seeds union"
  (artdag/dirty-closure an-D (list an-b an-c))
  (artdag/sort-strings (list an-b an-c an-d)))

(artdag-test
  "dirty closure: empty seed set"
  (artdag/dirty-closure an-D (list))
  (list))
