Prolog 简单布尔表达式测试

Prolog 简单布尔表达式测试,prolog,boolean,clpb,Prolog,Boolean,Clpb,我基本上只想问,表达式集{p或Q,~p}是可满足的吗 但是错误消息在这里没有帮助 答案应该是“是”,当p=false和Q=true时,这个公式就满足了。Gnu Prolog支持“裸变量”调用,这是一种语法特性,允许编写类似于公式\u 0/2中所示的代码。但在执行时,变量必须绑定 | ?- [user]. compiling user for byte code... formula_0(P, Q):- (P; Q), \+ P. user compiled, 2 lines read - 76

我基本上只想问,表达式集{p或Q,~p}是可满足的吗

但是错误消息在这里没有帮助


答案应该是“是”,当p=false和Q=true时,这个公式就满足了。

Gnu Prolog支持“裸变量”调用,这是一种语法特性,允许编写类似于
公式\u 0/2
中所示的代码。但在执行时,变量必须绑定

| ?- [user].
compiling user for byte code...
formula_0(P, Q):- (P; Q), \+ P.

user compiled, 2 lines read - 768 bytes written, 37208 ms

yes
| ?- formula_0(P, Q).
uncaught exception: error(instantiation_error,formula_0/2)
然后只需使用callables:


出现实例化错误的原因是,在将
p
Q
用作目标时,对它们的了解太少,无法对它们进行任何说明。你是对的,例如,当你问:

| ?- formula_0(fail,true). 
yes
?- maplist(boolean, [P,Q]), formula(P, Q).
然后,
G=true
是使查询成功的解决方案。但例如
G=(a=a)
也是如此,因为
a=a
也是正确的。由于无法枚举成功的所有目标
G
,因此会出现实例化错误。但请注意,例如,当您显式地提供绑定时,您将得到预期的结果:

?- G.
因此,您应该提供一组您感兴趣的值:

?- G = true, G.
G = true.
并定义例如:

| ?- formula_0(fail,true). 
yes
?- maplist(boolean, [P,Q]), formula(P, Q).
获得具体的解决方案。或者使用约束,这样可以在使用变量之前约束变量域

编辑:由于对此进行了一些讨论,我将详细介绍。出现的主要问题是:为什么查询

boolean(true).
boolean(false).
没有成功的唯一解决办法

?- Q.
显然,
true
成功了,因此是一个有效的解决方案?回答:还有其他可能的答案,因为
true
不是成功的唯一目标。例如,连词
(true,true)
也会成功。现在假设
Q=true
是上述查询的唯一解决方案,则情况如下:

Q = true.
失败(因为
dif(true,(true,true))
本身就是true),但只需交换如下目标

?- Q, Q = (true, true).
成功的原因是,否则
?-true,true
也将失败,而事实并非如此。对于最基本的谓词(统一),这将破坏连接的交换性

请注意,虽然
true
(true,true)
作为目标执行时都会成功,但它们显然是不同的术语,通常不能相互替换。类似地,术语
append([]、[]、[])
与术语
true
不同,尽管两者在作为目标执行时都会成功。因此,您会得到一个实例化错误,因为在像
?-Q.
这样的查询中,对
Q
了解太少,无法给出有用的结果。

用于constraintlogicpBooleans上编程

?- Q = (true,true), Q.

来自公共Lisp背景,这听起来有点奇怪。。。在序言中还有什么东西也是“假”的,但不是“失败”的吗?或者,换一种说法,是否有一种类型系统可以告诉您,如果值在布尔上下文中,会发生什么?我只是想象布尔上下文中的任何内容都是“true”,除了“fail”,所以如果解算器不能想出唯一的“true”值,它只会尝试使用唯一的“false”值(反正只有一个)。对不起,如果这没什么意义。哦,顺便说一句,谢谢你的解释。至少现在我知道如何让它工作了!很多东西在声明上等同于
false
,例如
0=1
,因此您也可以在使用它的任何地方编写例如
a=b
,而不是
false
。正如我所说的,考虑使用约束,如果你事先知道你正在推理的值,检查GNU Prolog的内置有限域约束解算器,或者<代码>库(CPLFD)在YAP、SWI和SICSTUS PROlog中,你可以在0…1代码中写出<代码>值,当你说
Value\\=0
时,解算器会自动推断出
Value=1
。至少对我来说,这仍然是一个问题。。。如果所有这些多个假值都存在(我甚至不会称它们为值),但它们最终都会变成假值,为什么还要为它们的存在而烦恼呢?但我会把这个问题留待以后,因为一次处理的信息太多了。感谢您推荐这个库。每个Prolog目标和Prolog目标在Prolog中自然地表示为Prolog术语,要么失败,要么成功(或者抛出异常)。您可以将您的
公式\u 0/2
也称为:
公式\u 0(0=1,append([],[],[])
,并查看它是否成功,因为给定的目标(以术语表示)具有合适的真值。但是,由于您明确地将问题标记为
boolean
,因此您可能只对布尔值感兴趣,例如,您可以用Prolog原子
true
false
表示布尔值,或者任意地用
+
/
-
t
/
f
表示布尔值,这些值不能直接调用。
?- sat((P+Q) * ~P).
P = 0, Q = 1.                   % succeeds deterministically