2

我试图了解存在量化的用法。我现在知道的是这种技术与setof, findall,一起使用bagof。此外,我找到了一个教程。但是,我不确定何时以及如何Vars^Goal在 Prolog 中进行(存在量化)。

这是示例,我的目标是找到两个彼此认识但在不同公司工作的员工,将结果与L显示绑定Name1-Name2

company('Babbling Books', 500, 10000000).
company('Crafty Crafts', 5, 250000).
company('Hatties Hats', 25, 10000).

employee(mary, 'Babbling Books').
employee(julie, 'Babbling Books').
employee(michelle, 'Hatties Hats').
employee(mary, 'Hatties Hats').
employee(javier, 'Crafty Crafts').

knows(javier, michelle).

我的第一直觉是使用查询

?-employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2).

查询找到了答案,但没有将其呈现为正确的格式。正确的是:

?-setof(N1-N2, (C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2)), L).

我怎么能理解(C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2))?它的概念是什么?谢谢。

4

1 回答 1

1

我不确定何时以及如何在 Prolog 中执行 Vars^Goal(存在量化)。

最简单的答案是:永远不要这样做。您始终可以引入一个辅助谓词,该谓词准确地捕获您想要的查询,准确地公开您想要的参数而不是其他任何东西(这需要量化),并且具有一个很好的自文档名称。

在您的示例中,您可以定义:

different_company_acquaintances(N1, N2) :-
    employee(N1, C1),
    employee(N2, C2),
    C1 \= C2,
    knows(N1, N2).

然后将您的setof查询表达为:

?- setof(N1-N2, different_company_acquaintances(N1, N2), L).
L = [javier-michelle].

由于谓词名称和隐藏了不相关的实现细节,这更容易阅读。请注意,在谓词定义中,参数只是调用者关心的数据(员工),而调用者不关心的数据(公司)没有参数。

我怎么能理解(C1,C2)^(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2))

语法,无论确切的^正确形式是什么,都是为了表示变量,如果你写出一个单独的谓词定义,只会出现在谓词的主体中,而不是作为它的参数。这告诉setof朋友们,每次尝试执行目标(employee(N1,C1),employee(N2,C2),C1\=C2,knows(N1,N2))时,它都应该使用未绑定的变量C1C2. 换句话说,它不应该尝试保留从一次尝试到下一次尝试C1的值。C2

于 2021-06-14T10:35:42.920 回答