prolog - 我自己父亲的侄子在序言中

标签 prolog logic

我正在用 prolog 编写一个家庭程序,但我在 nephew 实现方面遇到了问题。当我问 erick 是否是 Alberto 的侄子时,它返回 true,当它应该返回 false 因为 Alberto 是 erick 的父亲时,它确实适用于所有其他应该为真的情况。如果有人可以帮助我,我将不胜感激。 我的代码:

man(beto).
man(fransisco).
man(alberto).
man(jaime).
man(manolo).
man(nolo).
man(lito).
man(manuel).
man(erick).
man(jesu).
man(jesus).
woman(emi).
woman(harumi).
woman(haru).
woman(yuneisi).
woman(yasmeli).
woman(mioara).
woman(elia).
woman(iza).
woman(alice).
woman(ofelia).
woman(arlet).
parent(manuel, alberto).
parent(ofelia, alberto).
parent(manuel, jaime).
parent(ofelia, jaime).
parent(manuel, manolo).
parent(ofelia, manolo).
parent(alberto, erick).
parent(alberto, beto).
parent(alberto, fransisco).
parent(emi, erick).
parent(emi, beto).
parent(manolo, nolo).
parent(manolo, arlet).
parent(nolo, lito).
parent(iza, lito).
parent(mioara, yuneisi).
parent(mioara, yasmeli).
parent(jaime, yuneisi).
parent(jaime, yasmeli).
parent(jesus_padre, jesu)
parent(jesus_padre, alice).
parent(jesus_padre, haru).
parent(harumi, haru).
parent(harumi, jesu).
parent(harumi, alice).
father(X,Y) :- parent(X,Y), man(X).
mother(X,Y) :- parent(X,Y), woman(X).
brother(X,Y) :- man(X), parent(F, X), parent(F, Y).
sister(X,Y) :- woman(X), parent(P, X), parent(P, Y).
grandpa(X,Y) :- father(F,Y), father(X,F), man(X).
grandma(X,Y) :- father(F,Y), mother(X,F), woman(X).
son(X,Y) :- father(Y,X), man(X).
nephew(X,Y) :- father(F,X), brother(F,Y).

最佳答案

除了 @LuaiGhunim 指出的 parent(jesus_padre, jesu) 之后缺少的点之外,您的谓词还有一些其他问题。你对 brother/2 的定义太笼统了。没有人是他自己的兄弟,但如果你查询你的谓词,你会发现几个这样的例子:

?- brother(X,X).
X = beto ;
X = beto ;
X = fransisco ;
X = alberto ;
X = alberto ;
X = jaime ;
X = jaime ;
X = manolo ;
X = manolo ;
X = nolo ;
X = lito ;
X = lito ;
X = erick ;
X = erick ;
X = jesu ;
X = jesu ;
false.

您可以通过添加目标 dif/2 轻松解决此问题:

brother(X,Y) :-
   dif(X,Y),
   man(X),
   parent(F, X),
   parent(F, Y).

现在上面的查询失败了:

?- brother(X,X).
false.

两次你仍然会得到很多对:

?- brother(X,Y).
X = beto,               % <- 1st occurrence
Y = erick ;             % <- 1st occurrence
X = beto,
Y = fransisco ;
X = beto,               % <- 2nd occurrence
Y = erick ;             % <- 2nd occurrence
.
.
.

原因是您可以通过母亲或父亲获得它。在上面的示例中(betoerick),您将通过 emialberto 到达那里。这些解决方案可能是多余的,但它们是正确的。您的谓词 sister/2 也是如此:

?- sister(X,X).
X = haru ;
X = haru ;
X = yuneisi ;
X = yuneisi ;
X = yasmeli ;
X = yasmeli ;
X = alice ;
X = alice ;
X = arlet.

补救方法同上:

sister(X,Y) :-
   dif(X,Y),
   woman(X),
   parent(P, X),
   parent(P, Y).

?- sister(X,X).
false.

?- sister(X,Y).
X = haru,
Y = jesu ;
X = haru,
Y = alice ;
X = haru,
Y = jesu ;
.
.
.

另一方面,您对 grandma/2 和 grandpa/2 的定义过于具体。为了看到这一点,让我们将以下事实添加到您的代码中:

man(m1).
man(m2).

woman(w1).
woman(w2).
woman(w3).

parent(m1,w1).
parent(w1,w2).
parent(w2,w3).

那么下面的查询应该会成功,但它们会失败:

?- grandpa(m1,w2).
false.

?- grandma(w1,w3).
false.

原因是您定义的 grandpa/2 和 grandma/2 中的中间父级是 father/2,而它应该是 parent/2。此外,最后一个目标(man(X)woman(X))是多余的,因为它们已经分别被 father/2 和 mother/2 覆盖了。相反,您可以像这样定义两个谓词:

grandpa(X,Y) :-
   parent(F,Y),
   father(X,F).

grandma(X,Y) :-
   parent(F,Y),
   mother(X,F).

现在上面的查询产生了想要的结果:

?- grandpa(m1,w2).
true.

?- grandma(w1,w3).
true.

最后是侄子照了Cambridge Dictionary您姐妹或兄弟的儿子,或您丈夫或妻子的姐妹或兄弟的儿子。由于您没有关于丈夫和妻子的谓词,我将坚持使用您姐妹或兄弟的儿子部分。如果您为丈夫和妻子添加事实,您可以添加额外的规则来涵盖定义的其他部分。您可以像这样在 Prolog 中编写定义的第一部分:

nephew(X,Y) :-
   man(X),
   dif(F,Y),
   parent(P,F),
   parent(P,Y),
   parent(F,X).

如果您查询此谓词,则不再有 erick/alberto 解决方案:

?- nephew(erick,X).
X = jaime ;
X = manolo ;
X = jaime ;
X = manolo ;
false.

关于prolog - 我自己父亲的侄子在序言中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47106120/

相关文章:

mysql - 获取最大总和为 3 列的行 - Mysql

algorithm - 拼车预订的数据库/算法

prolog - Prolog 中的 (+,?,?) 或 (-,-,+) 是什么意思?

prolog - 关系运算符在序言中用于变量

python - 安装 PySWIP 以在 Python 中使用 Prolog 时出错

algorithm - 使用给定的 n 个字符串输入生成 Bulls 和 Cows 密码

prolog - Prolog 中的数字递增

module - 为什么 prolog 的 ISO 模块标准失败了?

prolog - Prolog 事实中的存在量化

java - 为什么我无法从哈希表中正确检索?