Newsgroups: comp.lang.prolog
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel!delmarva.com!newsfeed.internetmci.com!news.mathworks.com!zombie.ncsc.mil!simtel!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!marlin.jcu.edu.au!geoff
From: geoff@cs.jcu.edu.au (Geoff Sutcliffe)
Subject: Re: Q: Write my own occurs check?
Message-ID: <geoff.810164749@coral.cs.jcu.edu.au>
Sender: news@marlin.jcu.edu.au (USENET News System)
Organization: James Cook University
References: <fry.808374087@Csli.Stanford.EDU> <fry.808481070@Csli.Stanford.EDU> <9522913.25982@mulga.cs.mu.OZ.AU>
Date:  3 Sep 95 21:45:49 GMT
Lines: 82

>fry@Csli.Stanford.EDU (John Fry) writes:

>>My question is, is there some way to do my own occurs check?
>>I'm using Sicstus 2.1 for Sparc...

Here's my article which appeared in the Association for Automated
Reasoning newsletter ...

Implementing Sound Unification in Prolog
----------------------------------------

Geoff Sutcliffe, Department of Computer Science, James Cook University
geoff@cs.jcu.edu.au

Prolog is a convenient language in which to implement ATP systems for
1st order logic, because the formulae to be manipulated can be represented
directly as Prolog terms. In the logic programming community there is
some debate as to the desirability of using Prolog variables to represent
the logic variables in that data, but doing so does make life easy in
many respects. Given this approach, sound unification (i.e., with occurs
check) of Prolog terms is required for implementing ATP inference operations.
Some Prolog implementations now provide sound unification directly, and
the problem is solved. In other cases, sound unification is still a 
procedure that ATP implementors have to code up. I have played with
various Prolog implementations of sound unification. Below is the most
elegant version I have come up with (the most elegant is not necessarily 
the fastest, but Prolog programmers know that "elegance is not optional").
I would be interested to hear of anything neater!

%----------------------------------------------------------------------
%----Identical things unify. This is a short cut, and also used by pairs
%----of empty lists.
unify(Term1,Term2):-
    Term1 == Term2,
    !.

%----There's a variable about
unify(Variable,Term):-
    var(Variable),
    !,
%----Do occurs check
%----Copy the term. This should be replaced by a built in copy_term/2, if
%----available, because asserting and retracting is slow.
    asserta(saved_term(Term)),
    retract(saved_term(TermCopy)),
%----Count how many variables in the copy
    numbervars(TermCopy,0,NumberOfVariables),
    \+ \+ (
%----Instantiate the variable
        Variable = dummy_value_no_one_will_use,
%----Make sure the original has the same number of variables still. If it
%----doesn't then the Term contains the variable.
        numbervars(Term,0,NumberOfVariables)
        ),
    Variable = Term.

unify(Term,Variable):-
    var(Variable),
    !,
    unify(Variable,Term).

%----Lists of terms
unify([H1|T1],[H2|T2]):-
    !,
    unify(H1,H2),
    unify(T1,T2).

%----Functions
unify(Function1,Function2):-
    Function1 =.. [Functor|Arguments1],
    Function2 =.. [Functor|Arguments2],
    unify(Arguments1,Arguments2).
%----------------------------------------------------------------------

Cheers,

Geoff
--
Geoff Sutcliffe
Department of Computer Science    Email : geoff@cs.jcu.edu.au
James Cook University             Phone : +61 77 815085/814622
Townsville, Australia, 4811.      FAX   : +61 77 814029
