; cost model: critical path, makespan under cap, total work, speedup.

(define
  cost-CHAIN
  (artdag/build
    (list
      (list "a" "in" (list) {})
      (list "b" "f" (list "a") {})
      (list "c" "f" (list "b") {})
      (list "d" "f" (list "c") {}))))

(define
  cost-DIA
  (artdag/build
    (list
      (list "a" "in" (list) {})
      (list "b" "f" (list "a") {})
      (list "c" "g" (list "a") {})
      (list "d" "add" (list "b" "c") {} true))))

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

; ---- unit cost ----

(artdag-test
  "critical path: chain is its length"
  (artdag/critical-path cost-CHAIN artdag/const-cost)
  4)

(artdag-test
  "critical path: diamond longest path"
  (artdag/critical-path cost-DIA artdag/const-cost)
  3)

(artdag-test
  "total work: unit cost equals node count"
  (artdag/total-work cost-DIA artdag/const-cost)
  4)

(artdag-test
  "single node critical path is its cost"
  (artdag/critical-path
    (artdag/build (list (list "a" "in" (list) {})))
    artdag/const-cost)
  1)

; ---- makespan vs cap ----

(artdag-test
  "full plan makespan equals critical path"
  (artdag/makespan
    cost-DIA
    (artdag/plan cost-DIA 0)
    artdag/const-cost)
  (artdag/critical-path cost-DIA artdag/const-cost))

(artdag-test
  "serial plan makespan equals total work"
  (artdag/makespan
    cost-DIA
    (artdag/plan cost-DIA 1)
    artdag/const-cost)
  (artdag/total-work cost-DIA artdag/const-cost))

(artdag-test
  "capped makespan is never below the critical path"
  (>=
    (artdag/makespan
      cost-DIA
      (artdag/plan cost-DIA 1)
      artdag/const-cost)
    (artdag/critical-path cost-DIA artdag/const-cost))
  true)

; ---- weighted costs ----

(artdag-test
  "weighted critical path follows heavy ops"
  (artdag/critical-path cost-DIA cost-W)
  8)

(artdag-test
  "weighted total work sums all node costs"
  (artdag/total-work cost-DIA cost-W)
  9)

(artdag-test
  "op-cost defaults unknown ops to 1"
  (artdag/total-work
    (artdag/build (list (list "a" "in" (list) {})))
    cost-W)
  1)

(artdag-test
  "weighted full-plan makespan equals critical path"
  (artdag/makespan cost-DIA (artdag/plan cost-DIA 0) cost-W)
  (artdag/critical-path cost-DIA cost-W))

; ---- speedup ----

(artdag-test
  "serial plan has no speedup"
  (artdag/speedup
    cost-DIA
    (artdag/plan cost-DIA 1)
    artdag/const-cost)
  1)

(artdag-test
  "parallel plan beats serial"
  (>
    (artdag/speedup
      cost-DIA
      (artdag/plan cost-DIA 0)
      artdag/const-cost)
    1)
  true)
