[comp.lang.prolog] Delayed Inequality Predicate

ludemann@mlpvm1.iinus1.ibm.com ("Peter Ludemann") (01/26/91)

takahash@rex.cs.tulane.edu (Silvia Takahashi) asks:

> I am looking for a Prolog that implements the inequality
> predicate using delayed evaluation.  ...

As you mentioned, MU-Prolog and IC-Prolog have this.  Others
include:  the NU-Prolog (MU-Prolog's successor), Prolog-II
Prolog-III, Prolog/MALI, and IBM-Prolog (apologies for those
I have missed).

IBM-Prolog provides delayed inequality and "not"; it also provides
a general delay mechanism.  For example, when writing
coroutining predicates, it is often handy to merge two streams
(that is, lists which may not yet be fully instantiated),
delaying until at least one of the streams has its head
instantiated.  For example, we want to handle:

   <- merge(A, B, C) & A = [a|X] & B = [c,d] & X = [b] .

The notation "P when (^var(X) | ^var(Y))" means "wait until
either X or Y is instantiated before calling goal P" (other
Prologs call this "freeze" or "geler"); the notation
"p(notvar$X)" in the head of a clause means "succeed only if X
is not a variable" (yes, Richard, I could have used var/1, etc.).

  merge(In1, In2, Out) <- merge2(In1, In2, Out) when (^var(In1) | ^var(In2)) .

  merge2(notvar$ In1,      In2, Out) <- merge3(In1, In2, Out) .
  merge2(var$ In1, notvar$ In2, Out) <- merge3(In2, In1, Out) .

  merge3([],      In2, In2) .
  merge3([I|In1], In2, [I|Out]) <- merge(In1, In2, Out) .

(This program does not run backwards; to handle that, I would need to
change the first "when" to include ^var(In3), and modify merge2/3.)

- Peter Ludemann    ludemann@mlpvm1.iinus1.ibm.com

lee@munnari.oz.au (Lee Naish) (01/30/91)

In article <9101260626.AA06894@ucbvax.Berkeley.EDU> ludemann@mlpvm1.iinus1.ibm.com writes:
>takahash@rex.cs.tulane.edu (Silvia Takahashi) asks:
>
>> I am looking for a Prolog that implements the inequality
>> predicate using delayed evaluation.  ...
>
>As you mentioned, MU-Prolog and IC-Prolog have this.  Others
>include:  the NU-Prolog (MU-Prolog's successor), Prolog-II
>Prolog-III, Prolog/MALI, and IBM-Prolog

Also Sepia and Sicstus.

One difference between systems is whether quantifiers are supported.
Reasonably often I want to express things such as X is not a cons cell;
in other words, for all H and T, X is not equal to H.T.  This can be
expressed in NU-Prolog as follows:

	all [H,T] X ~= H.T

The implementation limits the scopes of H and T to this call and they
are allowed to be instantated by the unification with X.  The original
dif/2 prediate from Prolog-II (and adopted in several systems) cannot
express this (you can do it by using functor; other more complex cases
need disjunction also).

It is also often desirable to check for equality and return true or
false, rather than fail or succeed (dif and ~= are not flexible enough
for this).  It can be done in NU-Prolog by using termCompare/3 (like
compare/3, but it delays until the terms are sufficiently instantiated).
If-then-else is also treaded specially in NU-Prolog if the condition is
a call to =/2 (possibly with quantifiers).

One final thing which is sometimes nice (but non-logical) is to treat
variables as being quantified (so they are allowed to be instantated by
the unification), without limiting their scope.  This can be done in
NU-Prolog by using gAll instead of all.  One use is meta interpreters:

	solve((all Vars T1 ~= T2)) :- gAll Vars T1 ~= T2.
	...

Here all variables in Vars are treated as being quantified and the scope
of Vars is the whole clause.  There is a paper in the London ICLP, LNCS
225, (1986) discussing the negation facilities of NU-Prolog.

	lee