所以我试图解决着名着作“To Mock A Mockingbird”中的第一个问题。 它被称为“花园”,定义为:
在某个花园中,每朵花都是红色,黄色或蓝色,并且所有三种颜色都有代表。一位统计学家曾经访问过这个花园,并观察到你挑选的三朵花,其中至少有一朵必然是红色的。第二位统计学家参观了花园,并观察到无论你选择了哪三朵花,至少有一朵花一定是黄色的。两个逻辑学生听说了这个并且引起了争论。第一个学生说:“因此,无论你挑选哪三朵花,至少有一朵必然是蓝色的,不是吗?”第二个学生说:“当然不是!”
哪个学生是对的,为什么?
因此,如果您考虑解决方案,解决方案非常简单,但解决方案需要什么?
(你可以在书中找到P.19的解决方案:http://www.scribd.com/doc/194863914/Raymond-M-Smullyan-To-Mock-a-Mockingbird-and-Other-Logic-Puzzles-Including-an-Amazing-Adventure-in-Combinatory-Logic-Knopf-1985)
我认为Prolog可能是正确的语言选择,因为它与逻辑编程有关...... 虽然我已经设置了一些推论,但这应该给我解决方案,但我有点卡住了,因为程序没有正确完成。
到目前为止,我有什么建议,你有什么建议我错过了什么/做错了吗?
#!/usr/bin/env swipl -q -g main -s
subsets_contain_item(_, []).
subsets_contain_item(Item, [H|T]) :-
member(Item, H), subsets_contain_item(Item, T).
subsets_length([], _).
subsets_length([H|T], Len) :-
length(H, Len), subsets_length(T, Len).
all_are_members_and_only(Items, L) :-
all_are_members(Items, L),
only_members(Items, L).
all_are_members([], _).
all_are_members([M|T], L) :-
member(M, L), all_are_members(T, L).
only_members(_, []).
only_members(Items, [H|T]) :-
member(H, Items), only_members(Items, T).
main(_) :-
all_are_members_and_only([red, yellow, blue], Solution),
subsets_contain_item(red, L),
subsets_contain_item(yellow, L),
findall(X0, only_members(Solution, X0), L),
length(X0, 3),
write(Solution).
答案 0 :(得分:1)
完全不同的方法 - 使用ECLiPSe CLP Prolog http://www.eclipseclp.org/进行约束逻辑编程(可以翻译成其他Prolog)。
:- lib(ic).
:- lib(ic_global).
model(N, Flowers) :-
dim(Flowers, [N]),
Flowers :: 1..3, % 1 - Red, 2 - Yellow, 3 - Blue
% all three colours were represented
atleast(1, Flowers, 1), atleast(1, Flowers, 2), atleast(1, Flowers, 3),
( multifor([I, J, K], 1, N), param(Flowers) do
( (I =:= J ; I =:= K; J =:= K) ->
% skip for non-different flowers
true
;
% at least one of them was bound to be red
Flowers[I] #= 1 or Flowers[J] #= 1 or Flowers[K] #= 1,
% at least one was bound to be yellow
Flowers[I] #= 2 or Flowers[J] #= 2 or Flowers[K] #= 2
)
).
在我们拥有我们的模型之后,我们可以要求我们为3花园提供所有可能的配置:
[eclipse]: findall(Flowers, (model(3, Flowers), labeling(Flowers)), Sols).
Flowers = Flowers
Sols = [[](1, 2, 3), [](1, 3, 2), [](2, 1, 3), [](2, 3, 1), [](3, 1, 2), [](3, 2, 1)]
所有找到的配置只是1,2,3的排列 - 一个红色,一个黄色和一个蓝色花。 (我们可以在我们的模型中添加所谓的对称破坏约束,只有[](1,2,3)没有排列。)
现在让我们尝试更大的花园尺寸:
[eclipse]: findall(Flowers, (model(4, Flowers), labeling(Flowers)), Sols).
Flowers = Flowers
Sols = []
[eclipse]: findall(Flowers, (model(5, Flowers), labeling(Flowers)), Sols).
Flowers = Flowers
Sols = []
对于尺寸4和5没有解决方案。我们可以尝试更大的数字 - 没有解决方案,所以我们可以高度自信地推测(尽管我们还没有证明)唯一的解决方案是大小的花园3有一朵红色,一朵黄色和一朵蓝色花朵。第一个学生是对的。