在 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]
最佳答案
两种解决方案。干净的解决方案是有一个表格,列出您所描述的宇宙中的所有“事物”:
person(martha).
person(charlotte).
% etc
然后你的“喜欢”会是:
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)
);
据我所知,您不在 Prolog 中做完全相同的事情的唯一原因是,大多数介绍性教程都试图引诱您并避免深入讨论此类细节。当然,Prolog“数据库”并不是真正的关系数据库(例如,参数位置确实很重要!)。
TL;DR 在使用 Prolog 时,你无法避免思考 Prolog 的解析策略。
关于prolog - 如何在序言中找到所有普遍事实?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36806750/