我四处搜寻,找不到答案。我在制作家谱清单时遇到了麻烦。
所以,我有一些is_a关系,例如:
is_a(cow, animal).
is_a(calf, cow).
is_a(dog, animal).
.... etc.
我想要一个执行以下操作的过程:
toAnimal(cow, X).
that outputs
X= [calf, cow, animal].
基本上,如果我给它一个输入(牛),那么它将从牛到动物并将每一步添加到列表中。
到目前为止,我有这个:
toAnimal(A, B) :- is_a(A,B).
toAnimal(A, B) :- is_a(A, X), toAnimal(X, B).
这个的输出是
X= cow;
X = animal;
false
我如何才能成为名单?
编辑:
descend(X,Y) :- is_a(X,Y).
descend(X,Y) :- is_a(X,Z), descend(Z,Y).
toAnimal(X,Y):-
findall(X, descend('animal', X), Y).
在查看建议后,我已将其更新为此内容。但是,如何打印列表?我还是新手。 findall页面说它将返回列表,但它不会对我这样做。
toAnimal(calf, Y)
outputs:
false.
编辑:
现在返回一个空列表。我不确定这里的问题是什么。我根本没有改变代码,所以输出不应该改变,但它有。
编辑:
感谢MrBratch的回复。 我提出了建议的更改,但我现在有另一个问题。 例如, 如果我有关系:
is_a(calf, cow).
is_a(calf, animal).
is_a(cow, cool).
is_a(cool, awesome).
但我只想要从小牛到令人敬畏的道路。 代码将为我提供来自calf,x的所有可能路径。 例如,
descend(X,Y) :- is_a(X,Y).
descend(X,Y) :- is_a(X,Z), descend(Z,Y).
toAwesome(A,Y) :-
findall(X, descend(calf, X), Y).
会给我一个包含
的列表Y.[cow,animal,cool,awesome].
但我想要的是
[calf,cow,cool,awesome].
如何过滤其他路径? 还加上了起点?我想我可以把头部作为头部添加到头部,但是如何忽略其他路径?
编辑:
感谢您的帮助 我想通了,但我失去了结束路径并开始了路径。例如, L包含牛,很酷。 但小牛和真棒不在那里。我尝试追加,但我真的不懂语法。我不被允许附加(X,L,anewlist)?
descend(X,Y) :- is_a(X,Y).
descend(X,Y) :- is_a(X,Z), descend(Z,Y).
toAnimal(A,B) :-
setof(X, (descend(A,X), descend(X,'awesome')), B).
--> append(A, L,anewlist).
?? Is this line not allowed here? How else would I do it? or is there a simpler way to just add it from the beginning
答案 0 :(得分:1)
在这里。 (注意:您不需要下降谓词来计算树的特定分支的路径)
is_a(calf, cow).
is_a(calf, animal).
is_a(cow, cool).
is_a(cool, awesome).
path(X,Y,[Z|T]) :- \+ is_a(X,Y), is_a(X,Z), path(Z,Y,T).
path(X,Y,[Y]) :- is_a(X,Y).
find_path(X,Y,[X|L]) :- path(X,Y,L).
用法:
| ?- find_path(calf,awesome,L).
L = [calf,cow,cool,awesome] ? ;
答案 1 :(得分:0)
toAnimal(X,Y) :- setof(X, descend('animal', X), Y).
应该这样做。或findall/3
。
Info and some examples of bagof, setof, findall.
但请记住,您要求的是descend(animal, X)
,因此它与is_a(dog, animal)
的事实descend(X, animal)
不匹配,descend
会。您需要is_a
来搜索双方,或者只是确保您的toAnimal(X,Y) :- setof(X, (descend('animal', X), not(X = animal)), Y).
事实在左侧说动物。
如果你想过滤你可以做
animal
但是你得到了{{1}},因为我之前提到过。
答案 2 :(得分:0)
此示例或多或少符合您的要求:
is_a(cow, animal).
is_a(calf, cow).
is_a(dog, animal).
is_a(snoopy, dog).
is_a(lassie, collie).
is_a(collie, dog).
toAnimal3( X, [X,animal] , animal ):- is_a( X, animal).
toAnimal3( X, [X|R], R ):- is_a( X, Y), toAnimal3(Y, R, _).
:- initialization(main).
main :- toAnimal3( lassie, A, B), write(A), write(B).
运行时,这是输出:
[恋人,牧羊犬,狗,动物] [牧羊犬,狗,动物]
使用this Prolog online interpreter
在线测试POST编辑:啊,就是这样!我应该为第一个条款写“[X,animal]”而不是“[X | animal]”!非常感谢@mbratch,现在该程序完全符合预期。