在prolog语句的HEAD中使用And子句

时间:2009-11-30 19:57:15

标签: prolog

这个俱乐部的每个成员都要么受过教育,要么有钱,要么两者都兼得。

我想在我的PROLOG代码中写一个与上面非常相似的陈述。我写了其他一切。

edu(X);rich(X) :- member(X). 

这就是我写的。但是PROLOG确实允许head子句中的任何运算符。到目前为止,我花了5个小时尝试使用此声明做各种事情,但无法找到有效的解决方案。 :(

4 个答案:

答案 0 :(得分:2)

请参阅http://en.wikipedia.org/wiki/Horn_clause,了解Prolog所基于的逻辑形式。

鉴于你的陈述,(“这个俱乐部的每个成员要么受过教育,要么富有或两者兼而有之。”),你唯一可以宣布为真的是:

  • 如果一个人是会员并且不富裕,他们就会接受教育。
  • 如果一个人是会员而且没有受过教育,那么他就很富有。

例如,以下内容不一定如此:

  • 富裕和受过教育的人是会员。
  • 富有的成员受过教育。
  • 富裕的成员没有受过教育。

答案 1 :(得分:1)

您不能组合多个头。如果您希望在edu(X)为真时rich(X)member(X)为真,则必须单独定义(“此俱乐部的每位成员都接受教育”,并且“此俱乐部的每位成员都是富“):

edu(X) :-
   member(X).
rich(X) :-
   member(X).

棘手的部分是你的原始陈述不是很好。它说一些成员可能富裕但没有受过教育,反之亦然。这是有问题的。例如,让我们采取一种天真的情况,如果一个成员不富裕,他就受过教育,反之亦然:

edu(X) :-
    member(X), \+ rich(X).
rich(X) :-
    member(X), \+ edu(X).

现在,根据这些规则,没有人会自动使用进行教育。只要我们将每个成员定义为两个中的至少一个,这很好。但是,请考虑以下事实:

member(alice).
member(bob).
member(charlie).
member(dave).

rich(alice).
edu(bob).
rich(charlie).
edu(charlie).

在这种情况下,rich(alice)工作正常,因为这是事实。 edu(alice)会产生no。鲍勃反过来也是如此。有了查理,我们将两者都定义为事实,所以两者都是真的。但戴夫怎么样? edu(dave)rich(dave)都引用另一个,创建无限递归。如果不了解您正在做什么,我们可以做的最好的解决方法是将edu(X)rich(X)默认为true:

edu(X) :-
    member(X).
rich(X) :-
    member(X), \+ edu(X).

现在假设每个人都受过教育,除非我们明确声明。如果你愿意,你可以做同样的事情,默认为富人。如果没有其他信息,这是您可以做的最好的事情。

答案 2 :(得分:1)

作为旁注:在子句元首中使用析取的想法导致析取逻辑编程,参见,例如,Jorge Lobo,Jack Minker,Arcot的“析取逻辑编程的基础” Rajaseka。 edu(X);rich(X) :- member(X).将是一个有效的析取条款。 Nicola Leone,Gerald Pfeifer和Wolfgang Faber在DLV项目中探讨了一个相关的话题,析取数据目录:http://www.dbai.tuwien.ac.at/proj/dlv/

答案 3 :(得分:-1)

也许你想写:

member(X) :- edu(X) ; rich(X)

如果有人接受过教育,有钱人或两者兼有,都是俱乐部的成员。