Prolog:解决难题
Prolog: Solving a Puzzle
我是 prolog 的新手,我正在尝试解决以下问题。我很难理解解决问题的逻辑。我知道它类似于斑马问题,但我不确定如何处理。任何帮助将不胜感激。
五名学生提交的 T/F 测验答案如下。
Teresa: T T F T F
Tim: F T T T F
Tania: T F T T F
Tom: F T T F T
Tony: T F T F T
- Tania 比 Teresa 答对了更多。
- Tom 比 Tim 更正确。
- 托尼并没有答对所有的答案,也没有全部答错。
编写一个 Prolog 程序 quiz(Answer)
断言 Answer 是 t
和 f
常量的列表,它是测验的正确答案..
像这样的小谜题可以通过生成和测试来解决
solve(L) :-
% generator
length(L, 5), maplist(tf, L),
% Tania got more answers right than Teresa did.
matches(L, tania, Tania),
matches(L, teresa, Teresa), Tania > Teresa,
...
tf(t).
tf(f).
teresa(t, t, f, t, f).
tim(f, t, t, t, f).
...
当然,matches(L, tania, Tania)
会计算 Tania 的正确答案。
但是,我没有找到解决方案。 'get thru' Tony 唯一的元组,它是它的确切结果。所以,这个条件
Tony did not get all the answers right
无法解决...
编辑 我在 matches/3 中有一个错误。当然是有办法的。
编辑好吧,CLP(FD) 版本可以非常紧凑,同时更通用...
teresa(t, t, f, t, f).
...
matches(L, P, N) :-
call(P, A,B,C,D,E),
foldl(eqsum, [A,B,C,D,E], L, 0, N).
eqsum(t,Ls,Acc,N) :- N #= Acc + (° #<==> Ls #= 1).
eqsum(f,Ls,Acc,N) :- N #= Acc + (° #<==> Ls #= 0).
solve(L) :-
length(°L, 5) ins 0..1,
% Tania got more answers right than Teresa did.
matches(L, tania, °) #> matches(L, teresa, °),
% Tom got more right than Tim.
matches(L, tom, °) #> matches(L, tim, °),
% Tony did not get all the answers right, nor did he get them all wrong.
matches(L, tony, °Tony) #> 0, Tony #< 5.
我在这里使用了我的lifter。
如果你使用 SWI-Prolog,你可以使用库 clpfd 来解决这个难题:,我只有一个解决方案 (f,f,t,f,t)。
你有一个解决方案 [A,B,C,D,E]。
您使用
初始化可能的解决方案
[A,B,C,D,E] ins 0..1,
例如,您具体化了 teresa 的所有答案
teresea([1,1,0,1,0]).
A #= 1 #<==> TA
B #= 1 #<==> TB
.....
你计算 Tis 的总和
sum([TA, TB, ...], #= , Steresa),
稍后你将有
Tania 比 Teresa 答对了更多。
Stania #> Steresa
你得到解决方案
label([A,B,C,D,E]).
希望对您有所帮助
我是 prolog 的新手,我正在尝试解决以下问题。我很难理解解决问题的逻辑。我知道它类似于斑马问题,但我不确定如何处理。任何帮助将不胜感激。
五名学生提交的 T/F 测验答案如下。
Teresa: T T F T F
Tim: F T T T F
Tania: T F T T F
Tom: F T T F T
Tony: T F T F T
- Tania 比 Teresa 答对了更多。
- Tom 比 Tim 更正确。
- 托尼并没有答对所有的答案,也没有全部答错。
编写一个 Prolog 程序 quiz(Answer)
断言 Answer 是 t
和 f
常量的列表,它是测验的正确答案..
像这样的小谜题可以通过生成和测试来解决
solve(L) :-
% generator
length(L, 5), maplist(tf, L),
% Tania got more answers right than Teresa did.
matches(L, tania, Tania),
matches(L, teresa, Teresa), Tania > Teresa,
...
tf(t).
tf(f).
teresa(t, t, f, t, f).
tim(f, t, t, t, f).
...
当然,matches(L, tania, Tania)
会计算 Tania 的正确答案。
但是,我没有找到解决方案。 'get thru' Tony 唯一的元组,它是它的确切结果。所以,这个条件
Tony did not get all the answers right
无法解决...
编辑 我在 matches/3 中有一个错误。当然是有办法的。
编辑好吧,CLP(FD) 版本可以非常紧凑,同时更通用...
teresa(t, t, f, t, f).
...
matches(L, P, N) :-
call(P, A,B,C,D,E),
foldl(eqsum, [A,B,C,D,E], L, 0, N).
eqsum(t,Ls,Acc,N) :- N #= Acc + (° #<==> Ls #= 1).
eqsum(f,Ls,Acc,N) :- N #= Acc + (° #<==> Ls #= 0).
solve(L) :-
length(°L, 5) ins 0..1,
% Tania got more answers right than Teresa did.
matches(L, tania, °) #> matches(L, teresa, °),
% Tom got more right than Tim.
matches(L, tom, °) #> matches(L, tim, °),
% Tony did not get all the answers right, nor did he get them all wrong.
matches(L, tony, °Tony) #> 0, Tony #< 5.
我在这里使用了我的lifter。
如果你使用 SWI-Prolog,你可以使用库 clpfd 来解决这个难题:,我只有一个解决方案 (f,f,t,f,t)。
你有一个解决方案 [A,B,C,D,E]。 您使用
初始化可能的解决方案[A,B,C,D,E] ins 0..1,
例如,您具体化了 teresa 的所有答案
teresea([1,1,0,1,0]).
A #= 1 #<==> TA
B #= 1 #<==> TB
.....
你计算 Tis 的总和
sum([TA, TB, ...], #= , Steresa),
稍后你将有 Tania 比 Teresa 答对了更多。
Stania #> Steresa
你得到解决方案
label([A,B,C,D,E]).
希望对您有所帮助