| ?- [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)
我基本上想做的就是要求表达式{P或Q,~P}满足吗?
但错误信息在这里没有帮助......
PS。答案应该是“是”,当P = false且Q =真时,满足该公式。
答案 0 :(得分:3)
您获得实例化错误的原因是,P
和Q
在将它们用作目标时对它们说了什么,知之甚少。当你问一个例子时,你是对的:
?- G.
然后G = true
是一个使查询成功的解决方案。但例如G = (a=a)
也是如此,因为a=a
也是如此。由于无法枚举成功的所有目标G
,因此会出现实例化错误。但请注意,例如,当您明确提供绑定时,您会得到您期望的结果:
?- G = true, G.
G = true.
因此,您应该提供一组您感兴趣的值:
?- maplist(boolean, [P,Q]), formula(P, Q).
并定义例如:
boolean(true).
boolean(false).
获得具体的解决方案。或者使用约束,它允许您在使用它们之前约束变量域。
编辑:由于对此有一些讨论,我会详细介绍。出现的主要问题是:为什么查询
?- Q.
单一解决方案没有成功
Q = true.
因为很明显,true
成功了,因此是一个有效的解决方案?答:还有其他可能的答案,因为true
不是唯一成功的目标。例如,联合(true,true)
也会成功。假设现在Q = true
是上述查询的唯一解决方案,那么就是这样的情况:
?- Q, Q = (true, true).
失败(因为dif(true, (true,true))
本身就是真的),但只是交换目标,如
?- Q = (true,true), Q.
成功因为否则?- true, true
也必须失败,而事实并非如此。对于最基本的谓词(统一),这将违反连词的交换性。
请注意,虽然true
和(true,true)
两者在作为目标执行时都会成功,但它们显然是不同的术语,并且一般不能互相替换。同样,术语append([], [], [])
与术语true
不同,但在作为目标执行时都成功。因此,您会收到实例化错误,因为对Q
之类的查询中的?- Q.
知之甚少,无法提供有用的结果。
答案 1 :(得分:3)
答案 2 :(得分:1)
Gnu Prolog支持'裸变量'调用,这是一种语法功能,允许编写您在formula_0/2
中显示的代码。但是当它执行时,必须绑定变量!
| ?- P.
uncaught exception: error(instantiation_error,top_level/0)
| ?- P=write(1), P.
1
P = write(1)
然后只使用 callables :
| ?- formula_0(fail,true).
yes