From ok@atlas.otago.ac.nz Fri Jun  1 02:26:27 2001
Received: from atlas.otago.ac.nz (atlas.otago.ac.nz [139.80.32.250])
	by swi.psy.uva.nl (8.11.2/8.11.2) with ESMTP id f510QO315378
	for <prolog@swi.psy.uva.nl>; Fri, 1 Jun 2001 02:26:26 +0200 (MET DST)
Received: (from ok@localhost)
	by atlas.otago.ac.nz (8.9.3/8.9.3) id MAA494598;
	Fri, 1 Jun 2001 12:26:15 +1200 (NZST)
Date: Fri, 1 Jun 2001 12:26:15 +1200 (NZST)
From: "Richard A. O'Keefe" <ok@atlas.otago.ac.nz>
Message-Id: <200106010026.MAA494598@atlas.otago.ac.nz>
To: jpar@aegean.gr, prolog@swi.psy.uva.nl
Subject: Re:  [SWIPL] constraining the variable domain

Partsakoulakis Ioannis <jpar@aegean.gr> wrote:
	Assume that I have rule
	
	a(X, Y):-
	    b(X, Y),
	    c(X, Y).
	
	and the facts
	
	c(1, 1).
	c(1, 2).
	
	I want by b/2 to declare that X and Y must not be equal and a/2
	to return only the solution {X = 1, Y = 2}.  How can I do this.

In plain Prolog, you can't.
In Mercury, you would write

    :- pred a(int::out, int::out) is nondet.
    a(X, Y) :- b(X, Y), c(X, Y).
    :- pred b(int::in, int::in) is semidet.
    b(X, Y) :- X \= Y.
    :- pred c(int::out, int::out) is multi.
    c(1, 1).
    c(1, 2).

and the compiler would use the mode information to move the call to b/2
after the call to c/2.
In NU Prolog, you would write
    ?- b(X, Y) when ground(X) and ground(Y).
    b(X, Y) :- X =\= Y.
and the call to b/2 would be automatically suspended at run time until
the call to c/2 had bound its arguments.
In a constraint logic programming language, you would write
    b(X, Y) :- X =\= Y.
and let the implementation sort it out at run time.

In short, what you need is for the calls to b/2 and c/2 to be reordered,
which can be done using compile-time information that plain Prolog cannot
express or run-time machinery that plain Prolog doesn't have.

NU Prolog, SICStus prolog, and Eclipse are Prolog systems that can do what
you want.

