QuotMain.thy
changeset 254 77ff9624cfd6
parent 252 e30997c88050
child 255 264c7b9d19f4
equal deleted inserted replaced
252:e30997c88050 254:77ff9624cfd6
   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
   337 
   340 
   338 ML {*
   341 ML {*
   339 val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants"
   342 val _ = OuterSyntax.local_theory "quotient_def" "lifted definition of constants"
   340   OuterKeyword.thy_decl (qd_parser >> parse_qd_spec)
   343   OuterKeyword.thy_decl (qd_parser >> parse_qd_spec)
   341 *}
   344 *}
       
   345 
       
   346 (* ML {* show_all_types := true *} *)
   342 
   347 
   343 section {* ATOMIZE *}
   348 section {* ATOMIZE *}
   344 
   349 
   345 text {*
   350 text {*
   346   Unabs_def converts a definition given as
   351   Unabs_def converts a definition given as
   499          if (needs_lift rty T) then
   504          if (needs_lift rty T) then
   500            (mk_bex ty1) $ (mk_resp ty2 $ rrel) $ (apply_subt (my_reg lthy rel rty) t)
   505            (mk_bex ty1) $ (mk_resp ty2 $ rrel) $ (apply_subt (my_reg lthy rel rty) t)
   501          else
   506          else
   502            Const (@{const_name "Ex"}, ty) $ apply_subt (my_reg lthy rel rty) t
   507            Const (@{const_name "Ex"}, ty) $ apply_subt (my_reg lthy rel rty) t
   503        end
   508        end
   504   | Const (@{const_name "op ="}, ty) $ t =>
       
   505       if needs_lift rty (fastype_of t) then
       
   506         (tyRel (fastype_of t) rty rel lthy) $ t
       
   507       else Const (@{const_name "op ="}, ty) $ (my_reg lthy rel rty t)
       
   508   | t1 $ t2 => (my_reg lthy rel rty t1) $ (my_reg lthy rel rty t2)
   509   | t1 $ t2 => (my_reg lthy rel rty t1) $ (my_reg lthy rel rty t2)
   509   | _ => trm
   510   | _ => trm
   510 *}
   511 *}
   511 
   512 
   512 text {* Assumes that the given theorem is atomized *}
   513 text {* Assumes that the given theorem is atomized *}
   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 *}
   563         Type (s, tys) => Type (s, map (old_exchange_ty rty qty) tys)
   549         Type (s, tys) => Type (s, map (old_exchange_ty rty qty) tys)
   564       | _ => ty
   550       | _ => ty
   565      )
   551      )
   566 *}
   552 *}
   567 
   553 
       
   554 ML {* make_const_def *}
       
   555 
   568 ML {*
   556 ML {*
   569 fun old_get_fun flag rty qty lthy ty =
   557 fun old_get_fun flag rty qty lthy ty =
   570   get_fun flag [(qty, rty)] lthy ty 
   558   get_fun flag [(qty, rty)] lthy ty 
   571 
   559 *}
       
   560 
       
   561 ML {*
   572 fun old_make_const_def nconst_bname otrm mx rty qty lthy =
   562 fun old_make_const_def nconst_bname otrm mx rty qty lthy =
   573   make_const_def nconst_bname otrm mx [(qty, rty)] lthy
   563   make_const_def nconst_bname otrm mx [(qty, rty)] lthy
   574 *}
   564 *}
   575 
   565 
   576 text {* Does the same as 'subst' in a given prop or theorem *}
   566 text {* Does the same as 'subst' in a given prop or theorem *}
   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;