Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

(Not) Understanding ->

0 views
Skip to first unread message

Paul Murray

unread,
Sep 30, 2009, 11:12:00 AM9/30/09
to
I'm trying to write a very simple program, and am clearly not understanding
how -> works. (I'm using Eclipse 6.0, but I think this is basic Prolog
question.)

A simple example of what I don't understand:

are_same(C1,C2,V) :- C1 = C2 -> V #= 1 ; V #= 0.

(I realise this isn't a sensible function, but it illustrates my question).

With actual numbers, this works as expected:

?- are_same(1, 1, V).
V = 1
?- are_same(1, 2, V).
V = 0

But the following do not:
?- are_same(X, Y, V).
X = X
Y = X
V = 1
?- are_same(X, Y, 1).
X = X
Y = X
?- are_same(X, Y, 0).
No

I would expect that are_same(X, Y, V) should give me two solutions, but I only
get one, and are_same(X, Y, 0) should be valid. The C1 = C2 seems to have been
interpreted as a fact, with no branching:


If I rewrite this as:

are_same2(C1,C1,1).
are_same2(C1,C2,0) :- C1 #\= C2.

Then I get the answers I expected:

?- are_same2(X, Y, V).
X = X
Y = X
V = 1

X = X{-1.0Inf .. 1.0Inf}
Y = Y{-1.0Inf .. 1.0Inf}
V = 0
There is 1 delayed goal.

?- are_same2(X, Y, 0).
X = X{-1.0Inf .. 1.0Inf}
Y = Y{-1.0Inf .. 1.0Inf}
There is 1 delayed goal.

What have I misunderstood about the workings of ->, and how should I be using
it to get a simple if/then/else construct that works as I expect?

afa

unread,
Sep 30, 2009, 1:41:38 PM9/30/09
to
On Sep 30, 11:12 am, Paul Murray <p...@murray.net> wrote:
> I'm trying to write a very simple program, and am clearly not understanding
> how -> works. (I'm usingEclipse6.0, but I think this is basic Prolog

> question.)
>
> A simple example of what I don't understand:
>
> are_same(C1,C2,V) :- C1 = C2 -> V #= 1 ; V #= 0.
>
Maybe you wanted this:

are_same(C1,C2,V) :- (C1 #= C2) #<=> (V#=1).

Cheers,
Neng-Fa

Chip Eastham

unread,
Sep 30, 2009, 7:57:26 PM9/30/09
to
On Sep 30, 11:12 am, Paul Murray <p...@murray.net> wrote:

My understanding is that the Prolog if/then/else does
not permit backtracking over the logical "if" condition.
Once it's done, the Prolog engine is committed to that
branch (unless backtracking carries you further back
than the if/then/else).

So you will not get two solutions even from are_same(X,Y,V).

[Note that your "if" condition, X = Y, asks to unify X and Y,
which succeeds if both are free, or even if only one of them
is free.]

regards, chip

Joachim Schimpf

unread,
Oct 1, 2009, 1:08:58 AM10/1/09
to
Paul Murray wrote:
> I'm trying to write a very simple program, and am clearly not understanding
> how -> works. (I'm using Eclipse 6.0, but I think this is basic Prolog
> question.)
>
> A simple example of what I don't understand:
>
> are_same(C1,C2,V) :- C1 = C2 -> V #= 1 ; V #= 0.

The problem with -> is that it is one of Prolog's (potentially)
non-declarative features: its result can depend of the order
of execution as in the following example

?- (X = 3 -> writeln(equal) ; writeln(differ)), X = 2.
equal

?- X = 2, (X = 3 -> writeln(equal) ; writeln(differ)).
differ

What it basically says is "if, AT THE TIME OF EXECUTION,
the condition is satisfiable, then commit to the then-branch,
otherwise the else branch". Sadly, if we later obtain further
information which contradicts the condition's satisfiability
(in the example X=2 contradicting X=3), then it's too late
to change the committment made.

So -> has be be used with care. Basically, you should only
use conditions whose truth can be decided once and forever
at the time the if-then-else executes (which is trivially
guaranteed when the condition is variable-free at execution
time, e.g. 3=3). Clearly, this does not hold in your case.


...


> If I rewrite this as:
>
> are_same2(C1,C1,1).
> are_same2(C1,C2,0) :- C1 #\= C2.
>
> Then I get the answers I expected:
>
> ?- are_same2(X, Y, V).
> X = X
> Y = X
> V = 1
>
> X = X{-1.0Inf .. 1.0Inf}
> Y = Y{-1.0Inf .. 1.0Inf}
> V = 0
> There is 1 delayed goal.
>
> ?- are_same2(X, Y, 0).
> X = X{-1.0Inf .. 1.0Inf}
> Y = Y{-1.0Inf .. 1.0Inf}
> There is 1 delayed goal.

Though this is logically correct, it has the disadvantage of
introducing a choice early on in your program: the execution
engine will initially assume (for no good reason) that C1=C2,
and set V=1, and continue with this assumption until it finds
a contradiction. At which point it has to undo everything it
has done since the choice was made, and that can be a lot!

What you want instead is something that magically monitors
the satisfiability of the condition, and reflects this in
your variable V. For simple conditions, this is implemented
in the form of so-called "reified" constraints, which have
an extra boolean argument:

are_same3(C1,C2,V) :- #=(C1,C2,V). % alternative syntax: (C1#=C2) #= V.

?- are_same3(X, Y, V).


X = X{-1.0Inf .. 1.0Inf}
Y = Y{-1.0Inf .. 1.0Inf}

V = V{[0, 1]}


There is 1 delayed goal.

Yes (0.00s cpu)

?- are_same3(X, Y, V), X = 3, Y = 4.
X = 3
Y = 4
V = 0
Yes (0.00s cpu)

As you see, no choice is made initially. Instead, V gets a
domain of [0,1]. Only when enough information about X and Y
materialises later, then V gets set to 0 or 1 respectively.

More complex conditions can either be assembled via logical
combinations of the basic reified constraints, or you have to
resort to ECLiPSe's features for explicitly delaying execution
(see delay clauses, suspend/3 builtin).


-- Joachim

Paul Murray

unread,
Oct 1, 2009, 5:04:50 AM10/1/09
to
Thank you to Neng-Fa, Chip and Joachim for thier replies.
It seems that I missed the following points:
1) (relatively complex) the way -> works with backtracking
2) (relatively simple) that using = rather than #= meant that
my 'if' statement could be matched earlier in a search than I
would have expected.

I hadn't read about reifed constraints, but it seems that I
had basically got there with my third argument are_same2, it
just looked 'wrong' to me, coming from an imperative
background.

I've been reading 'CLP Using Eclipse' by Apy and Wallace, but
haven't really been getting on with it, and it doesn't even
mention the #<=> option discussed. Is there an alternative
book anyone would suggest for someone coming to Prolog from the
CLP direction? I'm not strongly tied to Eclipse, if a different
implementation has other advantanges.

Wit Jakuczun

unread,
Oct 1, 2009, 5:22:37 AM10/1/09
to
On 1 Paź, 11:04, Paul Murray <p...@murray.net> wrote:

> I've been reading 'CLP Using Eclipse' by Apy and Wallace, but
> haven't really been getting on with it, and it doesn't even
> mention the #<=> option discussed. Is there an alternative
> book anyone would suggest for someone coming to Prolog from the
> CLP direction? I'm not strongly tied to Eclipse, if a different
> implementation has other advantanges.

Checkout tutorials by Helmut Simonis: http://4c.ucc.ie/~hsimonis/ELearning/index.htm

Best regards
--
Wit Jakuczun, WLOG Solutions

0 new messages