artdag: Phase 7 cost-directed opt-improvement/opt-cheaper? + 5 tests
artdag/opt-improvement compares the original output cone (dce to id) vs the maude-reduced DAG under an injected cost-fn, returning before/after total-work and critical-path. opt-cheaper? asserts optimisation never increases cost: the 5-node chain drops to 2 (work 5->2, path 5->2) and stays cheaper under radius-weighted cost (5->3); over dedup and untouched DAGs are never pessimised. Consumes cost.sx. Phase 7 base + (later) cost box done. maude-optimize 38/38, total 196/196. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -186,3 +186,28 @@
|
|||||||
(let
|
(let
|
||||||
((o (artdag/opt-reduce dag id)))
|
((o (artdag/opt-reduce dag id)))
|
||||||
(artdag/opt-last (artdag/dag-order o)))))
|
(artdag/opt-last (artdag/dag-order o)))))
|
||||||
|
|
||||||
|
; ---- cost-directed: the maude-optimised cone never costs more than the original ----
|
||||||
|
; compares the original output cone (dce to id) against the maude-reduced DAG under an
|
||||||
|
; injected cost-fn (op params). Monotone per-node costs => optimisation is never a
|
||||||
|
; pessimisation: fewer nodes (DCE/dedup) and fused ops (one blur(M+N) for two blurs).
|
||||||
|
|
||||||
|
(define
|
||||||
|
artdag/opt-improvement
|
||||||
|
(fn
|
||||||
|
(dag id cost-fn)
|
||||||
|
(let
|
||||||
|
((orig (artdag/dce dag (list id))) (opt (artdag/opt-reduce dag id)))
|
||||||
|
{:before (artdag/total-work orig cost-fn)
|
||||||
|
:after (artdag/total-work opt cost-fn)
|
||||||
|
:before-path (artdag/critical-path orig cost-fn)
|
||||||
|
:after-path (artdag/critical-path opt cost-fn)
|
||||||
|
:optimized opt})))
|
||||||
|
|
||||||
|
(define
|
||||||
|
artdag/opt-cheaper?
|
||||||
|
(fn
|
||||||
|
(dag id cost-fn)
|
||||||
|
(let
|
||||||
|
((imp (artdag/opt-improvement dag id cost-fn)))
|
||||||
|
(<= (get imp :after) (get imp :before)))))
|
||||||
|
|||||||
@@ -10,9 +10,9 @@
|
|||||||
"serialize": {"pass": 13, "fail": 0},
|
"serialize": {"pass": 13, "fail": 0},
|
||||||
"stats": {"pass": 12, "fail": 0},
|
"stats": {"pass": 12, "fail": 0},
|
||||||
"fault": {"pass": 14, "fail": 0},
|
"fault": {"pass": 14, "fail": 0},
|
||||||
"maude-optimize": {"pass": 33, "fail": 0}
|
"maude-optimize": {"pass": 38, "fail": 0}
|
||||||
},
|
},
|
||||||
"total_pass": 191,
|
"total_pass": 196,
|
||||||
"total_fail": 0,
|
"total_fail": 0,
|
||||||
"total": 191
|
"total": 196
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,5 +14,5 @@ _Generated by `lib/artdag/conformance.sh`_
|
|||||||
| serialize | 13 | 0 | 13 |
|
| serialize | 13 | 0 | 13 |
|
||||||
| stats | 12 | 0 | 12 |
|
| stats | 12 | 0 | 12 |
|
||||||
| fault | 14 | 0 | 14 |
|
| fault | 14 | 0 | 14 |
|
||||||
| maude-optimize | 33 | 0 | 33 |
|
| maude-optimize | 38 | 0 | 38 |
|
||||||
| **Total** | **191** | **0** | **191** |
|
| **Total** | **196** | **0** | **196** |
|
||||||
|
|||||||
@@ -268,3 +268,36 @@
|
|||||||
(artdag/node-params
|
(artdag/node-params
|
||||||
(artdag/dag-get mo-plain-opt (artdag/opt-last (artdag/dag-order mo-plain-opt))))
|
(artdag/dag-get mo-plain-opt (artdag/opt-last (artdag/dag-order mo-plain-opt))))
|
||||||
{:radius 3})
|
{:radius 3})
|
||||||
|
|
||||||
|
; ---- cost-directed: optimisation never increases cost ----
|
||||||
|
|
||||||
|
(define
|
||||||
|
mo-rcost
|
||||||
|
(fn (op params) (if (= op "blur") (max 1 (get params :radius)) 1)))
|
||||||
|
|
||||||
|
(artdag-test
|
||||||
|
"opt-improvement: const-cost total work drops on fused chain"
|
||||||
|
(let ((imp (artdag/opt-improvement mo-chain5 mo-chain5-id artdag/const-cost)))
|
||||||
|
(list (get imp :before) (get imp :after)))
|
||||||
|
(list 5 2))
|
||||||
|
|
||||||
|
(artdag-test
|
||||||
|
"opt-improvement: critical path shrinks under const cost"
|
||||||
|
(let ((imp (artdag/opt-improvement mo-chain5 mo-chain5-id artdag/const-cost)))
|
||||||
|
(< (get imp :after-path) (get imp :before-path)))
|
||||||
|
true)
|
||||||
|
|
||||||
|
(artdag-test
|
||||||
|
"opt-cheaper?: fused chain is cheaper under radius-weighted cost"
|
||||||
|
(artdag/opt-cheaper? mo-chain5 mo-chain5-id mo-rcost)
|
||||||
|
true)
|
||||||
|
|
||||||
|
(artdag-test
|
||||||
|
"opt-cheaper?: over dedup is cheaper"
|
||||||
|
(artdag/opt-cheaper? mo-dedup mo-dedup-id artdag/const-cost)
|
||||||
|
true)
|
||||||
|
|
||||||
|
(artdag-test
|
||||||
|
"opt-cheaper?: untouched DAG keeps equal cost (never a pessimisation)"
|
||||||
|
(artdag/opt-cheaper? mo-plain mo-plain-id artdag/const-cost)
|
||||||
|
true)
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ edges.
|
|||||||
|
|
||||||
## Status (rolling)
|
## Status (rolling)
|
||||||
|
|
||||||
`bash lib/artdag/conformance.sh` → **191/191** (11 suites: dag, analyze, plan, execute, optimize, fed, cost, serialize, stats, fault, maude-optimize)
|
`bash lib/artdag/conformance.sh` → **196/196** (11 suites: dag, analyze, plan, execute, optimize, fed, cost, serialize, stats, fault, maude-optimize)
|
||||||
|
|
||||||
Base roadmap (Phases 1–6) COMPLETE. Now extending.
|
Base roadmap (Phases 1–6) COMPLETE. Now extending.
|
||||||
|
|
||||||
@@ -172,7 +172,10 @@ declaratively and prove it equivalent to the hand-written `optimize.sx`.
|
|||||||
needs. API also: `mau/critical-pairs`, `mau/joinable?`.
|
needs. API also: `mau/critical-pairs`, `mau/joinable?`.
|
||||||
- [x] `lib/artdag/tests/maude-optimize.sx` — bridge round-trip, each law,
|
- [x] `lib/artdag/tests/maude-optimize.sx` — bridge round-trip, each law,
|
||||||
result-preserving equivalence, `(mau/confluent? rules-module)` holds (33 tests).
|
result-preserving equivalence, `(mau/confluent? rules-module)` holds (33 tests).
|
||||||
- [ ] (later) cost-directed choice among confluent-equivalent forms; (optional)
|
- [x] cost-directed: `artdag/opt-improvement`/`opt-cheaper?` compare the optimised
|
||||||
|
cone vs the original cone under an injected `cost-fn` — optimisation is never a
|
||||||
|
pessimisation (fewer nodes + fused ops ⇒ total-work and critical-path never
|
||||||
|
increase, under const and radius-weighted costs). (optional, not pursued)
|
||||||
miniKanren scheduling.
|
miniKanren scheduling.
|
||||||
|
|
||||||
maude is a READ-ONLY consumed substrate (like datalog/persist) — load it, don't
|
maude is a READ-ONLY consumed substrate (like datalog/persist) — load it, don't
|
||||||
@@ -188,6 +191,18 @@ be an op token.
|
|||||||
|
|
||||||
## Progress log
|
## Progress log
|
||||||
|
|
||||||
|
- **2026-06-19 Phase 7 — cost-directed: optimisation is never a pessimisation**
|
||||||
|
(maude-optimize 38/38, total 196/196). `artdag/opt-improvement dag id cost-fn` compares
|
||||||
|
the original output cone (`artdag/dce` to `id`) against the maude-reduced DAG under an
|
||||||
|
injected `cost-fn (op params)` — returns `{:before :after :before-path :after-path
|
||||||
|
:optimized}` (total-work + critical-path each side). `artdag/opt-cheaper?` asserts
|
||||||
|
`after <= before`. Under monotone per-node costs the optimised DAG never costs more:
|
||||||
|
the 5-node chain drops to 2 (const work 5→2, critical path 5→2) and stays cheaper under
|
||||||
|
a radius-weighted cost (5→3 — one `blur(M+N)` costs the same as the two it replaces);
|
||||||
|
the `over` dedup and an untouched DAG are both `opt-cheaper?`. Consumes `cost.sx`'s
|
||||||
|
`total-work`/`critical-path`. Phase 7 base + the "(later)" cost box now done; only the
|
||||||
|
optional miniKanren scheduling remains.
|
||||||
|
|
||||||
- **2026-06-19 Phase 7 — opt-reduce: bridge normal form back to a DAG** (maude-optimize
|
- **2026-06-19 Phase 7 — opt-reduce: bridge normal form back to a DAG** (maude-optimize
|
||||||
33/33, total 191/191). `artdag/opt-reduce dag id`: encode the DAG cone at `id` into an
|
33/33, total 191/191). `artdag/opt-reduce dag id`: encode the DAG cone at `id` into an
|
||||||
opt-term (`artdag/dag->opt-term` — leaves→nullary const, `:radius` nodes→`op(inputs…,
|
opt-term (`artdag/dag->opt-term` — leaves→nullary const, `:radius` nodes→`op(inputs…,
|
||||||
|
|||||||
Reference in New Issue
Block a user