153 val ((rep, rep_def), lthy3) = define (rep_name, NoSyn, rep_trm) lthy2 |
153 val ((rep, rep_def), lthy3) = define (rep_name, NoSyn, rep_trm) lthy2 |
154 |
154 |
155 (* quot_type theorem *) |
155 (* quot_type theorem *) |
156 val quot_thm = typedef_quot_type_thm (rel, Abs_const, Rep_const, equiv_thm, typedef_info) lthy3 |
156 val quot_thm = typedef_quot_type_thm (rel, Abs_const, Rep_const, equiv_thm, typedef_info) lthy3 |
157 |
157 |
158 (* quotient theorem *) |
158 (* quotient theorem *) |
159 val quotient_thm = typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_thm) lthy3 |
159 val quotient_thm = typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_thm) lthy3 |
160 val quotient_thm_name = Binding.prefix_name "Quotient_" qty_name |
160 val quotient_thm_name = Binding.prefix_name "Quotient_" qty_name |
161 |
161 |
162 (* name equivalence theorem *) |
162 (* name equivalence theorem *) |
163 val equiv_thm_name = Binding.suffix_name "_equivp" qty_name |
163 val equiv_thm_name = Binding.suffix_name "_equivp" qty_name |
187 val illegal_rel_vars = |
187 val illegal_rel_vars = |
188 if null rel_vars andalso null rel_tvars then [] |
188 if null rel_vars andalso null rel_tvars then [] |
189 else [qty_str ^ "illegal schematic variable(s) in the relation."] |
189 else [qty_str ^ "illegal schematic variable(s) in the relation."] |
190 |
190 |
191 val dup_vs = |
191 val dup_vs = |
192 (case duplicates (op =) vs of |
192 (case duplicates (op =) vs of |
193 [] => [] |
193 [] => [] |
194 | dups => [qty_str ^ "duplicate type variable(s) on the lhs: " ^ commas_quote dups]) |
194 | dups => [qty_str ^ "duplicate type variable(s) on the lhs: " ^ commas_quote dups]) |
195 |
195 |
196 val extra_rty_tfrees = |
196 val extra_rty_tfrees = |
197 (case subtract (op =) vs rty_tfreesT of |
197 (case subtract (op =) vs rty_tfreesT of |
198 [] => [] |
198 [] => [] |
199 | extras => [qty_str ^ "extra type variable(s) on the lhs: " ^ commas_quote extras]) |
199 | extras => [qty_str ^ "extra type variable(s) on the lhs: " ^ commas_quote extras]) |
200 |
200 |
201 val extra_rel_tfrees = |
201 val extra_rel_tfrees = |
202 (case subtract (op =) vs rel_tfrees of |
202 (case subtract (op =) vs rel_tfrees of |
203 [] => [] |
203 [] => [] |
204 | extras => [qty_str ^ "extra type variable(s) in the relation: " ^ commas_quote extras]) |
204 | extras => [qty_str ^ "extra type variable(s) in the relation: " ^ commas_quote extras]) |
205 |
205 |
206 val illegal_rel_frees = |
206 val illegal_rel_frees = |
207 (case rel_frees of |
207 (case rel_frees of |
208 [] => [] |
208 [] => [] |
209 | xs => [qty_str ^ "illegal variable(s) in the relation: " ^ commas_quote xs]) |
209 | xs => [qty_str ^ "illegal variable(s) in the relation: " ^ commas_quote xs]) |
210 |
210 |
211 val errs = illegal_rel_vars @ dup_vs @ extra_rty_tfrees @ extra_rel_tfrees @ illegal_rel_frees |
211 val errs = illegal_rel_vars @ dup_vs @ extra_rty_tfrees @ extra_rel_tfrees @ illegal_rel_frees |
212 in |
212 in |
246 |
246 |
247 it opens a proof-state in which one has to show that the |
247 it opens a proof-state in which one has to show that the |
248 relations are equivalence relations |
248 relations are equivalence relations |
249 *) |
249 *) |
250 |
250 |
251 fun quotient_type quot_list lthy = |
251 fun quotient_type quot_list lthy = |
252 let |
252 let |
253 (* sanity check *) |
253 (* sanity check *) |
254 val _ = List.app sanity_check quot_list |
254 val _ = List.app sanity_check quot_list |
255 val _ = List.app (map_check lthy) quot_list |
255 val _ = List.app (map_check lthy) quot_list |
256 |
256 |
257 fun mk_goal (rty, rel) = |
257 fun mk_goal (rty, rel) = |
258 let |
258 let |
259 val equivp_ty = ([rty, rty] ---> @{typ bool}) --> @{typ bool} |
259 val equivp_ty = ([rty, rty] ---> @{typ bool}) --> @{typ bool} |
260 in |
260 in |
261 HOLogic.mk_Trueprop (Const (@{const_name equivp}, equivp_ty) $ rel) |
261 HOLogic.mk_Trueprop (Const (@{const_name equivp}, equivp_ty) $ rel) |
262 end |
262 end |
263 |
263 |
264 val goals = map (mk_goal o snd) quot_list |
264 val goals = map (mk_goal o snd) quot_list |
265 |
265 |
266 fun after_qed thms lthy = |
266 fun after_qed thms lthy = |
267 fold_map mk_quotient_type (quot_list ~~ thms) lthy |> snd |
267 fold_map mk_quotient_type (quot_list ~~ thms) lthy |> snd |
268 in |
268 in |
269 theorem after_qed goals lthy |
269 theorem after_qed goals lthy |
270 end |
270 end |
271 |
271 |
272 fun quotient_type_cmd specs lthy = |
272 fun quotient_type_cmd specs lthy = |
273 let |
273 let |
274 fun parse_spec ((((vs, qty_name), mx), rty_str), rel_str) lthy = |
274 fun parse_spec ((((vs, qty_name), mx), rty_str), rel_str) lthy = |
275 let |
275 let |
276 (* new parsing with proper declaration *) |
276 (* new parsing with proper declaration *) |
277 val rty = Syntax.read_typ lthy rty_str |
277 val rty = Syntax.read_typ lthy rty_str |
278 val lthy1 = Variable.declare_typ rty lthy |
278 val lthy1 = Variable.declare_typ rty lthy |
279 val pre_rel = Syntax.parse_term lthy1 rel_str |
279 val pre_rel = Syntax.parse_term lthy1 rel_str |
280 val pre_rel' = Syntax.type_constraint (rty --> rty --> @{typ bool}) pre_rel |
280 val pre_rel' = Syntax.type_constraint (rty --> rty --> @{typ bool}) pre_rel |
281 val rel = Syntax.check_term lthy1 pre_rel' |
281 val rel = Syntax.check_term lthy1 pre_rel' |
282 val lthy2 = Variable.declare_term rel lthy1 |
282 val lthy2 = Variable.declare_term rel lthy1 |
283 |
283 |
284 (* old parsing *) |
284 (* old parsing *) |
285 (* val rty = Syntax.read_typ lthy rty_str |
285 (* val rty = Syntax.read_typ lthy rty_str |
286 val rel = Syntax.read_term lthy rel_str *) |
286 val rel = Syntax.read_term lthy rel_str *) |
287 in |
287 in |
288 (((vs, qty_name, mx), (rty, rel)), lthy2) |
288 (((vs, qty_name, mx), (rty, rel)), lthy2) |
289 end |
289 end |
290 |
290 |
291 val (spec', lthy') = fold_map parse_spec specs lthy |
291 val (spec', lthy') = fold_map parse_spec specs lthy |
292 in |
292 in |
293 quotient_type spec' lthy' |
293 quotient_type spec' lthy' |
294 end |
294 end |
295 |
295 |
296 val quotspec_parser = |
296 val quotspec_parser = |
297 OuterParse.and_list1 |
297 OuterParse.and_list1 |
298 ((OuterParse.type_args -- OuterParse.binding) -- |
298 ((OuterParse.type_args -- OuterParse.binding) -- |
299 OuterParse.opt_infix -- (OuterParse.$$$ "=" |-- OuterParse.typ) -- |
299 OuterParse.opt_infix -- (OuterParse.$$$ "=" |-- OuterParse.typ) -- |
300 (OuterParse.$$$ "/" |-- OuterParse.term)) |
300 (OuterParse.$$$ "/" |-- OuterParse.term)) |
301 |
301 |
302 val _ = OuterKeyword.keyword "/" |
302 val _ = OuterKeyword.keyword "/" |
303 |
303 |
304 val _ = |
304 val _ = |
305 OuterSyntax.local_theory_to_proof "quotient_type" |
305 OuterSyntax.local_theory_to_proof "quotient_type" |
306 "quotient type definitions (require equivalence proofs)" |
306 "quotient type definitions (require equivalence proofs)" |
307 OuterKeyword.thy_goal (quotspec_parser >> quotient_type_cmd) |
307 OuterKeyword.thy_goal (quotspec_parser >> quotient_type_cmd) |
308 |
308 |
309 end; (* structure *) |
309 end; (* structure *) |