Newsgroups: comp.lang.prolog
Path: utzoo!utdoe!peter
From: peter@doe.utoronto.ca (Peter Mielke)
Subject: Re: Tree drawing
Message-ID: <1991Feb16.203209.29369@doe.utoronto.ca>
Reply-To: peter@doe.utoronto.ca (Peter Mielke)
Organization: Dictionary of Old English Project, University of Toronto
Date: Sat, 16 Feb 1991 20:32:09 GMT


In <1991Feb16.035944.3055@athena.cs.uga.edu>, Michael A. Covington writes:
> Has anyone written a routine to display a Prolog structure in
> tree form, so that for example
> 
>       s(np(d(the),n(dog)),vp(v(barked)))
> 
> prints as something like this: --?
> 
>            s
>            |
>       ----------
>       np       vp
>       |        |
>     ------     |
>     |    |     |
>     d    n     v
> 
>    the  dog  barked

Are you writing some sort of NL parser? :-)

Here is some code that i used to print out tree diagrams for my
project. (It is written in the C-Prolog variant). It's not quite the
way you want but it may help...

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% USER INTERFACE
%
% $Header: /usr/u/jrrandall/prolog/RCS/io,v 3.3 91/01/29 09:35:32 jrrandall Exp $
%
% $Log: io,v $
% Revision 3.3  91/01/29  09:35:32  jrrandall
% added the move frame, and cleaned stuff up so it would work under quintus log.
% 
% Revision 3.2  91/01/26  12:59:19  psmielke
% made changes to the print struct routine and the way annotation is
% done.
% 
% Revision 3.1  91/01/22  19:06:49  psmielke
% removed misc routines that are no longer needed
% 
%
print_output([Word]) :- !, write(Word), nl.
%
% do not follow punctuation with a space
%
print_output([Word,','|Words]) :-
        write(Word),
        print_output([','|Words]),
        !.
print_output([Word,'?'|Words]) :-
        write(Word),
        print_output(['?'|Words]),
        !.
print_output([Word|Words]) :-
        write(Word),
        write(' '),
        print_output(Words),
        !.
print_output([]).
 
read_sent(Words) :-
        get0(Char),
        read_sent(Char,Words).
read_sent(C,[]) :- newline(C),!.
read_sent(C,Words) :-
        skipchar(C),
        !,
        get0(Char),
        read_sent(Char,Words).
read_sent(Char,[Word|Words]) :-
        read_word(Char,Chars,Next),
        name(Word,Chars),
        read_sent(Next,Words).
 
skipchar(32).        % skip spaces
skipchar(33).        % skip exclamation mark
skipchar(44).        % skip comma
skipchar(46).        % skip period
skipchar(58).        % skip colon
skipchar(59).        % skip semi-colon
skipchar(63).        % skip question mark

newline(10).

read_word(C,[],C) :- skipchar(C),!.
read_word(C,[],C) :- newline(C),!.
read_word(Char,[Char|Chars],New) :-
        get0(Next),
        read_word(Next,Chars,New).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% print a structure tree
%
% (now also prints lists)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% print_struct(Tree)
% print_struct(Tree,Tab)
%
% eg.  print_struct(a(b,c,d(e,f))) gives:
%
% a(
%     b,
%     c,
%     d(
%         e,
%         f
%     )
% )
%

print_struct(Tree, Tab) :- !,
    Tree =.. [Node|List],
    p_struct(0, Tab, Node, List), nl.
print_struct(Tree) :- !,
    Tree =.. [Node|List],
    p_struct(0, 4, Node, List), nl.

%
% list of printable nodes (all others are rejected; used for
% information hiding)
%
allowable_nodes( [ adjectives, aux_verb, copula, determiner, ind_object,
    infinitive_clause, noun, noun_phrase, prep_phrase, preposition, pronoun,
    proper_noun, quantifier, rel_phrase, sentence, verb, verb_phrase,
    comp, mods, qualifier ] ).
%
% print the node name of the current node and then list all the
% (check to see if node is in current list of printable nodes)
%
% subnodes (if only one subnode print it on the same line)
%
p_struct(Offset, Tab, frame, [Head|[SList]] ) :- !,
    tab(Offset), write( frame ), nl,
    Offset2 is Offset + Tab,
    tab(Offset2), write( Head ), nl,
    p_slots( Offset2, SList ).

p_slots( _, [] ).
p_slots( Offset, [Slot|Rest] ) :-
    p_slot( Offset, Slot ),
    nl,
    p_slots( Offset, Rest ).

p_slot( Offset, [Slotname|Filler] ) :-
    tab(Offset), write( Slotname ), put(32), put(58), put(32), % double colon
    p_slot2( Filler ).

p_slot2( [] ).
%
%   exception for uninstatiated values
%
p_slot2( [Head|Tail] ) :-
    var( Head ), !,
    write( '_' ),
    p_comma( Tail ),
    p_slot2( Tail ).
p_slot2( [Head|Tail] ) :-
    write( Head ),
    p_comma( Tail ),
    p_slot2( Tail ).
    
%
% print a comma only if we are NOT at the end of the list
%
p_comma([]).
p_comma(_) :- put(44), put(32).
    
p_struct(Offset, _, Node, [Head|Tail]) :-
    allowable_nodes( NList ),
    member( Node, NList ),
    atom(Head), Tail = [], !,
    nl, tab(Offset), write(Node), put(40), % left bracket
    put(32), write(Head), put(32), put(41). % finishing right bracket
%
% normal processing
%
p_struct(Offset, Tab, Node, List) :-
    allowable_nodes( NList ),
    member( Node, NList ), !,
    nl, tab(Offset), write( Node ), put(40), % left bracket
    Offset2 is Offset + Tab,
    p_list(Offset2, Tab, List),
    nl, tab(Offset), put(41). % finishing right bracket

%
% the fall through if the node is not to be printed
%
p_struct(_, _, _, _).
%
% p_struct(_, _, Node, _) :-
%   write( '**'), write( Node ), write('**').


%
% prints out the list of subnodes for a given node,
%
%
% (if the element is a list print it out all on one line)
%
p_list(_, _,[]).
p_list(Offset, Tab, [Head|List]) :-
    atom(Head), !,
    nl, tab(Offset), write( Head ), p_comma(List),
    p_list(Offset, Tab, List).
%
%   exception for uninstatiated values
%
p_list(Offset, Tab, [Head|List]) :-
    var(Head), !,
    nl, tab(Offset), write( '_' ), p_comma(List),
    p_list(Offset, Tab, List).
%
% the element is a list
%
p_list(Offset, Tab, [Head|List]) :-
    Head =.. [Node|_],
    Node = '.', !,
    tab(Offset), put( 91), put( 32 ),
    p_list2( Head ),
    p_comma(List),
    p_list(Offset, Tab, List).

p_list(Offset, Tab, [Head|List]) :-
    Head =.. [Node|Sublist],
    p_struct(Offset, Tab, Node, Sublist),
    p_comma(List),
    p_list(Offset, Tab, List).

%
% print out a list structure
%
p_list2( [] ) :-
    put( 32 ), put( 93 ).
%
%   exception for uninstatiated values
%
p_list2( [Head|Tail] ) :-
    var( Head ), !,
    write( '_' ),
    p_comma( Tail ),
    p_list2( Tail ).
p_list2( [Head|Tail] ) :-
    write( Head ),
    p_comma( Tail ),
    p_list2( Tail ).
    
%
% print a comma only if we are NOT at the end of the list
%
p_comma([]).
p_comma(_) :- put(44), put(32).
-- 
Peter Mielke                                    peter@doe.utoronto.ca
Dictionary of Old English Project               utgpu!utzoo!utdoe!peter
University of Toronto
