Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 40s
Parser reads trailing eq attributes (eq L = R [owise] .) via mau/split-attrs. mau/crewrite-top is two-pass: ordinary equations first, owise last — an owise catch-all fires only when no ordinary equation applies, regardless of declaration order. Verified a catch-all declared first still defers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
165 lines
4.7 KiB
Plaintext
165 lines
4.7 KiB
Plaintext
;; lib/maude/conditional.sx — conditional equations (Phase 4) + owise.
|
|
;;
|
|
;; A condition-aware superset of the Phase 3 reducer. `ceq L = R if COND` fires
|
|
;; only when COND holds under the matching substitution. Conditions come from
|
|
;; the parser as:
|
|
;; {:kind :eq :lhs L :rhs R} — holds iff reduce(s L) =AC= reduce(s R)
|
|
;; {:kind :bool :term T} — holds iff reduce(s T) =AC= true
|
|
;; Condition evaluation recurses through the SAME reducer (mau/cnormalize), so
|
|
;; a ceq whose guard mentions other (possibly conditional) equations Just Works
|
|
;; — termination rests on the guard reducing on structurally smaller arguments
|
|
;; (and the global fuel guard).
|
|
;;
|
|
;; `owise` (otherwise): an equation tagged [owise] fires at a redex only when
|
|
;; NO ordinary equation applies there. crewrite-top is two-pass: ordinary
|
|
;; equations first, owise equations last.
|
|
;;
|
|
;; Single-step firing uses the short-circuiting matcher in fire.sx
|
|
;; (mau/fire-eq). The eager candidate enumeration (mau/eq-candidates) is
|
|
;; retained for `search` (rewrite.sx), which genuinely needs every successor.
|
|
|
|
(define
|
|
mau/ac-candidates
|
|
(fn
|
|
(theory f th eq term)
|
|
(let
|
|
((id (get th :id))
|
|
(pels (mau/flatten-op theory f (get eq :lhs)))
|
|
(sels (mau/flatten-op theory f term)))
|
|
(let
|
|
((matches (if (get th :comm) (mau/match-multiset theory f (mau/append2 pels (list (mau/var "$R" ""))) sels {} id) (mau/match-sequence theory f (mau/append2 (list (mau/var "$L" "")) (mau/append2 pels (list (mau/var "$R" "")))) sels {} id))))
|
|
(map (fn (s) {:s s :result (mau/ac-eq-result theory f th eq s)}) matches)))))
|
|
|
|
(define
|
|
mau/eq-candidates
|
|
(fn
|
|
(theory eq term)
|
|
(let
|
|
((lhs (get eq :lhs)))
|
|
(let
|
|
((th (if (mau/app? lhs) (mau/th-of theory (mau/op lhs)) {:id nil :assoc false :comm false})))
|
|
(if
|
|
(and (mau/app? lhs) (get th :assoc))
|
|
(mau/ac-candidates theory (mau/op lhs) th eq term)
|
|
(map (fn (s) {:s s :result (mau/subst-apply s (get eq :rhs))}) (mau/mm theory lhs term {})))))))
|
|
|
|
(define
|
|
mau/cond-holds?
|
|
(fn
|
|
(theory eqs cond s)
|
|
(if
|
|
(= cond nil)
|
|
true
|
|
(if
|
|
(= (get cond :kind) "eq")
|
|
(mau/ac-equal?
|
|
theory
|
|
(mau/cnormalize
|
|
theory
|
|
eqs
|
|
(mau/subst-apply s (get cond :lhs))
|
|
mau/reduce-fuel)
|
|
(mau/cnormalize
|
|
theory
|
|
eqs
|
|
(mau/subst-apply s (get cond :rhs))
|
|
mau/reduce-fuel))
|
|
(mau/ac-equal?
|
|
theory
|
|
(mau/cnormalize
|
|
theory
|
|
eqs
|
|
(mau/subst-apply s (get cond :term))
|
|
mau/reduce-fuel)
|
|
(mau/const "true"))))))
|
|
|
|
(define
|
|
mau/try-candidates
|
|
(fn
|
|
(theory all-eqs cond term cands)
|
|
(if
|
|
(empty? cands)
|
|
nil
|
|
(let
|
|
((c (first cands)))
|
|
(if
|
|
(and
|
|
(not (mau/ac-equal? theory (get c :result) term))
|
|
(mau/cond-holds? theory all-eqs cond (get c :s)))
|
|
(get c :result)
|
|
(mau/try-candidates theory all-eqs cond term (rest cands)))))))
|
|
|
|
;; ---- owise partitioning ----
|
|
|
|
(define mau/eq-owise? (fn (e) (= (get e :owise) true)))
|
|
(define mau/filter-owise (fn (eqs) (filter mau/eq-owise? eqs)))
|
|
(define
|
|
mau/filter-noowise
|
|
(fn (eqs) (filter (fn (e) (not (mau/eq-owise? e))) eqs)))
|
|
|
|
(define
|
|
mau/crewrite-loop
|
|
(fn
|
|
(theory all-eqs eqs term)
|
|
(if
|
|
(empty? eqs)
|
|
nil
|
|
(let
|
|
((r (mau/fire-eq theory all-eqs (first eqs) term)))
|
|
(if (= r nil) (mau/crewrite-loop theory all-eqs (rest eqs) term) r)))))
|
|
|
|
(define
|
|
mau/crewrite-top
|
|
(fn
|
|
(theory eqs term)
|
|
(let
|
|
((r (mau/crewrite-loop theory eqs (mau/filter-noowise eqs) term)))
|
|
(if
|
|
(= r nil)
|
|
(mau/crewrite-loop theory eqs (mau/filter-owise eqs) term)
|
|
r))))
|
|
|
|
(define
|
|
mau/cnormalize
|
|
(fn
|
|
(theory eqs term fuel)
|
|
(if
|
|
(<= fuel 0)
|
|
term
|
|
(cond
|
|
((mau/var? term) term)
|
|
((mau/app? term)
|
|
(let
|
|
((nargs (map (fn (a) (mau/cnormalize theory eqs a fuel)) (mau/args term))))
|
|
(let
|
|
((t2 (mau/app (mau/op term) nargs)))
|
|
(let
|
|
((r (mau/crewrite-top theory eqs t2)))
|
|
(if
|
|
(= r nil)
|
|
t2
|
|
(mau/cnormalize theory eqs r (- fuel 1)))))))
|
|
(else term)))))
|
|
|
|
(define
|
|
mau/creduce
|
|
(fn
|
|
(m term)
|
|
(mau/cnormalize
|
|
(mau/build-theory m)
|
|
(mau/module-eqs m)
|
|
term
|
|
mau/reduce-fuel)))
|
|
|
|
(define
|
|
mau/creduce-term
|
|
(fn (m src) (mau/creduce m (mau/parse-term-in m src))))
|
|
|
|
(define
|
|
mau/creduce->str
|
|
(fn (m src) (mau/term->str (mau/creduce-term m src))))
|
|
|
|
(define
|
|
mau/ccanon
|
|
(fn (m src) (mau/canon (mau/build-theory m) (mau/creduce-term m src))))
|