gpt4 book ai didi

Prolog取谓词的逆

转载 作者:行者123 更新时间:2023-12-04 17:46:09 25 4
gpt4 key购买 nike

我有一个看起来像的数据库

hasChild(person1, person2).
hasChild(person1, person3).
hasChild(person4, person5).

这意味着(例如)person1 有一个名为 person2 的 child 。

然后我创建一个谓词来识别此人是否是 parent
parent(A):- hasChild(A,_).

标识此人是否为 parent ,即是否有 child

然后我尝试创建一个谓词 childless(A)如果用户没有任何 child ,这应该返回 true,这基本上是 parent(A) 的倒数。 .

所以我在这里有两个问题:

a) 是否有可能以某种方式取谓词的“逆”,例如 childless(A):-not(parent(A)).或以任何其他方式使用 hasChild或任何其他方法?

b) parent(A)如果此人有多个 child ,将多次返回 true。是否有可能让它只返回一次?

最佳答案

对于问题 1,是的。 Prolog 对某些人来说并不完全神奇,因为它将否定和失败混为一谈,但你绝对可以这样写:

childless(X) :- \+ hasChild(X, _).

对于没有 child 的人,您会看到“真实”。您还将看到蔬菜、矿物质、意识形态、程序、鞋盒、啤酒配方和无羽毛的两足动物的“真实”。如果这对您来说是个问题,一个简单的解决方案是改进您的数据模型,但提示 Prolog 是一个非常流行的选择。 :)

对于问题 2,最简单的解决方案是使用 once :
parent(A) :- once(hasChild(A, _)).

这是使用 cut 运算符的更安全的替代方法,如下所示:
parent(A) :- hasChild(A, _), !.

这有相当大的成本: parent/1只会生成一个有效的解决方案,尽管它会验证其他正确的解决方案。以机智:
?- parent(X).
X = person1.

注意它没有建议 person4 .然而,
?- childless(person4).
true.

对于像我这样的大多数中级 Prolog 程序员来说,这种不对称无疑是一种“代码味道”。就好像 Prolog 有某种健忘症或选择性听力取决于查询。这不是被邀请参加上流社会事件的方式!

我建议这里最好的解决方案(也处理上面的矿物/蔬菜问题)是添加更多关于人的事实。毕竟,一个人在他们有 child 之前就已经存在了(或者他们有吗?)所以他们没有被这种关系“定义”。但是继续玩游戏,或许可以使用 setof/3来规避问题。构建所有人的列表:
parent(Person) :- 
setof(X, C^hasChild(X, C), People),
member(Person, People).

奇怪的表达式 C^hasChild(X, C)告诉 Prolog C 是一个自由变量;这确保我们在 hasChild/2 的第一个参数中获得所有事物的集合绑定(bind)到列表 People .伙计们,这不再是一阶逻辑了!这里的优点是 member/2将为我们生成并检查:
?- parent(person4).
true.

?- parent(X).
X = person1 ;
X = person4.

这有效率吗?不,它聪明吗?可能不是。它是否也能解决您的问题?是的,似乎是。嗯,三分之一还不错。 :)

最后,一些 Prolog 实现将 not/1作为 \+/1 的别名;如果您碰巧使用其中之一,我建议您不要将与前 ISO 约定的兼容性误认为是对多样性的愉快容忍:更正 not(X) 的拼写至 \+ X . :)

关于Prolog取谓词的逆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33905846/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com