Reputation: 117
I'm working on a function that converts a tree into a list of integers. My issue is, I can append to the list when I only have to add one or two integers. But I can't seem to be able to append three integers without getting this:
[[2], 3, 4]
, when I should be getting [2, 3, 4]
.
I know that the issue stems from this statement
append([Temp1 | Temp2] , Temp3, L)
Where Temp1, Temp2, and Temp3 are the integers I'd like to add. L is the main list that contains all integers from the tree so far.
I tried having two append statements, but that returns a false
boolean instead of [2, 3, 4]
. I tried moving around the [ | ]
but I don't think I know enough about them to have made a difference.
The append/3 page also only goes up to concatenating two lists into one. Any help would be greatly appreciated :)
Edit: my code is as below, and I added my test example.
chopTree(leaf(_), []).
chopTree(node1(Leaf, Node), L) :-
chopTree(Node, Temp),
append([], [Leaf | Temp], L).
chopTree(node2(Leaf, Node1, Node2), L) :-
chopTree(Node1, Temp1),
chopTree(Node2, Temp2),
append(Temp1, [Leaf | Temp2], L).
chopTree(node3(_, Node1, Node2, Node3), L) :-
chopTree(Node1, Temp1),
chopTree(Node2, Temp2),
chopTree(Node3, Temp3),
append([Temp1 | Temp2] , Temp3, L).
query(E) :-
chopTree(node3(1,
node1(2, leaf(1)),
node2(3, leaf(1), leaf(1)),
node1(4, leaf(1))),
E).
Upvotes: 1
Views: 187
Reputation: 40768
When relating trees to lists, checkout DCG notation: DCGs let you avoid append/3
entirely, making your code simpler and at the same time often improve its termination properties.
For example:
tree_list(leaf(Leaf)) --> [Leaf]. tree_list(node1(Leaf, Node)) --> [Leaf], tree_list(Node). tree_list(node2(Leaf, Node1, Node2)) --> tree_list(Node1), [Leaf], tree_list(Node2). tree_list(node3(_, Node1, Node2, Node3)) --> tree_list(Node1), tree_list(Node2), tree_list(Node3).
Sample query and answer:
?- phrase(tree_list(node3(1, node1(2, leaf(1)), node2(3, leaf(1), leaf(1)), node1(4, leaf(1)))), Ls). Ls = [2, 1, 1, 3, 1, 4, 1].
You can easily adapt this to other desired orders, by simply moving the terminals and nonterminals within the DCG bodies.
Note that all the auxiliary variables are gone entirely!
Upvotes: 1
Reputation: 71065
Your naming is off. The variable looks better called "Label". Then, node3
should probably have two of them:
chopTree(leaf(_), []).
chopTree(node1(Label, Node), L) :-
chopTree(Node, Temp),
% append([], [Label | Temp], L).
L = [Label | Temp].
chopTree(node2(Label, Node1, Node2), L) :-
chopTree(Node1, Temp1),
chopTree(Node2, Temp2),
append(Temp1, [Label | Temp2], L).
chopTree(node3(Label1, Label2, Node1, Node2, Node3), L) :-
chopTree(Node1, Temp1),
chopTree(Node2, Temp2),
chopTree(Node3, Temp3),
append(Temp1, [Label1 | Temp2] , L1),
append(L1, [Label2 | Temp3], L).
Perhaps node1
shouldn't have any labels in it, too. Anyway, as you can see, we just call append
twice, or however many times we need, to build the result list piece by piece.
Upvotes: 1