-
Notifications
You must be signed in to change notification settings - Fork 0
/
Exercise2_2.thy
141 lines (107 loc) · 3.67 KB
/
Exercise2_2.thy
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
(* author: wzh *)
theory Exercise2_2
imports Main
begin
(* Exer 2.6 *)
datatype 'a tree = Tip | Node "'a tree" 'a "'a tree"
(* Convert a tree to a list *)
fun contents :: "'a tree \<Rightarrow> 'a list" where
"contents Tip = []" |
"contents (Node l x r) = (contents l) @ [x] @ (contents r)"
fun sum_tree :: "nat tree \<Rightarrow> nat" where
"sum_tree Tip = 0" |
"sum_tree (Node l x r) = (sum_tree l) + x + (sum_tree r)"
theorem "sum_tree t = sum_list(contents t)"
apply(induction t)
apply(auto)
done
(* Exer 2.7 *)
fun pre_order :: "'a tree \<Rightarrow> 'a list" where
"pre_order Tip = []" |
"pre_order (Node l x r) = [x] @ (pre_order l) @ (pre_order r)"
fun post_order :: "'a tree \<Rightarrow> 'a list" where
"post_order Tip = []" |
"post_order (Node l x r) = (post_order l) @ (post_order r) @ [x]"
fun mirror :: "'a tree \<Rightarrow> 'a tree" where
"mirror Tip = Tip" |
"mirror (Node l x r) = Node (mirror r) x (mirror l)"
lemma mirr: "mirror (mirror t) = t"
apply(induction t)
apply(auto)
done
theorem "rev(post_order t) = pre_order(mirror t)"
apply(induction t)
apply(auto)
done
(* Exer 2.8 *)
fun intersperse :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list" where
"intersperse x [] = [x]" |
"intersperse x (y # ys) = [y] @ [x] @ (intersperse x ys)"
theorem "map f (intersperse a xs) = intersperse (f a) (map f xs)"
apply(induction xs)
apply(auto)
done
(* Exer 2.9 *)
fun itadd :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
"itadd 0 x = x" |
"itadd (Suc m) n = itadd m (Suc n)"
fun add :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
"add 0 m = m" |
"add (Suc(n)) m = Suc(add n m)"
(* Exer 2.10 *)
datatype tree0 = Tip | Node tree0 tree0
fun nodes :: "tree0 \<Rightarrow> nat" where
"nodes Tip = 0" |
"nodes (Node l r) = 1 + (nodes l) + (nodes r)"
fun explode :: "nat \<Rightarrow> tree0 \<Rightarrow> tree0" where
"explode 0 t = t" |
"explode (Suc n) t = explode n (Node t t)"
(* arbitrary t is used to fix t when inducting *)
theorem "nodes (explode n t) = 2^n * (nodes t) + (2^n - 1)"
apply(induction n arbitrary: t)
apply(auto)
apply(simp add: algebra_simps)
done
(* Exer 2.11 *)
datatype exp = Var | Const int | Add exp exp | Mult exp exp
fun eval :: "exp \<Rightarrow> int \<Rightarrow> int" where
"eval Var x = x" |
"eval (Const n) x = n" |
"eval (Add ex1 ex2) x = (eval ex1 x) + (eval ex2 x)" |
"eval (Mult ex1 ex2) x = (eval ex1 x) * (eval ex2 x)"
fun evalp :: "int list \<Rightarrow> int \<Rightarrow> int" where
"evalp [] y = 0" |
"evalp (x # xs) y = x + y * (evalp xs y)"
value "evalp [4, 2, -1, 3] 2"
fun sum :: "int list \<Rightarrow> int list \<Rightarrow> int list" where
"sum [] ys = ys" |
"sum xs [] = xs" |
"sum (x # xs) (y # ys) = [x + y] @ (sum xs ys)"
value "sum [4, 2, 1] [1, 4]"
fun mul :: "int list \<Rightarrow> int list \<Rightarrow> int list" where
"mul [] ys = []" |
"mul xs [] = []" |
"mul [x] (y # ys) = [x * y] @ (mul [x] ys)" |
"mul (x # xs) ys = sum (mul [x] ys) ([0] @ (mul xs ys))"
value "mul [2] [2, 3]"
value "mul [1, 2] [2, 3]"
value "mul [1, 2, 3] [4, 5, 6]"
fun coeffs :: "exp \<Rightarrow> int list" where
"coeffs Var = [0, 1]" |
"coeffs (Const n) = [n]" |
"coeffs (Add ex1 ex2) = sum (coeffs ex1) (coeffs ex2)" |
"coeffs (Mult ex1 ex2) = mul (coeffs ex1) (coeffs ex2)"
(* prove correctness for add and mul respectively *)
lemma evalp_add[simp]: "evalp (sum xs ys) a = evalp xs a + evalp ys a"
apply (induction rule: sum.induct)
apply (auto simp add:Int.int_distrib)
done
lemma evalp_mul[simp]: "evalp (mul xs ys) a = evalp xs a * evalp ys a"
apply (induction rule: mul.induct)
apply (auto simp add:Int.int_distrib)
done
theorem "evalp (coeffs e) x = eval e x"
apply(induction e)
apply(auto)
done
end