在Prolog我可以写
child(martha,charlotte).
child(charlotte,caroline).
child(caroline,laura).
child(laura,rose).
descend(X,Y) :-
child(X,Y).
descend(X,Y) :-
child(X,Z),
descend(Z,Y).
然后写
?- findall(X,descend(martha,X),Z).
获得四种解决方案
Z = [charlotte,caroline,laura,rose]
但如果我再添加一个普遍的事实
likes(X,pomegranate).
并尝试
?- findall(X,likes(X, pomegranate),Z).
我明白了:
Z = [_G17].
那是什么_G17
?
我需要更改什么才能获得基本上所有变量? (因为likes(X,pomegranate)
应该意味着一切都像石榴......对吧?):
Z = [martha,charlotte,caroline,laura,rose]
答案 0 :(得分:3)
两种解决方案。干净的解决方案是有一个表格列出所有的东西"在你描述的宇宙中:
person_likes(P, pomegranate) :-
person(P).
然后你的"喜欢"宁愿:
person(P) :- child(P, _).
person(P) :- child(_, P).
您也可以尝试破解它:
CREATE TABLE person (
id INTEGER PRIMARY KEY, -- usually autogenerated
name TEXT NOT NULL
);
CREATE TABLE parent_child (
parent_id INTEGER NOT NULL,
child_id INTEGER NOT NULL,
FOREIGN KEY parent_id REFERENCES person(id),
FOREIGN KEY child_id REFERENCES person(id)
);
但这是......不满意?想想一个关系数据库:你会有两个表:
{{1}}
据我所知,唯一的原因是,为什么你不能在Prolog中做同样的事情,因为大多数入门教程试图引诱你并避免进入这些细节。当然还有Prolog"数据库"不是一个真正的关系数据库(例如,参数位置确实很重要!)。
TL; DR使用Prolog时,您无法考虑Prolog的解决策略。