首页 文章

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

提问于
浏览
1

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 回答

  • 2

    您的查询应该是:

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

    此查询表示:

    X住在达尔文,X有一辆车或者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或生活在凯恩斯的X,X有一辆车

    并不是

    (住在达尔文的X或生活在凯恩斯的X)和X有一辆车

    我明白你为什么犯了这个错误 . 这个查询将是:

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

    你必须添加一对括号 .

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

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

  • 2

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

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

    A ; B , C
    

    也可以绑定

    • ( A ; B ) , C

    • A ; ( B , C )

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

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

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

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

    if ( A || B && C ) ...
    

    将有完全相同的问题 .

相关问题