带列表的序言祖先



我四处搜索,找不到答案。我在制作家谱列表时遇到麻烦。

所以,我有一些is_a关系,例如:

is_a(cow, animal).
is_a(calf, cow).
is_a(dog, animal).
.... etc.

我想要一个执行以下操作的过程:

toAnimal(cow, X).
that outputs
X= [calf, cow, animal].

基本上,如果我给它一个输入(cow),那么它将从牛到动物,并将每一步添加到列表中。

到目前为止,我有这个:

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.

编辑:

它现在返回一个空列表。我不确定这里的问题是什么。我根本没有更改代码,因此输出不应更改,但已更改。

编辑:

感谢布拉奇先生的回复。 我进行了建议的更改,但现在我有另一个问题。 例如 如果我有关系:

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,新列表)?

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

来了。(注意:你不需要下降谓词来找出树的特定分支的路径)

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] ? ;

此示例或多或少地执行您想要的操作:

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).

运行时,这是输出:

[拉西,牧羊犬,狗,动物

][牧羊犬,狗,动物]

使用此Prolog在线解释器在线测试了它

帖子编辑:啊,就是这样!我应该在第一句中写"[X,动物]"而不是"[X|动物]"!感谢@mbratch,现在该程序完全符合预期。

toAnimal(X,Y) :- setof(X, descend('animal', X), Y).应该这样做。或者findall/3.

信息和一些例子的袋子,设置,找到所有。

但请记住,您要求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,因为我之前提到的。

最新更新