我四处寻找,找不到答案。我在制作家谱清单时遇到了麻烦。
所以,我有一些 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).
但我只想要从小牛到真棒的道路。该代码将为我提供来自小牛,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 包含牛,酷。但是calf和awesome都不在。我尝试追加,但我并不真正理解语法。我不允许追加(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