%---------------------------------------------------------------------------% % vim: ts=4 sw=4 et ft=mercury %---------------------------------------------------------------------------% % The "groundunify.simple" Benchmark Part of the DPPD Library. General Description A ground unification algorithm calculating explicit substitutions which uses built-ins and negation. The program is taken from a Lopstr'92 article by John Gallagher and Andre de Waal. More details about this program can also be found in the technical report CW 210. The benchmark program unify(X, Y, S) :- unify(X, Y, [], S). unify(var(N), T, S, S1) :- bound(var(N), S, B, V), unify(var(N), T, S, S1, B, V). unify(struct(F, Args), var(N), S, S1) :- unify(var(N), struct(F, Args), S, S1). unify(struct(F, Args1), struct(F, Args2), S, S2) :- unifyargs(Args1, Args2, S, S2). unify(var(_), T, S, S1, B, true) :- unify(B, T, S, S1). unify(var(N), T, S, S1, _, false) :- unify1(T, var(N), S, S1). unifyargs([], [], S, S). unifyargs([T | Ts], [R | Rs], S, S2) :- unify(T, R, S, S1), unifyargs(Ts, Rs, S1, S2). unify1(struct(F, Args), var(N), S, [var(N)/struct(F, Args) | S]) :- \+(occur_args(var(N), Args, S)). unify1(var(N), var(N), S, S). unify1(var(M), var(N), S, S1) :- M \== N, bound(var(M), S, B, V), unify1(var(M), var(N), S, S1, B, V). unify1(var(_), var(N), S, S1, B, true) :- unify1(B, var(N), S, S1). unify1(var(M), var(N), S, [var(N)/var(M) | S], _, false). bound(var(N), [var(N)/T | _], T, true) :- T \== var(N). bound(var(N), [B/_ | S], T, F) :- B \== var(N), bound(var(N), S, T, F). bound(var(_), [], _, false). dereference(var(N), [var(N)/T | _], T) :- T \== var(N). dereference(var(N), [B/_ | S], T) :- B \== var(N), dereference(var(N), S, T). occur(var(N), var(M), S) :- dereference(var(M), S, T), occur(var(N), T, S). occur(var(N), var(N), _). occur(var(N), struct(_, Args), S) :- occur_args(var(N), Args, S). occur_args(var(N), [A | _], S) :- occur(var(N), A, S). occur_args(var(N), [_ | As], S) :- occur_args(var(N), As, S). The partial deduction query :- unify(struct(p, [X]), struct(p, [struct(a, [])]), Sub). The run-time queries :- unify(struct(p, [var(1)]), struct(p, [struct(a, [])]), Sub). :- unify(struct(p, [struct(a, [])]), struct(p, [struct(a, [])]), Sub). :- unify(struct(p, [struct(b, [])]), struct(p, [struct(a, [])]), Sub). :- unify(struct(p, [struct(c, [var(1)])]), struct(p, [struct(a, [])]), Sub). :- unify(struct(p, [struct(X, [])]), struct(p, [struct(a, [])]), Sub). Example solution This benchmark can be fully unfolded. With the ECCE partial deduction system one can obtain the following: unify__1(var(X1), ['/'(var(X1), struct(a, []))]). unify__1(struct(a, []), []). _________________________________________________________________ Michael Leuschel / K.U. Leuven / michael@cs.kuleuven.ac.be