;; ;; Unification ;; - Main program is originally written by Yuichi Nishiwaki ;; - Utity functions are originally written by Momoko Hattori ;; (define $term (matcher {[ integer {[ {i}] [_ {}]}] [ [string (list term)] {[ {[s l]}] [_ {}]}] [ something {[$s (match (unify t s) (maybe something) {[(just $σ) {σ}] [(nothing) {}]})]}] [ [term something] {[$s (subterm s)]}] [$ something {[$tgt {tgt}]}]})) (define $var (lambda [$n] )) (define $app (cambda $xs (match xs (list something) {[ ]}))) (define $occur (pattern-function [$v] (| >>))) (define $fv (match-all-lambda [term] {[(occur $v) v]})) (define $tsubst (match-lambda [something term] {[[$σ ] (match σ (multiset [integer term]) {[ t] [_ ]})] [[$σ ] ]})) (define $unify (match-lambda (unordered-pair term) {[[ ] (Just {})] [[ (& $t !(occur ,x))] (Just {[x t]})] [[> >] (Just {})] [[ ] (unify-list xs ys)] [_ Nothing]})) (define $unify-list (match-lambda [(list term) (list term)] {[[ ] (Just {})] [[ ] (match (unify x y) (maybe something) {[(nothing) Nothing] [(just $σ1) (match (unify-list (map (tsubst σ1 $) xs) (map (tsubst σ1 $) ys)) (maybe something) {[(nothing) Nothing] [(just $σ2) (Just {@σ1 @σ2})]})]})] [_ Nothing]})) ;; ;; Utility for tests ;; ; variables (define $x (var 0)) (define $y (var 1)) (define $z (var 2)) (define $w (var 3)) ; constants (define $a (app "a")) (define $b (app "b")) (define $c (app "c")) (define $d (app "d")) ; function (define $f "f") (define $g "g") (define $h "h") (define $show-σ (lambda [$σ] (S.concat {"{" (show-σ' σ) "}"}))) (define $show-σ' (match-lambda (list [something something]) {[ ""] [> (S.concat {"[" (show-var v) ", " (show-term t) "]"})] [ (S.concat {"[" (show-var v) ", " (show-term t) "], " (show-σ' σ)})]})) (define $show-var (match-lambda integer {[,0 "x"] [,1 "y"] [,2 "z"] [,3 "w"] })) (define $show-term (match-lambda term {[ "x"] [ "y"] [ "z"] [ "w"] [ (S.concat {"x" (show x)})] [ f] [ $x) >>> (S.concat {"(" (show-term x) ") + " (show-term y)})] [>>> (S.concat {(show-term x) " + " (show-term y)})] [ $x) >>> (S.concat {"(" (show-term x) ") * " (show-term y)})] [>>> (S.concat {(show-term x) " * " (show-term y)})] [ (S.concat {f "(" (S.intercalate ", " (map show-term xs)) ")"})] })) ;; ;; Test ;; (show-σ (car (unify (app "+" a b) x))) ; "{[x, a + b]}" (show-σ (car (unify x (app "+" y z)))) ; "{[x, y + z]}" (show-σ (car (unify (app f x (app g y z) (app h x)) (app f a w y)))) ; "{[x, a], [w, g(y, z)], [y, h(a)]}"