繁体   English   中英

Prolog打印存储地址,而不是实际变量

[英]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(_).

两个问题:

  1. 当我编译它时,在16个团队的数据库中有大量的单例警告,为什么?

  2. 调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM