In ISO Prolog unification is defined only for those cases that are NSTO (not subject to occurs-check). The idea behind is to cover those cases of unifications that are mostly u
Here goes my attempt:
unify_sto(X,Y):-
unify_with_occurs_check(X,Y) -> true ;
(
term_general(X, XG),
term_general(Y, YG),
\+(unify_sto1(XG,YG)),
throw(error(type_error(acyclic,unify(X,Y)),_))
).
unify_sto1(X, Y):-
unify_with_occurs_check(X,Y).
unify_sto1(X, Y):-
X\=Y.
term_general(X, Y):-
(var(X) -> Y=X ;
(atomic(X) -> Y=_ ;
(
X=..[Functor|L],
term_general1(L, NL),
Y=..[Functor|NL]
))).
term_general1([X|XTail], [Y|YTail]):-
term_general(X, Y),
term_general1(XTail, YTail).
term_general1([], []).
It first tries to unify_with_occurs_check
, and if it does not succeed then it proceed to build a more general term for each argument, then it tries to unify such a term and test to see if it is cyclic. If it is cyclic a type_error
of the kind acyclic is thrown.
E.g:
?- unify_sto(1+A,2+s(A)).
ERROR: Unhandled exception: error(type_error(acyclic,unify(1+_G3620,2+s(_G3620))))