Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 47s
The chisel. lib/maude/matching.sx: multi-valued matcher mau/mm returning ALL substitutions, dispatching on op theory (free/comm/assoc/AC). Identity lets variables grab empty blocks. AC-canonical form (mau/canon) powers ac-equal? and deterministic printout. AC rewriting extends f-AC equations with rest vars so a rule fires on any sub-multiset/subword; mau/first-change only commits rewrites that change the canonical form (idempotency/identity terminate). Verified on multiset rewriting, set theory, group equations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
171 lines
5.2 KiB
Plaintext
171 lines
5.2 KiB
Plaintext
;; lib/maude/tests/matching.sx — Phase 3: matching modulo assoc/comm/id.
|
|
|
|
(define mmt-pass 0)
|
|
(define mmt-fail 0)
|
|
(define mmt-failures (list))
|
|
|
|
(define
|
|
mmt-check!
|
|
(fn
|
|
(name got expected)
|
|
(if
|
|
(= got expected)
|
|
(set! mmt-pass (+ mmt-pass 1))
|
|
(do
|
|
(set! mmt-fail (+ mmt-fail 1))
|
|
(append!
|
|
mmt-failures
|
|
(str name " expected: " expected " got: " got))))))
|
|
|
|
;; ---- multi-valued matching enumeration ----
|
|
|
|
(define
|
|
mmt-acg
|
|
(mau/parse-module
|
|
"fmod ACG is\n sort S .\n op a : -> S .\n op b : -> S .\n op c : -> S .\n op _+_ : S S -> S [assoc comm] .\n op _._ : S S -> S [assoc] .\n vars X Y : S .\nendfm"))
|
|
|
|
;; X + Y against a + b + c (AC, no id): 6 solutions (each non-empty 2-split).
|
|
(mmt-check!
|
|
"ac-match-count"
|
|
(len
|
|
(mau/match-all
|
|
mmt-acg
|
|
(mau/parse-term-in mmt-acg "X + Y")
|
|
(mau/parse-term-in mmt-acg "a + b + c")))
|
|
6)
|
|
;; X + a against a + b + c: X must be b + c (one solution, multiset).
|
|
(mmt-check!
|
|
"ac-match-partial"
|
|
(len
|
|
(mau/match-all
|
|
mmt-acg
|
|
(mau/parse-term-in mmt-acg "X + a")
|
|
(mau/parse-term-in mmt-acg "a + b + c")))
|
|
1)
|
|
;; assoc-only X . Y against a . b . c: ordered 2-splits -> 2 solutions.
|
|
(mmt-check!
|
|
"assoc-match-count"
|
|
(len
|
|
(mau/match-all
|
|
mmt-acg
|
|
(mau/parse-term-in mmt-acg "X . Y")
|
|
(mau/parse-term-in mmt-acg "a . b . c")))
|
|
2)
|
|
;; no match: a + a pattern against a + b
|
|
(mmt-check!
|
|
"ac-no-match"
|
|
(len
|
|
(mau/match-all
|
|
mmt-acg
|
|
(mau/parse-term-in mmt-acg "a + a")
|
|
(mau/parse-term-in mmt-acg "a + b")))
|
|
0)
|
|
|
|
;; ---- comm (non-assoc) matching ----
|
|
|
|
(define
|
|
mmt-pair
|
|
(mau/parse-module
|
|
"fmod PAIR is\n sort S .\n op a : -> S .\n op b : -> S .\n op p : S S -> S [comm] .\n op fst : S -> S .\n vars X Y : S .\n eq fst(p(X, a)) = X .\nendfm"))
|
|
|
|
(mmt-check!
|
|
"comm-both-orders"
|
|
(mau/ac-reduce->str mmt-pair "fst(p(b, a))")
|
|
"b")
|
|
(mmt-check! "comm-swapped" (mau/ac-reduce->str mmt-pair "fst(p(a, b))") "b")
|
|
|
|
;; ---- identity ----
|
|
|
|
(define
|
|
mmt-id
|
|
(mau/parse-module
|
|
"fmod IDMOD is\n sort S .\n op a : -> S .\n op b : -> S .\n op e : -> S .\n op _*_ : S S -> S [assoc comm id: e] .\n vars X Y : S .\nendfm"))
|
|
|
|
(mmt-check! "id-drop" (mau/ac-canon mmt-id "a * e") "a")
|
|
(mmt-check! "id-drop-mid" (mau/ac-canon mmt-id "a * e * b") "_*_(a,b)")
|
|
(mmt-check! "id-only" (mau/ac-canon mmt-id "e * e") "e")
|
|
;; with id, X * Y matching a (singleton) succeeds (one var empty)
|
|
(mmt-check!
|
|
"id-match-singleton"
|
|
(>
|
|
(len
|
|
(mau/match-all
|
|
mmt-id
|
|
(mau/parse-term-in mmt-id "X * Y")
|
|
(mau/parse-term-in mmt-id "a")))
|
|
0)
|
|
true)
|
|
|
|
;; ---- multiset / bag rewriting ----
|
|
|
|
(define
|
|
mmt-bag
|
|
(mau/parse-module
|
|
"fmod BAG is\n sort S .\n op a : -> S .\n op b : -> S .\n op c : -> S .\n op _+_ : S S -> S [assoc comm] .\n eq a + a = a .\nendfm"))
|
|
|
|
(mmt-check! "bag-collapse" (mau/ac-canon mmt-bag "a + b + a") "_+_(a,b)")
|
|
(mmt-check! "bag-deep" (mau/ac-canon mmt-bag "a + a + a") "a")
|
|
(mmt-check! "bag-reorder" (mau/ac-canon mmt-bag "c + a + b + a") "_+_(a,b,c)")
|
|
(mmt-check!
|
|
"bag-flatten-assoc"
|
|
(mau/ac-canon mmt-bag "(a + b) + (a + c)")
|
|
"_+_(a,b,c)")
|
|
|
|
;; ---- set theory: idempotent union with empty (identity) ----
|
|
|
|
(define
|
|
mmt-set
|
|
(mau/parse-module
|
|
"fmod SET is\n sort Set .\n op empty : -> Set .\n op a : -> Set .\n op b : -> Set .\n op c : -> Set .\n op _U_ : Set Set -> Set [assoc comm id: empty] .\n var X : Set .\n eq X U X = X .\nendfm"))
|
|
|
|
(mmt-check! "set-dedup" (mau/ac-canon mmt-set "a U b U a") "_U_(a,b)")
|
|
(mmt-check! "set-triple" (mau/ac-canon mmt-set "a U a U a") "a")
|
|
(mmt-check!
|
|
"set-union"
|
|
(mau/ac-canon mmt-set "a U b U c U a U b")
|
|
"_U_(a,b,c)")
|
|
(mmt-check! "set-empty" (mau/ac-canon mmt-set "a U empty") "a")
|
|
(mmt-check! "set-empty-only" (mau/ac-canon mmt-set "empty U empty") "empty")
|
|
|
|
;; ---- group equations (assoc, non-comm, identity + inverse) ----
|
|
|
|
(define
|
|
mmt-group
|
|
(mau/parse-module
|
|
"fmod GROUP is\n sort G .\n op e : -> G .\n op a : -> G .\n op b : -> G .\n op _*_ : G G -> G [assoc] .\n op i : G -> G .\n var X : G .\n eq e * X = X .\n eq X * e = X .\n eq i(X) * X = e .\n eq X * i(X) = e .\n eq i(e) = e .\n eq i(i(X)) = X .\nendfm"))
|
|
|
|
(mmt-check! "group-inverse" (mau/ac-canon mmt-group "i(a) * a") "e")
|
|
(mmt-check! "group-cancel" (mau/ac-canon mmt-group "i(a) * a * b") "b")
|
|
(mmt-check! "group-cancel-mid" (mau/ac-canon mmt-group "b * i(a) * a") "b")
|
|
(mmt-check! "group-double-inv" (mau/ac-canon mmt-group "i(i(a))") "a")
|
|
(mmt-check! "group-id-left" (mau/ac-canon mmt-group "e * a") "a")
|
|
(mmt-check! "group-right-inv" (mau/ac-canon mmt-group "a * i(a) * b") "b")
|
|
|
|
;; ---- AC equality (canonical form) ----
|
|
|
|
(define mmt-th (mau/build-theory mmt-acg))
|
|
|
|
(mmt-check!
|
|
"ac-equal-reorder"
|
|
(mau/ac-equal?
|
|
mmt-th
|
|
(mau/parse-term-in mmt-acg "a + b + c")
|
|
(mau/parse-term-in mmt-acg "c + a + b"))
|
|
true)
|
|
(mmt-check!
|
|
"ac-equal-renest"
|
|
(mau/ac-equal?
|
|
mmt-th
|
|
(mau/parse-term-in mmt-acg "(a + b) + c")
|
|
(mau/parse-term-in mmt-acg "a + (b + c)"))
|
|
true)
|
|
(mmt-check!
|
|
"ac-noncomm-order"
|
|
(mau/ac-equal?
|
|
mmt-th
|
|
(mau/parse-term-in mmt-acg "a . b")
|
|
(mau/parse-term-in mmt-acg "b . a"))
|
|
false)
|
|
|
|
(define mau-matching-tests-run! (fn () {:failures mmt-failures :total (+ mmt-pass mmt-fail) :passed mmt-pass :failed mmt-fail}))
|