Prolog Ancestor with List

时间:2014-01-31 18:52:51

标签: list prolog ancestor genealogy

我四处搜寻,找不到答案。我在制作家谱清单时遇到了麻烦。

所以,我有一些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

3 个答案:

答案 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,现在该程序完全符合预期。