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

时间:2015-01-14 00:55:58

标签: prolog

我正在使用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 V.S _G2033

  3. 为什么?

    另外,我知道在自动绘制中调用8个选择谓词不是正确的方法,我想确保所有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()并且直接调用匹配(调用pick是多余的)之后,自动绘制现在几乎按照我的预期工作,除了它只生成一个可能的结果。我希望得到所有可能的8对结果。现在它只打印一个固定的列表,因为在开始时输入的团队的顺序。例如,'bayernMunich'总是与'basel'配对,因为'bayernMunich'是第一支进入Rank == 1的球队,而basel是第一支可以与拜仁合法匹配的球队(勒沃库森来自德国)。 / p>

    如何修改此程序以便程序可以为我提供所有可能的组合?看起来我需要一种让prolog随机访问团队数据库而不是按顺序搜索的方法。我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

最好将逻辑与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])).