Date 与和的序言问题;或符号
我有以下几个事实Date 与和的序言问题;或符号,date,prolog,rule,Date,Prolog,Rule,我有以下几个事实 letter(monica, suzane, '2012-02-13'). letter(suzane, janet, '2012-02-14'). letter(suzane, monica, '2012-02-14'). letter(tom, phillip, '2012-02-14'). letter(phillip, suzane, '2012-02-14'). letter(monica, phillip, '2012-02-15'). 我想创建一个规则,返回在指
letter(monica, suzane, '2012-02-13').
letter(suzane, janet, '2012-02-14').
letter(suzane, monica, '2012-02-14').
letter(tom, phillip, '2012-02-14').
letter(phillip, suzane, '2012-02-14').
letter(monica, phillip, '2012-02-15').
我想创建一个规则,返回在指定日期之前与X和Y交换信件的所有人的姓名。例如,如果X是monica,Y是suzane,D是2012-02-16,那么它应该只返回phillip,因为monica和suzane都与phillip交换了一封信
目前我有这个规定,
letterexch(X,Y,D):-
(( ( letter(X, Z, D1); letter(Z, X, D1) ), \+ Z = Y);
( ( letter(Y, Z, D1); letter(Z, Y, D1) ), \+ Z = X)), D1 @<D, nl, print(Z),false.
我得到:
false
phillip
janet
phillip
但如果我使用or符号(;)设置上述规则,并按如下方式查询它:
?- letterexch(monica, suzane, '2012-02-16').
?- letterexch(monica, suzane, '2012-02-16').
我得到:
false
phillip
janet
phillip
然而,我只需要菲利普被打印出来。(我不介意菲利普被复制,因为我知道以后如何摆脱它)
因此,我需要知道为什么当使用and符号(,)时,我会得到false而不是phillip打印两次
任何帮助都将不胜感激
提前谢谢。是“和”还是“或”是一个在上下文中有意义的逻辑问题。在本例中,您的表达式
( letter(X, Z, D1); letter(X, Z, D1) )
应该是
( letter(X, Z, D1); letter(Z, X, D1) )
OR表示如果X
有一个字母指向Z
,或者Z
有一个字母指向X
,则希望表达式成功。如果您使用AND,那么您的意思是,只有当有一个字母在两个方向(X
到Z
和Z
到Y
)时,您才希望它成功。如果这是您真正的意思,那么请使用“and”(,
)
转到更大的表达式:
( ( letter(X, Z, D1); letter(X, Z, D1) ), \+ Z = Y) ;
( ( letter(Y, Z, D1); letter(Y, Z, D1) ), \+ Z = X))
在这种情况下,您实际上是在寻找AND,而不是OR,因为您希望这两组事务同时为真。另一个问题是,您可能不希望在两组交换中规定相同的日期(D1
)。您可能希望将其表示为:
letterexch(X,Y,D):-
(letter(X, Z, D1); letter(Z, X, D1)), % look for exch 'twixt X Z on date D1
(letter(Y, Z, D2); letter(Z, Y, D2)), % look for exch 'twixt Y Z on date D2
\+ Z = Y,
\+ Z = X,
print(Z), nl,
false.
如果运行此操作,您将获得:
| ?- letterexch(monica, suzane, '2012-02-16').
phillip
no
一个解决方案。我确实把D
作为一个单身汉离开了,我把它作为一个练习来决定如何处理D
。
附录 在处理这样的问题时,Prolog最方便的地方是,您可以手动键入这些片段作为调试工具,以了解预期的结果。例如,如果输入:
| ?- (letter(monica, Z, D1); letter(Z, monica, D1)).
D1 = '2012-02-13'
Z = suzane ? a
D1 = '2012-02-15'
Z = phillip
D1 = '2012-02-14'
Z = suzane
(1 ms) no
对于苏珊娜来说,情况也是如此:
| ?- (letter(suzane, Z, D2); letter(Z, suzane, D2)).
D2 = '2012-02-14'
Z = janet ? a
D2 = '2012-02-14'
Z = monica
D2 = '2012-02-13'
Z = monica
D2 = '2012-02-14'
Z = phillip
(1 ms) no
然后将它们结合起来:
| ?- (letter(monica, Z, D1); letter(Z, monica, D1)),
(letter(suzane, Z, D2); letter(Z, suzane, D2)).
D1 = '2012-02-15'
D2 = '2012-02-14'
Z = phillip ? a
你可以看到这些片段组合在一起,并在进行过程中解决问题。是“和”还是“或”是一个逻辑问题,在上下文中是有意义的。在这种情况下,您的表达式
(字母(X,Z,D1);字母(X,Z,D1))
应该是(字母(X,Z,D1);字母(Z,X,D1))
,并且“or”是正确的,除非您希望要求X和Z之间的字母关系是双向的。我在您指出的规则中输入了一个错误。这是我的实际规则:字母exch(X,Y,D):-((字母(X,Z,D1);字母(Z,X,D1)),\+Z=Y;((字母(Y,Z,D1);字母(Z,Y,D1)),\+Z=X)),D1@我也尝试了你告诉我的规则,但它不起作用,它只是给了我false@user3182311,这是因为我从您的原始子句复制的规则声明日期必须始终为D1
。为了解决这个问题,我们需要设置第二条语句的日期D2
,这样它就不会像以前一样强制执行了。请参阅更新。但是你需要决定:你想把D
和什么做比较?我试过你让我做的事情,结果成功了。我想主要的问题是我有两个D1,而不是D1和D2。非常感谢你,谢谢你的建议