bigger(whale,shark).
bigger(shark,tiger).
bigger(tiger,dog).
bigger(dog,rat).
bigger(rat,ant).
bigger(rat,mouse).
bigger(cat,rat).
bigger(dog,cat).
smaller(X,Y) :- bigger(Y,X).
smaller(X,Y) :- bigger(Z,X),smaller(Z,Y).
当我问prolog smaller(X,whale)
时,它会吐出所有正确的动物,但会重复几个动物。任何人都可以告诉我为什么以及是否有办法阻止它重复?
答案 0 :(得分:2)
首先发表一些评论:
谓词bigger/2
描述的是什么样的关系?
由于名称,我们假设它是传递:bigger(A, B)
和 bigger(B, C)
==> bigger(A, C)
我们也可以放心地假设它是严格(而不是反身):bigger(A, A)
永远不会是真的
assymetric (不是对称):bigger(A, B)
==> bigger(B, A)
不是真的
我们不能从程序中了解到的是,如果关系描述总排序或弱排序:我们不知道(a)bigger(mouse, ant)
,或(b)不是 bigger(mouse, ant)
,还是(c)mouse
和{{1}是等价的(我们假设它们绝对不是相等)
所有这些只是说对于定义了ant
关系的所有元素,你没有线性排序。如果你这样做了,你可以对所有动物进行分类(比较大到小)并做类似的事情:
bigger
由于没有线性排序,因此无法对所有元素进行排序,并将“更小/更大”的问题简化为“之前/之后的内容”。相反,我们需要遍历animal_bigger(A, Bigger) :-
animal_list(Animals),
append(Bigger, [A|_Smaller], Animals),
member(A, Bigger).
描述的图形。至少我们可以放心地假设它是定向的,非循环图。我把它留作练习如何遍历图表。要解决这个问题,我们可以使用library(ugraphs)
(你可以看到源here),并回答“哪些动物小于X”,我们可以改为问“哪些节点可以到达”来自X“:
这是完整的程序:
bigger/2
如果要查找更大的所有元素,可以转置图表并查找可到达的节点。
我希望你花时间阅读这个答案......
修改强>
最后,消息是:
您的bigger(whale,shark).
bigger(shark,tiger).
bigger(tiger,dog).
bigger(dog,rat).
bigger(rat,ant).
bigger(rat,mouse).
bigger(cat,rat).
bigger(dog,cat).
:- use_module(library(ugraphs)).
animal_graph(G) :-
findall(A-B, bigger(A, B), Edges),
vertices_edges_to_ugraph([], Edges, G).
animal_smaller(A, B) :-
animal_graph(G),
reachable(A, G, R),
select(A, R, Smaller),
member(B, Smaller).
没有描述列表(它不是线性排序),也没有描述树(您有多条路径指向同一个节点)。因此,在列表上工作的算法在这里不起作用,并且在树上工作的算法也不起作用。因此,您必须实施bigger/2
以使用图表,或者使用可以处理图表的库。
答案 1 :(得分:1)
在SWI-Prolog开发分支的最新版本中,这一点变得特别容易:
?- use_module(library(solution_sequences)).
true.
?- distinct(X, smaller(X, whale)).
X = shark ;
X = tiger ;
X = dog ;
X = rat ;
X = ant ;
X = mouse ;
X = cat ;
false.
允许此文件的库记录为over here。
可以这样做的另一种方式(在旧版本的SWI-Prolog中也支持):
?- aggregate_all(set(X), smaller(X, whale), Xs), member(X, Xs).
答案 2 :(得分:0)
可能的标准Prolog用法:
?- X=whale,setof(Y,smaller(Y,X),L).
X = whale,
L = [ant, cat, dog, mouse, rat, shark, tiger].
我试图证明这些功能依赖性'选择符号。如果有列表,则可以使用member / 2枚举元素。