
[英]Prolog, Printing variable instead of actual answer, works for different answer but not for duplicates
[英]Prolog printing storage address instead of actual variables
我正在使用Prolog为冠军联赛淘汰赛编写自动抽奖程序。 代码如下。
/* ChampionLeagueAutoDraw_KnockOutRound */
%% by Zach X.
% some "nice" prolog settings
%
:- set_prolog_flag( prompt_alternatives_on, groundness ).
:- set_prolog_flag(toplevel_print_options, [quoted(true),
portray(true), attributes(portray), max_depth(999), priority(699)]).
%% Dynamic database for team candidates.
:- dynamic team/5.
%% team(name, nationality, rank, group, bool_taken).
team(BayernMunich, Germany, 1, E, 0).
team(AtleticoMadird, Spain, 1, A, 0).
team(RealMadrid, Spain, 1, B, 0).
team(Monaco, France, 1, C, 0).
team(Dortmund, Germany, 1, D, 0).
team(Barcelona, Spain, 1, F, 0).
team(Chelsea, England, 1, G, 0).
team(Porto, Portugal, 1, H, 0).
team(Juventus, Italy, 2, A, 0).
team(Basel, Switzerland, 2, B, 0).
team(Leverkusen, Germany, 2, C, 0).
team(Arsenal, England, 2, D, 0).
team(ManCity, England, 2, E, 0).
team(PSG, France, 2, F, 0).
team(Schalke04, Germany, 2, G, 0).
team(Shaktar, Ukraine, 2, H, 0).
%% Pick the first team ready for matching.
%% When a team is picked, the bool_taken flag is set to 1.
pick(X) :-
team(X,N,R,G,0),
retract(team(X,_,_,_,_)),
assert(team(X,N,R,G,1)),
match(X,_).
%% Rules for match():
%% Teams from the same country do not meet;
%% Teams from the same group do not meet;
%% Teams with the same rank do not meet;
match(X,Y) :-
team(X,Nx,Rx,Gx,1),
team(Y,Ny,Ry,Gy,0),
X\==Y,
Nx\==Ny,
Rx\==Ry,
Gx\==Gy,
retract(team(Y,_,_,_,_)),
assert(team(Y,Ny,Ry,Gy,1)),
nl,write(X), write(' V.S '), write(Y).
%% Pick all 8 matches (pretty sure this is not the right way to
% write it...)
autodraw :-
pick(_),pick(_),pick(_),pick(_),pick(_),pick(_),pick(_),pick(_).
两个问题:
当我编译它时,在16个团队的数据库中有大量的单例警告,为什么?
调用autodraw时,应该打印出每场比赛的球队名称,但会打印出类似以下内容:
_G2032 VS _G2033
为什么?
另外,我知道在自动绘制中调用8个pick谓词不是正确的方法,我想确保所有8个匹配项都一次完成并打印出来。 有更好的选择吗?
===========更新============
/* ChampionLeagueAutoDraw_KnockOutRound */
%% by Zach X.
% some "nice" prolog settings
%
:- set_prolog_flag( prompt_alternatives_on, groundness ).
:- set_prolog_flag(toplevel_print_options, [quoted(true),
portray(true), attributes(portray), max_depth(999), priority(699)]).
% Dynamic database for team candidates.
:- dynamic team/5.
% team(name, nationality, rank, group, bool_taken).
team(bayernMunich, germany, 1, e, 0).
team(atleticoMadird, spain, 1, a, 0).
team(realMadrid, spain, 1, b, 0).
team(monaco, france, 1, c, 0).
team(dortmund, germany, 1, d, 0).
team(barcelona, spain, 1, f, 0).
team(chelsea, england, 1, g, 0).
team(porto, portugal, 1, h, 0).
team(leverkusen, germany, 2, c, 0).
team(basel, switzerland, 2, b, 0).
team(juventus, italy, 2, a, 0).
team(arsenal, england, 2, d, 0).
team(manCity, england, 2, e, 0).
team(psg, france, 2, f, 0).
team(schalke04, germany, 2, g, 0).
team(shaktar, ukraine, 2, h, 0).
%% Rules for match():
%% Teams from the same country do not meet;
%% Teams from the same group do not meet;
%% Teams with the same rank do not meet;
match(X,Y) :-
X\==Y,
team(X,Nx,Rx,Gx,Bx),
team(Y,Ny,Ry,Gy,By),
Bx==0,
By==0,
Nx\==Ny,
Rx\==Ry,
Gx\==Gy,
retract(team(X,Nx,Rx,Gx,Bx)),
assert(team(X,Nx,Rx,Gx,1)),
retract(team(Y,Ny,Ry,Gy,By)),
assert(team(Y,Ny,Ry,Gy,1)),
nl,write(X), write(' V.S '), write(Y).
%% Pick all 8 matches (Correct way to do it?)
autodraw :-
match(_,_), fail.
在摆脱了pick()并直接调用match(调用pick是多余的)之后,自动绘制现在几乎可以按我的预期工作,除了它只会生成一个可能的结果。 我想得到所有可能的8对结果。 现在,由于开始时输入的团队顺序,它仅打印固定列表。 例如,“ bayernMunich”始终与“ basel”配对,因为“ bayernMunich”是第一个进入Rank == 1的球队,而Basel是第一个可以合法与Bayern比赛的球队(勒沃库森来自德国)。
我如何修改它,以便程序可以给我所有可能的组合? 看来我需要一种方法来使序言随机访问团队数据库,而不是按顺序搜索它。 我怎样才能做到这一点?
最好将逻辑与IO分开,并避免在不需要时产生副作用(如断言/收回)。 它们会使您的程序很难调试。
match(X,Y) :-
team(X,Nx,Rx,Gx,_Bx),
team(Y,Ny,Ry,Gy,_By),
Nx\==Ny,
Rx\==Ry,
Gx\==Gy.
autodraw :-
forall(match(X,Y), (nl, write(X), write(' V.S '), write(Y))).
team / 5的最后一个参数似乎专用于跟踪“加入”,我认为这没有用。
要打印格式化的输出,格式化它通常比多次写入更适合:
autodraw :-
forall(match(X,Y), format('~n~w V.S ~w', [X,Y])).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.