Unification in OBJ3
in list
obj SUBST is
sorts Eqn Term .
protecting QID .
subsorts Id < Term .
pr TERMS is (LIST *(sort List to TermList, sort NeList to NeTermList))[Term].
dfn Op is QID .
op _[_] : Op TermList -> Term [prec 1] .
op _=_ : Term Term -> Eqn [comm prec 120] .
pr SYSTEM is (LIST *(sort List to System, sort NeList to NeSystem,
op nil to null, op (__) to (_&_)))[Eqn].
op {_} : System -> System . *** scope delimiter
op _=_ : TermList TermList -> System [comm prec 120] .
vars T U V : Term . var Us : NeTermList .
var S : NeSystem . var Ts : TermList .
eq (T Ts = U Us) = (T = U) & (Ts = Us).
op let_be_in_ : Id Term Term -> Term .
op let_be_in_ : Id Term TermList -> TermList .
op let_be_in_ : Id Term Eqn -> Eqn .
op let_be_in_ : Id Term System -> System .
vars X Y : Id . var F : Op .
eq let X be T in nil = nil .
eq let X be T in Y = if X == Y then T else Y fi .
eq let X be T in F[Ts] = F[let X be T in Ts].
eq let X be T in (U Us) = (let X be T in U) (let X be T in Us).
eq let X be T in (U = V) = (let X be T in U) = (let X be T in V) .
eq let X be T in null = null .
eq let X be T in ((U = V) & S) = (let X be T in (U = V)) & (let X be T in S).
endo
***> first without occur check
obj UNIFY is
using SUBST with SYSTEM and TERMS .
op unify_ : System -> System [prec 120].
op fail : -> Eqn .
var T : Term . vars Ts Us : NeTermList .
vars S S' S'' : System . var X : Id .
eq unify S = {{S}} .
eq S & (T = T) & S' = S & S' .
eq S & fail & S' = fail .
eq let X be T in fail = fail .
eq {null} = null .
eq {fail} = fail .
vars F G : Op . vars X : Id .
eq {S & (F[Ts] = G[Us]) & S'} = if F == G and | Ts | == | Us |
then {S & (Ts = Us) & S'} else fail fi .
eq {S & {S' & (X = T) & S''}} = if X == T then {S & {S' & S''}} else
{(X = T) & (let X be T in S) & {let X be T in S' & S''}} fi .
endo
reduce unify 'f['g['X] 'Y] = 'f['g['h['Y]] 'h['Z]].
reduce unify 'f['X 'Y] = 'f['Y 'g['Y]].
reduce unify ('f['g['X] 'Y] = 'f['g['h['Y]] 'h['Z]]) & ('h['X] = 'Z).
reduce unify 'f['X 'g['Y]] = 'f['Z 'Z].
reduce unify 'f['X 'g['Y]] = 'f['Z].
reduce unify 'f['Y 'g['Y]] = 'f['h['Z] 'Z].
reduce unify 'f['Y 'a[nil]] = 'f['g['a[nil]] 'Z].
***> now add occur check
obj UNIFY-OCH is
using UNIFY .
op _in_ : Id TermList -> Bool .
vars X Y : Id . var F : Op .
var T : Term . var Ts : NeTermList .
eq X in Y = X == Y .
eq X in F[Ts] = X in Ts .
eq X in T Ts = X in T or X in Ts .
cq (X = T) = fail if X in T .
endo
reduce unify 'f['g['X] 'Y] = 'f['g['h['Y]] 'h['Z]].
reduce unify 'f['X 'Y] = 'f['Y 'g['Y]].
reduce unify ('f['g['X] 'Y] = 'f['g['h['Y]] 'h['Z]]) & ('h['X] = 'Z).
reduce unify 'f['X 'g['Y]] = 'f['Z 'Z].
reduce unify 'f['X 'g['Y]] = 'f['Z].
reduce unify 'f['Y 'g['Y]] = 'f['h['Z] 'Z].
reduce unify 'f['Y 'a[nil]] = 'f['g['a[nil]] 'Z].