检查孩子是否在Prolog中至少有3个父母
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检查孩子是否在Prolog中至少有3个父母相关的知识,希望对你有一定的参考价值。
我试图解决一个问题,你会得到一个事实列表,如:
parent(a,b).
其中b
是a
的父母,我需要写一个条款来确定某人是否至少有3个父母。
这是我的尝试
has3Parent(A) :- parent(A,B), parent(A,C), parent(A,D).
我的尝试,
如果A
有1个父母,它将返回true一次,
如果A
有2个父母,它将返回真实的8次,
如果A
有3个父母,它将返回真实27次。
我对Prolog很新,我无法理解为什么会这样,所以任何帮助都会非常感激。
因为你从来没有保证B
,C
和D
是不同的人,只要true
甚至有一个A
,你将永远得到parent
。
所以1 parent
的情况很简单; 2,你有这八种组合:
A = jane, B = jane, C = jane
A = jane, B = jane, C = john
A = jane, B = john, C = jane
A = jane, B = john, C = john
A = john, B = jane, C = jane
A = john, B = jane, C = john
A = john, B = john, C = jane
A = john, B = john, C = john
即使你只是说他们不平等,你也会因为少于3而得到假,而对于3或更多则是假的。但你仍然会得到多种解决方案,因为秩序很重要。
理想情况下,你会使用findall/3
获取父母的数量并计算它,这将给你一个独特的解决方案。就像是:
has3Parent(A) :- findall(P, parent(A, P), Ps), length(Ps, 3).
(另请注意,与之前的不同,这测试A
是否有3个父母,而不是至少3个父母。为了让前面的想法测试正好3个父母,你不得不说除了B
,C
和D
之外不同,也不存在E
不同于所有这些也是parent
。虽然findall
解决方案很容易适应不同类型的比较,因为你正在处理一个数字,而不是一堆不守规矩的变量。)
首先是一个小问题:你使用的关系parent/2
与parent(Child, Parent)
这样的参数。有许多人使用这个名称与交换的参数,因此parent(Parent, Child)
。因此,在名称中直接说明您想要的订单会更安全。因此,child_parent(Child, Parent)
是一个更好的名称,或短的child_of(Child, Parent)
。
每当您尝试定义谓词时,首先要考虑当谓词依赖于更改时该谓词的行为方式。在你的情况下,如果将更多事实添加到child_of/2
会发生什么?
你最初要求至少有3个父母,让我们称之为has3parentsminimum/1
这种关系。然后定义正好3个父母has3parents/1
然后@Amadan的definition has3parentsA/1
。
让我们在向child_of/2
添加事实之前和之后比较一组解决方案。
has3parentsminimum/1
:这套解决方案增加或保持不变。如果另一个孩子现在有3个或更多父母,它会增加。
has3parents/1
:解决方案集可能增加或减少,或两者兼而有之(因此只是改变)。因为有些孩子现在可能有四个或更多的父母,而其他孩子现在有三个。
has3parentsA/1
:与has3parents/1
一样,但另外,如果添加冗余事实,解决方案集也可能会发生变化。
所以has3parentsminimum/1
在添加更多事实时非常稳定。这被称为单调性:在添加新条款时,您知道的所有内容在真实之前都是真实的。尽可能长时间地保持Prolog的单调子集是一个非常好的主意,因为在这个部分你可以学到很多关于关系的知识。 (这可能就是你练习这个练习的原因。)
has3parentsminimum/1
最自然的定义是使用dif/2
:
has3parentsminimum(Ch) :-
dif(P1,P2), dif(P1,P3), dif(P2, P3), % all parents are different
child_of(Ch, P1),
child_of(Ch, P2),
child_of(Ch, P3).
这可能是你需要去的地方。是的,你会得到3! = 6个多余的解决方案,每个孩子只有三个父母,对于3个以上父母的孩子更是如此,但这套解决方案很好。
但是还有进一步的改进(以一定的价格得到)。如果child_of/2
仅包含基本事实,您可以写:
has3parentsminimum(Ch) :-
setof(P, child_of(Ch, P), [_,_,_|_]).
以上是关于检查孩子是否在Prolog中至少有3个父母的主要内容,如果未能解决你的问题,请参考以下文章