如何在prolog中找到普遍的事实?

时间:2016-04-23 04:46:47

标签: prolog universal quantifiers

在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]

1 个答案:

答案 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的解决策略。