Here's a pure variant that doesn't require all-solution meta-predicates like aggregate/3
.
First, here's your sample tree again:
sampleTree([[[],r,[[],u,[[],t,[]]]],a,[[],c,[]]]).
Next, is_tree/1
defines what trees look like:
is_tree([]).
is_tree([Left,_,Right]) :-
is_tree(Left),
is_tree(Right).
Finally, we define tree_leftmostLongestPath/2
which we use for pre-order tree traversal.
Compared to is_tree/1
, tree_leftmostLongestPath_/4
has 3 additional arguments:
RPath
which is the path so far in reversed order
Best0
is a pair Len-Path
and holds the longest path found so far
Best
also is a pair Len-Path
and holds the longest path of the entire tree/subtree
Here's the code:
:- use_module(library(clpfd)).
tree_leftmostLongestPath(Tree, Path) :-
tree_leftmostLongestPath_(Tree, [], 0-[], _-Path).
% "internal" auxiliary predicate
tree_leftmostLongestPath_([], RPath, Best0, Best) :-
Best0 = L0-_,
length(RPath, Len),
( Len #=< L0, Best = Best0
; Len #> L0, reverse(RPath, Path), Best = Len-Path
).
tree_leftmostLongestPath_([Left,Name,Right], RPath, Best0, Best) :-
RPath1 = [Name|RPath],
tree_leftmostLongestPath_(Left , RPath1, Best0, Best1),
tree_leftmostLongestPath_(Right, RPath1, Best1, Best).
Some queries and answers:
?- sampleTree(Tree), tree_leftmostLongestPath(Tree, Path).
Path = [a,r,u,t], Tree = [[[],r,[[],u,[[],t,[]]]],a,[[],c,[]]]).
?- is_tree(Tree), tree_leftmostLongestPath(Tree, Path).
Path = [] , Tree = []
; Path = [A] , Tree = [[],A,[]]
; Path = [A,B] , Tree = [[],A,[[],B,[]]]
; Path = [A,B,C], Tree = [[],A,[[],B,[[],C,[]]]]
…
%Tree tree([ [ [],r,[[],u,[[],t,[]]] ], a , [ [], c, [] ]]). %Homework 1 %Interface: most_dep_path(TREE,PATH):- %Example to testing: %tree(X),most_dep_path(X,PATH),print(X). %Expected result: %X = [[[], r, [[], u, [[], t|...]]], a, [[], c, []]], %PATH = [a, r, u, t].
I apologize for the code. It looks like a mess. :/ @repeat - Bampelito