您可能想尝试使用 SAT Solver 的 Prolog 系统,例如 SWI-Prolog、Jekejeke Minlog 等……您可以在 Prolog 系统的 REPL 中轻松使用它。要加载 SAT 求解器,只需键入(您不需要键入 ?- 本身):
/* in SWI-Prolog */
?- use_module(library(clpb)).
/* in Jekejeke Minlog */
?- use_module(library(finite/clpb)).
然后,您可以使用顶层搜索布尔公式的解决方案,例如这里的 xor 示例:
?- sat(X#Y), labeling([X,Y]).
X = 0,
Y = 1 ;
X = 1,
Y = 0.
这是厨房规划师代码的示例。厨房有3个地方,我们分配了一个冰箱和一个炉子。冰箱不允许靠近炉子。
冰箱的代码为 0,1,炉子的代码为 1,0。我们利用卡片约束来放置冰箱和炉子。
:- use_module(library(finite/clpb)).
freezer([X,Y|L],[(~X)*Y|R]) :-
freezer(L, R).
freezer([], []).
stove([X,Y|L],[X*(~Y)|R]) :-
stove(L, R).
stove([], []).
free([X,Y|L],[(~X)*(~Y)|R]) :-
free(L, R).
free([], []).
allowed([X,Y,Z,T|L]) :-
sat(~((~X)*Y*Z*(~T))),
sat(~(X*(~Y)*(~Z)*T)),
allowed([Z,T|L]).
allowed([_,_]).
allowed([]).
kitchen(L) :-
freezer(L, F), card(1, F),
stove(L, G), card(1, G),
free(L, H), card(1, H),
allowed(L).
我想用 Prolog 代码演示的好处是,可以通过 Prolog 代码本身来完成对 SAT 公式的问题编码。运行上述代码时,我按预期得到以下结果:
?- L=[_,_,_,_,_,_], kitchen(L), labeling(L).
L = [0,1,0,0,1,0] ;
L = [1,0,0,0,0,1] ;
No