[Prolog]論理パズル/正直者は誰? (失敗例)

非常に素直に実装してみたら解けてない。
「嘘つきは1人いる」か否かをチェックするために、「嘘つきは1人いる」か否かをチェックするため、無限再帰に陥る。

非常に素直に実装してみたら解けてない。
「嘘つきは1人いる」か否かをチェックするために、「嘘つきは1人いる」か否かをチェックするため、無限再帰に陥る。

% 嘘つき問題
/*
	正直者は誰?
	A1「ここに、嘘つきは1人いる。」
	A2「ここに、嘘つきは2人いる。」
	A3「ここに、嘘つきは3人いる。」
	A4「ここに、嘘つきは4人いる。」
	A5「ここに、嘘つきは5人いる。」
	
	引用('数学ガール ゲーデルの不完全性定理', page: 3).
*/

% 定義
嘘(A) :- \+(A).

正直者(P) :- 人(P), \+(嘘つき(P)).
嘘つき(P) :- 人(P), 主張(P, A), 嘘(A).

'嘘つきはN人いる'(N) :- setof(P, 嘘つき(P), L), length(L, N).

% 問題
人(a1). 主張(a1, '嘘つきはN人いる'(1)).	% 元々閉世界なので「ここに、」は不要
人(a2). 主張(a2, '嘘つきはN人いる'(2)).
人(a3). 主張(a3, '嘘つきはN人いる'(3)).
人(a4). 主張(a4, '嘘つきはN人いる'(4)).
人(a5). 主張(a5, '嘘つきはN人いる'(5)).

:- trace. % ステップ実行にて無限再帰を確認なされ
?- setof(P, 正直者(P), L).	% 正直者リスト L を求める。
%	L = [a4]