[Prolog]論理パズル/帽子は何色?

意外とすっきりした解答が得られたので。

意外とすっきりした解答が得られたので。

/*
	帽子は何色?
	論理的思考力を持つ3人の正直者 a, b, c に、5つの帽子(赤×3, 白×2)のうち3つを1つずつ被せる。
	どの人も、他2人の帽子の色を知っている(∵見えている)が、自身の帽子の色は知らない。
	出題者「あなたの帽子の色は?」 a「……わかりません。」
	出題者「あなたの帽子の色は?」 b「……わかりません。」
	出題者「あなたの帽子の色は?」 ――さて、c の帽子の色は?

% 出展('数学ガール ゲーデルの不完全性定理', page: 16).
% (同値な問題だが、文字数圧縮のため問題文は書き直した。)
*/

insert(E, Set, [E|Set]).
insert(E, [X|Set0], [X|Set]) :- insert(E, Set0, Set).

部分集合([], X).
部分集合([H|L], R) :- insert(H, R0, R), 部分集合(L, R0).

不確定(X, Cond) :-		% 条件 Cond を満たす変数 X は一意に存在しない
	setof(X, Cond, L), \+(length(L, 1)).
	
?-	_hats = [赤, 赤, 赤, 白, 白],		% 簡単のため
	A = 赤, B = 赤, (C = 赤 ; C = 白),
%	部分集合([A, B, C], _hats),
	
	% a には自身の帽子の色 ASelf が確定できない
	不確定(ASelf, 部分集合([ASelf, B, C], _hats)),
	
	% a には自身の帽子の色 ASelf が確定できないことが分かっていても、
	% b には自身の帽子の色 BSelf が確定できない
	不確定(BSelf, (
		部分集合([A, BSelf, C], _hats),
		不確定(ASelf2, 部分集合([ASelf2, BSelf, C], _hats))
	)).

% A = 赤, B = 赤, C = 赤