Prolog中事实数据库的复合查询

时间:2014-05-06 18:59:09

标签: prolog

Prolog新手在这里。我想知道。 如果我有以下谓词:

住在(人,地方)。 有一辆车(人)。

这是事实的实际数据库:

lives_in( julie, canterbury).
lives_in( pete, darwin).
lives_in( chris, eliot).
lives_in( samantha, darwin).
lives_in( james, whitstable).
lives_in( john, keynes).
lives_in( sue, canterbury).
lives_in( 'mary jane', darwin).
lives_in( rachael, sturry).
lives_in( brad, keynes).
lives_in( keith, whitstable).

% has_a_car( Person)
% ------------------
has_a_car( pete).
has_a_car( samantha).
has_a_car( james).
has_a_car( brad).

我想制定一个查询,告诉我住在达尔文或凯恩斯并拥有汽车的人

为什么我的查询:

lives_in(X,darwin);lives_in(X,keynes),has_a_car(X).

不行吗?这个查询给了我'mary jane',他住在达尔文,但没有车。 X不是必须与达尔文或凯恩斯统一,然后有车吗?

提前谢谢

2 个答案:

答案 0 :(得分:2)

您需要阅读运算符优先级和关联性

;/2(逻辑OR)具有与,/2(逻辑AND)不同的优先级。这意味着你的表达不会像你想象的那样绑定。像

这样的表达式
A ; B , C

可以绑定为

  • ( A ; B ) , C
  • A ; ( B , C )

绑定由运算符优先级和关联性控制。鉴于你的问题陈述,“这个问题给了我'mary jane',他住在达尔文,但没有车。”,你认为你有哪些约束?

尝试使用括号使您的意图明确。更好的是,不要使用'; / 2'。说这样的话:

has_a_car(X) , lives_in(X,City) , member(City,[darwin,keynes]).

应该注意的是,除了prolog之外,你在大多数语言中都会遇到同样的问题。例如,C / C ++ / C#/ Java等,像

这样的表达式
if ( A || B && C ) ...

会有完全相同的问题。

答案 1 :(得分:2)

您的查询应该是:

lives_in(X):- lives_in(X,darwin), has_a_car(X); lives_in(X,keynes), has_a_car(X).

此查询表示:

  

住在达尔文的X和X有一辆汽车 OR X住在凯恩斯,X有一辆车。

此查询的结果是:

3 ?- lives_in(X).
X = pete ;
X = samantha ;
X = brad.

就像我们想要的那样。

您的查询

lives_in(X,darwin);lives_in(X,keynes),has_a_car(X).

意思是:

  

住在达尔文的X OR X住在凯恩斯,X有车?

而不是

  

(X住在达尔文 OR X住在凯恩斯) X有车吗

我能理解为什么你犯了这个错误。此查询将是:

lives_in(X):- (lives_in(X,darwin); lives_in(X,keynes)), has_a_car(X).

你必须添加一对括号。

在Prolog中,当你写;时,就像在说OR。逗号(,)表示AND

Αlso,一个小提示:有两个具有相同名称的谓词(lives_in)可能会令人困惑,因此您可以重命名其中一个谓词。