在Prolog中使用OR

时间:2018-09-30 01:41:25

标签: prolog

我想在Prolog中使用want_to_eat(Jack, food)格式写出以下事实:Jack想吃食物A或食物B。我试图将其写为want_to_eat(Jack, (A ; B)),但是{{1} }返回false。我还能做什么?

后续问题:假设杰克要吃苹果,以及面包和樱桃中的至少一种。似乎无法区分And和Or如果使用以下内容。

want_to_eat(Jack, A)

在这种情况下我该怎么办?

1 个答案:

答案 0 :(得分:2)

首先,语法存在问题:大写标识符是变量,而不是常量。所以你应该只写:

wants_to_eat(jack, apple).

不是:

wants_to_eat(Jack, Apple).

接下来,参数中的;只是一个仿函数。 Prolog不会将任何语义附加到这些函子。对于Prolog (;)/2仅为(;)/2。逗号也会发生同样的情况:wants_to_eat(jack, (apple, apple, apple))不会“折叠”到jack会吃掉apple的事实,它只是{{ 1}}函子。仅在子句的主体中,它才被视为“逻辑或”(尽管在Prolog中,大多数运算符的含义与其逻辑对应物的含义略有不同,尤其是 not 是棘手的)。

如果您写:

(,)/2

然后,它仅与 entire 第二个参数统一:

wants_to_eat(jack, (apple; bread; cherry)).

或由于统一,您可以将其中一部分进行统一:

?- wants_to_eat(jack, A).
A =  (apple;bread;cherry).

因此,我们不能只将这些值写在以分号分隔的列表中。通常情况下,要做的是写一些事实,例如:

?- wants_to_eat(jack, (A;_)).
A = apple.

?- wants_to_eat(jack, (_;B)).
B =  (bread;cherry).

我们还可以在体内执行统一,然后使用分号,例如:

wants_to_eat(jack, apple).
wants_to_eat(jack, bread).
wants_to_eat(jack, cherry).

如果人很多(wants_to_eat(jack, F) :- F = apple; F = bread; F = cherry. alicebob等)并且有很多食物({ {1}},jackapple),我们想定义一个叉积:所以 all 这些人都喜欢 all 这些食物。在这种情况下,我们可以这样写:

bread

但是以上内容相当难看。我们可以通过编写两个列表来解决此问题,并改用member/2 [swi-doc]

cherry

以上内容也仅适用于wants_to_eat(P, F) :- ( P = alice; P = bob; P = jack ), ( F = apple; F = bread; F = cherry ).

wants_to_eat(P, F) :-
    member(P, [alice, bob, jack]),
    member(F, [apple, bread, cherry]).