157 *} |
157 *} |
158 |
158 |
159 section {* lifting of constants *} |
159 section {* lifting of constants *} |
160 |
160 |
161 ML {* |
161 ML {* |
162 (* whether ty1 is an instance of ty2 *) |
|
163 fun matches (ty1, ty2) = |
|
164 Type.raw_instance (ty1, Logic.varifyT ty2) |
|
165 |
|
166 fun lookup_snd _ [] _ = NONE |
162 fun lookup_snd _ [] _ = NONE |
167 | lookup_snd eq ((value, key)::xs) key' = |
163 | lookup_snd eq ((value, key)::xs) key' = |
168 if eq (key', key) then SOME value |
164 if eq (key', key) then SOME value |
169 else lookup_snd eq xs key'; |
165 else lookup_snd eq xs key'; |
170 |
166 |
171 fun lookup_qenv qenv qty = |
167 fun lookup_qenv qenv qty = |
172 (case (AList.lookup matches qenv qty) of |
168 (case (AList.lookup (op =) qenv qty) of |
173 SOME rty => SOME (qty, rty) |
169 SOME rty => SOME (qty, rty) |
174 | NONE => NONE) |
170 | NONE => NONE) |
175 *} |
171 *} |
176 |
172 |
177 ML {* |
173 ML {* |
223 end |
219 end |
224 |
220 |
225 fun mk_identity ty = Abs ("", ty, Bound 0) |
221 fun mk_identity ty = Abs ("", ty, Bound 0) |
226 |
222 |
227 in |
223 in |
228 if (AList.defined matches qenv ty) |
224 if (AList.defined (op =) qenv ty) |
229 then (get_const flag (the (lookup_qenv qenv ty))) |
225 then (get_const flag (the (lookup_qenv qenv ty))) |
230 else (case ty of |
226 else (case ty of |
231 TFree _ => (mk_identity ty, (ty, ty)) |
227 TFree _ => (mk_identity ty, (ty, ty)) |
232 | Type (_, []) => (mk_identity ty, (ty, ty)) |
228 | Type (_, []) => (mk_identity ty, (ty, ty)) |
233 | Type ("fun" , [ty1, ty2]) => |
229 | Type ("fun" , [ty1, ty2]) => |
257 in |
253 in |
258 fns $ otrm |
254 fns $ otrm |
259 end |
255 end |
260 *} |
256 *} |
261 |
257 |
262 ML {* lookup_snd *} |
|
263 |
258 |
264 ML {* |
259 ML {* |
265 fun exchange_ty qenv ty = |
260 fun exchange_ty qenv ty = |
266 case (lookup_snd matches qenv ty) of |
261 case (lookup_snd (op =) qenv ty) of |
267 SOME qty => qty |
262 SOME qty => qty |
268 | NONE => |
263 | NONE => |
269 (case ty of |
264 (case ty of |
270 Type (s, tys) => Type (s, map (exchange_ty qenv) tys) |
265 Type (s, tys) => Type (s, map (exchange_ty qenv) tys) |
271 | _ => ty |
266 | _ => ty |
272 ) |
267 ) |
273 *} |
268 *} |
274 |
269 |
|
270 ML {* |
|
271 fun ppair lthy (ty1, ty2) = |
|
272 "(" ^ (Syntax.string_of_typ lthy ty1) ^ "," ^ (Syntax.string_of_typ lthy ty2) ^ ")" |
|
273 *} |
|
274 |
|
275 ML {* |
|
276 fun print_env qenv lthy = |
|
277 map (ppair lthy) qenv |
|
278 |> commas |
|
279 |> tracing |
|
280 *} |
|
281 |
275 ML {* |
282 ML {* |
276 fun make_const_def nconst_bname otrm mx qenv lthy = |
283 fun make_const_def nconst_bname otrm mx qenv lthy = |
277 let |
284 let |
278 val otrm_ty = fastype_of otrm |
285 val otrm_ty = fastype_of otrm |
279 val nconst_ty = exchange_ty qenv otrm_ty |
286 val nconst_ty = exchange_ty qenv otrm_ty |
280 val nconst = Const (Binding.name_of nconst_bname, nconst_ty) |
287 val nconst = Const (Binding.name_of nconst_bname, nconst_ty) |
281 val def_trm = get_const_def nconst otrm qenv lthy |
288 val def_trm = get_const_def nconst otrm qenv lthy |
|
289 |
|
290 val _ = print_env qenv lthy |
|
291 val _ = Syntax.string_of_typ lthy otrm_ty |> tracing |
|
292 val _ = Syntax.string_of_typ lthy nconst_ty |> tracing |
|
293 val _ = Syntax.string_of_term lthy def_trm |> tracing |
282 in |
294 in |
283 define (nconst_bname, mx, def_trm) lthy |
295 define (nconst_bname, mx, def_trm) lthy |
284 end |
296 end |
285 *} |
297 *} |
286 |
298 |
287 ML {* |
299 ML {* |
288 fun build_qenv lthy qtys = |
300 fun build_qenv lthy qtys = |
289 let |
301 let |
290 val qenv = map (fn {qtyp, rtyp, ...} => (qtyp, rtyp)) (quotdata_lookup lthy) |
302 val qenv = map (fn {qtyp, rtyp, ...} => (qtyp, rtyp)) (quotdata_lookup lthy) |
291 |
303 val tsig = Sign.tsig_of (ProofContext.theory_of lthy) |
292 fun find_assoc qty = |
304 |
293 case (AList.lookup matches qenv qty) of |
305 fun find_assoc ((qty', rty')::rest) qty = |
294 SOME rty => (qty, rty) |
306 let |
295 | NONE => error (implode |
307 val inst = Type.typ_match tsig (qty', qty) Vartab.empty |
296 ["Quotient type ", |
308 in |
297 quote (Syntax.string_of_typ lthy qty), |
309 (Envir.norm_type inst qty, Envir.norm_type inst rty') |
298 " does not exists"]) |
310 end |
|
311 | find_assoc [] qty = |
|
312 let |
|
313 val qtystr = quote (Syntax.string_of_typ lthy qty) |
|
314 in |
|
315 error (implode ["Quotient type ", qtystr, " does not exists"]) |
|
316 end |
299 in |
317 in |
300 map find_assoc qtys |
318 map (find_assoc qenv) qtys |
301 end |
319 end |
302 *} |
|
303 |
|
304 ML {* |
|
305 (* taken from isar_syn.ML *) |
|
306 val constdecl = |
|
307 OuterParse.binding -- |
|
308 (OuterParse.where_ >> K (NONE, NoSyn) || |
|
309 OuterParse.$$$ "::" |-- OuterParse.!!! ((OuterParse.typ >> SOME) -- |
|
310 OuterParse.opt_mixfix' --| OuterParse.where_) || |
|
311 Scan.ahead (OuterParse.$$$ "(") |-- |
|
312 OuterParse.!!! (OuterParse.mixfix' --| OuterParse.where_ >> pair NONE)) |
|
313 *} |
320 *} |
314 |
321 |
315 ML {* |
322 ML {* |
316 val qd_parser = |
323 val qd_parser = |
317 (Args.parens (OuterParse.$$$ "for" |-- (Scan.repeat OuterParse.typ))) -- |
324 (Args.parens (OuterParse.$$$ "for" |-- (Scan.repeat OuterParse.typ))) -- |
318 (constdecl -- (SpecParse.opt_thm_name ":" -- OuterParse.prop)) |
325 (SpecParse.constdecl -- (SpecParse.opt_thm_name ":" -- OuterParse.prop)) |
319 *} |
326 *} |
320 |
327 |
321 ML {* |
328 ML {* |
322 fun pair lthy (ty1, ty2) = |
329 fun parse_qd_spec (qtystrs, ((bind, tystr, mx), (attr__, propstr))) lthy = |
323 "(" ^ (Syntax.string_of_typ lthy ty1) ^ "," ^ (Syntax.string_of_typ lthy ty2) ^ ")" |
|
324 *} |
|
325 |
|
326 ML {* |
|
327 fun parse_qd_spec (qtystrs, ((bind, (typstr__, mx)), (attr__, propstr))) lthy = |
|
328 let |
330 let |
329 val qtys = map (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystrs |
331 val qtys = map (Syntax.check_typ lthy o Syntax.parse_typ lthy) qtystrs |
330 val qenv = build_qenv lthy qtys |
332 val qenv = build_qenv lthy qtys |
|
333 val qty = Syntax.parse_typ lthy (the tystr) |> Syntax.check_typ lthy |
331 val prop = Syntax.parse_prop lthy propstr |> Syntax.check_prop lthy |
334 val prop = Syntax.parse_prop lthy propstr |> Syntax.check_prop lthy |
332 val (lhs, rhs) = Logic.dest_equals prop |
335 val (lhs, rhs) = Logic.dest_equals prop |
333 in |
336 in |
334 make_const_def bind rhs mx qenv lthy |> snd |
337 make_const_def bind rhs mx qenv lthy |> snd |
335 end |
338 end |
515 Logic.mk_implies |
516 Logic.mk_implies |
516 ((prop_of thm), |
517 ((prop_of thm), |
517 (my_reg lthy rel rty (prop_of thm))) |
518 (my_reg lthy rel rty (prop_of thm))) |
518 *} |
519 *} |
519 |
520 |
520 lemma universal_twice: "(\<And>x. (P x \<longrightarrow> Q x)) \<Longrightarrow> ((\<forall>x. P x) \<longrightarrow> (\<forall>x. Q x))" |
521 ML {* |
521 apply (auto) |
522 fun regularize thm rty rel rel_eqv lthy = |
522 done |
|
523 |
|
524 lemma implication_twice: "(c \<longrightarrow> a) \<Longrightarrow> (a \<Longrightarrow> b \<longrightarrow> d) \<Longrightarrow> (a \<longrightarrow> b) \<longrightarrow> (c \<longrightarrow> d)" |
|
525 apply (auto) |
|
526 done |
|
527 |
|
528 ML {* |
|
529 fun regularize thm rty rel rel_eqv rel_refl lthy = |
|
530 let |
523 let |
531 val g = build_regularize_goal thm rty rel lthy; |
524 val g = build_regularize_goal thm rty rel lthy; |
532 fun tac ctxt = |
525 fun tac ctxt = |
533 (ObjectLogic.full_atomize_tac) THEN' |
526 (asm_full_simp_tac ((Simplifier.context ctxt HOL_ss) addsimps |
534 REPEAT_ALL_NEW (FIRST' [ |
|
535 rtac rel_refl, |
|
536 atac, |
|
537 rtac @{thm universal_twice}, |
|
538 rtac @{thm implication_twice}, |
|
539 (fn i => CHANGED (asm_full_simp_tac ((Simplifier.context ctxt HOL_ss) addsimps |
|
540 [(@{thm equiv_res_forall} OF [rel_eqv]), |
527 [(@{thm equiv_res_forall} OF [rel_eqv]), |
541 (@{thm equiv_res_exists} OF [rel_eqv])]) i)), |
528 (@{thm equiv_res_exists} OF [rel_eqv])])) THEN_ALL_NEW |
542 (rtac @{thm impI} THEN' (asm_full_simp_tac (Simplifier.context ctxt HOL_ss)) THEN' rtac rel_refl), |
529 (((rtac @{thm RIGHT_RES_FORALL_REGULAR}) THEN' (RANGE [fn _ => all_tac, atac]) THEN' |
543 (rtac @{thm RIGHT_RES_FORALL_REGULAR}) |
530 (MetisTools.metis_tac ctxt [])) ORELSE' (MetisTools.metis_tac ctxt [])); |
544 ]); |
|
545 val cthm = Goal.prove lthy [] [] g (fn x => tac (#context x) 1); |
531 val cthm = Goal.prove lthy [] [] g (fn x => tac (#context x) 1); |
546 in |
532 in |
547 cthm OF [thm] |
533 cthm OF [thm] |
548 end |
534 end |
549 *} |
535 *} |
924 fun lift_thm lthy qty qty_name rsp_thms defs t = let |
914 fun lift_thm lthy qty qty_name rsp_thms defs t = let |
925 val (rty, rel, rel_refl, rel_eqv) = lookup_quot_data lthy qty; |
915 val (rty, rel, rel_refl, rel_eqv) = lookup_quot_data lthy qty; |
926 val (trans2, reps_same, quot) = lookup_quot_thms lthy qty_name; |
916 val (trans2, reps_same, quot) = lookup_quot_thms lthy qty_name; |
927 val consts = lookup_quot_consts defs; |
917 val consts = lookup_quot_consts defs; |
928 val t_a = atomize_thm t; |
918 val t_a = atomize_thm t; |
929 val t_r = regularize t_a rty rel rel_eqv rel_refl lthy; |
919 val t_r = regularize t_a rty rel rel_eqv lthy; |
930 val t_t = repabs lthy t_r consts rty qty quot rel_refl trans2 rsp_thms; |
920 val t_t = repabs lthy t_r consts rty qty quot rel_refl trans2 rsp_thms; |
931 val abs = findabs rty (prop_of t_a); |
921 val abs = findabs rty (prop_of t_a); |
932 val simp_lam_prs_thms = map (make_simp_lam_prs_thm lthy quot) abs; |
922 val simp_lam_prs_thms = map (make_simp_lam_prs_thm lthy quot) abs; |
933 val t_l = repeat_eqsubst_thm lthy simp_lam_prs_thms t_t; |
923 val t_l = repeat_eqsubst_thm lthy simp_lam_prs_thms t_t; |
934 val t_a = simp_allex_prs lthy quot t_l; |
924 val t_a = simp_allex_prs lthy quot t_l; |