Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make prolong understand a connection by other relationship

Tags:

prolog

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 ?

like image 466
Thanasis Namikazee Avatar asked Sep 07 '25 09:09

Thanasis Namikazee


2 Answers

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.

like image 60
Willem Van Onsem Avatar answered Sep 10 '25 08:09

Willem Van Onsem


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.

like image 31
DuDa Avatar answered Sep 10 '25 07:09

DuDa