34 Local_Theory.define ((cr_rel_name, NoSyn), ((Thm.def_binding cr_rel_name, []), fixed_def_term)) lthy' |
34 Local_Theory.define ((cr_rel_name, NoSyn), ((Thm.def_binding cr_rel_name, []), fixed_def_term)) lthy' |
35 in |
35 in |
36 (def_thm, lthy'') |
36 (def_thm, lthy'') |
37 end |
37 end |
38 |
38 |
39 fun define_abs_type gen_abs_code quot_thm lthy = |
39 fun define_code_constr gen_code quot_thm lthy = |
40 if gen_abs_code andalso Lifting_Def.can_generate_code_cert quot_thm then |
40 let |
|
41 val abs = Lifting_Term.quot_thm_abs quot_thm |
|
42 val abs_background = Morphism.term (Local_Theory.target_morphism lthy) abs |
|
43 in |
|
44 if gen_code andalso is_Const abs_background then |
|
45 let |
|
46 val (const_name, typ) = dest_Const abs_background |
|
47 val fake_term = Logic.mk_type typ |
|
48 val (fixed_fake_term, lthy') = yield_singleton(Variable.importT_terms) fake_term lthy |
|
49 val fixed_type = Logic.dest_type fixed_fake_term |
|
50 in |
|
51 Local_Theory.background_theory(Code.add_datatype [(const_name, fixed_type)]) lthy' |
|
52 end |
|
53 else |
|
54 lthy |
|
55 end |
|
56 |
|
57 fun define_abs_type gen_code quot_thm lthy = |
|
58 if gen_code andalso Lifting_Def.can_generate_code_cert quot_thm then |
41 let |
59 let |
42 val abs_type_thm = quot_thm RS @{thm Quotient_abs_rep} |
60 val abs_type_thm = quot_thm RS @{thm Quotient_abs_rep} |
43 val add_abstype_attribute = |
61 val add_abstype_attribute = |
44 Thm.declaration_attribute (fn thm => Context.mapping (Code.add_abstype thm) I) |
62 Thm.declaration_attribute (fn thm => Context.mapping (Code.add_abstype thm) I) |
45 val add_abstype_attrib = Attrib.internal (K add_abstype_attribute); |
63 val add_abstype_attrib = Attrib.internal (K add_abstype_attribute); |
74 in |
92 in |
75 if null errs then () else error (cat_lines (["Sanity check of the quotient theorem failed:",""] |
93 if null errs then () else error (cat_lines (["Sanity check of the quotient theorem failed:",""] |
76 @ (map Pretty.string_of errs))) |
94 @ (map Pretty.string_of errs))) |
77 end |
95 end |
78 |
96 |
79 fun setup_lifting_infr gen_abs_code quot_thm lthy = |
97 fun setup_lifting_infr gen_code quot_thm maybe_reflp_thm lthy = |
80 let |
98 let |
81 val _ = quot_thm_sanity_check lthy quot_thm |
99 val _ = quot_thm_sanity_check lthy quot_thm |
82 val (_, qtyp) = Lifting_Term.quot_thm_rty_qty quot_thm |
100 val (_, qtyp) = Lifting_Term.quot_thm_rty_qty quot_thm |
83 val qty_full_name = (fst o dest_Type) qtyp |
101 val qty_full_name = (fst o dest_Type) qtyp |
84 val quotients = { quot_thm = quot_thm } |
102 val quotients = { quot_thm = quot_thm } |
85 fun quot_info phi = Lifting_Info.transform_quotients phi quotients |
103 fun quot_info phi = Lifting_Info.transform_quotients phi quotients |
86 in |
104 val lthy' = case maybe_reflp_thm of |
87 lthy |
105 SOME reflp_thm => lthy |
|
106 |> (snd oo Local_Theory.note) ((Binding.empty, [Lifting_Info.add_reflp_preserve_rule_attrib]), |
|
107 [reflp_thm]) |
|
108 |> define_code_constr gen_code quot_thm |
|
109 | NONE => lthy |
|
110 |> define_abs_type gen_code quot_thm |
|
111 in |
|
112 lthy' |
88 |> Local_Theory.declaration {syntax = false, pervasive = true} |
113 |> Local_Theory.declaration {syntax = false, pervasive = true} |
89 (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi)) |
114 (fn phi => Lifting_Info.update_quotients qty_full_name (quot_info phi)) |
90 |> define_abs_type gen_abs_code quot_thm |
|
91 end |
115 end |
92 |
116 |
93 (* |
117 (* |
94 Sets up the Lifting package by a quotient theorem. |
118 Sets up the Lifting package by a quotient theorem. |
95 |
119 |
96 gen_abs_code - flag if an abstract type given by quot_thm should be registred |
120 gen_code - flag if an abstract type given by quot_thm should be registred |
97 as an abstract type in the code generator |
121 as an abstract type in the code generator |
98 quot_thm - a quotient theorem (Quotient R Abs Rep T) |
122 quot_thm - a quotient theorem (Quotient R Abs Rep T) |
99 maybe_reflp_thm - a theorem saying that a relation from quot_thm is reflexive |
123 maybe_reflp_thm - a theorem saying that a relation from quot_thm is reflexive |
100 (in the form "reflp R") |
124 (in the form "reflp R") |
101 *) |
125 *) |
102 |
126 |
103 fun setup_by_quotient gen_abs_code quot_thm maybe_reflp_thm lthy = |
127 fun setup_by_quotient gen_code quot_thm maybe_reflp_thm lthy = |
104 let |
128 let |
105 val transfer_attr = Attrib.internal (K Transfer.transfer_add) |
129 val transfer_attr = Attrib.internal (K Transfer.transfer_add) |
106 val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm |
130 val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm |
107 val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty)))) |
131 val induct_attr = Attrib.internal (K (Induct.induct_type (fst (dest_Type qty)))) |
108 val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty |
132 val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty |
115 [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}]) |
139 [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}]) |
116 |> (snd oo Local_Theory.note) ((qualify "abs_induct", [induct_attr]), |
140 |> (snd oo Local_Theory.note) ((qualify "abs_induct", [induct_attr]), |
117 [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_induct}]) |
141 [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_induct}]) |
118 |> (snd oo Local_Theory.note) ((qualify "abs_eq_iff", []), |
142 |> (snd oo Local_Theory.note) ((qualify "abs_eq_iff", []), |
119 [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_eq_iff}]) |
143 [[quot_thm, reflp_thm] MRSL @{thm Quotient_total_abs_eq_iff}]) |
120 |> (snd oo Local_Theory.note) ((Binding.empty, [Lifting_Info.add_reflp_preserve_rule_attrib]), |
|
121 [reflp_thm]) |
|
122 | NONE => lthy |
144 | NONE => lthy |
123 |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), |
145 |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), |
124 [quot_thm RS @{thm Quotient_All_transfer}]) |
146 [quot_thm RS @{thm Quotient_All_transfer}]) |
125 |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), |
147 |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), |
126 [quot_thm RS @{thm Quotient_Ex_transfer}]) |
148 [quot_thm RS @{thm Quotient_Ex_transfer}]) |
134 [quot_thm RS @{thm Quotient_right_unique}]) |
156 [quot_thm RS @{thm Quotient_right_unique}]) |
135 |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), |
157 |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), |
136 [quot_thm RS @{thm Quotient_right_total}]) |
158 [quot_thm RS @{thm Quotient_right_total}]) |
137 |> (snd oo Local_Theory.note) ((qualify "rel_eq_transfer", [transfer_attr]), |
159 |> (snd oo Local_Theory.note) ((qualify "rel_eq_transfer", [transfer_attr]), |
138 [quot_thm RS @{thm Quotient_rel_eq_transfer}]) |
160 [quot_thm RS @{thm Quotient_rel_eq_transfer}]) |
139 |> setup_lifting_infr gen_abs_code quot_thm |
161 |> setup_lifting_infr gen_code quot_thm maybe_reflp_thm |
140 end |
162 end |
141 |
163 |
142 (* |
164 (* |
143 Sets up the Lifting package by a typedef theorem. |
165 Sets up the Lifting package by a typedef theorem. |
144 |
166 |
145 gen_abs_code - flag if an abstract type given by typedef_thm should be registred |
167 gen_code - flag if an abstract type given by typedef_thm should be registred |
146 as an abstract type in the code generator |
168 as an abstract type in the code generator |
147 typedef_thm - a typedef theorem (type_definition Rep Abs S) |
169 typedef_thm - a typedef theorem (type_definition Rep Abs S) |
148 *) |
170 *) |
149 |
171 |
150 fun setup_by_typedef_thm gen_abs_code typedef_thm lthy = |
172 fun setup_by_typedef_thm gen_code typedef_thm lthy = |
151 let |
173 let |
152 val transfer_attr = Attrib.internal (K Transfer.transfer_add) |
174 val transfer_attr = Attrib.internal (K Transfer.transfer_add) |
153 val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o prop_of) typedef_thm |
175 val (_ $ rep_fun $ _ $ typedef_set) = (HOLogic.dest_Trueprop o prop_of) typedef_thm |
154 val (T_def, lthy') = define_cr_rel rep_fun lthy |
176 val (T_def, lthy') = define_cr_rel rep_fun lthy |
155 |
177 |
164 val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm |
186 val (_, qty) = Lifting_Term.quot_thm_rty_qty quot_thm |
165 val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty |
187 val qty_name = (Binding.name o Long_Name.base_name o fst o dest_Type) qty |
166 fun qualify suffix = Binding.qualified true suffix qty_name |
188 fun qualify suffix = Binding.qualified true suffix qty_name |
167 val simplify = Raw_Simplifier.rewrite_rule [mk_meta_eq @{thm mem_Collect_eq}] |
189 val simplify = Raw_Simplifier.rewrite_rule [mk_meta_eq @{thm mem_Collect_eq}] |
168 |
190 |
169 val lthy'' = case typedef_set of |
191 val (maybe_reflp_thm, lthy'') = case typedef_set of |
170 Const ("Orderings.top_class.top", _) => |
192 Const ("Orderings.top_class.top", _) => |
171 let |
193 let |
172 val equivp_thm = typedef_thm RS @{thm UNIV_typedef_to_equivp} |
194 val equivp_thm = typedef_thm RS @{thm UNIV_typedef_to_equivp} |
173 val reflp_thm = equivp_thm RS @{thm equivp_reflp2} |
195 val reflp_thm = equivp_thm RS @{thm equivp_reflp2} |
174 in |
196 in |
175 lthy' |
197 lthy' |
176 |> (snd oo Local_Theory.note) ((qualify "bi_total", [transfer_attr]), |
198 |> (snd oo Local_Theory.note) ((qualify "bi_total", [transfer_attr]), |
177 [[quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total}]) |
199 [[quot_thm, reflp_thm] MRSL @{thm Quotient_bi_total}]) |
178 |> (snd oo Local_Theory.note) ((qualify "id_abs_transfer", [transfer_attr]), |
200 |> (snd oo Local_Theory.note) ((qualify "id_abs_transfer", [transfer_attr]), |
179 [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}]) |
201 [[quot_thm, reflp_thm] MRSL @{thm Quotient_id_abs_transfer}]) |
180 |> (snd oo Local_Theory.note) ((Binding.empty, [Lifting_Info.add_reflp_preserve_rule_attrib]), |
202 |> pair (SOME reflp_thm) |
181 [reflp_thm]) |
|
182 end |
203 end |
183 | _ => lthy' |
204 | _ => lthy' |
184 |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), |
205 |> (snd oo Local_Theory.note) ((qualify "All_transfer", [transfer_attr]), |
185 [[typedef_thm, T_def] MRSL @{thm typedef_All_transfer}]) |
206 [[typedef_thm, T_def] MRSL @{thm typedef_All_transfer}]) |
186 |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), |
207 |> (snd oo Local_Theory.note) ((qualify "Ex_transfer", [transfer_attr]), |
187 [[typedef_thm, T_def] MRSL @{thm typedef_Ex_transfer}]) |
208 [[typedef_thm, T_def] MRSL @{thm typedef_Ex_transfer}]) |
188 |> (snd oo Local_Theory.note) ((qualify "forall_transfer", [transfer_attr]), |
209 |> (snd oo Local_Theory.note) ((qualify "forall_transfer", [transfer_attr]), |
189 [simplify ([typedef_thm, T_def] MRSL @{thm typedef_forall_transfer})]) |
210 [simplify ([typedef_thm, T_def] MRSL @{thm typedef_forall_transfer})]) |
|
211 |> pair NONE |
190 in |
212 in |
191 lthy'' |
213 lthy'' |
192 |> (snd oo Local_Theory.note) ((qualify "bi_unique", [transfer_attr]), |
214 |> (snd oo Local_Theory.note) ((qualify "bi_unique", [transfer_attr]), |
193 [[typedef_thm, T_def] MRSL @{thm typedef_bi_unique}]) |
215 [[typedef_thm, T_def] MRSL @{thm typedef_bi_unique}]) |
194 |> (snd oo Local_Theory.note) ((qualify "rep_transfer", [transfer_attr]), |
216 |> (snd oo Local_Theory.note) ((qualify "rep_transfer", [transfer_attr]), |
195 [[typedef_thm, T_def] MRSL @{thm typedef_rep_transfer}]) |
217 [[typedef_thm, T_def] MRSL @{thm typedef_rep_transfer}]) |
196 |> (snd oo Local_Theory.note) ((qualify "right_unique", [transfer_attr]), |
218 |> (snd oo Local_Theory.note) ((qualify "right_unique", [transfer_attr]), |
197 [[quot_thm] MRSL @{thm Quotient_right_unique}]) |
219 [[quot_thm] MRSL @{thm Quotient_right_unique}]) |
198 |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), |
220 |> (snd oo Local_Theory.note) ((qualify "right_total", [transfer_attr]), |
199 [[quot_thm] MRSL @{thm Quotient_right_total}]) |
221 [[quot_thm] MRSL @{thm Quotient_right_total}]) |
200 |> setup_lifting_infr gen_abs_code quot_thm |
222 |> setup_lifting_infr gen_code quot_thm maybe_reflp_thm |
201 end |
223 end |
202 |
224 |
203 fun setup_lifting_cmd gen_abs_code xthm opt_reflp_xthm lthy = |
225 fun setup_lifting_cmd gen_code xthm opt_reflp_xthm lthy = |
204 let |
226 let |
205 val input_thm = singleton (Attrib.eval_thms lthy) xthm |
227 val input_thm = singleton (Attrib.eval_thms lthy) xthm |
206 val input_term = (HOLogic.dest_Trueprop o prop_of) input_thm |
228 val input_term = (HOLogic.dest_Trueprop o prop_of) input_thm |
207 handle TERM _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported." |
229 handle TERM _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported." |
208 |
230 |
221 SOME reflp_xthm => |
243 SOME reflp_xthm => |
222 let |
244 let |
223 val reflp_thm = singleton (Attrib.eval_thms lthy) reflp_xthm |
245 val reflp_thm = singleton (Attrib.eval_thms lthy) reflp_xthm |
224 val _ = sanity_check_reflp_thm reflp_thm |
246 val _ = sanity_check_reflp_thm reflp_thm |
225 in |
247 in |
226 setup_by_quotient gen_abs_code input_thm (SOME reflp_thm) lthy |
248 setup_by_quotient gen_code input_thm (SOME reflp_thm) lthy |
227 end |
249 end |
228 | NONE => setup_by_quotient gen_abs_code input_thm NONE lthy |
250 | NONE => setup_by_quotient gen_code input_thm NONE lthy |
229 |
251 |
230 fun setup_typedef () = |
252 fun setup_typedef () = |
231 case opt_reflp_xthm of |
253 case opt_reflp_xthm of |
232 SOME _ => error "The reflexivity theorem cannot be specified if the type_definition theorem is used." |
254 SOME _ => error "The reflexivity theorem cannot be specified if the type_definition theorem is used." |
233 | NONE => setup_by_typedef_thm gen_abs_code input_thm lthy |
255 | NONE => setup_by_typedef_thm gen_code input_thm lthy |
234 in |
256 in |
235 case input_term of |
257 case input_term of |
236 (Const (@{const_name Quotient}, _) $ _ $ _ $ _ $ _) => setup_quotient () |
258 (Const (@{const_name Quotient}, _) $ _ $ _ $ _ $ _) => setup_quotient () |
237 | (Const (@{const_name type_definition}, _) $ _ $ _ $ _) => setup_typedef () |
259 | (Const (@{const_name type_definition}, _) $ _ $ _ $ _) => setup_typedef () |
238 | _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported." |
260 | _ => error "Unsupported type of a theorem. Only Quotient or type_definition are supported." |
239 end |
261 end |
240 |
262 |
241 val opt_gen_abs_code = |
263 val opt_gen_code = |
242 Scan.optional (@{keyword "("} |-- Parse.!!! ((Parse.reserved "no_abs_code" >> K false) --| @{keyword ")"})) true |
264 Scan.optional (@{keyword "("} |-- Parse.!!! ((Parse.reserved "no_code" >> K false) --| @{keyword ")"})) true |
243 |
265 |
244 val _ = |
266 val _ = |
245 Outer_Syntax.local_theory @{command_spec "setup_lifting"} |
267 Outer_Syntax.local_theory @{command_spec "setup_lifting"} |
246 "Setup lifting infrastructure" |
268 "Setup lifting infrastructure" |
247 (opt_gen_abs_code -- Parse_Spec.xthm -- Scan.option Parse_Spec.xthm >> |
269 (opt_gen_code -- Parse_Spec.xthm -- Scan.option Parse_Spec.xthm >> |
248 (fn ((gen_abs_code, xthm), opt_reflp_xthm) => setup_lifting_cmd gen_abs_code xthm opt_reflp_xthm)) |
270 (fn ((gen_code, xthm), opt_reflp_xthm) => setup_lifting_cmd gen_code xthm opt_reflp_xthm)) |
249 end; |
271 end; |