Reputation: 39
I have a question in prolog here is the code:
sound(time1).
sound(time2).
sun(time3).
relax(X):-
not(sound(X)),
!,
sun(X).
relax(_):-
sun(_).
now I an running - relax(T)
. I get true when I run relax(F)
I get true also. Why does it happen?
and one more question, why relax(time4)
. also gets false? I think I am missing something.
thanks a lot!
Upvotes: 2
Views: 88
Reputation: 476503
The fact that relax(T)
and relax(F)
both give the same result, is normal: uppercase identifiers are variables. So the two queries are semantically the same: you query with an ungrounded variable.
Now why do we get true.
? If you query relax(T)
, Prolog will first call the first clause of relax(X)
.
The first clause has a body that starts with not(sound(X))
. So we actually query not(sound(T))
. Not is satisfied by the negation as finite failure principle: Prolog will aim to "prove" sound(T)
, and if that fails (it cannot find a way to satisfy that query).
So now Prolog queries sound(T)
, and this query is satisfied: indeed, sound(time1)
satisfies this query, since Prolog reasons that now T = time1
. As a result not(sound(T))
is false
, and thus Prolog backtracks.
Now Prolog will try the next clause: relax(_) :- sun(_).
The _
is a "wildcard" or "don't care" variable. Furthermore if you use multiple _
s in the same clause, those are not related. So you basically say: everything is relax/1
, given there is at least one sun/1
. So now Prolog will query for a sun(_)
. This query succeeds: sun(time3)
is a valid candidate, since _ = time3
. So that means that relax(_)
succeeds. We did not alter the variable T
(or F
), so Prolog can only say that the query is true
.
Now if we query relax(time4)
, that's a different story. Again Prolog will first try to satisfy the first clause of relax/1
. This is again done by calling not(sound(time4))
. But note that time4
is a constant. And in Prolog all constants are different: so time1
and time4
cannot unify.
So now Prolog first aims to unify sound(time1)
(first clause for sound/1
) with sound(time4)
, but since time1
and time4
are different, that fails. Next it aims to unify sound(time2)
(second clause of sound/1
) with sound(time4)
, but again no luck. Now there are no clauses of sound/1
anymore. So Prolog gives up and considers not(sound(time4))
to be true.
That means that Prolog will continu in the body of the first clause of relax/1
. The next statement is a !
, that is a "cut" in Prolog. It means that Prolog should, for this branching point - no longer consider the remaining clauses. So it will from now on, ignore the second clause of relax/1
. Next it encounters sun(X)
. So now Prolog will call sun(time4)
and aim to satisfy this. It will aim to unify with the first (and only) clause of sun/1
: sun(time3)
. But as said before, time3
and time4
do not unify. So as a result, that fails. Since Prolog cannot take the second clause of relax/1
(due to the cut (!
)), it thus has exhausted all the options, and decides that the query relax(time4)
is false
.
Upvotes: 2