15 assumes equiv: "EQUIV R" |
15 assumes equiv: "EQUIV R" |
16 and rep_prop: "\<And>y. \<exists>x. Rep y = R x" |
16 and rep_prop: "\<And>y. \<exists>x. Rep y = R x" |
17 and rep_inverse: "\<And>x. Abs (Rep x) = x" |
17 and rep_inverse: "\<And>x. Abs (Rep x) = x" |
18 and abs_inverse: "\<And>x. (Rep (Abs (R x))) = (R x)" |
18 and abs_inverse: "\<And>x. (Rep (Abs (R x))) = (R x)" |
19 and rep_inject: "\<And>x y. (Rep x = Rep y) = (x = y)" |
19 and rep_inject: "\<And>x y. (Rep x = Rep y) = (x = y)" |
20 begin |
20 begin |
21 |
21 |
22 definition |
22 definition |
23 "ABS x \<equiv> Abs (R x)" |
23 "ABS x \<equiv> Abs (R x)" |
24 |
24 |
25 definition |
25 definition |
26 "REP a = Eps (Rep a)" |
26 "REP a = Eps (Rep a)" |
27 |
27 |
28 lemma lem9: |
28 lemma lem9: |
29 shows "R (Eps (R x)) = R x" |
29 shows "R (Eps (R x)) = R x" |
30 proof - |
30 proof - |
31 have a: "R x x" using equiv by (simp add: EQUIV_REFL_SYM_TRANS REFL_def) |
31 have a: "R x x" using equiv by (simp add: EQUIV_REFL_SYM_TRANS REFL_def) |
32 then have "R x (Eps (R x))" by (rule someI) |
32 then have "R x (Eps (R x))" by (rule someI) |
33 then show "R (Eps (R x)) = R x" |
33 then show "R (Eps (R x)) = R x" |
34 using equiv unfolding EQUIV_def by simp |
34 using equiv unfolding EQUIV_def by simp |
35 qed |
35 qed |
36 |
36 |
37 theorem thm10: |
37 theorem thm10: |
38 shows "ABS (REP a) = a" |
38 shows "ABS (REP a) = a" |
39 unfolding ABS_def REP_def |
39 unfolding ABS_def REP_def |
40 proof - |
40 proof - |
41 from rep_prop |
41 from rep_prop |
42 obtain x where eq: "Rep a = R x" by auto |
42 obtain x where eq: "Rep a = R x" by auto |
43 have "Abs (R (Eps (Rep a))) = Abs (R (Eps (R x)))" using eq by simp |
43 have "Abs (R (Eps (Rep a))) = Abs (R (Eps (R x)))" using eq by simp |
44 also have "\<dots> = Abs (R x)" using lem9 by simp |
44 also have "\<dots> = Abs (R x)" using lem9 by simp |
45 also have "\<dots> = Abs (Rep a)" using eq by simp |
45 also have "\<dots> = Abs (Rep a)" using eq by simp |
46 also have "\<dots> = a" using rep_inverse by simp |
46 also have "\<dots> = a" using rep_inverse by simp |
47 finally |
47 finally |
48 show "Abs (R (Eps (Rep a))) = a" by simp |
48 show "Abs (R (Eps (Rep a))) = a" by simp |
49 qed |
49 qed |
50 |
50 |
51 lemma REP_refl: |
51 lemma REP_refl: |
52 shows "R (REP a) (REP a)" |
52 shows "R (REP a) (REP a)" |
53 unfolding REP_def |
53 unfolding REP_def |
54 by (simp add: equiv[simplified EQUIV_def]) |
54 by (simp add: equiv[simplified EQUIV_def]) |
55 |
55 |
56 lemma lem7: |
56 lemma lem7: |
95 |
95 |
96 |
96 |
97 ML {* |
97 ML {* |
98 (* constructs the term \<lambda>(c::ty \<Rightarrow> bool). \<exists>x. c = rel x *) |
98 (* constructs the term \<lambda>(c::ty \<Rightarrow> bool). \<exists>x. c = rel x *) |
99 fun typedef_term rel ty lthy = |
99 fun typedef_term rel ty lthy = |
100 let |
100 let |
101 val [x, c] = [("x", ty), ("c", ty --> @{typ bool})] |
101 val [x, c] = [("x", ty), ("c", ty --> @{typ bool})] |
102 |> Variable.variant_frees lthy [rel] |
102 |> Variable.variant_frees lthy [rel] |
103 |> map Free |
103 |> map Free |
104 in |
104 in |
105 lambda c |
105 lambda c |
106 (HOLogic.mk_exists |
106 (HOLogic.mk_exists |
107 ("x", ty, HOLogic.mk_eq (c, (rel $ x)))) |
107 ("x", ty, HOLogic.mk_eq (c, (rel $ x)))) |
108 end |
108 end |
109 *} |
109 *} |
110 |
110 |
111 (* |
111 (* |
114 |> Syntax.string_of_term @{context} |
114 |> Syntax.string_of_term @{context} |
115 |> writeln |
115 |> writeln |
116 *}*) |
116 *}*) |
117 |
117 |
118 ML {* |
118 ML {* |
119 val typedef_tac = |
119 val typedef_tac = |
120 EVERY1 [rewrite_goal_tac @{thms mem_def}, |
120 EVERY1 [rewrite_goal_tac @{thms mem_def}, |
121 rtac @{thm exI}, rtac @{thm exI}, rtac @{thm refl}] |
121 rtac @{thm exI}, rtac @{thm exI}, rtac @{thm refl}] |
122 *} |
122 *} |
123 |
123 |
124 ML {* |
124 ML {* |
125 (* makes the new type definitions *) |
125 (* makes the new type definitions *) |
126 fun typedef_make (qty_name, rel, ty) lthy = |
126 fun typedef_make (qty_name, rel, ty) lthy = |
127 LocalTheory.theory_result |
127 LocalTheory.theory_result |
128 (Typedef.add_typedef false NONE |
128 (Typedef.add_typedef false NONE |
129 (qty_name, map fst (Term.add_tfreesT ty []), NoSyn) |
129 (qty_name, map fst (Term.add_tfreesT ty []), NoSyn) |
130 (typedef_term rel ty lthy) |
130 (typedef_term rel ty lthy) |
131 NONE typedef_tac) lthy |
131 NONE typedef_tac) lthy |
132 *} |
132 *} |
133 |
133 |
134 text {* proves the QUOT_TYPE theorem for the new type *} |
134 text {* proves the QUOT_TYPE theorem for the new type *} |
135 ML {* |
135 ML {* |
136 fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) = |
136 fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) = |
137 let |
137 let |
138 val rep_thm = #Rep typedef_info |
138 val rep_thm = #Rep typedef_info |
139 val rep_inv = #Rep_inverse typedef_info |
139 val rep_inv = #Rep_inverse typedef_info |
140 val abs_inv = #Abs_inverse typedef_info |
140 val abs_inv = #Abs_inverse typedef_info |
141 val rep_inj = #Rep_inject typedef_info |
141 val rep_inj = #Rep_inject typedef_info |
143 val ss = HOL_basic_ss addsimps @{thms mem_def} |
143 val ss = HOL_basic_ss addsimps @{thms mem_def} |
144 val rep_thm_simpd = Simplifier.asm_full_simplify ss rep_thm |
144 val rep_thm_simpd = Simplifier.asm_full_simplify ss rep_thm |
145 val abs_inv_simpd = Simplifier.asm_full_simplify ss abs_inv |
145 val abs_inv_simpd = Simplifier.asm_full_simplify ss abs_inv |
146 in |
146 in |
147 EVERY1 [rtac @{thm QUOT_TYPE.intro}, |
147 EVERY1 [rtac @{thm QUOT_TYPE.intro}, |
148 rtac equiv_thm, |
148 rtac equiv_thm, |
149 rtac rep_thm_simpd, |
149 rtac rep_thm_simpd, |
150 rtac rep_inv, |
150 rtac rep_inv, |
151 rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl}, |
151 rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl}, |
152 rtac rep_inj] |
152 rtac rep_inj] |
153 end |
153 end |
154 *} |
154 *} |
155 |
155 |
156 term QUOT_TYPE |
156 term QUOT_TYPE |
157 ML {* HOLogic.mk_Trueprop *} |
157 ML {* HOLogic.mk_Trueprop *} |
158 ML {* Goal.prove *} |
158 ML {* Goal.prove *} |
159 ML {* Syntax.check_term *} |
159 ML {* Syntax.check_term *} |
160 |
160 |
161 ML {* |
161 ML {* |
162 fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy = |
162 fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy = |
163 let |
163 let |
164 val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT) |
164 val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT) |
165 val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep) |
165 val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep) |
166 |> Syntax.check_term lthy |
166 |> Syntax.check_term lthy |
170 end |
170 end |
171 *} |
171 *} |
172 |
172 |
173 ML {* |
173 ML {* |
174 fun typedef_quotient_thm_tac defs quot_type_thm = |
174 fun typedef_quotient_thm_tac defs quot_type_thm = |
175 EVERY1 [K (rewrite_goals_tac defs), |
175 EVERY1 [K (rewrite_goals_tac defs), |
176 rtac @{thm QUOT_TYPE.QUOTIENT}, |
176 rtac @{thm QUOT_TYPE.QUOTIENT}, |
177 rtac quot_type_thm] |
177 rtac quot_type_thm] |
178 *} |
178 *} |
179 |
179 |
180 ML {* |
180 ML {* |
181 fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy = |
181 fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy = |
182 let |
182 let |
183 val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT) |
183 val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT) |
184 val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep) |
184 val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep) |
185 |> Syntax.check_term lthy |
185 |> Syntax.check_term lthy |
188 (fn _ => typedef_quotient_thm_tac [abs_def, rep_def] quot_type_thm) |
188 (fn _ => typedef_quotient_thm_tac [abs_def, rep_def] quot_type_thm) |
189 end |
189 end |
190 *} |
190 *} |
191 |
191 |
192 text {* two wrappers for define and note *} |
192 text {* two wrappers for define and note *} |
193 ML {* |
193 ML {* |
194 fun make_def (name, mx, trm) lthy = |
194 fun make_def (name, mx, trm) lthy = |
195 let |
195 let |
196 val ((trm, (_ , thm)), lthy') = |
196 val ((trm, (_ , thm)), lthy') = |
197 LocalTheory.define Thm.internalK ((name, mx), (Attrib.empty_binding, trm)) lthy |
197 LocalTheory.define Thm.internalK ((name, mx), (Attrib.empty_binding, trm)) lthy |
198 in |
198 in |
199 ((trm, thm), lthy') |
199 ((trm, thm), lthy') |
200 end |
200 end |
201 *} |
201 *} |
206 |
206 |
207 ML {* make_def (@{binding foo}, NoSyn, @{term "x + x"}) @{context} *} |
207 ML {* make_def (@{binding foo}, NoSyn, @{term "x + x"}) @{context} *} |
208 *) |
208 *) |
209 |
209 |
210 ML {* |
210 ML {* |
211 fun reg_thm (name, thm) lthy = |
211 fun reg_thm (name, thm) lthy = |
212 let |
212 let |
213 val ((_,[thm']), lthy') = LocalTheory.note Thm.theoremK ((name, []), [thm]) lthy |
213 val ((_,[thm']), lthy') = LocalTheory.note Thm.theoremK ((name, []), [thm]) lthy |
214 in |
214 in |
215 (thm',lthy') |
215 (thm',lthy') |
216 end |
216 end |
217 *} |
217 *} |
218 |
218 |
241 |
241 |
242 ML {* Binding.str_of @{binding foo} *} |
242 ML {* Binding.str_of @{binding foo} *} |
243 |
243 |
244 ML {* |
244 ML {* |
245 fun typedef_main (qty_name, rel, ty, equiv_thm) lthy = |
245 fun typedef_main (qty_name, rel, ty, equiv_thm) lthy = |
246 let |
246 let |
247 (* generates typedef *) |
247 (* generates typedef *) |
248 val ((_,typedef_info), lthy') = typedef_make (qty_name, rel, ty) lthy |
248 val ((_,typedef_info), lthy') = typedef_make (qty_name, rel, ty) lthy |
249 |
249 |
250 (* abs and rep functions *) |
250 (* abs and rep functions *) |
251 val abs_ty = #abs_type typedef_info |
251 val abs_ty = #abs_type typedef_info |
256 val rep = Const (rep_name, abs_ty --> rep_ty) |
256 val rep = Const (rep_name, abs_ty --> rep_ty) |
257 |
257 |
258 (* ABS and REP definitions *) |
258 (* ABS and REP definitions *) |
259 val ABS_const = Const (@{const_name "QUOT_TYPE.ABS"}, dummyT ) |
259 val ABS_const = Const (@{const_name "QUOT_TYPE.ABS"}, dummyT ) |
260 val REP_const = Const (@{const_name "QUOT_TYPE.REP"}, dummyT ) |
260 val REP_const = Const (@{const_name "QUOT_TYPE.REP"}, dummyT ) |
261 val ABS_trm = Syntax.check_term lthy' (ABS_const $ rel $ abs) |
261 val ABS_trm = Syntax.check_term lthy' (ABS_const $ rel $ abs) |
262 val REP_trm = Syntax.check_term lthy' (REP_const $ rep) |
262 val REP_trm = Syntax.check_term lthy' (REP_const $ rep) |
263 val ABS_name = Binding.prefix_name "ABS_" qty_name |
263 val ABS_name = Binding.prefix_name "ABS_" qty_name |
264 val REP_name = Binding.prefix_name "REP_" qty_name |
264 val REP_name = Binding.prefix_name "REP_" qty_name |
265 val (((ABS, ABS_def), (REP, REP_def)), lthy'') = |
265 val (((ABS, ABS_def), (REP, REP_def)), lthy'') = |
266 lthy' |> make_def (ABS_name, NoSyn, ABS_trm) |
266 lthy' |> make_def (ABS_name, NoSyn, ABS_trm) |
267 ||>> make_def (REP_name, NoSyn, REP_trm) |
267 ||>> make_def (REP_name, NoSyn, REP_trm) |
268 |
268 |
269 (* REMOVE VARIFY *) |
269 (* REMOVE VARIFY *) |
270 val _ = tracing (Syntax.string_of_typ lthy' (type_of ABS_trm)) |
270 val _ = tracing (Syntax.string_of_typ lthy' (type_of ABS_trm)) |
365 axioms rmy_eq: "EQUIV Rmy" |
365 axioms rmy_eq: "EQUIV Rmy" |
366 |
366 |
367 term "\<lambda>(c::'a my\<Rightarrow>bool). \<exists>x. c = Rmy x" |
367 term "\<lambda>(c::'a my\<Rightarrow>bool). \<exists>x. c = Rmy x" |
368 |
368 |
369 datatype 'a trm' = |
369 datatype 'a trm' = |
370 var' "'a" |
370 var' "'a" |
371 | app' "'a trm'" "'a trm'" |
371 | app' "'a trm'" "'a trm'" |
372 | lam' "'a" "'a trm'" |
372 | lam' "'a" "'a trm'" |
373 |
373 |
374 consts R' :: "'a trm' \<Rightarrow> 'a trm' \<Rightarrow> bool" |
374 consts R' :: "'a trm' \<Rightarrow> 'a trm' \<Rightarrow> bool" |
375 axioms r_eq': "EQUIV R'" |
375 axioms r_eq': "EQUIV R'" |
376 |
376 |
377 |
377 |
378 local_setup {* |
378 local_setup {* |
415 val empty = Symtab.empty |
415 val empty = Symtab.empty |
416 val extend = I |
416 val extend = I |
417 fun merge _ = Symtab.merge (K true)) |
417 fun merge _ = Symtab.merge (K true)) |
418 in |
418 in |
419 val lookup = Symtab.lookup o Data.get |
419 val lookup = Symtab.lookup o Data.get |
420 fun update k v = Data.map (Symtab.update (k, v)) |
420 fun update k v = Data.map (Symtab.update (k, v)) |
421 end |
421 end |
422 *} |
422 *} |
423 |
423 |
424 (* mapfuns for some standard types *) |
424 (* mapfuns for some standard types *) |
425 setup {* |
425 setup {* |
432 ML {* lookup (Context.Proof @{context}) @{type_name list} *} |
432 ML {* lookup (Context.Proof @{context}) @{type_name list} *} |
433 |
433 |
434 ML {* |
434 ML {* |
435 datatype abs_or_rep = abs | rep |
435 datatype abs_or_rep = abs | rep |
436 |
436 |
437 fun get_fun abs_or_rep rty qty lthy ty = |
437 fun get_fun abs_or_rep rty qty lthy ty = |
438 let |
438 let |
439 val qty_name = Long_Name.base_name (fst (dest_Type qty)) |
439 val qty_name = Long_Name.base_name (fst (dest_Type qty)) |
440 |
440 |
441 fun get_fun_aux s fs_tys = |
441 fun get_fun_aux s fs_tys = |
442 let |
442 let |
443 val (fs, tys) = split_list fs_tys |
443 val (fs, tys) = split_list fs_tys |
444 val (otys, ntys) = split_list tys |
444 val (otys, ntys) = split_list tys |
445 val oty = Type (s, otys) |
445 val oty = Type (s, otys) |
446 val nty = Type (s, ntys) |
446 val nty = Type (s, ntys) |
447 val ftys = map (op -->) tys |
447 val ftys = map (op -->) tys |
448 in |
448 in |
449 (case (lookup (Context.Proof lthy) s) of |
449 (case (lookup (Context.Proof lthy) s) of |
450 SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty)) |
450 SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty)) |
451 | NONE => raise ERROR ("no map association for type " ^ s)) |
451 | NONE => raise ERROR ("no map association for type " ^ s)) |
452 end |
452 end |
453 |
453 |
454 fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty)) |
454 fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty)) |
457 if ty = qty |
457 if ty = qty |
458 then (get_const abs_or_rep) |
458 then (get_const abs_or_rep) |
459 else (case ty of |
459 else (case ty of |
460 TFree _ => (Abs ("x", ty, Bound 0), (ty, ty)) |
460 TFree _ => (Abs ("x", ty, Bound 0), (ty, ty)) |
461 | Type (_, []) => (Abs ("x", ty, Bound 0), (ty, ty)) |
461 | Type (_, []) => (Abs ("x", ty, Bound 0), (ty, ty)) |
462 | Type (s, tys) => get_fun_aux s (map (get_fun abs_or_rep rty qty lthy) tys) |
462 | Type (s, tys) => get_fun_aux s (map (get_fun abs_or_rep rty qty lthy) tys) |
463 | _ => raise ERROR ("no variables") |
463 | _ => raise ERROR ("no variables") |
464 ) |
464 ) |
465 end |
465 end |
466 *} |
466 *} |
467 |
467 |
478 let |
478 let |
479 val ty = fastype_of nconst |
479 val ty = fastype_of nconst |
480 val (arg_tys, res_ty) = strip_type ty |
480 val (arg_tys, res_ty) = strip_type ty |
481 |
481 |
482 val fresh_args = arg_tys |> map (pair "x") |
482 val fresh_args = arg_tys |> map (pair "x") |
483 |> Variable.variant_frees lthy [nconst, oconst] |
483 |> Variable.variant_frees lthy [nconst, oconst] |
484 |> map Free |
484 |> map Free |
485 |
485 |
486 val rep_fns = map (fst o get_fun rep rty qty lthy) arg_tys |
486 val rep_fns = map (fst o get_fun rep rty qty lthy) arg_tys |
487 val abs_fn = (fst o get_fun abs rty qty lthy) res_ty |
487 val abs_fn = (fst o get_fun abs rty qty lthy) res_ty |
488 |
488 |
493 |> fold_rev lambda fresh_args |
493 |> fold_rev lambda fresh_args |
494 end |
494 end |
495 *} |
495 *} |
496 |
496 |
497 ML {* |
497 ML {* |
498 fun exchange_ty rty qty ty = |
498 fun exchange_ty rty qty ty = |
499 if ty = rty then qty |
499 if ty = rty then qty |
500 else |
500 else |
501 (case ty of |
501 (case ty of |
502 Type (s, tys) => Type (s, map (exchange_ty rty qty) tys) |
502 Type (s, tys) => Type (s, map (exchange_ty rty qty) tys) |
503 | _ => ty) |
503 | _ => ty) |
504 *} |
504 *} |
505 |
505 |
506 ML {* |
506 ML {* |
507 fun make_const_def nconst_name oconst mx rty qty lthy = |
507 fun make_const_def nconst_name oconst mx rty qty lthy = |
508 let |
508 let |
509 val oconst_ty = fastype_of oconst |
509 val oconst_ty = fastype_of oconst |
510 val nconst_ty = exchange_ty rty qty oconst_ty |
510 val nconst_ty = exchange_ty rty qty oconst_ty |
511 val nconst = Const (nconst_name, nconst_ty) |
511 val nconst = Const (nconst_name, nconst_ty) |
512 val def_trm = get_const_def nconst oconst rty qty lthy |
512 val def_trm = get_const_def nconst oconst rty qty lthy |
513 in |
513 in |
514 make_def (Binding.name nconst_name, mx, def_trm) lthy |
514 make_def (Binding.name nconst_name, mx, def_trm) lthy |
515 end |
515 end |
516 *} |
516 *} |
517 |
517 |
518 local_setup {* |
518 local_setup {* |
519 make_const_def "VR" @{term "vr"} NoSyn @{typ "t"} @{typ "qt"} #> snd |
519 make_const_def "VR" @{term "vr"} NoSyn @{typ "t"} @{typ "qt"} #> snd |
520 *} |
520 *} |