【发布时间】:2015-12-17 19:06:35
【问题描述】:
我正在尝试编写一个算法来天真地寻找布尔公式(NNF,但不是 CNF)的模型。
我拥有的代码可以检查现有模型,但当被要求查找模型时它会失败(或无法完成),似乎是因为它为 member(X, Y) 生成了无限多的解决方案,类似于 [X|_], [_,X|_], [_,_,X|_]...
到目前为止,我所拥有的是:
:- op(100, fy, ~).
:- op(200, xfx, /\).
:- op(200, xfx, \/).
:- op(300, xfx, =>).
:- op(300, xfx, <=>).
formula(X) :- atom(X).
formula(~X) :- formula(X).
formula(X /\ Y) :- formula(X), formula(Y).
formula(X \/ Y) :- formula(X), formula(Y).
formula(X => Y) :- formula(X), formula(Y).
formula(X <=> Y) :- formula(X), formula(Y).
model(1, _).
model(X, F) :- atom(X), member([X, 1], F).
model(~X, F) :- atom(X), member([X, 0], F). % NNF
model(A /\ B, F) :- model(A, F), model(B, F).
model(A \/ B, F) :- (model(A, F); model(B, F)).
model(A => B, F) :- model(~A \/ B, F).
model(A <=> B, F) :- model((A => B) /\ (B => A), F).
sat(A) :- model(A, F), \+ (member([X, 1], F), member([X, 0], F)).
%%% examples:
% formula(~(~ (a /\ b) \/ (c => d))).
% model(a, [[a,1]]).
F 是否有更好的数据结构,或者其他方式可以截断部分实例化的列表?
编辑:添加定义和示例。
【问题讨论】:
-
请将您的代码自成一体,以便其他人实际尝试。
-
抱歉,我在其余代码中进行了编辑。
-
关于表示的一条评论:您知道每个这样的列表正好有 2 个元素。在这种情况下,最好使用
x=0、x=1之类的术语来更紧凑地表示绑定:[x,0]是.(x, .(0, []),浪费空间用于一个额外的仿函数./2和一个原子[]这样的结构。相比之下,x=0是=(x,0),即只有一个函子及其两个参数。正如其他人所说,您实际上可以通过使用实际的逻辑变量轻松地将绑定委托给 Prolog。您可以存储符号/变量对应而不是变量/值一!