🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #4174

Re: prolog tree building question

#4174
From: Dan Brahme
Date: Sun, 11 Feb 1990 23:39
108 lines
3520 bytes
skumar@cbnewsh.ATT.COM (swaminathan.ravikumar) writes:


>I have the following facts asserted in the prolog database:

>	linked(a, b).
>	linked(a, c).
>	linked(b, d).
>	linked(b, e).
>	linked(b, f).

>and I want to construct an "m-way" tree strcuture as follows:

>		a
>		|
>	     -------
>	     |     |
>	     b     c
>	     |
>           -----	   
>	   | | |
>	   d e f

>I would appreciate any suggestions or pointers to reference
>materials on doing this.

>Thanks.

>-- ravi
>skumar@hocus.att.com

Try representing trees by t(Nodename, Listofchildnodes).
which would give you 
t(a,[t(b,[t(d,[]),t(e,[]),t(f,[])]), t(c, [])])

However if your database is a set of links then you have to write a
program to get this tree. 
------------------------

One way to write this is:

tree(T) :- 
   grow_downtree(_A, T0),
   grow_uptree(T0, T).

grow_downtree(A, t(A, Ts)) :- 
   down_links(A, Bs),
   grow_downtrees(Bs, Ts).
   
down_links(A, Bs) :- bagof(B, (functor(L, l, 2), arg(1, L, A), arg(2, L, B),
                               call(L)), Bs).

grow_downtrees([], []).
grow_downtrees([A1|A2], [T1|T2]) :-
   grow_downtree(A1, T1),
   grow_downtrees(A2, T2).

grow_uptree(t(A, T), Tree) :- 
   l(B, A) -->
   (down_links(B, A, As),
    grow_downtrees(As, Ts),
    grow_uptree(t(B, [t(A, T)|Ts])))
  ; Tree = t(A, T).

down_links(A, B, Bs) :- 
    bagof( B1, (functor(L, l, 2), arg(1, L, A), arg(2, L, B1),
                call(L), B1 <> B), Bs).


-------------------------------------------------------------


If you write this program in the Lisp or C style
the prolog version may turn out to be much
slower than the lisp or C version. By lisp or C style I mean something
like what we have below:

tree(T) :- get_links(Ls), transform(Ls, T).

get_links(Links) :- bagof(Link, (functor(Link, l, 2), call(Link)), Links).

transform([Link_orSubtree|Forest], Tree) :- 
   insert(Link_or_Subtree, Forest, NewForest),
     NewForest = [Tree] --> true
   ; transform(NewForest, Tree).
transform([], _Tree).

insert(l(A, B), [l(A0, A)|FR], [t(A0, [t(A, t(B, []))])|FR]).
insert(l(A, B), [l(B, B0)|FR], [t(A, [t(B, t(B0, []))])|FR]).
insert(t(A, T), [Tree|FR], [NewTree|FR]) :- merge(t(A, T), Tree, NewTree).
insert(Link_or_Subtree, [F1|FR], [F1|NewFR]) :- 
    insert(Link_or_Subtree, FR, NewFR).
insert(_L, [], []).
    
I have omitted merge(T1, T2, T) which basically merges
T1 and T2 if possible (that is they share a
node) otherwise it fails. 

---------------------------------------------------

Dan brahme

PS: One of the differences in the prolog versus Lisp/C like versions
is that former uses backtracking extensively whereas the latter has
no backtracking. In fact you could transform most of the clauses to lisp conds.
Also I have'nt compiled this code (thus there may be errors in the
use of bagof (i.e., free variables, use of quantifier) 
so check a manual before using it.
Technical Details
Message-ID: <110154@ti-csl.csc.ti.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!decwrl!sun-barr!newstop!texsun!smunews!ti-csl!vlsic2!brahme
References: <8052@cbnewsh.ATT.COM>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!decwrl!sun-barr!newstop!texsun!smunews!ti-csl!vlsic2!brahme
From: brahme@vlsic2.ti.com (Dan Brahme)
Newsgroups: comp.lang.prolog
Subject: Re: prolog tree building question
Keywords: m-way trees
Message-ID: <110154@ti-csl.csc.ti.com>
Date: 11 Feb 90 23:39:13 GMT
References: <8052@cbnewsh.ATT.COM>
Sender: news@ti-csl.csc.ti.com
Organization: Texas Instruments Inc, SPDC Operations, Dallas, TX
Lines: 108