[net.lang.prolog] More On Equal

Vijay.Saraswat@CMU-CS-A@sri-unix.UUCP (07/21/83)

I didn't realise my earlier query was still active, otherwise I would 
have posted the solution I found most convenient.  Essentially, as 
Hardy points out it is much better to use Negation as failure rather 
than use ASSERTS and RETRACTS. My solution is :

        equal(X,Y):- \+ eq(X,Y), !, fail.
        equal(X,Y).

        eq(X,Y):-
                numbervars(X,0,P),
                numbervars(Y,0,P),
                !, X == Y.

Clearly this can be generalised to create a 'test' predicate for any 
predicate R, which checks to see if R holds for the given arguments 
without causing any side-effects on the arguments.

        test(R) :- \+ R, !, fail.
        test(R).

If test returns successfully and is redone due to the failure of 
subsequent goals, it fails.  That is as it should be because an
attempt to reprove the same relationship between the same arguments is
absurd.  Another way of saying that is that since test does not
introduce any bindings in the arguments passed to it, it would not
mean anything to redo it.

The use of the "!,fail" sequence is rather unfortunate.  What is
required is a general mechanism to "return" deterministically from a
procedure call, I.e. without saving any choice points so that if the
called procedure is "redone", it will fail.  We clearly need to return
a true or a false value, so that we should have a "treturn" and an
"freturn".

In which case we would rewrite the above as:

        test(R):- (\+ R, freturn ; treturn).

Note that the semantics of freturn is exactly that of "!,fail" so that
any previous sub-goals are not redone. (treturn corresponds to a
"true."  I.e. it causes a return to occur successfully and so it
should be the last subgoal in a procedure.)

Which brings me to a question.  Has anyone studied the relative
abilities of a pattern-match based language such as ICON and Prolog ?
By 'relative abilities' I mean the ease of expressibility of common
programming idioms.  It would certainly seem that much of the thinking
that goes into devising patterns in ICON and in introducing mechanisms
to control back-tracking is quite similar to what one needs to do when
programming in Prolog.  Indeed that is quite obvious because they 
share a common comutational metaphor.  Responses would be appreciated.