34 instantiation "finfun" :: (type, bot) bot begin |
34 instantiation "finfun" :: (type, bot) bot begin |
35 definition "bot = finfun_const bot" |
35 definition "bot = finfun_const bot" |
36 instance by(intro_classes)(simp add: bot_finfun_def le_finfun_def) |
36 instance by(intro_classes)(simp add: bot_finfun_def le_finfun_def) |
37 end |
37 end |
38 |
38 |
39 lemma bot_finfun_apply [simp]: "bot\<^sub>f = (\<lambda>_. bot)" |
39 lemma bot_finfun_apply [simp]: "op $ bot = (\<lambda>_. bot)" |
40 by(auto simp add: bot_finfun_def) |
40 by(auto simp add: bot_finfun_def) |
41 |
41 |
42 instantiation "finfun" :: (type, top) top begin |
42 instantiation "finfun" :: (type, top) top begin |
43 definition "top = finfun_const top" |
43 definition "top = finfun_const top" |
44 instance by(intro_classes)(simp add: top_finfun_def le_finfun_def) |
44 instance by(intro_classes)(simp add: top_finfun_def le_finfun_def) |
45 end |
45 end |
46 |
46 |
47 lemma top_finfun_apply [simp]: "top\<^sub>f = (\<lambda>_. top)" |
47 lemma top_finfun_apply [simp]: "op $ top = (\<lambda>_. top)" |
48 by(auto simp add: top_finfun_def) |
48 by(auto simp add: top_finfun_def) |
49 |
49 |
50 instantiation "finfun" :: (type, inf) inf begin |
50 instantiation "finfun" :: (type, inf) inf begin |
51 definition [code]: "inf f g = (\<lambda>(x, y). inf x y) \<circ>\<^isub>f (f, g)\<^sup>f" |
51 definition [code]: "inf f g = (\<lambda>(x, y). inf x y) \<circ>\<^isub>f (f, g)\<^sup>f" |
52 instance .. |
52 instance .. |
53 end |
53 end |
54 |
54 |
55 lemma inf_finfun_apply [simp]: "(inf f g)\<^sub>f = inf f\<^sub>f g\<^sub>f" |
55 lemma inf_finfun_apply [simp]: "op $ (inf f g) = inf (op $ f) (op $ g)" |
56 by(auto simp add: inf_finfun_def o_def inf_fun_def) |
56 by(auto simp add: inf_finfun_def o_def inf_fun_def) |
57 |
57 |
58 instantiation "finfun" :: (type, sup) sup begin |
58 instantiation "finfun" :: (type, sup) sup begin |
59 definition [code]: "sup f g = (\<lambda>(x, y). sup x y) \<circ>\<^isub>f (f, g)\<^sup>f" |
59 definition [code]: "sup f g = (\<lambda>(x, y). sup x y) \<circ>\<^isub>f (f, g)\<^sup>f" |
60 instance .. |
60 instance .. |
61 end |
61 end |
62 |
62 |
63 lemma sup_finfun_apply [simp]: "(sup f g)\<^sub>f = sup f\<^sub>f g\<^sub>f" |
63 lemma sup_finfun_apply [simp]: "op $ (sup f g) = sup (op $ f) (op $ g)" |
64 by(auto simp add: sup_finfun_def o_def sup_fun_def) |
64 by(auto simp add: sup_finfun_def o_def sup_fun_def) |
65 |
65 |
66 instance "finfun" :: (type, semilattice_inf) semilattice_inf |
66 instance "finfun" :: (type, semilattice_inf) semilattice_inf |
67 by(intro_classes)(simp_all add: inf_finfun_def le_finfun_def) |
67 by(intro_classes)(simp_all add: inf_finfun_def le_finfun_def) |
68 |
68 |
80 instantiation "finfun" :: (type, minus) minus begin |
80 instantiation "finfun" :: (type, minus) minus begin |
81 definition "f - g = split (op -) \<circ>\<^isub>f (f, g)\<^sup>f" |
81 definition "f - g = split (op -) \<circ>\<^isub>f (f, g)\<^sup>f" |
82 instance .. |
82 instance .. |
83 end |
83 end |
84 |
84 |
85 lemma minus_finfun_apply [simp]: "(f - g)\<^sub>f = f\<^sub>f - g\<^sub>f" |
85 lemma minus_finfun_apply [simp]: "op $ (f - g) = op $ f - op $ g" |
86 by(simp add: minus_finfun_def o_def fun_diff_def) |
86 by(simp add: minus_finfun_def o_def fun_diff_def) |
87 |
87 |
88 instantiation "finfun" :: (type, uminus) uminus begin |
88 instantiation "finfun" :: (type, uminus) uminus begin |
89 definition "- A = uminus \<circ>\<^isub>f A" |
89 definition "- A = uminus \<circ>\<^isub>f A" |
90 instance .. |
90 instance .. |
91 end |
91 end |
92 |
92 |
93 lemma uminus_finfun_apply [simp]: "(- g)\<^sub>f = - g\<^sub>f" |
93 lemma uminus_finfun_apply [simp]: "op $ (- g) = - op $ g" |
94 by(simp add: uminus_finfun_def o_def fun_Compl_def) |
94 by(simp add: uminus_finfun_def o_def fun_Compl_def) |
95 |
95 |
96 instance "finfun" :: (type, boolean_algebra) boolean_algebra |
96 instance "finfun" :: (type, boolean_algebra) boolean_algebra |
97 by(intro_classes) |
97 by(intro_classes) |
98 (simp_all add: uminus_finfun_def inf_finfun_def expand_finfun_eq sup_fun_def inf_fun_def fun_Compl_def o_def inf_compl_bot sup_compl_top diff_eq) |
98 (simp_all add: uminus_finfun_def inf_finfun_def expand_finfun_eq sup_fun_def inf_fun_def fun_Compl_def o_def inf_compl_bot sup_compl_top diff_eq) |
109 |
109 |
110 definition finfun_single :: "'a \<Rightarrow> 'a pred\<^isub>f" |
110 definition finfun_single :: "'a \<Rightarrow> 'a pred\<^isub>f" |
111 where [code]: "finfun_single x = finfun_empty(\<^sup>f x := True)" |
111 where [code]: "finfun_single x = finfun_empty(\<^sup>f x := True)" |
112 |
112 |
113 lemma finfun_single_apply [simp]: |
113 lemma finfun_single_apply [simp]: |
114 "(finfun_single x)\<^sub>f y \<longleftrightarrow> x = y" |
114 "finfun_single x $ y \<longleftrightarrow> x = y" |
115 by(simp add: finfun_single_def finfun_upd_apply) |
115 by(simp add: finfun_single_def finfun_upd_apply) |
116 |
116 |
117 lemma [iff]: |
117 lemma [iff]: |
118 shows finfun_single_neq_bot: "finfun_single x \<noteq> bot" |
118 shows finfun_single_neq_bot: "finfun_single x \<noteq> bot" |
119 and bot_neq_finfun_single: "bot \<noteq> finfun_single x" |
119 and bot_neq_finfun_single: "bot \<noteq> finfun_single x" |
120 by(simp_all add: expand_finfun_eq fun_eq_iff) |
120 by(simp_all add: expand_finfun_eq fun_eq_iff) |
121 |
121 |
122 lemma finfun_leI [intro!]: "(!!x. A\<^sub>f x \<Longrightarrow> B\<^sub>f x) \<Longrightarrow> A \<le> B" |
122 lemma finfun_leI [intro!]: "(!!x. A $ x \<Longrightarrow> B $ x) \<Longrightarrow> A \<le> B" |
123 by(simp add: le_finfun_def) |
123 by(simp add: le_finfun_def) |
124 |
124 |
125 lemma finfun_leD [elim]: "\<lbrakk> A \<le> B; A\<^sub>f x \<rbrakk> \<Longrightarrow> B\<^sub>f x" |
125 lemma finfun_leD [elim]: "\<lbrakk> A \<le> B; A $ x \<rbrakk> \<Longrightarrow> B $ x" |
126 by(simp add: le_finfun_def) |
126 by(simp add: le_finfun_def) |
127 |
127 |
128 text {* Bounded quantification. |
128 text {* Bounded quantification. |
129 Warning: @{text "finfun_Ball"} and @{text "finfun_Ex"} may raise an exception, they should not be used for quickcheck |
129 Warning: @{text "finfun_Ball"} and @{text "finfun_Ex"} may raise an exception, they should not be used for quickcheck |
130 *} |
130 *} |
131 |
131 |
132 definition finfun_Ball_except :: "'a list \<Rightarrow> 'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
132 definition finfun_Ball_except :: "'a list \<Rightarrow> 'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
133 where [code del]: "finfun_Ball_except xs A P = (\<forall>a. A\<^sub>f a \<longrightarrow> a \<in> set xs \<or> P a)" |
133 where [code del]: "finfun_Ball_except xs A P = (\<forall>a. A $ a \<longrightarrow> a \<in> set xs \<or> P a)" |
134 |
134 |
135 lemma finfun_Ball_except_const: |
135 lemma finfun_Ball_except_const: |
136 "finfun_Ball_except xs (\<lambda>\<^isup>f b) P \<longleftrightarrow> \<not> b \<or> set xs = UNIV \<or> FinFun.code_abort (\<lambda>u. finfun_Ball_except xs (\<lambda>\<^isup>f b) P)" |
136 "finfun_Ball_except xs (\<lambda>\<^isup>f b) P \<longleftrightarrow> \<not> b \<or> set xs = UNIV \<or> FinFun.code_abort (\<lambda>u. finfun_Ball_except xs (\<lambda>\<^isup>f b) P)" |
137 by(auto simp add: finfun_Ball_except_def) |
137 by(auto simp add: finfun_Ball_except_def) |
138 |
138 |
148 fixes a :: "'a :: card_UNIV" |
148 fixes a :: "'a :: card_UNIV" |
149 shows "finfun_Ball_except xs (finfun_update_code f a b) P = ((a \<in> set xs \<or> (b \<longrightarrow> P a)) \<and> finfun_Ball_except (a # xs) f P)" |
149 shows "finfun_Ball_except xs (finfun_update_code f a b) P = ((a \<in> set xs \<or> (b \<longrightarrow> P a)) \<and> finfun_Ball_except (a # xs) f P)" |
150 by(simp add: finfun_Ball_except_update) |
150 by(simp add: finfun_Ball_except_update) |
151 |
151 |
152 definition finfun_Ball :: "'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
152 definition finfun_Ball :: "'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
153 where [code del]: "finfun_Ball A P = Ball {x. A\<^sub>f x} P" |
153 where [code del]: "finfun_Ball A P = Ball {x. A $ x} P" |
154 |
154 |
155 lemma finfun_Ball_code [code]: "finfun_Ball = finfun_Ball_except []" |
155 lemma finfun_Ball_code [code]: "finfun_Ball = finfun_Ball_except []" |
156 by(auto intro!: ext simp add: finfun_Ball_except_def finfun_Ball_def) |
156 by(auto intro!: ext simp add: finfun_Ball_except_def finfun_Ball_def) |
157 |
157 |
158 |
158 |
159 definition finfun_Bex_except :: "'a list \<Rightarrow> 'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
159 definition finfun_Bex_except :: "'a list \<Rightarrow> 'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
160 where [code del]: "finfun_Bex_except xs A P = (\<exists>a. A\<^sub>f a \<and> a \<notin> set xs \<and> P a)" |
160 where [code del]: "finfun_Bex_except xs A P = (\<exists>a. A $ a \<and> a \<notin> set xs \<and> P a)" |
161 |
161 |
162 lemma finfun_Bex_except_const: |
162 lemma finfun_Bex_except_const: |
163 "finfun_Bex_except xs (\<lambda>\<^isup>f b) P \<longleftrightarrow> b \<and> set xs \<noteq> UNIV \<and> FinFun.code_abort (\<lambda>u. finfun_Bex_except xs (\<lambda>\<^isup>f b) P)" |
163 "finfun_Bex_except xs (\<lambda>\<^isup>f b) P \<longleftrightarrow> b \<and> set xs \<noteq> UNIV \<and> FinFun.code_abort (\<lambda>u. finfun_Bex_except xs (\<lambda>\<^isup>f b) P)" |
164 by(auto simp add: finfun_Bex_except_def) |
164 by(auto simp add: finfun_Bex_except_def) |
165 |
165 |
175 fixes a :: "'a :: card_UNIV" |
175 fixes a :: "'a :: card_UNIV" |
176 shows "finfun_Bex_except xs (finfun_update_code f a b) P \<longleftrightarrow> ((a \<notin> set xs \<and> b \<and> P a) \<or> finfun_Bex_except (a # xs) f P)" |
176 shows "finfun_Bex_except xs (finfun_update_code f a b) P \<longleftrightarrow> ((a \<notin> set xs \<and> b \<and> P a) \<or> finfun_Bex_except (a # xs) f P)" |
177 by(simp add: finfun_Bex_except_update) |
177 by(simp add: finfun_Bex_except_update) |
178 |
178 |
179 definition finfun_Bex :: "'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
179 definition finfun_Bex :: "'a pred\<^isub>f \<Rightarrow> ('a \<Rightarrow> bool) \<Rightarrow> bool" |
180 where [code del]: "finfun_Bex A P = Bex {x. A\<^sub>f x} P" |
180 where [code del]: "finfun_Bex A P = Bex {x. A $ x} P" |
181 |
181 |
182 lemma finfun_Bex_code [code]: "finfun_Bex = finfun_Bex_except []" |
182 lemma finfun_Bex_code [code]: "finfun_Bex = finfun_Bex_except []" |
183 by(auto intro!: ext simp add: finfun_Bex_except_def finfun_Bex_def) |
183 by(auto intro!: ext simp add: finfun_Bex_except_def finfun_Bex_def) |
184 |
184 |
185 |
185 |
186 text {* Automatically replace predicate operations by finfun predicate operations where possible *} |
186 text {* Automatically replace predicate operations by finfun predicate operations where possible *} |
187 |
187 |
188 lemma iso_finfun_le [code_unfold]: |
188 lemma iso_finfun_le [code_unfold]: |
189 "A\<^sub>f \<le> B\<^sub>f \<longleftrightarrow> A \<le> B" |
189 "op $ A \<le> op $ B \<longleftrightarrow> A \<le> B" |
190 by (metis le_finfun_def le_funD le_funI) |
190 by (metis le_finfun_def le_funD le_funI) |
191 |
191 |
192 lemma iso_finfun_less [code_unfold]: |
192 lemma iso_finfun_less [code_unfold]: |
193 "A\<^sub>f < B\<^sub>f \<longleftrightarrow> A < B" |
193 "op $ A < op $ B \<longleftrightarrow> A < B" |
194 by (metis iso_finfun_le less_finfun_def less_fun_def) |
194 by (metis iso_finfun_le less_finfun_def less_fun_def) |
195 |
195 |
196 lemma iso_finfun_eq [code_unfold]: |
196 lemma iso_finfun_eq [code_unfold]: |
197 "A\<^sub>f = B\<^sub>f \<longleftrightarrow> A = B" |
197 "op $ A = op $ B \<longleftrightarrow> A = B" |
198 by(simp only: expand_finfun_eq) |
198 by(simp only: expand_finfun_eq) |
199 |
199 |
200 lemma iso_finfun_sup [code_unfold]: |
200 lemma iso_finfun_sup [code_unfold]: |
201 "sup A\<^sub>f B\<^sub>f = (sup A B)\<^sub>f" |
201 "sup (op $ A) (op $ B) = op $ (sup A B)" |
202 by(simp) |
202 by(simp) |
203 |
203 |
204 lemma iso_finfun_disj [code_unfold]: |
204 lemma iso_finfun_disj [code_unfold]: |
205 "A\<^sub>f x \<or> B\<^sub>f x \<longleftrightarrow> (sup A B)\<^sub>f x" |
205 "A $ x \<or> B $ x \<longleftrightarrow> sup A B $ x" |
206 by(simp add: sup_fun_def) |
206 by(simp add: sup_fun_def) |
207 |
207 |
208 lemma iso_finfun_inf [code_unfold]: |
208 lemma iso_finfun_inf [code_unfold]: |
209 "inf A\<^sub>f B\<^sub>f = (inf A B)\<^sub>f" |
209 "inf (op $ A) (op $ B) = op $ (inf A B)" |
210 by(simp) |
210 by(simp) |
211 |
211 |
212 lemma iso_finfun_conj [code_unfold]: |
212 lemma iso_finfun_conj [code_unfold]: |
213 "A\<^sub>f x \<and> B\<^sub>f x \<longleftrightarrow> (inf A B)\<^sub>f x" |
213 "A $ x \<and> B $ x \<longleftrightarrow> inf A B $ x" |
214 by(simp add: inf_fun_def) |
214 by(simp add: inf_fun_def) |
215 |
215 |
216 lemma iso_finfun_empty_conv [code_unfold]: |
216 lemma iso_finfun_empty_conv [code_unfold]: |
217 "(\<lambda>_. False) = {}\<^isub>f\<^sub>f" |
217 "(\<lambda>_. False) = op $ {}\<^isub>f" |
218 by simp |
218 by simp |
219 |
219 |
220 lemma iso_finfun_UNIV_conv [code_unfold]: |
220 lemma iso_finfun_UNIV_conv [code_unfold]: |
221 "(\<lambda>_. True) = finfun_UNIV\<^sub>f" |
221 "(\<lambda>_. True) = op $ finfun_UNIV" |
222 by simp |
222 by simp |
223 |
223 |
224 lemma iso_finfun_upd [code_unfold]: |
224 lemma iso_finfun_upd [code_unfold]: |
225 fixes A :: "'a pred\<^isub>f" |
225 fixes A :: "'a pred\<^isub>f" |
226 shows "A\<^sub>f(x := b) = (A(\<^sup>f x := b))\<^sub>f" |
226 shows "(op $ A)(x := b) = op $ (A(\<^sup>f x := b))" |
227 by(simp add: fun_eq_iff) |
227 by(simp add: fun_eq_iff) |
228 |
228 |
229 lemma iso_finfun_uminus [code_unfold]: |
229 lemma iso_finfun_uminus [code_unfold]: |
230 fixes A :: "'a pred\<^isub>f" |
230 fixes A :: "'a pred\<^isub>f" |
231 shows "- A\<^sub>f = (- A)\<^sub>f" |
231 shows "- op $ A = op $ (- A)" |
232 by(simp) |
232 by(simp) |
233 |
233 |
234 lemma iso_finfun_minus [code_unfold]: |
234 lemma iso_finfun_minus [code_unfold]: |
235 fixes A :: "'a pred\<^isub>f" |
235 fixes A :: "'a pred\<^isub>f" |
236 shows "A\<^sub>f - B\<^sub>f = (A - B)\<^sub>f" |
236 shows "op $ A - op $ B = op $ (A - B)" |
237 by(simp) |
237 by(simp) |
238 |
238 |
239 text {* |
239 text {* |
240 Do not declare the following two theorems as @{text "[code_unfold]"}, |
240 Do not declare the following two theorems as @{text "[code_unfold]"}, |
241 because this causes quickcheck to fail frequently when bounded quantification is used which raises an exception. |
241 because this causes quickcheck to fail frequently when bounded quantification is used which raises an exception. |
242 For code generation, the same problems occur, but then, no randomly generated FinFun is usually around. |
242 For code generation, the same problems occur, but then, no randomly generated FinFun is usually around. |
243 *} |
243 *} |
244 |
244 |
245 lemma iso_finfun_Ball_Ball: |
245 lemma iso_finfun_Ball_Ball: |
246 "(\<forall>x. A\<^sub>f x \<longrightarrow> P x) \<longleftrightarrow> finfun_Ball A P" |
246 "(\<forall>x. A $ x \<longrightarrow> P x) \<longleftrightarrow> finfun_Ball A P" |
247 by(simp add: finfun_Ball_def) |
247 by(simp add: finfun_Ball_def) |
248 |
248 |
249 lemma iso_finfun_Bex_Bex: |
249 lemma iso_finfun_Bex_Bex: |
250 "(\<exists>x. A\<^sub>f x \<and> P x) \<longleftrightarrow> finfun_Bex A P" |
250 "(\<exists>x. A $ x \<and> P x) \<longleftrightarrow> finfun_Bex A P" |
251 by(simp add: finfun_Bex_def) |
251 by(simp add: finfun_Bex_def) |
252 |
252 |
253 text {* Test replacement setup *} |
253 text {* Test replacement setup *} |
254 |
254 |
255 notepad begin |
255 notepad begin |