我正在使用SWI-Prolog根据四色定理(http://en.wikipedia.org/wiki/Four_color_theorem)着色地图。到目前为止,我的程序看起来像这样:
colour(red).
colour(blue).
map_color(A,B,C) :- colour(A),
colour(B),
colour(C),
C \= B,
C \= A.
(实际的程序会更复杂,有4种颜色和更多的字段,但我想我会从一个简单的案例开始)
现在,我想避免使用具有相同结构的双重解决方案。例如。对于具有三个字段的地图,解决方案“红色,红色,蓝色”将具有与“蓝色,蓝色,红色”相同的结构,仅具有不同的颜色名称,并且我不希望它们都显示。
所以我想我会有一个动态谓词解决方案/ 3,并在我的map_color谓词的末尾调用assert(解决方案(A,B,C))。然后,对于每个解决方案,检查它们是否已作为解决方案/ 3事实存在。问题是我必须断言像解决方案(Color1,Color1,Color2),即使用变量来进行统一检查。我无法想到实现这一目标的方法。
所以,问题是,断言找到解决方案然后进行统一测试的最佳方法是什么,以便“红色,红色,蓝色”与“蓝色,蓝色,红色”统一?
答案 0 :(得分:1)
建立变量之间的关系:
mask_helper(_, _, [], []).
mask_helper(A, B, [A|_], [B|_]):- !.
mask_helper(A, B, [X|Xs], [_|Ys]):-
A \= X,
mask_helper(A, B, Xs, Ys).
mask([], []).
mask([X|Xs], [Y|Ys]):-
mask_helper(X,Y,Xs,Ys),
mask(Xs, Ys).
你可以建立你的面具:
?- mask([red,red,blue],X).
X = [_G300, _G300, _G306] .
但:
?- mask([red,red,blue],X), mask([blue,red,red],Y), X=Y.
X = [_G27, _G27, _G27],
Y = [_G27, _G27, _G27].
即。如果您使用Color1 \= Color2
(没有规则正文),则assert
没有关系。
您可能会考虑分配颜色的顺序(非常流行的方法):
colour(red). colour(green). colour(blue).
colour_order(red, red).
colour_order(red, green).
colour_order(red, blue).
colour_order(green, green).
colour_order(green, blue).
colour_code([]).
colour_code([X]):- colour(X).
colour_code([X|[Y|T]]):-
colour_order(X,Y),
colour_code([Y|T]).
map_color(A,B,C):-
colour_code([A,B,C]),
C \= B, C \= A.
但如果您的条件为A \= B, B \= C
,您将永远不会得到“红色,蓝色,红色”的结果。
想一想:
unify([], [], _).
unify([X|Xs], [Y|Ys], M):-
member((X=Z), M), !,
Z = Y,
unify(Xs, Ys, M).
unify([X|Xs], [Y|Ys], M):-
% X is not assigned yet
not(member((_=Y),M)), % Y is not used as well
unify(Xs, Ys, [(X=Y)|M]).
比你可以比较:
?- unify([red,red,blue],[blue,blue,red],[]).
true.
?- unify([red,red,blue],[blue,blue,blue],[]).
false.
?- unify([red,red,blue],[blue,red,red],[]).
false.
答案 1 :(得分:0)
我认为最简单的解决方案是说A总是红色(例如)。