开始使用prolog,我正在尝试做一些简单的练习,但是我很早就被卡住了...我想要的是什么''是:迈克喜欢任何人,如果它是一个男人或一个女人,它不是迈克。但X \= mike
似乎被忽略了:
man(mike).
man(danny).
man(samuel).
man(henry).
woman(samantha).
woman(jane).
woman(betty).
woman(jenny).
likes(mike, X) :-
man(X);
woman(X),
X \= mike.
麦克出现了......
?- findall(X, likes(mike, X), L).
L = [mike, danny, samuel, henry, samantha, jane, betty, jenny].
我假设它是因为prolog首先评估规则man(X)
所以迈克是true
。但是,如果我将其更改为:
likes(mike, X) :-
X \= mike,
man(X);
woman(X).
我只会得到女性。
?- findall(X, likes(mike, X), L).
L = [samantha, jane, betty, jenny].
问题是如何做到呢?谢谢!
注意:我正在使用swi-prolog
答案 0 :(得分:2)
问题是运营商优先级。只是C / C#/ Java / SQL和其他过程语言,在Prolog中,逻辑OR(;
)具有与逻辑AND不同的优先级(',' )。
在大多数程序语言中,表达式为
A || B && C
被解析为
A || (B& C)
在Prolog中,像你这样的表达
A ; B , C
解析就像写
一样A ; (B,C)
所以你的
likes(mike, X) :-
man(X);
woman(X),
X \= mike.
基本上是
likes(mike,X) :- man(X) ; ( woman(X) , X \= mike ) .
你断言Mike喜欢
的任何人当你的意思是迈克喜欢任何人 - 男性或女性 - 而不是他自己。
所以......你需要用括号明确优先级,
likes(A,B) :- ( man(B) ; woman(B) ) , A \= B .
或者更好的是,将您的谓词分解为2个子句并使其成为通用的:
likes(A,B) :- man(B) , A \= B .
likes(A,B) :- woman(B) , A \= B .
通过将性别作为实体(一个人)的属性而不是事实本身来改进事物:
person( mike , male ) .
person( danny , male ) .
person( samuel , male ) .
person( henry , male ) .
person( samantha , female ) .
person( jane , female ) .
person( betty , female ) .
person( jenny , female ) .
然后likes/2
更简单,因为人们可以喜欢两种性别的人:
likes(A,B) :- person(B,_) , A \= B .
答案 1 :(得分:1)
问题在于 OR 运算符(; ):
man(mike).
man(danny).
man(samuel).
man(henry).
woman(samantha).
woman(jane).
woman(betty).
woman(jenny).
您的解决方案:
likes(mike, X) :- (man(X);woman(X)),X\=mike.
另一种解决方案(使用等效于OR运算符)可以是:
likes(mike, X) :- man(X), X\=mike.
likes(mike, X) :- woman(X).
请注意,您不需要OR运算符。
答案 2 :(得分:1)
除了OR问题,还有另一个问题。谓词(\ =)/ 2不是约束,意味着它本质上不是完全声明性的谓词。
谓词通常通过否定作为失败来引导,而作为失败本身并不是完全声明的否定。
谓词是从普通统一引导的,如下所示:
X \= Y :- \+ X = Y.
另一种定义是:
X \= X :- !, fail.
_ \= _.
如果你真的希望能够绕过不平等,你应该采用带有约束的Prolog系统,然后求助于dif / 2.
使用dif / 2,您可以写:
likes(mike, X) :-
(dif(X, mike),
man(X)
; woman(X)).
或以下内容:
likes(mike, X) :-
(man(X),
dif(X, mike)
; woman(X)).
你会得到相同的结果。 (\=)/2
无法做到这一点。
再见
P.S。:(\=)/2
出现问题的原因。作为失败的否定\+ A
有时不仅充当~A
,还充当~exists X1,..,Xn A
。感兴趣的读者可能会喜欢勉强通过这个小老,但仍然适用:
具有否定的逻辑程序的证明理论
RobertStärk,伯尔尼,1992年
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.29.2745&rep=rep1&type=pdf