-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathworkshop08.answers
100 lines (73 loc) · 2.65 KB
/
workshop08.answers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
QUESTION 1
This definition of sumlist/2 is not tail recursive:
sumlist([], 0).
sumlist([N|Ns], Sum) :-
sumlist(Ns, Sum0),
Sum is N + Sum0.
Rewrite it to be tail recursive.
ANSWER
sumlist(List, Sum) :-
sumlist(List, 0, Sum).
sumlist7 Sum, Sum).
sumlist([N|Ns], Sum0, Sum) :-
Sum1 is Sum0 + N,
sumlist(Ns, Sum1, Sum).
QUESTION 2
Given a binary tree defined to satisfy the predicate tree/1
tree(empty).
tree(node(Left,_,Right)) :-
tree(Left),
tree(Right).
write a predicate tree_list(Tree, List) that holds when List is a
list of all the elements of Tree, in left-to-right order. This code
need only work in the mode where the tree is input.
ANSWER
tree_list(empty, []).
tree_list(node(Left,Elt,Right), List) :-
tree_list(Left, List1),
tree_list(Right, List2),
append(List1, [Elt|List2], List).
QUESTION 3
Revise the definition from the previous question not to use append/3
to construct the list. That is, ensure the cost of the operation is
proportional to the number of elements in the tree.
Hint: look at the approach taken to write a tail recursive reverse
predicate for inspiration.
ANSWER
tree_list(Tree, List) :-
tree_list(Tree, List, []).
tree_list(empty, List, List).
tree_list(node(Left,Elt,Right), List, List0) :-
tree_list(Left, List, List1),
List1 = [Elt|List2],
tree_list(Right, List2, List0).
Note that we've swapped the order of the last two arguments from what
you might expect. This is more natural, since
tree_list(Tree, List, List0)
then says "List is the list of the elements of Tree with List0
appended to the end".
QUESTION 4
Write a predicate list_tree(List, Tree) that holds when Tree is a
balanced tree whose elements are the elements of List, in the order
they appear in List. This need only work in the mode where List is a
proper list.
Hint: First divide the list into the first half, the middle element,
and the last half, then recursively construct a tree from the first
half and second half, and assemble these into the resulting tree.
Clarification: The main intended use of this predicate is to
build a balanced tree from a list. It should, as far as
reasonable, work in other modes. One complication is that it's
possible for there to be different trees, balanced in different
ways, with the same nodes in order. You don't need to handle
this possibility here (though it would make an interesting
challenge exercise). You just need to handle balanced trees
that could have been produced by this predicate.
ANSWER
list_tree([], empty).
list_tree([E|List], node(Left,Elt,Right)) :-
length(List, Len),
Len2 is Len // 2,
length(Front, Len2),
append(Front, [Elt|Back], [E|List]),
list_tree(Front, Left),
list_tree(Back, Right).