My DataBase =>
fact(a).
fact(b).
likes(a, rain).
likes(a, snow).
likes(b, X) :- not(likes(a, X)).
human(X) :-
not(likes(X, rain)),
fact(X).
alien(X) :-
likes(X, snow),
fact(X).
Prolog question =>
?- human(X)
no
The logic here is
likes(a, rain),
so by rule
not(likes(b, rain)) is True AND fact(b) is True
human(b) is No
human(X) is No
Should be Yes but it doesnt make the connection
How can I make with prolong this check so it understands that it should return b ?
A lowercase x
is a constant, so it looks for not(likes(x, rain))
, which indeed holds, but fact(x)
does not hold since there is no clause fact(x)
, only for a
and b
.
As for human(X)
(so as a variable), not(likes(X, rain))
will not succeed, since there is an X
that likes rain: a
likes rain, hence likes(X, rain)
can be unfied, and therefore not(likes(X, rain))
fails. The fact that there is a b
that does not like rain, is not relevant. Negation in Prolog is not constructive, it is implemented as finite failure: something is not true if all attempts to proof that it is true fail and these attempts are finite (otherwise we get stuck in an infinite loop).
You can however swap the fact(X)
and not(likes(X, rain))
clauses:
human(X) :-
fact(X),
\+ likes(X, rain).
If you then call human(X)
, it will succeed with X = b
. This works since it will first unify X
with a
, but that will fail for the \+ likes(a, rain)
clause, but then it will retry by unfying X
with b
, and this will succeed.
I just altered the order of the predicate and it seems to work know:
human(X) :-
fact(X),
\+ likes(X, rain).
?- human(X).
X = b.
The reason behind this is that before unification of X
you ask for likes(X, rain)
and you want it to be false. So prolog searches for likes(X, rain)
, finds likes(a, rain)
returns true, negates it and will therefore fail. Resolve the issue by adressing fact(X)
first, so it will ask for this particular X
and not just any value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With