Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Date 与和的序言问题;或符号_Date_Prolog_Rule - Fatal编程技术网

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。非常感谢你,谢谢你的建议