Quot/quotient_tacs.ML
changeset 773 d6acae26d027
parent 772 a95f6bb081cf
child 774 b4ffb8826105
equal deleted inserted replaced
772:a95f6bb081cf 773:d6acae26d027
     1 signature QUOTIENT_TACS =
     1 signature QUOTIENT_TACS =
     2 sig
     2 sig
     3     val regularize_tac: Proof.context -> int -> tactic
     3     val regularize_tac: Proof.context -> int -> tactic
     4     val all_inj_repabs_tac: Proof.context -> int -> tactic
     4     val all_injection_tac: Proof.context -> int -> tactic
     5     val clean_tac: Proof.context -> int -> tactic
     5     val clean_tac: Proof.context -> int -> tactic
     6     val procedure_tac: Proof.context -> thm -> int -> tactic
     6     val procedure_tac: Proof.context -> thm -> int -> tactic
     7     val lift_tac: Proof.context ->thm -> int -> tactic
     7     val lift_tac: Proof.context -> thm -> int -> tactic
     8     val quotient_tac: Proof.context -> int -> tactic
     8     val quotient_tac: Proof.context -> int -> tactic
     9 end;
     9 end;
    10 
    10 
    11 structure Quotient_Tacs: QUOTIENT_TACS =
    11 structure Quotient_Tacs: QUOTIENT_TACS =
    12 struct
    12 struct
    46 in
    46 in
    47   @{thm equal_elim_rule1} OF [thm'', thm']
    47   @{thm equal_elim_rule1} OF [thm'', thm']
    48 end
    48 end
    49 
    49 
    50 
    50 
       
    51 (*********************)
    51 (* Regularize Tactic *)
    52 (* Regularize Tactic *)
    52 
    53 (*********************)
       
    54 
       
    55 (* solvers for equivp and quotient assumptions *)
    53 fun equiv_tac ctxt =
    56 fun equiv_tac ctxt =
    54   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
    57   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
    55 
    58 
    56 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
    59 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
    57 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
    60 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
       
    61 
       
    62 (* test whether DETERM makes any difference *)
       
    63 fun quotient_tac ctxt = SOLVES'  
       
    64   (REPEAT_ALL_NEW (FIRST'
       
    65     [rtac @{thm identity_quotient},
       
    66      resolve_tac (quotient_rules_get ctxt)]))
       
    67 
       
    68 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
       
    69 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
       
    70 
       
    71 fun solve_quotient_assm ctxt thm =
       
    72   case Seq.pull (quotient_tac ctxt 1 thm) of
       
    73     SOME (t, _) => t
       
    74   | _ => error "solve_quotient_assm failed. Maybe a quotient_thm is missing"
       
    75 
    58 
    76 
    59 fun prep_trm thy (x, (T, t)) =
    77 fun prep_trm thy (x, (T, t)) =
    60   (cterm_of thy (Var (x, T)), cterm_of thy t)
    78   (cterm_of thy (Var (x, T)), cterm_of thy t)
    61 
    79 
    62 fun prep_ty thy (x, (S, ty)) =
    80 fun prep_ty thy (x, (S, ty)) =
    72   (map (prep_ty thy) tyenv, map (prep_trm thy) tenv)
    90   (map (prep_ty thy) tyenv, map (prep_trm thy) tenv)
    73 end
    91 end
    74 
    92 
    75 (* calculates the instantiations for te lemmas *)
    93 (* calculates the instantiations for te lemmas *)
    76 (* ball_reg_eqv_range and bex_reg_eqv_range    *)
    94 (* ball_reg_eqv_range and bex_reg_eqv_range    *)
    77 fun calculate_instance ctxt ball_bex_thm redex R1 R2 =
    95 fun calculate_inst ctxt ball_bex_thm redex R1 R2 =
    78 let
    96 let
    79   fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm))
    97   fun get_lhs thm = fst (Logic.dest_equals (Thm.concl_of thm))
    80   val thy = ProofContext.theory_of ctxt
    98   val thy = ProofContext.theory_of ctxt
    81   val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)]
    99   val typ_inst1 = map (SOME o ctyp_of thy) [domain_type (fastype_of R2)]
    82   val trm_inst1 = map (SOME o cterm_of thy) [R2, R1]
   100   val trm_inst1 = map (SOME o cterm_of thy) [R2, R1]
    91 (* FIXME/TODO: What is the place where the exception is raised,  *)
   109 (* FIXME/TODO: What is the place where the exception is raised,  *)
    92 (* FIXME/TODO: and which exception is it?                        *)
   110 (* FIXME/TODO: and which exception is it?                        *)
    93 (* FIXME/TODO: Can one not find out from the types of R1 or R2,  *)
   111 (* FIXME/TODO: Can one not find out from the types of R1 or R2,  *)
    94 (* FIXME/TODO: or from their form, when NONE should be returned? *)
   112 (* FIXME/TODO: or from their form, when NONE should be returned? *)
    95 
   113 
    96 
       
    97 fun ball_bex_range_simproc ss redex =
   114 fun ball_bex_range_simproc ss redex =
    98 let
   115 let
    99   val ctxt = Simplifier.the_context ss
   116   val ctxt = Simplifier.the_context ss
   100 in 
   117 in 
   101   case redex of
   118   case redex of
   102     (Const (@{const_name "Ball"}, _) $ (Const (@{const_name "Respects"}, _) $ 
   119     (Const (@{const_name "Ball"}, _) $ (Const (@{const_name "Respects"}, _) $ 
   103       (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) =>
   120       (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) =>
   104         calculate_instance ctxt @{thm ball_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   121         calculate_inst ctxt @{thm ball_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   105 
   122 
   106   | (Const (@{const_name "Bex"}, _) $ (Const (@{const_name "Respects"}, _) $ 
   123   | (Const (@{const_name "Bex"}, _) $ (Const (@{const_name "Respects"}, _) $ 
   107       (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) =>  
   124       (Const (@{const_name "fun_rel"}, _) $ R1 $ R2)) $ _) =>  
   108         calculate_instance ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   125         calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2
       
   126 
   109   | _ => NONE
   127   | _ => NONE
   110 end
   128 end
   111 
       
   112 (* test whether DETERM makes any difference *)
       
   113 fun quotient_tac ctxt = SOLVES'  
       
   114   (REPEAT_ALL_NEW (FIRST'
       
   115     [rtac @{thm identity_quotient},
       
   116      resolve_tac (quotient_rules_get ctxt)]))
       
   117 
       
   118 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
       
   119 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
       
   120 
       
   121 fun solve_quotient_assm ctxt thm =
       
   122   case Seq.pull (quotient_tac ctxt 1 thm) of
       
   123     SOME (t, _) => t
       
   124   | _ => error "solve_quotient_assm failed. Maybe a quotient_thm is missing"
       
   125 
       
   126 
   129 
   127 (* 0. preliminary simplification step according to *)
   130 (* 0. preliminary simplification step according to *)
   128 (*    thm ball_reg_eqv bex_reg_eqv babs_reg_eqv    *)
   131 (*    thm ball_reg_eqv bex_reg_eqv babs_reg_eqv    *)
   129 (*        ball_reg_eqv_range bex_reg_eqv_range     *)
   132 (*        ball_reg_eqv_range bex_reg_eqv_range     *)
   130 (*                                                 *)
   133 (*                                                 *)
   131 (* 1. eliminating simple Ball/Bex instances        *)
   134 (* 1. eliminating simple Ball/Bex instances        *)
   132 (*    thm ball_reg_right bex_reg_left              *)
   135 (*    thm ball_reg_right bex_reg_left              *)
   133 (*                                                 *)
   136 (*                                                 *)
   134 (* 2. monos                                        *)
   137 (* 2. monos                                        *)
       
   138 (*                                                 *)
   135 (* 3. commutation rules for ball and bex           *)
   139 (* 3. commutation rules for ball and bex           *)
   136 (*    thm ball_all_comm bex_ex_comm                *)
   140 (*    thm ball_all_comm bex_ex_comm                *)
   137 (*                                                 *)
   141 (*                                                 *)
   138 (* 4. then rel-equality (which need to be          *)
   142 (* 4. then rel-equalities, which need to be        *)
   139 (*    instantiated to avoid loops)                 *)
   143 (*    instantiated with the followig theorem       *)
       
   144 (*    to avoid loops:                              *)
   140 (*    thm eq_imp_rel                               *)
   145 (*    thm eq_imp_rel                               *)
   141 (*                                                 *)
   146 (*                                                 *)
   142 (* 5. then simplification like 0                   *)
   147 (* 5. then simplification like 0                   *)
   143 (*                                                 *)
   148 (*                                                 *)
   144 (* finally jump back to 1                          *)
   149 (* finally jump back to 1                          *)
   154                        addsimprocs [simproc] 
   159                        addsimprocs [simproc] 
   155                        addSolver equiv_solver addSolver quotient_solver
   160                        addSolver equiv_solver addSolver quotient_solver
   156   val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt)
   161   val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt)
   157 in
   162 in
   158   simp_tac simpset THEN'
   163   simp_tac simpset THEN'
   159   REPEAT_ALL_NEW (CHANGED o FIRST' [
   164   REPEAT_ALL_NEW (CHANGED o FIRST' 
   160     resolve_tac @{thms ball_reg_right bex_reg_left},
   165     [resolve_tac @{thms ball_reg_right bex_reg_left},
   161     resolve_tac (Inductive.get_monos ctxt),
   166      resolve_tac (Inductive.get_monos ctxt),
   162     resolve_tac @{thms ball_all_comm bex_ex_comm},
   167      resolve_tac @{thms ball_all_comm bex_ex_comm},
   163     resolve_tac eq_eqvs,  
   168      resolve_tac eq_eqvs,  
   164     simp_tac simpset])
   169      simp_tac simpset])
   165 end
   170 end
   166 
   171 
   167 
   172 
   168 
   173 (********************)
   169 (* Injection Tactic *)
   174 (* Injection Tactic *)
   170 
   175 (********************)
   171 (* looks for QUOT_TRUE assumtions, and in case its parameter   *)
   176 
   172 (* is an application, it returns the function and the argument *)
   177 (* Looks for Quot_True assumtions, and in case its parameter    *)
       
   178 (* is an application, it returns the function and the argument. *)
   173 fun find_qt_asm asms =
   179 fun find_qt_asm asms =
   174 let
   180 let
   175   fun find_fun trm =
   181   fun find_fun trm =
   176     case trm of
   182     case trm of
   177       (Const(@{const_name Trueprop}, _) $ (Const (@{const_name QUOT_TRUE}, _) $ _)) => true
   183       (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true
   178     | _ => false
   184     | _ => false
   179 in
   185 in
   180  case find_first find_fun asms of
   186  case find_first find_fun asms of
   181    SOME (_ $ (_ $ (f $ a))) => SOME (f, a)
   187    SOME (_ $ (_ $ (f $ a))) => SOME (f, a)
   182  | _ => NONE
   188  | _ => NONE
   183 end
   189 end
   184 
   190 
   185 fun quot_true_simple_conv ctxt fnctn ctrm =
   191 fun quot_true_simple_conv ctxt fnctn ctrm =
   186   case (term_of ctrm) of
   192   case (term_of ctrm) of
   187     (Const (@{const_name QUOT_TRUE}, _) $ x) =>
   193     (Const (@{const_name Quot_True}, _) $ x) =>
   188     let
   194     let
   189       val fx = fnctn x;
   195       val fx = fnctn x;
   190       val thy = ProofContext.theory_of ctxt;
   196       val thy = ProofContext.theory_of ctxt;
   191       val cx = cterm_of thy x;
   197       val cx = cterm_of thy x;
   192       val cfx = cterm_of thy fx;
   198       val cfx = cterm_of thy fx;
   193       val cxt = ctyp_of thy (fastype_of x);
   199       val cxt = ctyp_of thy (fastype_of x);
   194       val cfxt = ctyp_of thy (fastype_of fx);
   200       val cfxt = ctyp_of thy (fastype_of fx);
   195       val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QUOT_TRUE_imp}
   201       val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QT_imp}
   196     in
   202     in
   197       Conv.rewr_conv thm ctrm
   203       Conv.rewr_conv thm ctrm
   198     end
   204     end
   199 
   205 
   200 fun quot_true_conv ctxt fnctn ctrm =
   206 fun quot_true_conv ctxt fnctn ctrm =
   201   case (term_of ctrm) of
   207   case (term_of ctrm) of
   202     (Const (@{const_name QUOT_TRUE}, _) $ _) =>
   208     (Const (@{const_name Quot_True}, _) $ _) =>
   203       quot_true_simple_conv ctxt fnctn ctrm
   209       quot_true_simple_conv ctxt fnctn ctrm
   204   | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm
   210   | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm
   205   | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm
   211   | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm
   206   | _ => Conv.all_conv ctrm
   212   | _ => Conv.all_conv ctrm
   207 
   213 
   223   | dest_fun_type _ = error "dest_fun_type"
   229   | dest_fun_type _ = error "dest_fun_type"
   224 
   230 
   225 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl
   231 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl
   226 
   232 
   227 
   233 
   228 (* we apply apply_rsp only in case if the type needs lifting,      *)
   234 (* We apply apply_rsp only in case if the type needs lifting.      *)
   229 (* which is the case if the type of the data in the QUOT_TRUE      *)
   235 (* This is the case if the type of the data in the Quot_True       *)
   230 (* assumption is different from the corresponding type in the goal *)
   236 (* assumption is different from the corresponding type in the goal *)
   231 val apply_rsp_tac =
   237 val apply_rsp_tac =
   232   Subgoal.FOCUS (fn {concl, asms, context,...} =>
   238   Subgoal.FOCUS (fn {concl, asms, context,...} =>
   233   let
   239   let
   234     val bare_concl = HOLogic.dest_Trueprop (term_of concl)
   240     val bare_concl = HOLogic.dest_Trueprop (term_of concl)
   260   val thm = Drule.instantiate' 
   266   val thm = Drule.instantiate' 
   261                [SOME (ctyp_of thy ty)] [SOME (cterm_of thy R)] @{thm equals_rsp}
   267                [SOME (ctyp_of thy ty)] [SOME (cterm_of thy R)] @{thm equals_rsp}
   262 in
   268 in
   263   rtac thm THEN' quotient_tac ctxt
   269   rtac thm THEN' quotient_tac ctxt
   264 end
   270 end
   265 (* raised by instantiate' *)
   271 (* Are they raised by instantiate'? *)
   266 handle THM _  => K no_tac  
   272 handle THM _  => K no_tac  
   267      | TYPE _ => K no_tac    
   273      | TYPE _ => K no_tac    
   268      | TERM _ => K no_tac
   274      | TERM _ => K no_tac
   269 
   275 
   270 
   276 
   307  D) unfolding lambda on one side
   313  D) unfolding lambda on one side
   308  E) simplifying (= ===> =) for simpler respectfulness
   314  E) simplifying (= ===> =) for simpler respectfulness
   309 *)
   315 *)
   310 
   316 
   311 
   317 
   312 fun inj_repabs_tac_match ctxt = SUBGOAL (fn (goal, i) =>
   318 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) =>
   313 (case (bare_concl goal) of
   319 (case (bare_concl goal) of
   314     (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *)
   320     (* (R1 ===> R2) (%x...) (%x...) ----> [|R1 x y|] ==> R2 (...x) (...y) *)
   315   (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _)
   321   (Const (@{const_name fun_rel}, _) $ _ $ _) $ (Abs _) $ (Abs _)
   316       => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam
   322       => rtac @{thm fun_rel_id} THEN' quot_true_tac ctxt unlam
   317 
   323 
   363        ORELSE' rep_abs_rsp_tac ctxt
   369        ORELSE' rep_abs_rsp_tac ctxt
   364 
   370 
   365 | _ => K no_tac
   371 | _ => K no_tac
   366 ) i)
   372 ) i)
   367 
   373 
   368 fun inj_repabs_step_tac ctxt rel_refl =
   374 fun injection_step_tac ctxt rel_refl =
   369  FIRST' [
   375  FIRST' [
   370     inj_repabs_tac_match ctxt,
   376     injection_match_tac ctxt,
   371     (* R (t $ ...) (t' $ ...) ----> apply_rsp   provided type of t needs lifting *)
   377 
   372     
   378     (* R (t $ ...) (t' $ ...) ----> apply_rsp   provided type of t needs lifting *)    
   373     apply_rsp_tac ctxt THEN'
   379     apply_rsp_tac ctxt THEN'
   374                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)],
   380                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)],
   375 
   381 
   376     (* (op =) (t $ ...) (t' $ ...) ----> Cong   provided type of t does not need lifting *)
   382     (* (op =) (t $ ...) (t' $ ...) ----> Cong   provided type of t does not need lifting *)
   377     (* merge with previous tactic *)
   383     (* merge with previous tactic *)
   386     
   392     
   387     (* reflexivity of the basic relations *)
   393     (* reflexivity of the basic relations *)
   388     (* R ... ... *)
   394     (* R ... ... *)
   389     resolve_tac rel_refl]
   395     resolve_tac rel_refl]
   390 
   396 
   391 fun inj_repabs_tac ctxt =
   397 fun injection_tac ctxt =
   392 let
   398 let
   393   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   399   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   394 in
   400 in
   395   simp_tac ((mk_minimal_ss ctxt) addsimps (id_simps_get ctxt)) (* HACK? *) 
   401   simp_tac ((mk_minimal_ss ctxt) addsimps (id_simps_get ctxt)) (* HACK? *) 
   396   THEN' inj_repabs_step_tac ctxt rel_refl
   402   THEN' injection_step_tac ctxt rel_refl
   397 end
   403 end
   398 
   404 
   399 fun all_inj_repabs_tac ctxt =
   405 fun all_injection_tac ctxt =
   400   REPEAT_ALL_NEW (inj_repabs_tac ctxt)
   406   REPEAT_ALL_NEW (injection_tac ctxt)
   401 
   407 
   402 
   408 
       
   409 (***************************)
   403 (* Cleaning of the Theorem *)
   410 (* Cleaning of the Theorem *)
   404 
   411 (***************************)
   405 
   412 
   406 (* expands all fun_maps, except in front of bound variables *)
   413 (* expands all fun_maps, except in front of bound variables *)
   407 fun fun_map_simple_conv xs ctrm =
   414 fun fun_map_simple_conv xs ctrm =
   408   case (term_of ctrm) of
   415   case (term_of ctrm) of
   409     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   416     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   470        Conv.rewr_conv ti ctrm
   477        Conv.rewr_conv ti ctrm
   471      end
   478      end
   472      handle _ => Conv.all_conv ctrm)
   479      handle _ => Conv.all_conv ctrm)
   473   | _ => Conv.all_conv ctrm
   480   | _ => Conv.all_conv ctrm
   474 
   481 
   475 val lambda_prs_conv =
   482 
   476   More_Conv.top_conv lambda_prs_simple_conv
   483 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   477 
       
   478 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   484 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   479 
   485 
   480 
   486 
   481 (* 1. folding of definitions and preservation lemmas;  *)
   487 (* 1. folding of definitions and preservation lemmas;  *)
   482 (*    and simplification with                          *)
   488 (*    and simplification with                          *)
   483 (*    thm babs_prs all_prs ex_prs                      *)
   489 (*    thm babs_prs all_prs ex_prs                      *)
   484 (*                                                     *) 
   490 (*                                                     *) 
   485 (* 2. unfolding of ---> in front of everything, except *)
   491 (* 2. unfolding of ---> in front of everything, except *)
   486 (*    bound variables (this prevents lambda_prs from   *)
   492 (*    bound variables (this prevents lambda_prs from   *)
   487 (*    becoming stuck                                   *)
   493 (*    becoming stuck)                                  *)
   488 (*    thm fun_map.simps                                *)
   494 (*    thm fun_map.simps                                *)
   489 (*                                                     *)
   495 (*                                                     *)
   490 (* 3. simplification with                              *)
   496 (* 3. simplification with                              *)
   491 (*    thm lambda_prs                                   *)
   497 (*    thm lambda_prs                                   *)
   492 (*                                                     *)
   498 (*                                                     *)
   493 (* 4. simplification with                              *)
   499 (* 4. simplification with                              *)
   494 (*    thm Quotient_abs_rep Quotient_rel_rep id_simps   *) 
   500 (*    thm Quotient_abs_rep Quotient_rel_rep id_simps   *) 
   495 (*                                                     *)
   501 (*                                                     *)
   496 (* 5. Test for refl                                    *)
   502 (* 5. test for refl                                    *)
   497 
   503 
   498 fun clean_tac_aux lthy =
   504 fun clean_tac_aux lthy =
   499   let
   505   let
   500     val thy = ProofContext.theory_of lthy;
   506     val thy = ProofContext.theory_of lthy;
   501     val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   507     val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   512             TRY o rtac refl]
   518             TRY o rtac refl]
   513   end
   519   end
   514 
   520 
   515 fun clean_tac lthy = REPEAT o CHANGED o (clean_tac_aux lthy) (* HACK?? *)
   521 fun clean_tac lthy = REPEAT o CHANGED o (clean_tac_aux lthy) (* HACK?? *)
   516 
   522 
       
   523 
       
   524 (********************************************************)
   517 (* Tactic for Genralisation of Free Variables in a Goal *)
   525 (* Tactic for Genralisation of Free Variables in a Goal *)
       
   526 (********************************************************)
   518 
   527 
   519 fun inst_spec ctrm =
   528 fun inst_spec ctrm =
   520    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
   529    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
   521 
   530 
   522 fun inst_spec_tac ctrms =
   531 fun inst_spec_tac ctrms =
   540       (K (EVERY1 [inst_spec_tac (rev cvrs), atac]))
   549       (K (EVERY1 [inst_spec_tac (rev cvrs), atac]))
   541   in
   550   in
   542     rtac rule i
   551     rtac rule i
   543   end)  
   552   end)  
   544 
   553 
   545 
   554 (**********************************************)
   546 (* The General Shape of the Lifting Procedure *)
   555 (* The General Shape of the Lifting Procedure *)
       
   556 (**********************************************)
   547 
   557 
   548 (* - A is the original raw theorem                       *)
   558 (* - A is the original raw theorem                       *)
   549 (* - B is the regularized theorem                        *)
   559 (* - B is the regularized theorem                        *)
   550 (* - C is the rep/abs injected version of B              *)
   560 (* - C is the rep/abs injected version of B              *)
   551 (* - D is the lifted theorem                             *)
   561 (* - D is the lifted theorem                             *)
   552 (*                                                       *)
   562 (*                                                       *)
   553 (* - 1st prem is the regularization step                 *)
   563 (* - 1st prem is the regularization step                 *)
   554 (* - 2nd prem is the rep/abs injection step              *)
   564 (* - 2nd prem is the rep/abs injection step              *)
   555 (* - 3rd prem is the cleaning part                       *)
   565 (* - 3rd prem is the cleaning part                       *)
   556 (*                                                       *)
   566 (*                                                       *)
   557 (* the QUOT_TRUE premise in 2 records the lifted theorem *)
   567 (* the Quot_True premise in 2 records the lifted theorem *)
   558 
   568 
   559 val lifting_procedure = 
   569 val lifting_procedure = 
   560    @{lemma  "[|A; 
   570    @{lemma  "[|A; 
   561                A --> B; 
   571                A --> B; 
   562                QUOT_TRUE D ==> B = C; 
   572                Quot_True D ==> B = C; 
   563                C = D|] ==> D" 
   573                C = D|] ==> D" 
   564       by (simp add: QUOT_TRUE_def)}
   574       by (simp add: Quot_True_def)}
   565 
   575 
   566 fun lift_match_error ctxt fun_str rtrm qtrm =
   576 fun lift_match_error ctxt str rtrm qtrm =
   567 let
   577 let
   568   val rtrm_str = Syntax.string_of_term ctxt rtrm
   578   val rtrm_str = Syntax.string_of_term ctxt rtrm
   569   val qtrm_str = Syntax.string_of_term ctxt qtrm
   579   val qtrm_str = Syntax.string_of_term ctxt qtrm
   570   val msg = cat_lines [enclose "[" "]" fun_str, "The quotient theorem", qtrm_str, 
   580   val msg = cat_lines [enclose "[" "]" str, "The quotient theorem", qtrm_str, 
   571              "", "does not match with original theorem", rtrm_str]
   581              "", "does not match with original theorem", rtrm_str]
   572 in
   582 in
   573   error msg
   583   error msg
   574 end
   584 end
   575  
   585  
   578   val thy = ProofContext.theory_of ctxt
   588   val thy = ProofContext.theory_of ctxt
   579   val rtrm' = HOLogic.dest_Trueprop rtrm
   589   val rtrm' = HOLogic.dest_Trueprop rtrm
   580   val qtrm' = HOLogic.dest_Trueprop qtrm
   590   val qtrm' = HOLogic.dest_Trueprop qtrm
   581   val reg_goal = 
   591   val reg_goal = 
   582         Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm')
   592         Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm')
   583         handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm
   593         handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm
   584   val inj_goal = 
   594   val inj_goal = 
   585         Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm'))
   595         Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm'))
   586         handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm
   596         handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm
   587 in
   597 in
   588   Drule.instantiate' []
   598   Drule.instantiate' []
   589     [SOME (cterm_of thy rtrm'),
   599     [SOME (cterm_of thy rtrm'),
   590      SOME (cterm_of thy reg_goal),
   600      SOME (cterm_of thy reg_goal),
   591      NONE,
   601      NONE,
   617 
   627 
   618 fun lift_tac ctxt rthm =
   628 fun lift_tac ctxt rthm =
   619   procedure_tac ctxt rthm
   629   procedure_tac ctxt rthm
   620   THEN' RANGE_WARN 
   630   THEN' RANGE_WARN 
   621      [(regularize_tac ctxt, msg1),
   631      [(regularize_tac ctxt, msg1),
   622       (all_inj_repabs_tac ctxt, msg2),
   632       (all_injection_tac ctxt, msg2),
   623       (clean_tac ctxt, msg3)]
   633       (clean_tac ctxt, msg3)]
   624 
   634 
   625 end; (* structure *)
   635 end; (* structure *)