21 |
21 |
22 consts sum :: "nat \<Rightarrow> nat" |
22 consts sum :: "nat \<Rightarrow> nat" |
23 primrec "sum 0 = 0" |
23 primrec "sum 0 = 0" |
24 "sum (Suc n) = Suc n + sum n" |
24 "sum (Suc n) = Suc n + sum n" |
25 |
25 |
26 lemma "sum n + sum n = n*(Suc n)"; |
26 lemma "sum n + sum n = n*(Suc n)" |
27 apply(induct_tac n); |
27 apply(induct_tac n) |
28 apply(auto); |
28 apply(auto) |
29 done |
29 done |
30 |
30 |
31 lemma "\<lbrakk> \<not> m < n; m < n+1 \<rbrakk> \<Longrightarrow> m = n" |
31 lemma "\<lbrakk> \<not> m < n; m < n+1 \<rbrakk> \<Longrightarrow> m = n" |
32 by(auto) |
32 by(auto) |
33 |
33 |
34 lemma "min i (max j k) = max (min k i) (min i (j::nat))"; |
34 lemma "min i (max j k) = max (min k i) (min i (j::nat))" |
35 by(arith) |
35 by(arith) |
36 |
36 |
37 lemma "n*n = n \<Longrightarrow> n=0 \<or> n=1" |
37 lemma "n*n = n \<Longrightarrow> n=0 \<or> n=1" |
38 oops |
38 oops |
39 |
39 |
89 oops |
89 oops |
90 |
90 |
91 |
91 |
92 subsubsection{*Assumptions*} |
92 subsubsection{*Assumptions*} |
93 |
93 |
94 lemma "\<lbrakk> xs @ zs = ys @ xs; [] @ xs = [] @ [] \<rbrakk> \<Longrightarrow> ys = zs"; |
94 lemma "\<lbrakk> xs @ zs = ys @ xs; [] @ xs = [] @ [] \<rbrakk> \<Longrightarrow> ys = zs" |
95 apply simp; |
95 apply simp |
96 done |
96 done |
97 |
97 |
98 lemma "\<forall>x. f x = g (f (g x)) \<Longrightarrow> f [] = f [] @ []"; |
98 lemma "\<forall>x. f x = g (f (g x)) \<Longrightarrow> f [] = f [] @ []" |
99 apply(simp (no_asm)); |
99 apply(simp (no_asm)) |
100 done |
100 done |
101 |
101 |
102 |
102 |
103 subsubsection{*Rewriting with Definitions*} |
103 subsubsection{*Rewriting with Definitions*} |
104 |
104 |
105 lemma "xor A (\<not>A)"; |
105 lemma "xor A (\<not>A)" |
106 apply(simp only:xor_def); |
106 apply(simp only: xor_def) |
107 by simp |
107 by simp |
108 |
108 |
109 |
109 |
110 subsubsection{*Conditional Equations*} |
110 subsubsection{*Conditional Equations*} |
111 |
111 |
117 by(simp) |
117 by(simp) |
118 |
118 |
119 |
119 |
120 subsubsection{*Automatic Case Splits*} |
120 subsubsection{*Automatic Case Splits*} |
121 |
121 |
122 lemma "\<forall>xs. if xs = [] then A else B"; |
122 lemma "\<forall>xs. if xs = [] then A else B" |
123 apply simp |
123 apply simp |
124 oops |
124 oops |
125 |
125 |
126 lemma "case xs @ [] of [] \<Rightarrow> P | y#ys \<Rightarrow> Q ys y"; |
126 lemma "case xs @ [] of [] \<Rightarrow> P | y#ys \<Rightarrow> Q ys y" |
127 apply simp |
127 apply simp |
128 apply(simp split: list.split) |
128 apply(simp split: list.split) |
129 oops |
129 oops |
130 |
130 |
131 |
131 |
132 subsubsection{*Arithmetic*} |
132 subsubsection{*Arithmetic*} |
133 |
133 |
134 lemma "\<lbrakk> \<not> m < n; m < n+1 \<rbrakk> \<Longrightarrow> m = n" |
134 lemma "\<lbrakk> \<not> m < n; m < n+1 \<rbrakk> \<Longrightarrow> m = n" |
135 by simp |
135 by simp |
136 |
136 |
137 lemma "\<not> m < n \<and> m < n+1 \<Longrightarrow> m = n"; |
137 lemma "\<not> m < n \<and> m < n+1 \<Longrightarrow> m = n" |
138 apply simp |
138 apply simp |
139 by(arith) |
139 by(arith) |
140 |
140 |
141 |
141 |
142 subsubsection{*Tracing*} |
142 subsubsection{*Tracing*} |
150 subsection{*Case Study: Compiling Expressions*} |
150 subsection{*Case Study: Compiling Expressions*} |
151 |
151 |
152 |
152 |
153 subsubsection{*Expressions*} |
153 subsubsection{*Expressions*} |
154 |
154 |
155 types 'v binop = "'v \<Rightarrow> 'v \<Rightarrow> 'v"; |
155 types 'v binop = "'v \<Rightarrow> 'v \<Rightarrow> 'v" |
156 |
156 |
157 datatype ('a,'v)expr = Cex 'v |
157 datatype ('a,'v)expr = Cex 'v |
158 | Vex 'a |
158 | Vex 'a |
159 | Bex "'v binop" "('a,'v)expr" "('a,'v)expr"; |
159 | Bex "'v binop" "('a,'v)expr" "('a,'v)expr" |
160 |
160 |
161 consts value :: "('a,'v)expr \<Rightarrow> ('a \<Rightarrow> 'v) \<Rightarrow> 'v"; |
161 consts value :: "('a,'v)expr \<Rightarrow> ('a \<Rightarrow> 'v) \<Rightarrow> 'v" |
162 primrec |
162 primrec |
163 "value (Cex v) env = v" |
163 "value (Cex v) env = v" |
164 "value (Vex a) env = env a" |
164 "value (Vex a) env = env a" |
165 "value (Bex f e1 e2) env = f (value e1 env) (value e2 env)"; |
165 "value (Bex f e1 e2) env = f (value e1 env) (value e2 env)" |
166 |
166 |
167 |
167 |
168 subsubsection{*The Stack Machine*} |
168 subsubsection{*The Stack Machine*} |
169 |
169 |
170 datatype ('a,'v) instr = Const 'v |
170 datatype ('a,'v) instr = Const 'v |
171 | Load 'a |
171 | Load 'a |
172 | Apply "'v binop"; |
172 | Apply "'v binop" |
173 |
173 |
174 consts exec :: "('a,'v)instr list \<Rightarrow> ('a\<Rightarrow>'v) \<Rightarrow> 'v list \<Rightarrow> 'v list"; |
174 consts exec :: "('a,'v)instr list \<Rightarrow> ('a\<Rightarrow>'v) \<Rightarrow> 'v list \<Rightarrow> 'v list" |
175 primrec |
175 primrec |
176 "exec [] s vs = vs" |
176 "exec [] s vs = vs" |
177 "exec (i#is) s vs = (case i of |
177 "exec (i#is) s vs = (case i of |
178 Const v \<Rightarrow> exec is s (v#vs) |
178 Const v \<Rightarrow> exec is s (v#vs) |
179 | Load a \<Rightarrow> exec is s ((s a)#vs) |
179 | Load a \<Rightarrow> exec is s ((s a)#vs) |
180 | Apply f \<Rightarrow> exec is s ((f (hd vs) (hd(tl vs)))#(tl(tl vs))))"; |
180 | Apply f \<Rightarrow> exec is s ((f (hd vs) (hd(tl vs)))#(tl(tl vs))))" |
181 |
181 |
182 |
182 |
183 subsubsection{*The Compiler*} |
183 subsubsection{*The Compiler*} |
184 |
184 |
185 consts comp :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list"; |
185 consts comp :: "('a,'v)expr \<Rightarrow> ('a,'v)instr list" |
186 primrec |
186 primrec |
187 "comp (Cex v) = [Const v]" |
187 "comp (Cex v) = [Const v]" |
188 "comp (Vex a) = [Load a]" |
188 "comp (Vex a) = [Load a]" |
189 "comp (Bex f e1 e2) = (comp e2) @ (comp e1) @ [Apply f]"; |
189 "comp (Bex f e1 e2) = (comp e2) @ (comp e1) @ [Apply f]" |
190 |
190 |
191 theorem "exec (comp e) s [] = [value e s]"; |
191 theorem "exec (comp e) s [] = [value e s]" |
192 oops |
192 oops |
193 |
193 |
194 |
194 |
195 |
195 |
196 subsection{*Advanced Datatypes*} |
196 subsection{*Advanced Datatypes*} |
202 | Sum "'a aexp" "'a aexp" |
202 | Sum "'a aexp" "'a aexp" |
203 | Var 'a |
203 | Var 'a |
204 | Num nat |
204 | Num nat |
205 and 'a bexp = Less "'a aexp" "'a aexp" |
205 and 'a bexp = Less "'a aexp" "'a aexp" |
206 | And "'a bexp" "'a bexp" |
206 | And "'a bexp" "'a bexp" |
207 | Neg "'a bexp"; |
207 | Neg "'a bexp" |
208 |
208 |
209 |
209 |
210 consts evala :: "'a aexp \<Rightarrow> ('a \<Rightarrow> nat) \<Rightarrow> nat" |
210 consts evala :: "'a aexp \<Rightarrow> ('a \<Rightarrow> nat) \<Rightarrow> nat" |
211 evalb :: "'a bexp \<Rightarrow> ('a \<Rightarrow> nat) \<Rightarrow> bool"; |
211 evalb :: "'a bexp \<Rightarrow> ('a \<Rightarrow> nat) \<Rightarrow> bool" |
212 |
212 |
213 primrec |
213 primrec |
214 "evala (IF b a1 a2) env = |
214 "evala (IF b a1 a2) env = |
215 (if evalb b env then evala a1 env else evala a2 env)" |
215 (if evalb b env then evala a1 env else evala a2 env)" |
216 "evala (Sum a1 a2) env = evala a1 env + evala a2 env" |
216 "evala (Sum a1 a2) env = evala a1 env + evala a2 env" |
235 "substb s (And b1 b2) = And (substb s b1) (substb s b2)" |
235 "substb s (And b1 b2) = And (substb s b1) (substb s b2)" |
236 "substb s (Neg b) = Neg (substb s b)" |
236 "substb s (Neg b) = Neg (substb s b)" |
237 |
237 |
238 lemma substitution_lemma: |
238 lemma substitution_lemma: |
239 "evala (substa s a) env = evala a (\<lambda>x. evala (s x) env) \<and> |
239 "evala (substa s a) env = evala a (\<lambda>x. evala (s x) env) \<and> |
240 evalb (substb s b) env = evalb b (\<lambda>x. evala (s x) env)"; |
240 evalb (substb s b) env = evalb b (\<lambda>x. evala (s x) env)" |
241 apply(induct_tac a and b); |
241 apply(induct_tac a and b) |
242 by simp_all |
242 by simp_all |
243 |
243 |
244 |
244 |
245 subsubsection{*Nested Recursion*} |
245 subsubsection{*Nested Recursion*} |
246 |
246 |