我想在Prolog中使用want_to_eat(Jack, food)
格式写出以下事实:Jack想吃食物A或食物B。我试图将其写为want_to_eat(Jack, (A ; B))
,但是{{1} }返回false。我还能做什么?
后续问题:假设杰克要吃苹果,以及面包和樱桃中的至少一种。似乎无法区分And和Or如果使用以下内容。
want_to_eat(Jack, A)
在这种情况下我该怎么办?
答案 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.
,alice
,bob
等)并且有很多食物({ {1}},jack
,apple
),我们想定义一个叉积:所以 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]).