我的代码应输出竞争计划,谓词scheduleround2
用于生成game(player1,player2,round)
列表。
但是,对于Z的统一,最有可能出现错误。
这是代码:
示例输入:
schedule_round([player(alex,2), player(jane,5), player(djokovich,1), player(nadal,3), player(anderson,4), player(jack,6), player(nilson,7), player(pete,8)], R).
,输出应为
R=[game(pete,djokovich,quarter_final), game(nilson,alex,quarter_final), game(jack,nadal,quarter_final), game(jack,jane,quarter_final)]
实际发生的事情就是计算永远不会产生任何东西
%gets the maximum player rating
maxf([H|T], R) :- maximum(T, H, R).
maximum([], R, R).
maximum([player(X,Y)|T], player(_,R), F) :-
Y > R,
maximum(T, player(X,Y), F).
maximum([player(_,Y)|T], player(Z,R), F) :-
R > Y,
maximum(T, player(Z,R), F).
%gets the minimum player rating
minf([H|T], R) :- minimum(T, H, R).
minimum([], R, R).
minimum([player(X,Y)|T], player(_,R), F):-
Y < R,
minimum(T, player(X,Y), F).
minimum([player(_,Y)|T], player(Z,R), F):-
R < Y,
minimum(T, player(Z,R), F).
%removes players who are scheduled from the list
del(X, [X|L], L).
del(X, [A|L], [A|L1]) :- del(X, L, L1).
%gets size of the list
size([], 0).
size([_|T], N) :- size(T, M), N is M+1.
%scheduling predicate
schedule_round(X, R) :-
size(X, N),
schedule_round2(N, X, R).
%helper
schedule_round2(0, _, []).
schedule_round2(N, H, Z) :-
N2 is N-2,
maxf(H, F),
minf(H, B),
del(F, H, L),
del(B, L, J),
append(Z, game(F, B, quarter_final), K),
schedule_round2(N2, J, K).
答案 0 :(得分:0)
schedule_round
的定义存在一些问题。
终止案例schedule_round(0, _, []).
失败,因为对schedule_round
的递归调用中的第三个参数始终是非空列表。另外,我原来的append/3
声明确实是个问题。由于您的第二个参数不是列表而且应该是[game(F, B, quarter_final)]
而不仅仅是game(F, B, quarter_final)
,因此它将在第一次出现后失败。当append
失败时,schedule_round
代码会回溯其他谓词查询,提出另一种可能的解决方案,并再次无效append
失败。另外,什么被附加到翻转的东西。我们希望对schedule_round2
的递归调用是任何给定调用的解决方案的尾部,因此新元素会在当前调用中为尾部提供新解决方案。
所以“快速修复”只是将schedule_round2
递归子句改为:
schedule_round2(N, H, Z) :-
N2 is N-2,
maxf(H, F),
minf(H, B),
del(F, H, L),
del(B, L, J),
append([game(F, B, quarter_final)], K, Z),
schedule_round2(N2, J, K).
这样可行,但事实证明您不需要append/3
,因为append([X], In, Out)
与Out = [X|List]
相同。我们可以将其减少为:
%helper
schedule_round2(0, _, []).
schedule_round2(N, H, [game(F,B,quater_final)|Z]) :-
N > 1, % This ensures N2 won't go negative due to bad input
N2 is N-2,
maxf(H, F),
minf(H, B),
del(F, H, L),
del(B, L, J),
schedule_round2(N2, J, Z). % Schedule round for rest of the list
此版本将使用第三个参数(解决方案的尾部)递归到schedule_round2
未实例化,直到它到达基本子句。此时,第三个参数(解决方案尾部)将实例化为[]
并将您的解决方案回滚到递归返回的所需结果。
以下是一些其他可选的建议更改:
(1)您的minimum
和maximum
假设比较的值永远不会相等。也许情况就是这样。但你可能会考虑:
maximum([player(_,Y)|T], player(Z,R), F) :-
R >= Y,
...
和
minimum([player(_,Y)|T], player(Z,R), F):-
R =< Y,
...
(2)在schedule_round2/3
我添加了对N > 1
的检查。如果你总是给它一个偶数奇偶校验列表(这是预期的)是没有必要的,但是如果你确实给它一个奇数奇偶校验列表,它将导致谓词优雅地失败而不是在负N
上递归很长一段时间。
(3)由于Prolog已提供列表长度谓词size/2
,因此您的length/2
谓词是不必要的。