How does Prolog answer this query?

你。 提交于 2019-12-12 04:07:28

问题


likes(alice, sports).
likes(alice, music).
likes(carol, music).
likes(david,animals).
likes(david,X) :- likes(X,sports).
likes(alice,X) :- likes(david,X).

?- likes(alice,X).

I've been trying to learn prolog an few days now, and when I attempted this question, I realised that I don't completely understand when the variables are instantiated and used. The initial goal is : likes(alice , X). After that, the next goal to prove is likes(david , X)? Then is it likes(X, sports). Then does X become alice?

Another route:

The initial goal is : likes(alice , X). After that, the next goal to prove is likes(david , X)? Then X becomes sports. Then the goal becomes likes(david , sports). Then I don't know.

Could someone please indicate where my thinking is flawed.


回答1:


Given your code Prolog would try to unify the goal against he first fact, likes(alice, sports)., and it would succeed. X would be unified with sports.

If you asked Prolog to continue then it would next unify X with music (the second fact).

And if you continued again it would skip the next three facts/rules, and try to prove likes(alice,X) :- likes(david,X).. This would lead to trying to prove likes(david,X) which succeeds with the fact likes(david,animals) so X, in the original goal, would unify with animals.

And if you asked it to continue again you would find that it tries to prove likes(david,X) :- likes(X,sports). which leads to X unifying with alice, so the original goal would suggest that alice likes alice.

When I ran your code with this goal:

?- likes(alice,X), write(X), nl, fail.

...I got this output:

sports
music
animals
alice
No.

With the final No. being caused because I had the fail predicate in my goal. It was a goal that was always going to fail, but it produced a side-effect by outputting the intermediate result of X.




回答2:


Let's break down the code. First, you have some facts:

likes(alice, sports).    % Alice likes sports
likes(alice, music).     % Alice likes music
likes(carol, music).     % Carol likes music
likes(david, animals).   % David likes animals

Just given these facts, you can make basic queries:

?- likes(alice, sports).   % Does Alice like sports?
true ;
false.  % no more solutions

So, yes, Alice likes sports (the result was true). Does Alice like animals?

?- likes(alice, animals).
false.

Evidently not. At least, according to the data we have, we cannot prove that Alice likes animals. (Remember, we only have the facts so far, but none of the rules, shown below.)

Well then, what does Alice like, according to the facts?

?- likes(alice, X).
X = sports ;
X = music.

Alice likes sports and music.

Now let's add in your rules:

likes(david, X) :- likes(X, sports).

This says that, David likes someone (X) if that someone (X) likes sports.

Let's see who/what David likes:

?- likes(david, X).
X = animals ;
X = alice ;
false  % no more solutions

So David likes animals (because a fact says so), and David likes Alice (because we have a rule that says David likes X if X likes sports, and Alice likes sports).

Your other rule:

likes(alice, X) :- likes(david, X).

Says, Alice likes someone (X) if David likes that same someone (X).

With the new rules added, let's see who/what Alice likes:

?- likes(alice, X).
X = sports ;
X = music ;
X = animals ;
X = alice ;
false

Alice likes sports and music (because the facts say so). Alice likes animals because David likes animals and the rule says that if David likes X, then Alice likes X. Alice also evidently likes herself because, according to the first rule, we showed that David likes Alice. According to the second rule, Alice likes anyone that David likes. Therefore, Alice likes Alice.

You can get the step-by-step execution by running trace. then execute your query.

Note that this is fairly well behaved with these simple rules and facts. In more complex cases you have to be careful about naming your rules and your facts the same way because it can lead to infinite logical loops.



来源:https://stackoverflow.com/questions/36464246/how-does-prolog-answer-this-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!