; execution stats: hit ratio + memoized work saved (cost-weighted).

(define st-RT (artdag/op-table-runner {:in (fn (p i) (get p :v)) :add (fn (p i) (+ (nth i 0) (nth i 1))) :inc (fn (p i) (+ 1 (first i)))}))

(define
  st-D
  (artdag/build
    (list
      (list "p" "in" (list) {:v 10})
      (list "q" "in" (list) {:v 20})
      (list "b" "inc" (list "p") {})
      (list "c" "inc" (list "q") {})
      (list "d" "add" (list "b" "c") {} true))))

; same shape, leaf q changed -> dirty closure {q,c,d}
(define
  st-D2
  (artdag/build
    (list
      (list "p" "in" (list) {:v 10})
      (list "q" "in" (list) {:v 21})
      (list "b" "inc" (list "p") {})
      (list "c" "inc" (list "q") {})
      (list "d" "add" (list "b" "c") {} true))))

(define st-W (artdag/op-cost {:add 5 :inc 2}))

; ---- cold run ----

(artdag-test
  "cold run: hit ratio is zero"
  (let
    ((cache (persist/open)))
    (artdag/hit-ratio (artdag/run st-D st-RT cache)))
  0)

(artdag-test
  "cold run: nothing saved"
  (let
    ((cache (persist/open)))
    (artdag/work-saved (artdag/run st-D st-RT cache) st-D artdag/const-cost))
  0)

(artdag-test
  "cold run: all work runs"
  (let
    ((cache (persist/open)))
    (artdag/work-recomputed
      (artdag/run st-D st-RT cache)
      st-D
      artdag/const-cost))
  5)

(artdag-test
  "cold run: weighted work ran"
  (let
    ((cache (persist/open)))
    (artdag/work-recomputed (artdag/run st-D st-RT cache) st-D st-W))
  11)

; ---- warm rerun ----

(artdag-test
  "warm rerun: hit ratio is one"
  (let
    ((cache (persist/open)))
    (begin
      (artdag/run st-D st-RT cache)
      (artdag/hit-ratio (artdag/run st-D st-RT cache))))
  1)

(artdag-test
  "warm rerun: savings ratio is one"
  (let
    ((cache (persist/open)))
    (begin
      (artdag/run st-D st-RT cache)
      (artdag/savings-ratio
        (artdag/run st-D st-RT cache)
        st-D
        artdag/const-cost)))
  1)

(artdag-test
  "warm rerun: all weighted work saved"
  (let
    ((cache (persist/open)))
    (begin
      (artdag/run st-D st-RT cache)
      (artdag/work-saved (artdag/run st-D st-RT cache) st-D st-W)))
  11)

; ---- partial (incremental) ----

(artdag-test
  "incremental: total is every node"
  (let
    ((cache (persist/open)))
    (begin
      (artdag/run st-D st-RT cache)
      (artdag/exec-total (artdag/run st-D2 st-RT cache))))
  5)

(artdag-test
  "incremental: saved work counts unchanged nodes"
  (let
    ((cache (persist/open)))
    (begin
      (artdag/run st-D st-RT cache)
      (artdag/work-saved
        (artdag/run st-D2 st-RT cache)
        st-D2
        artdag/const-cost)))
  2)

(artdag-test
  "incremental: ran work counts dirty closure"
  (let
    ((cache (persist/open)))
    (begin
      (artdag/run st-D st-RT cache)
      (artdag/work-recomputed
        (artdag/run st-D2 st-RT cache)
        st-D2
        artdag/const-cost)))
  3)

(artdag-test
  "summary reports recompute count"
  (let
    ((cache (persist/open)))
    (get
      (artdag/exec-summary
        (artdag/run st-D st-RT cache)
        st-D
        artdag/const-cost)
      :recomputed))
  5)

(artdag-test
  "summary reports total"
  (let
    ((cache (persist/open)))
    (get
      (artdag/exec-summary
        (artdag/run st-D st-RT cache)
        st-D
        artdag/const-cost)
      :total))
  5)
