
164 Logic Programming With Prolog
?- unify(person(a,b,c,d),person(a,b,c,f)).
May unify - check whether arguments unify pairwise
yes
To extend this program we need to modify the penultimate compare clause.
We start by adding two additional arguments to predicate compare, so we can pass
the two call terms to it from unify. We then change the penultimate clause of
compare so that when the call terms are both compound terms with the same
functor and arity they are passed to a new predicate unify2, which examines their
arguments pairwise.
unify2 works by converting the two compound terms to lists using univ, then
removing the heads of the lists (the common functor) and passing them to predicate
paircheck/2, which succeeds if and only if the corresponding pairs of list elements
can be unified. The standard Prolog unification is used to check that each pair of
elements can be unified.
unify(CT1,CT2):-
functor(CT1,Funct1,Arity1),
functor(CT2,Funct2,Arity2),
compare(CT1,CT2,Funct1,Arity1,Funct2,Arity2).
compare(CT1,CT2,F,0,F,0). /* Same atom*/
compare(CT1,CT2,F,0,F1,0):-fail. /* Different atoms */
compare(CT1,CT2,F,A,F,A):-unify2(CT1,CT2),!.
compare(CT1,CT2,_,_,_,_):-fail.
unify2(CT1,CT2):-
CT1=..[F|L1],CT2=..[F|L2],!,paircheck(L1,L2).
paircheck([],[]).
paircheck([A|L1],[A|L2]):-paircheck(L1,L2).
?- unify(person(a,b,c,d),person(a,b,X,Y)).
X = c ,
Y = d
?- unify(pred(6,A,[X,Y,[a,b,c]],pred2(p,q)),pred(P1,Q1,L,Z)).
A = Q1 = _ ,
X = _ ,
Y = _ ,
P1 = 6 ,
L = [X,Y,[a,b,c]] ,
Z = pred2(p,q)