"Which answer in this list is the correct answer to this question?" 的序言实施
Prolog implementation of "Which answer in this list is the correct answer to this question?"
我在 Math Exchange 上遇到 this post,要求解决以下逻辑难题:
Which answer in this list is the correct answer to this question?
- All of the below.
- None of the below.
- All of the above.
- One of the above.
- None of the above.
- None of the above.
我知道答案是 5,但是因为我正在尝试学习 Prolog,所以我想找到一种方法让 Prolog 给我答案。
我尝试使用以下知识库对拼图中给出的信息进行编码:
answer(1) :- answer(2),answer(3),answer(4),answer(5),answer(6).
answer(2) :- \+answer(3), \+answer(4), \+answer(5), \+answer(6).
answer(3) :- answer(1), answer(2).
answer(4) :- answer(1); answer(2); answer(3).
answer(5) :- \+answer(1), \+answer(2), \+answer(3), \+answer(4).
answer(6) :- \+answer(1), \+answer(2), \+answer(3), \+answer(4), \+answer(5).
但是,在尝试评估时
?- answer(X).
I 运行 进入无限递归(天真地替换谓词时这是可以预期的)。
- 有没有办法用 Prolog 解决这个特定的难题? 1
- 更一般地说,我如何提前知道逻辑难题何时适合 Prolog?
1:是的,我知道 Prolog 是图灵完备的,所以将问题编码到图灵机中并迭代所有可能的解决方案(就像第一个答案中所做的那样数学交换 post) 当然是可能的,但我正在寻找解决这个问题的“规范”方法。
这感觉像是 library(clpb) 的一个很好的用途,用于定义和解决使用布尔变量的直接解决方案:
:- use_module(library(clpb)).
solve(Answer) :-
Options = [A1, A2, A3, A4, A5, A6],
sat(*([
(A1 =:= (A2 * A3 * A4 * A5 * A6)),
(A2 =:= (~A3 * ~A4 * ~A5 * ~A6)),
(A3 =:= (A1 * A2)),
(A4 =:= (card([1], [A1, A2, A3]))),
(A5 =:= (~A1 * ~A2 * ~A3 * ~A4)),
(A6 =:= ( ~A1 * ~A2 * ~A3 * ~A4 * ~A5))
])),
labeling(Options),
nth1(Answer, Options, 1).
将选项提供为变量 A1
到 A6
,每个单独的表达式都必须成立,因此它们与 *(Exprs)
结合。大多数选项如问题中所列,只是转换为 CLP(B) 形式。 A4
使用基数约束,这意味着列出的选项中“只有一个”可以为真。经过运行选项到labeling
选项,从设置为1的选项中挑出答案,结果如预期:
?- solve(Answer).
Answer = 5 ;
false.
我在 Math Exchange 上遇到 this post,要求解决以下逻辑难题:
Which answer in this list is the correct answer to this question?
- All of the below.
- None of the below.
- All of the above.
- One of the above.
- None of the above.
- None of the above.
我知道答案是 5,但是因为我正在尝试学习 Prolog,所以我想找到一种方法让 Prolog 给我答案。 我尝试使用以下知识库对拼图中给出的信息进行编码:
answer(1) :- answer(2),answer(3),answer(4),answer(5),answer(6).
answer(2) :- \+answer(3), \+answer(4), \+answer(5), \+answer(6).
answer(3) :- answer(1), answer(2).
answer(4) :- answer(1); answer(2); answer(3).
answer(5) :- \+answer(1), \+answer(2), \+answer(3), \+answer(4).
answer(6) :- \+answer(1), \+answer(2), \+answer(3), \+answer(4), \+answer(5).
但是,在尝试评估时
?- answer(X).
I 运行 进入无限递归(天真地替换谓词时这是可以预期的)。
- 有没有办法用 Prolog 解决这个特定的难题? 1
- 更一般地说,我如何提前知道逻辑难题何时适合 Prolog?
1:是的,我知道 Prolog 是图灵完备的,所以将问题编码到图灵机中并迭代所有可能的解决方案(就像第一个答案中所做的那样数学交换 post) 当然是可能的,但我正在寻找解决这个问题的“规范”方法。
这感觉像是 library(clpb) 的一个很好的用途,用于定义和解决使用布尔变量的直接解决方案:
:- use_module(library(clpb)).
solve(Answer) :-
Options = [A1, A2, A3, A4, A5, A6],
sat(*([
(A1 =:= (A2 * A3 * A4 * A5 * A6)),
(A2 =:= (~A3 * ~A4 * ~A5 * ~A6)),
(A3 =:= (A1 * A2)),
(A4 =:= (card([1], [A1, A2, A3]))),
(A5 =:= (~A1 * ~A2 * ~A3 * ~A4)),
(A6 =:= ( ~A1 * ~A2 * ~A3 * ~A4 * ~A5))
])),
labeling(Options),
nth1(Answer, Options, 1).
将选项提供为变量 A1
到 A6
,每个单独的表达式都必须成立,因此它们与 *(Exprs)
结合。大多数选项如问题中所列,只是转换为 CLP(B) 形式。 A4
使用基数约束,这意味着列出的选项中“只有一个”可以为真。经过运行选项到labeling
选项,从设置为1的选项中挑出答案,结果如预期:
?- solve(Answer).
Answer = 5 ;
false.