Subject: Re: [SWIPL] constraining the variable domain

From: "Richard A. O'Keefe" <[email-masked]>
Date: Fri, 1 Jun 2001 12:26:15 +1200 (NZST)

Partsakoulakis Ioannis <[email-masked]> 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.