【问题标题】:Prolog - Issue using math operatorsProlog - 使用数学运算符的问题
【发布时间】:2016-11-23 11:55:41
【问题描述】:

我有一套规则,包括:

family(Mother,Father,Children),其中 children 是一个列表(例如 [ag,bg])和 person/6。日期是人,设置为日、月、年。

我想说的是,如果两个孩子不是同一天或连续天出生的,那一定是相隔一年。 我已经在这工作了几个小时,但似乎无法到达任何地方,下面是我的代码,我个人不明白为什么它不起作用。 任何建议将不胜感激。

bad_children() :-
      family(_,_,Q),
      member(J,Q),
      member(T,Q),
      person(J,_,_,_,date(E,M,Y),place(_,_)),
      person(T,_,_,_,date(F,M,K),place(_,_)),
      ( E \= F ; E \= (F+1) ; E \= (F-1) ),
      (Y-K) < 1
   ;  (K-Y) < 1,
      write(J),
      write(' and '),
      write(T),
      write(' are born to close together.').

【问题讨论】:

    标签: prolog


    【解决方案1】:

    主要的错误是关于运算符 (\=)/2。它确实表示don't unify,并且它不执行算术评估。

    此外,您应该将析取词 (Y-K) &lt; 1 ; (K-Y) &lt; 1 括起来。

    因此,(未经测试的)代码可能是

    bad_children :-
     family(_,_,Q),
     member(person(J,_,_,_,date(E,M,Y),_),Q), % You're not interested in place/2
     member(person(T,_,_,_,date(F,M,K),_),Q),
     J \= T, % Regardless the date, you should check the identity. Here \= is fine
     (E =\= F; E =\= F+1; E =\= F-1),
     (Y-K < 1 ; K-Y < 1),
     format('~w and ~w are born to close together.', [J, T]).
    

    【讨论】:

    • 感谢您的帮助,正确的输出正在打印,但它打印了 3 次答案,您知道为什么会发生这种情况吗?
    • 很可能是因为有多个匹配项。也许您可以将我发布的关于身份的条件更改为J @&lt; T。我有兴趣向您展示\= 可以适当使用的地方,但我的选择有点不幸。
    • 我忘了在J和T之间使用\=,看到trace结果后我才意识到我应该使用它。我很抱歉地问,但我已经看到应该进入几个月,并且看到它们是否相隔不到一年,所以仅仅评估一年是行不通的。您对如何解决这个问题有什么建议吗?
    • 我认为你应该做你的计算。最好编写一个单独的谓词,当您将 date/3 参数传递给它时,该谓词评估为真。 SWI-Prolog 中的时间/日期处理(就像我所知道的任何其他语言一样)可能非常复杂,不值得这个用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    • 2014-11-07
    • 1970-01-01
    相关资源
    最近更新 更多