Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
lib/maude/rewrite.sx: rl/crl transitions interleaved with eq normalisation. mau/rewrite = default strategy (top-down, leftmost-outermost, first rule); mau/rew bounded; mau/search = BFS reachability over all successors. lib/maude/fire.sx: short-circuiting matcher (mau/fire-eq) — finds the first productive match instead of enumerating the whole solution set. Fixes the exponential blowup of AC rewriting on many identical elements (8 coins: 60s+ to <1s). Eager match-multiset kept only for match-all / search. Verified on AC coin-change, traffic light, branching search, crl clock. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
115 lines
3.9 KiB
Plaintext
115 lines
3.9 KiB
Plaintext
;; lib/maude/tests/rewrite.sx — Phase 5: system modules + rewrite rules.
|
|
|
|
(define mrw-pass 0)
|
|
(define mrw-fail 0)
|
|
(define mrw-failures (list))
|
|
|
|
(define
|
|
mrw-check!
|
|
(fn
|
|
(name got expected)
|
|
(if
|
|
(= got expected)
|
|
(set! mrw-pass (+ mrw-pass 1))
|
|
(do
|
|
(set! mrw-fail (+ mrw-fail 1))
|
|
(append!
|
|
mrw-failures
|
|
(str name " expected: " expected " got: " got))))))
|
|
|
|
;; ---- AC multiset transition (the headline: rule on a sub-multiset) ----
|
|
|
|
(define
|
|
mrw-coins
|
|
(mau/parse-module
|
|
"mod COINS is\n sort Marking .\n op nil : -> Marking .\n op q : -> Marking .\n op d : -> Marking .\n op _;_ : Marking Marking -> Marking [assoc comm id: nil] .\n rl [change] : q ; q ; q ; q => d .\nendm"))
|
|
|
|
(mrw-check! "coins-kind" (mau/module-kind mrw-coins) "mod")
|
|
(mrw-check! "coins-rules" (len (mau/module-rules mrw-coins)) 1)
|
|
(mrw-check! "coins-exact" (mau/rewrite-canon mrw-coins "q ; q ; q ; q") "d")
|
|
(mrw-check!
|
|
"coins-5"
|
|
(mau/rewrite-canon mrw-coins "q ; q ; q ; q ; q")
|
|
"_;_(d,q)")
|
|
(mrw-check!
|
|
"coins-8"
|
|
(mau/rewrite-canon mrw-coins "q ; q ; q ; q ; q ; q ; q ; q")
|
|
"_;_(d,d)")
|
|
(mrw-check!
|
|
"coins-3-stuck"
|
|
(mau/rewrite-canon mrw-coins "q ; q ; q")
|
|
"_;_(q,q,q)")
|
|
|
|
;; ---- cyclic state machine (bounded rew) ----
|
|
|
|
(define
|
|
mrw-traffic
|
|
(mau/parse-module
|
|
"mod TRAFFIC is\n sort Light .\n ops red green yellow : -> Light .\n rl [g] : red => green .\n rl [y] : green => yellow .\n rl [r] : yellow => red .\nendm"))
|
|
|
|
(mrw-check! "traffic-1" (mau/rew->str mrw-traffic "red" 1) "green")
|
|
(mrw-check! "traffic-2" (mau/rew->str mrw-traffic "red" 2) "yellow")
|
|
(mrw-check! "traffic-3" (mau/rew->str mrw-traffic "red" 3) "red")
|
|
(mrw-check! "traffic-0" (mau/rew->str mrw-traffic "green" 0) "green")
|
|
|
|
;; ---- nondeterministic branching: rew (one path) vs search (all paths) ----
|
|
|
|
(define
|
|
mrw-ndet
|
|
(mau/parse-module
|
|
"mod NDET is\n sort S .\n ops a b c d goal : -> S .\n rl [r1] : a => b .\n rl [r2] : a => c .\n rl [r3] : b => d .\n rl [r4] : c => goal .\nendm"))
|
|
|
|
;; rew takes the first rule each step: a -> b -> d (stuck), never reaches goal.
|
|
(mrw-check! "ndet-rew-path" (mau/rewrite->str mrw-ndet "a") "d")
|
|
(mrw-check! "ndet-succ" (mau/successors mrw-ndet "a") (list "b" "c"))
|
|
(mrw-check!
|
|
"ndet-search-goal"
|
|
(mau/search mrw-ndet "a" "goal" 5)
|
|
true)
|
|
(mrw-check!
|
|
"ndet-search-shallow"
|
|
(mau/search mrw-ndet "a" "goal" 1)
|
|
false)
|
|
(mrw-check! "ndet-search-self" (mau/search mrw-ndet "a" "a" 3) true)
|
|
(mrw-check! "ndet-search-d" (mau/search mrw-ndet "a" "d" 5) true)
|
|
|
|
;; ---- conditional rule (crl with equational guard) ----
|
|
|
|
(define
|
|
mrw-clock
|
|
(mau/parse-module
|
|
"mod CLOCK is\n sorts Nat Bool .\n op 0 : -> Nat .\n op s_ : Nat -> Nat .\n op true : -> Bool .\n op false : -> Bool .\n op _<_ : Nat Nat -> Bool .\n op clk : Nat -> Nat .\n vars M N : Nat .\n eq 0 < s N = true .\n eq N < 0 = false .\n eq s M < s N = M < N .\n crl [tick] : clk(N) => clk(s N) if N < s s s 0 = true .\nendm"))
|
|
|
|
;; tick fires while N < 3, then stops at clk(3).
|
|
(mrw-check!
|
|
"clock-run"
|
|
(mau/rewrite->str mrw-clock "clk(0)")
|
|
"clk(s_(s_(s_(0))))")
|
|
(mrw-check!
|
|
"clock-from-1"
|
|
(mau/rewrite->str mrw-clock "clk(s 0)")
|
|
"clk(s_(s_(s_(0))))")
|
|
(mrw-check!
|
|
"clock-step1"
|
|
(mau/rew->str mrw-clock "clk(0)" 1)
|
|
"clk(s_(0))")
|
|
|
|
;; ---- eqs interleave with rules ----
|
|
|
|
(define
|
|
mrw-mix
|
|
(mau/parse-module
|
|
"mod MIX is\n sort Nat .\n op 0 : -> Nat .\n op s_ : Nat -> Nat .\n op _+_ : Nat Nat -> Nat .\n op f : Nat -> Nat .\n vars X Y : Nat .\n eq 0 + Y = Y .\n eq s X + Y = s (X + Y) .\n rl [step] : f(X) => f(X + s 0) .\nendm"))
|
|
|
|
;; each rule step adds one (via the rule), eqs normalise the sum.
|
|
(mrw-check!
|
|
"mix-step1"
|
|
(mau/rew->str mrw-mix "f(s 0)" 1)
|
|
"f(s_(s_(0)))")
|
|
(mrw-check!
|
|
"mix-step2"
|
|
(mau/rew->str mrw-mix "f(0)" 2)
|
|
"f(s_(s_(0)))")
|
|
|
|
(define mau-rewrite-tests-run! (fn () {:failures mrw-failures :total (+ mrw-pass mrw-fail) :passed mrw-pass :failed mrw-fail}))
|