	/****** Composition of two substitutions   ******/
	/*         (illustrates univ and sets)          */

mode none.
closure none.

compose(phi, Theta2)     equals Theta2.
compose(Theta1, phi)     equals Theta1.
compose(Theta1, Theta2)  equals merge_subst(compose2(Theta1,Theta2), Theta2).

	compose2({[X|T] \_}, Theta2) contains check(X,subst(Theta2,T)).

		subst(phi,T) equals T.
		subst({[V|T2] \ Theta},T) equals subst(Theta,subst(T,V,T2)).

		subst(univ(F,L),V,T2) equals univ(F,subst_list(L,V,T2)).
		subst({X\Y},V,T2)     equals {subst(X,V,T2)\subst(Y,V,T2)}.
		subst(V,V,T2)  equals T2.  /* matching var case */
		subst(W,_,_)   equals W.   /* const and nonmatching var case */

			subst_list([],_,_)     equals [].
			subst_list([H|T],V,T2) equals [subst(H,V,T2)
							| subst_list(T,V,T2)]. 

		check(X,X) equals phi.
		check(X,Y) equals {[X|Y]}.


	merge_subst(Theta1,  _)           contains   Theta1.
	merge_subst(Theta1, {[X|T2] \_})  contains   if domain_mem(X, Theta1) 
							then phi else {[X|T2]}.

		domain_mem(X, {[X|T2] \_})   equals true.
		domain_mem(X, _)             equals false.


/*** Typical Goals and Results:

compose({[a|[x,y]], [b|[y,x]]}, {[x|1],[y|2],[a|3],[b|4],[c|5]}).
{[a,1,2],[b,2,1],[x|1],[y|2],[c|5]}

compose( {[x|f(y)],[x2|g(y2)]}, {[y|f2(10)],[y2|g2(20,30)],[x|1]}).
{[x|f(f2(10))],[x2|g(g2(20, 30))],[y|f2(10)],[y2|g2(20, 30)]}

compose( {[x|y]}, {[y|x]}).
{[y|x]}

compose({[a|{f(x),g(3,{y})}]}, {[x|1],[y|2]}).
{[a|{f(1),g(1, {2})}],[x|1],[y|2]}

****/
