artdag: Phase 7 optimisation laws as confluent maude module + 11 tests
lib/artdag/optimize-rules.sx — the effect-pipeline optimisation passes (identity elim, no-op/zero-radius elim, adjacent fusion, idempotent over dedup) as a maude module. Radius algebra is _+_ [assoc comm id: 0] (NOT Peano successor rules, which are non-confluent here); mau/confluent? certifies 0 non-joinable critical pairs, so the optimised pipeline's normal form / content id is rewrite-order stable. Consumes lib/maude/confluence.sx. maude-optimize 25/25, total 183/183. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,13 +35,15 @@ run_suite() {
|
||||
(load "lib/maude/matching.sx")
|
||||
(load "lib/maude/conditional.sx")
|
||||
(load "lib/maude/fire.sx")
|
||||
(load "lib/maude/confluence.sx")
|
||||
(load "lib/maude/rewrite.sx")
|
||||
(load "lib/maude/searchpath.sx")
|
||||
(load "lib/maude/strategy.sx")
|
||||
(load "lib/maude/meta.sx")
|
||||
(load "lib/maude/pretty.sx")
|
||||
(load "lib/maude/run.sx")'
|
||||
BRIDGE_LOAD='(load "lib/artdag/maude-bridge.sx")'
|
||||
BRIDGE_LOAD='(load "lib/artdag/maude-bridge.sx")
|
||||
(load "lib/artdag/optimize-rules.sx")'
|
||||
fi
|
||||
cat > "$TMP" << EPOCHS
|
||||
(epoch 1)
|
||||
|
||||
69
lib/artdag/optimize-rules.sx
Normal file
69
lib/artdag/optimize-rules.sx
Normal file
@@ -0,0 +1,69 @@
|
||||
; lib/artdag/optimize-rules.sx — Phase 7: optimisation laws as a confluent maude module.
|
||||
; The optimised effect pipeline IS the normal form of the rule set, so confluence
|
||||
; (mau/confluent?) is exactly content-id stability: every rewrite order reaches the
|
||||
; same normal form. Media ops (blur/bright/id/over) are the opaque-op model from
|
||||
; lib/maude/tests/effects.sx — the engine reasons about the pipeline algebra, never
|
||||
; pixels. The radius algebra is an AC operator with identity 0 (unary 1s): Peano
|
||||
; successor rules (s M + N = s(M+N), 0 + N = N) are NOT confluent here (the symbolic
|
||||
; critical pairs M + 0 and (A+B)+C vs A+(B+C) stick), whereas [assoc comm id: 0]
|
||||
; joins them via canonical form. maude (lib/maude) is a READ-ONLY consumed substrate:
|
||||
; mau/parse-module, mau/creduce-term, mau/creduce->str, mau/ccanon, mau/confluent?,
|
||||
; mau/non-joinable-pairs, mau/cp->str.
|
||||
|
||||
(define
|
||||
artdag/opt-module-src
|
||||
(str
|
||||
"fmod ARTDAGOPT is\n"
|
||||
" sorts Img Num .\n"
|
||||
" op 0 : -> Num .\n"
|
||||
" op 1 : -> Num .\n"
|
||||
" op _+_ : Num Num -> Num [assoc comm id: 0] .\n"
|
||||
" op blur : Img Num -> Img .\n"
|
||||
" op bright : Img Num -> Img .\n"
|
||||
" op id : Img -> Img .\n"
|
||||
" op over : Img Img -> Img [comm] .\n"
|
||||
" vars I J : Img .\n"
|
||||
" vars M N : Num .\n"
|
||||
" eq id(I) = I .\n"
|
||||
" eq blur(I, 0) = I .\n"
|
||||
" eq bright(I, 0) = I .\n"
|
||||
" eq blur(blur(I, M), N) = blur(I, M + N) .\n"
|
||||
" eq bright(bright(I, M), N) = bright(I, M + N) .\n"
|
||||
" eq over(I, I) = I .\n"
|
||||
"endfm"))
|
||||
|
||||
(define artdag/opt-module (mau/parse-module artdag/opt-module-src))
|
||||
|
||||
; ---- reduce a surface pipeline to its optimised normal form ----
|
||||
|
||||
(define
|
||||
artdag/opt-reduce-term
|
||||
(fn (src) (mau/creduce-term artdag/opt-module src)))
|
||||
|
||||
(define
|
||||
artdag/opt-normal-form
|
||||
(fn (src) (mau/creduce->str artdag/opt-module src)))
|
||||
|
||||
(define artdag/opt-canon (fn (src) (mau/ccanon artdag/opt-module src)))
|
||||
|
||||
; two surface pipelines optimise to the same pipeline (=> same content id) iff
|
||||
; their normal forms coincide.
|
||||
(define
|
||||
artdag/opt-same-form?
|
||||
(fn (a b) (= (artdag/opt-normal-form a) (artdag/opt-normal-form b))))
|
||||
|
||||
; ---- confluence / content-id stability (consume lib/maude/confluence.sx) ----
|
||||
|
||||
(define artdag/opt-confluent? (fn () (mau/confluent? artdag/opt-module)))
|
||||
|
||||
(define
|
||||
artdag/opt-non-joinable
|
||||
(fn () (mau/non-joinable-pairs artdag/opt-module)))
|
||||
|
||||
(define
|
||||
artdag/opt-non-joinable->strs
|
||||
(fn
|
||||
()
|
||||
(map
|
||||
(fn (cp) (mau/cp->str artdag/opt-module cp))
|
||||
(artdag/opt-non-joinable))))
|
||||
@@ -10,9 +10,9 @@
|
||||
"serialize": {"pass": 13, "fail": 0},
|
||||
"stats": {"pass": 12, "fail": 0},
|
||||
"fault": {"pass": 14, "fail": 0},
|
||||
"maude-optimize": {"pass": 14, "fail": 0}
|
||||
"maude-optimize": {"pass": 25, "fail": 0}
|
||||
},
|
||||
"total_pass": 172,
|
||||
"total_pass": 183,
|
||||
"total_fail": 0,
|
||||
"total": 172
|
||||
"total": 183
|
||||
}
|
||||
|
||||
@@ -14,5 +14,5 @@ _Generated by `lib/artdag/conformance.sh`_
|
||||
| serialize | 13 | 0 | 13 |
|
||||
| stats | 12 | 0 | 12 |
|
||||
| fault | 14 | 0 | 14 |
|
||||
| maude-optimize | 14 | 0 | 14 |
|
||||
| **Total** | **172** | **0** | **172** |
|
||||
| maude-optimize | 25 | 0 | 25 |
|
||||
| **Total** | **183** | **0** | **183** |
|
||||
|
||||
@@ -110,3 +110,60 @@
|
||||
(artdag/dag-id mo-diamond "a")
|
||||
(keys (artdag/dag-nodes mo-diamond-rt)))
|
||||
true)
|
||||
|
||||
; ---- optimisation laws as a confluent maude module (optimize-rules.sx) ----
|
||||
; The optimised pipeline is the normal form; confluence => stable content id.
|
||||
|
||||
(artdag-test "opt module is confluent" (artdag/opt-confluent?) true)
|
||||
|
||||
(artdag-test
|
||||
"opt module has no non-joinable critical pairs"
|
||||
(len (artdag/opt-non-joinable))
|
||||
0)
|
||||
|
||||
(artdag-test
|
||||
"law: identity elimination"
|
||||
(artdag/opt-normal-form "id(src)")
|
||||
"src")
|
||||
|
||||
(artdag-test
|
||||
"law: zero-radius blur is a no-op"
|
||||
(artdag/opt-normal-form "blur(src, 0)")
|
||||
"src")
|
||||
|
||||
(artdag-test
|
||||
"law: zero-radius bright is a no-op"
|
||||
(artdag/opt-normal-form "bright(src, 0)")
|
||||
"src")
|
||||
|
||||
(artdag-test
|
||||
"law: adjacent blur fusion adds radii"
|
||||
(artdag/opt-normal-form "blur(blur(src, 1), 1)")
|
||||
"blur(src, _+_(1, 1))")
|
||||
|
||||
(artdag-test
|
||||
"fusion normal form is rewrite-order stable"
|
||||
(artdag/opt-same-form?
|
||||
"blur(blur(blur(src, 1), 1), 1)"
|
||||
"blur(blur(src, 1 + 1), 1)")
|
||||
true)
|
||||
|
||||
(artdag-test
|
||||
"laws compose: id + no-op + fusion"
|
||||
(artdag/opt-normal-form "bright(id(blur(blur(src, 1), 1)), 0)")
|
||||
"blur(src, _+_(1, 1))")
|
||||
|
||||
(artdag-test
|
||||
"law: idempotent over dedup (CSE)"
|
||||
(artdag/opt-normal-form "over(blur(src, 1), blur(src, 1))")
|
||||
"blur(src, 1)")
|
||||
|
||||
(artdag-test
|
||||
"distinct over operands do not dedup"
|
||||
(artdag/opt-same-form? "over(blur(src, 1), blur(src, 1 + 1))" "blur(src, 1)")
|
||||
false)
|
||||
|
||||
(artdag-test
|
||||
"distinct pipelines stay distinct"
|
||||
(artdag/opt-same-form? "blur(src, 1)" "bright(src, 1)")
|
||||
false)
|
||||
|
||||
Reference in New Issue
Block a user