我想创建一个子句,如果它的两个布尔参数相等且第三个参数为 1 或它的两个布尔参数不相等且第三个参数为 0,则该子句将成立。我的第一次尝试:
equal_bools(X, Y, N) :-
X = Y,
N=1.
equal_bools(X, Y, N) :-
\+ X = Y,
N=0.
这似乎有效:
?- equal_bools(true, true, 0).
false.
?- equal_bools(true, true, 1).
true.
?- equal_bools(true, false, 0).
true.
?- equal_bools(true, false, 1).
false.
问题是,我确实需要将 Y 绑定到正确的值。例如,
equal_bools(false, Y, 0).
应该回馈Y = true .
。相反:
?- equal_bools(false, Y, 0).
false.
似乎
\+ X = Y
检查是否相等,但不将 X
或 Y
绑定到任何值。我该如何解决?这是出于学习目的,所以我想确切地了解如何执行此操作,而不是获得一个内置的子句来完成所有这些或另一个库。
Prolog 使用否定原则作为失败。这意味着如果不可能使被否定的事物为真,则否定成功。
在这种情况下,可以通过将
false = Y
统一为 Y
来使 false
为真(在其他语言中,您会说给 Y
赋值 false
)。因此,当 X 或 Y 或两者都是(未绑定)变量时,\+ X = Y
never 可能为真。
换句话说:Prolog 不会尝试为
Y
找到一个值来使否定为真,而是检查是否有可能使等式为真,如果可能则否定为假。
此外,Prolog 没有布尔值作为数据类型。您可以在 https://www.swi-prolog.org/pldoc/man?section=typetest 查看类型列表,布尔值不是其中之一。
true
和 false
只是原子,例如 abc
。因此,Prolog 不会对 true
和 false
做任何布尔逻辑,比如 (非真)等于 false 或类似的东西。
如果你想实现这个你需要自己提供布尔逻辑,例如如下:
reverse_bool(true, false).
reverse_bool(false, true).
equal_bools(X, X, 1).
equal_bools(X, Y, 0) :-
reverse_bool(X, Y).
请注意,我通过使用相同的变量 X 并将 N = 1 作为常量放在第三个参数中来表示 X 和 Y 相等,从而将规则转化为事实,从而简化了 N = 1 的情况。类似地,N = 0 在 X 不等于 Y 的规则中表示为常数。