2:- module(printCCG,[printCCG/2]).    3
    4:- use_module(boxer(slashes)).    5:- use_module(library(lists),[reverse/2]).    6
    7
    8/* ----------------------------------------------------------------------
    9   Main Predicate
   10---------------------------------------------------------------------- */
   11
   12printCCG(CCG,Stream):-
   13   ccg2lines(CCG,_,Lines), !,
   14   reverse(Lines,Reversed),
   15   printLines(Reversed,Stream).
   16
   17printCCG(CCG,Stream):-
   18   write(Stream,CCG), nl(Stream).
   19
   20
   21/* ----------------------------------------------------------------------
   22   Print Lines (the CCG derivation)
   23---------------------------------------------------------------------- */
   24
   25printLines([],Stream):- 
   26   nl(Stream).
   27
   28printLines([X|L],Stream):- 
   29   tab(Stream,1), write(Stream,X), nl(Stream), 
   30   printLines(L,Stream).
   31
   32
   33/* ----------------------------------------------------------------------
   34   Compute each line
   35---------------------------------------------------------------------- */
   36
   37ccg2lines(n(X),Len,Lines):- !,
   38   ccg2lines(X,Len,Lines).
   39
   40ccg2lines(lf(Cat,_,_,Tok),Len,[Line1,Line2,Line3]):- !,
   41   ccg2lines(tok(Cat,Tok),Len,[Line1,Line2,Line3]).
   42
   43ccg2lines(t(Cat,Tok,_,_,_),Len,[Line1,Line2,Line3]):- !,
   44   ccg2lines(tok(Cat,Tok),Len,[Line1,Line2,Line3]).
   45
   46ccg2lines(tok(Cat,Tok),Len,[Line1,Line2,Line3]):- !,
   47   cat2atom(Cat,CatAtom),
   48   atom_length(CatAtom,CatLen),
   49   atom_length(Tok,TokLen),
   50   Len is max(7,max(CatLen,TokLen)),
   51   cat(CatAtom,Len,Line1),
   52   rule(lex,Len,Line2),
   53   cat(Tok,Len,Line3).
   54
   55ccg2lines(Rule,Max,[Line1,Line2|L3]):-
   56   ( Rule = tc(N,_,_,_,_,Tree), RuleName = '*'
   57   ; Rule = ftr(N,_,_,_,_,Tree), RuleName = '>T'
   58   ; Rule = btr(N,_,_,_,_,Tree), RuleName = '<T' ), !,
   59   cat2atom(N,Atom),
   60   atom_length(Atom,CatLen),
   61   ccg2lines(Tree,TreeLen,L2),
   62   fillRight(L2,TreeLen,CatLen,Max,L3),
   63   cat(Atom,Max,Line1),
   64   rule(RuleName,Max,Line2).
   65
   66ccg2lines(Rule,Max,[Line1,Line2|L5]):-
   67   binRuleName(Rule,N,Left,Right,Name), !,
   68   cat2atom(N,Atom),
   69   atom_length(Atom,CatLen),
   70   ccg2lines(Left,MaxLeft,L2),
   71   ccg2lines(Right,MaxRight,L3),
   72   combLines(MaxLeft,L2,MaxRight,L3,TreeLen,L4),
   73   fillRight(L4,TreeLen,CatLen,Max,L5),
   74   cat(Atom,Max,Line1),
   75   rule(Name,Max,Line2).
   76
   77ccg2lines(Rule,Max,[Line1,Line2|L7]):-
   78   Rule = coord(N,_,_,_,Left,Middle,Right), !,
   79   RuleName = coord,
   80   cat2atom(N,Atom),
   81   atom_length(Atom,CatLen),
   82   ccg2lines(Left,MaxLeft,L2),
   83   ccg2lines(Middle,MaxMiddle,L3),
   84   combLines(MaxLeft,L2,MaxMiddle,L3,MaxTemp,L4),
   85   ccg2lines(Right,MaxRight,L5),
   86   combLines(MaxTemp,L4,MaxRight,L5,TreeLen,L6),
   87   fillRight(L6,TreeLen,CatLen,Max,L7),
   88   cat(Atom,Max,Line1),
   89   rule(RuleName,Max,Line2).
   90
   91
   92/* ----------------------------------------------------------------------
   93   Combine Lines
   94---------------------------------------------------------------------- */
   95
   96combLines(MaxLeft,Left,MaxRight,Right,Max,New):-
   97   Max is MaxLeft + MaxRight + 1,
   98   fill(' ',MaxLeft,SpaceLeft),
   99   fill(' ',MaxRight,SpaceRight),
  100   combLines(Left,SpaceLeft,Right,SpaceRight,New).
  101
  102combLines([],_,[],_,[]):- !.
  103
  104combLines([],Space1,L2,Space2,L3):- !,
  105   combLines([Space1],Space1,L2,Space2,L3).
  106
  107combLines(L1,Space1,[],Space2,L3):- !,
  108   combLines(L1,Space1,[Space2],Space2,L3).
  109
  110combLines([X1|L1],Space1,[X2|L2],Space2,[X3|L3]):-
  111   atom_concat(X1,' ',Temp),
  112   atom_concat(Temp,X2,X3),
  113   combLines(L1,Space1,L2,Space2,L3).
  114
  115
  116/* ----------------------------------------------------------------------
  117   Filling out spaces to the right (sometimes needed)
  118---------------------------------------------------------------------- */
  119
  120fillRight(L,TreeLen,CatLen,TreeLen,L):- 
  121   TreeLen > CatLen, !.
  122
  123fillRight(L,TreeLen,CatLen,TreeLen,L):- 
  124   TreeLen = CatLen, !.
  125
  126fillRight(L1,TreeLen,CatLen,CatLen,L2):- 
  127   TreeLen < CatLen, !,
  128   Len is CatLen-TreeLen,
  129   fill(' ',Len,Fill),
  130   fillRight(L1,Fill,L2).
  131
  132fillRight([],_,[]).
  133
  134fillRight([X1|L1],Fill,[X2|L2]):-
  135   atom_concat(X1,Fill,X2),
  136   fillRight(L1,Fill,L2).
  137
  138
  139/* ----------------------------------------------------------------------
  140   Format a rule
  141---------------------------------------------------------------------- */
  142
  143rule(Rule,Max,Line):-
  144   atom_length(Rule,Len),
  145   FillLen is ((Max - Len) - 2),
  146   fill('-',FillLen,Fill),
  147   atom_concat(Fill,'[',Line1),
  148   atom_concat(Line1,Rule,Line2),
  149   atom_concat(Line2,']',Line), !.
  150
  151
  152/* ----------------------------------------------------------------------
  153   Format a cat
  154---------------------------------------------------------------------- */
  155
  156cat(Cat,Max,Line):-
  157   atom_length(Cat,Len),
  158   FillLen is Max - Len,
  159   fill(' ',FillLen,Fill),
  160   atom_concat(Cat,Fill,Line), !.
  161
  162
  163/* ----------------------------------------------------------------------
  164   Fill a line with a character
  165---------------------------------------------------------------------- */
  166
  167fill(Atom,Len,Result):-
  168   atom_codes(Atom,[Code]),
  169   fill2(Code,Codes,Len),
  170   atom_codes(Result,Codes), !.
  171
  172fill2(_,[],Len):- Len < 0, !.
  173
  174fill2(_,[],0):- !.
  175
  176fill2(X,[X|L],N):-
  177   M is N - 1,
  178   fill2(X,L,M).
  179
  180
  181/* ----------------------------------------------------------------------
  182   Convert a CCG cat to an atom
  183---------------------------------------------------------------------- */
  184
  185cat2atom(Cat,Atom):- cat2atom(Cat,Atom,top).
  186
  187cat2atom(conj:_,Atom,Level):- !, cat2atom(conj,Atom,Level).
  188
  189cat2atom(X:F,Cat,_):- 
  190   atom(X), atom(F), !,
  191   atom_concat(':',F,Temp),
  192   atom_concat(X,Temp,Cat), !.
  193
  194cat2atom(X,X,_):- atom(X), !.
  195
  196cat2atom(X/Y,Atom,top):- !,
  197   cat2atom(X,F,notop),
  198   cat2atom(Y,A,notop),
  199   atom_concat(F,'/',Temp),
  200   atom_concat(Temp,A,Atom).
  201
  202cat2atom(X/Y,Atom,notop):- !,
  203   cat2atom(X,F,notop),
  204   cat2atom(Y,A,notop),
  205   atom_concat('(',F,Temp1),
  206   atom_concat(Temp1,'/',Temp2),
  207   atom_concat(Temp2,A,Temp3),
  208   atom_concat(Temp3,')',Atom).
  209
  210cat2atom(X\Y,Atom,top):- !,
  211   cat2atom(X,F,notop),
  212   cat2atom(Y,A,notop),
  213   atom_concat(F,'\\',Temp),
  214   atom_concat(Temp,A,Atom).
  215
  216cat2atom(X\Y,Atom,notop):-
  217   cat2atom(X,F,notop),
  218   cat2atom(Y,A,notop),
  219   atom_concat('(',F,Temp1),
  220   atom_concat(Temp1,'\\',Temp2),
  221   atom_concat(Temp2,A,Temp3),
  222   atom_concat(Temp3,')',Atom).
  223
  224
  225/* ----------------------------------------------------------------------
  226   Binary Rule Name
  227---------------------------------------------------------------------- */
  228
  229binRuleName(ba(N,_,_,_,Left,Right),N,Left,Right,'<').
  230binRuleName(fa(N,_,_,_,Left,Right),N,Left,Right,'>').
  231binRuleName(fc(N,_,_,_,Left,Right),N,Left,Right,'>B').
  232binRuleName(bc(N,_,_,_,Left,Right),N,Left,Right,'<B').
  233binRuleName(fs(N,_,_,_,Left,Right),N,Left,Right,'>S').
  234binRuleName(bs(N,_,_,_,Left,Right),N,Left,Right,'<S').
  235binRuleName(fxc(N,_,_,_,Left,Right),N,Left,Right,'>Bx').
  236binRuleName(bxc(N,_,_,_,Left,Right),N,Left,Right,'<Bx').
  237binRuleName(fxs(N,_,_,_,Left,Right),N,Left,Right,'>Sx').
  238binRuleName(bxs(N,_,_,_,Left,Right),N,Left,Right,'<Sx').
  239binRuleName(gfc(N,_,_,_,_,Left,Right),N,Left,Right,gfc).
  240binRuleName(gbc(N,_,_,_,_,Left,Right),N,Left,Right,gbc).
  241binRuleName(gfxc(N,_,_,_,_,Left,Right),N,Left,Right,gfxc).
  242binRuleName(gbxc(N,_,_,_,_,Left,Right),N,Left,Right,gbxc).
  243binRuleName(conj(N,_,_,_,_,Left,Right),N,Left,Right,conj)