;; 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}))