[英]How to determine if two propositional formulas are equivalent in Prolog?
我是 Prolog 的新手,有一些疑问。
我需要编写一个 function form_equiv(A,B) 来告诉我们 B 是否等同于 A ,其中 A 和 B 应该是命题。
我知道两个命题是等价的,如果
重言式 (A iff B) = TRUE
但是我怎么能制作一个 function 来检查公式何时是重言式。
顺便说一句,我不能只使用内置的 function AND,OR 和 NOT。
现在这是我到目前为止所拥有的:
and(P,Q) :- P, Q, !.
or(P,Q) :- (P; Q), !.
impl(P,Q) :- or(not(P),Q).
syss(P,Q) :- and(impl(P,Q),impl(Q,P)).
t.
f :- fail.
t(_).
f(_) :- fail.
:- op(400,xf,not).
:- op(500,xfx,and).
:- op(500,xfx,or).
:- op(600,xfx,impl).
:- op(700,xfx,syss).
我在 Haskell 中完成了一个类似的程序,但我对 Prolog 真的很陌生。
谁能帮我写一个 function 来检查一个公式是否是重言式?
提前致谢...
首先是逻辑部分:如果A → B ∧ B → A
成立,则两个公式A
和B
等价。 如果你能证明这个公式,你就完成了。
现在到 prolog 部分:
and(A, B)
将失败,并显示A
未充分实例化的错误消息。 创建谓词eval
和定义eval(and(A,B))
、 eval(or(A,B))
等要容易得多。A
。 我如何确定A
是否可能是真/假? 我建议将变量显式包装到构造函数var(Truthvalue)
中,以在模式匹配期间将其与逻辑运算符区分开来。 否则,您的证明搜索将尝试将变量扩展为更复杂的公式,这显然没有帮助。and(P,Q)
只有一个定义,因此 cut 不会做任何事情。 同样,fail 会使规则失效,就好像它不存在一样——因此您可以删除这些规则(除非您使用 cut 的超逻辑功能)。 请记住,cut 的行为不像逻辑结构,应尽可能避免。A
为假或B
为假(或两者兼有),则A ∧ B
为假。 让我们将eval
分成两部分:如果X
为真,则eval_tt(X)
eval_ff(X)
可推导;如果X
为假,则 eval_ff(X) 可推导。将所有这些注释放在一起,这是一个仅适用于 ∧ 和 ¬ 的最小完整微积分:
eval_tt(var(true)).
eval_tt(and(A,B)) :-
eval_tt(A),
eval_tt(B).
eval_tt(not(A)) :-
eval_ff(A).
eval_ff(var(false)).
eval_ff(and(A,_B)) :-
eval_ff(A).
eval_ff(and(_A,B)) :-
eval_ff(B).
eval_ff(not(A)) :-
eval_tt(A).
我们可以使用以下查询查询模型中的¬(A ∧ ¬B)
:
?- eval_tt(not(and(var(A), not(var(B))))).
A = false ;
B = true.
如果我们使用 cut 或 negation 作为失败,我们可能不会找到两种解决方案。
A ∧ ¬A
也是不可满足的,正如预期的那样:
?- eval_tt(and(var(A), not(var(A)))).
false.
现在您只需要通过您想要的其他运算符(析取、蕴涵、等价等)来扩展这个最小演算。 顺便提一句。 如果你看过后续的微积分,你可能会认出一些想法:)
编辑:我还没有解释如何从可满足性到有效性。 “简单”的出路是将有效性定义为没有反模型(即valid(X):- \+ eval_ff(X).
),但我仍在考虑不包括 cut / 的更好方法失败的否定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.