Quot/quotient_tacs.ML
changeset 856 433f7c17255f
parent 853 3fd1365f5729
child 857 0ce025c02ef3
equal deleted inserted replaced
855:017cb46b27bb 856:433f7c17255f
     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 injection_tac: Proof.context -> int -> tactic
     4   val injection_tac: Proof.context -> int -> tactic
     5     val all_injection_tac: Proof.context -> int -> tactic
     5   val all_injection_tac: Proof.context -> int -> tactic
     6     val clean_tac: Proof.context -> int -> tactic
     6   val clean_tac: Proof.context -> int -> tactic
     7     val procedure_tac: Proof.context -> thm -> int -> tactic
     7   val procedure_tac: Proof.context -> thm -> int -> tactic
     8     val lift_tac: Proof.context -> thm -> int -> tactic
     8   val lift_tac: Proof.context -> thm -> int -> tactic
     9     val quotient_tac: Proof.context -> int -> tactic
     9   val quotient_tac: Proof.context -> int -> tactic
    10     val quot_true_tac: Proof.context -> (term -> term) -> int -> tactic
    10   val quot_true_tac: Proof.context -> (term -> term) -> int -> tactic
    11 end;
    11 end;
    12 
    12 
    13 structure Quotient_Tacs: QUOTIENT_TACS =
    13 structure Quotient_Tacs: QUOTIENT_TACS =
    14 struct
    14 struct
    15 
    15 
    16 open Quotient_Info;
    16 open Quotient_Info;
    17 open Quotient_Term;
    17 open Quotient_Term;
    18 
    18 
    19 (* various helper fuctions *)
    19 
       
    20 (** various helper fuctions **)
    20 
    21 
    21 (* Since HOL_basic_ss is too "big" for us, we *)
    22 (* Since HOL_basic_ss is too "big" for us, we *)
    22 (* need to set up our own minimal simpset.    *)
    23 (* need to set up our own minimal simpset.    *)
    23 fun  mk_minimal_ss ctxt =
    24 fun  mk_minimal_ss ctxt =
    24   Simplifier.context ctxt empty_ss
    25   Simplifier.context ctxt empty_ss
    46 in
    47 in
    47   @{thm equal_elim_rule1} OF [thm'', thm']
    48   @{thm equal_elim_rule1} OF [thm'', thm']
    48 end
    49 end
    49 
    50 
    50 
    51 
    51 (*********************)
    52 
    52 (* Regularize Tactic *)
    53 (*** Regularize Tactic ***)
    53 (*********************)
    54 
    54 
    55 (** solvers for equivp and quotient assumptions **)
    55 (* solvers for equivp and quotient assumptions *)
    56 
    56 (* FIXME / TODO: should this SOLVES' the goal, like with quotient_tac? *)
    57 (* FIXME / TODO: should this SOLVES' the goal, like with quotient_tac? *)
    57 (* FIXME / TODO: none of te examples break if added                    *)
    58 (* FIXME / TODO: none of te examples break if added                    *)
    58 fun equiv_tac ctxt = 
    59 fun equiv_tac ctxt =
    59   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
    60   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
    60 
    61 
    61 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
    62 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
    62 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
    63 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
    63 
    64 
    64 (* FIXME / TODO: test whether DETERM makes any runtime-difference *)
    65 (* FIXME / TODO: test whether DETERM makes any runtime-difference *)
    65 (* FIXME / TODO: reason: the tactic might back-track over the two alternatives in FIRST' *)
    66 (* FIXME / TODO: reason: the tactic might back-track over the two alternatives in FIRST' *)
    66 fun quotient_tac ctxt = SOLVES'  
    67 fun quotient_tac ctxt = SOLVES'
    67   (REPEAT_ALL_NEW (FIRST'
    68   (REPEAT_ALL_NEW (FIRST'
    68     [rtac @{thm identity_quotient},
    69     [rtac @{thm identity_quotient},
    69      resolve_tac (quotient_rules_get ctxt)]))
    70      resolve_tac (quotient_rules_get ctxt)]))
    70 
    71 
    71 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
    72 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
    72 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
    73 val quotient_solver =
       
    74   Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
    73 
    75 
    74 fun solve_quotient_assm ctxt thm =
    76 fun solve_quotient_assm ctxt thm =
    75   case Seq.pull (quotient_tac ctxt 1 thm) of
    77   case Seq.pull (quotient_tac ctxt 1 thm) of
    76     SOME (t, _) => t
    78     SOME (t, _) => t
    77   | _ => error "Solve_quotient_assm failed. Possibly a quotient theorem is missing."
    79   | _ => error "Solve_quotient_assm failed. Possibly a quotient theorem is missing."
    84   (ctyp_of thy (TVar (x, S)), ctyp_of thy ty)
    86   (ctyp_of thy (TVar (x, S)), ctyp_of thy ty)
    85 
    87 
    86 fun get_match_inst thy pat trm =
    88 fun get_match_inst thy pat trm =
    87 let
    89 let
    88   val univ = Unify.matchers thy [(pat, trm)]
    90   val univ = Unify.matchers thy [(pat, trm)]
    89   val SOME (env, _) = Seq.pull univ                   (* raises BIND, if no unifier *)
    91   val SOME (env, _) = Seq.pull univ             (* raises BIND, if no unifier *)
    90   val tenv = Vartab.dest (Envir.term_env env)
    92   val tenv = Vartab.dest (Envir.term_env env)
    91   val tyenv = Vartab.dest (Envir.type_env env)
    93   val tyenv = Vartab.dest (Envir.type_env env)
    92 in
    94 in
    93   (map (prep_ty thy) tyenv, map (prep_trm thy) tenv)
    95   (map (prep_ty thy) tyenv, map (prep_trm thy) tenv)
    94 end
    96 end
   128         calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   130         calculate_inst ctxt @{thm bex_reg_eqv_range[THEN eq_reflection]} redex R1 R2
   129 
   131 
   130   | _ => NONE
   132   | _ => NONE
   131 end
   133 end
   132 
   134 
   133 (* 0. preliminary simplification step according to *)
   135 (*
   134 (*    thm ball_reg_eqv bex_reg_eqv babs_reg_eqv    *)
   136 0. preliminary simplification step according to
   135 (*        ball_reg_eqv_range bex_reg_eqv_range     *)
   137    ball_reg_eqv bex_reg_eqv babs_reg_eqv ball_reg_eqv_range bex_reg_eqv_range
   136 (*                                                 *)
   138 
   137 (* 1. eliminating simple Ball/Bex instances        *)
   139 1. eliminating simple Ball/Bex instances (ball_reg_right bex_reg_left)
   138 (*    thm ball_reg_right bex_reg_left              *)
   140 
   139 (*                                                 *)
   141 2. monos
   140 (* 2. monos                                        *)
   142 
   141 (*                                                 *)
   143 3. commutation rules for ball and bex (ball_all_comm bex_ex_comm)
   142 (* 3. commutation rules for ball and bex           *)
   144 
   143 (*    thm ball_all_comm bex_ex_comm                *)
   145 4. then rel-equalities, which need to be instantiated with 'eq_imp_rel'
   144 (*                                                 *)
   146    to avoid loops
   145 (* 4. then rel-equalities, which need to be        *)
   147 
   146 (*    instantiated with the followig theorem       *)
   148 5. then simplification like 0
   147 (*    to avoid loops:                              *)
   149 
   148 (*    thm eq_imp_rel                               *)
   150 finally jump back to 1 *)
   149 (*                                                 *)
       
   150 (* 5. then simplification like 0                   *)
       
   151 (*                                                 *)
       
   152 (* finally jump back to 1                          *)
       
   153 
       
   154 fun regularize_tac ctxt =
   151 fun regularize_tac ctxt =
   155 let
   152 let
   156   val thy = ProofContext.theory_of ctxt
   153   val thy = ProofContext.theory_of ctxt
   157   val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"}
   154   val ball_pat = @{term "Ball (Respects (R1 ===> R2)) P"}
   158   val bex_pat  = @{term "Bex (Respects (R1 ===> R2)) P"}
   155   val bex_pat  = @{term "Bex (Respects (R1 ===> R2)) P"}
   159   val simproc = Simplifier.simproc_i thy "" [ball_pat, bex_pat] (K (ball_bex_range_simproc))
   156   val simproc = Simplifier.simproc_i thy "" [ball_pat, bex_pat] (K (ball_bex_range_simproc))
   160   val simpset = (mk_minimal_ss ctxt) 
   157   val simpset = (mk_minimal_ss ctxt) 
   161                        addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv babs_simp} @ (id_simps_get ctxt)
   158                        addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv babs_simp}
   162                        addsimprocs [simproc] 
   159                        addsimprocs [simproc] 
   163                        addSolver equiv_solver addSolver quotient_solver
   160                        addSolver equiv_solver addSolver quotient_solver
   164   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)
   165 in
   162 in
   166   simp_tac simpset THEN'
   163   simp_tac simpset THEN'
   171      resolve_tac eq_eqvs,  
   168      resolve_tac eq_eqvs,  
   172      simp_tac simpset])
   169      simp_tac simpset])
   173 end
   170 end
   174 
   171 
   175 
   172 
   176 (********************)
   173 
   177 (* Injection Tactic *)
   174 (*** Injection Tactic ***)
   178 (********************)
   175 
   179 
   176 (* Looks for Quot_True assumtions, and in case its parameter
   180 (* Looks for Quot_True assumtions, and in case its parameter    *)
   177    is an application, it returns the function and the argument. *)
   181 (* is an application, it returns the function and the argument. *)
       
   182 fun find_qt_asm asms =
   178 fun find_qt_asm asms =
   183 let
   179 let
   184   fun find_fun trm =
   180   fun find_fun trm =
   185     case trm of
   181     case trm of
   186       (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true
   182       (Const(@{const_name Trueprop}, _) $ (Const (@{const_name Quot_True}, _) $ _)) => true
   230 fun dest_fun_type (Type("fun", [T, S])) = (T, S)
   226 fun dest_fun_type (Type("fun", [T, S])) = (T, S)
   231   | dest_fun_type _ = error "dest_fun_type"
   227   | dest_fun_type _ = error "dest_fun_type"
   232 
   228 
   233 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl
   229 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl
   234 
   230 
   235 (* We apply apply_rsp only in case if the type needs lifting.       *)
   231 (* We apply apply_rsp only in case if the type needs lifting.
   236 (* This is the case if the type of the data in the Quot_True        *)
   232    This is the case if the type of the data in the Quot_True
   237 (* assumption is different from the corresponding type in the goal. *)
   233    assumption is different from the corresponding type in the goal. *)
   238 val apply_rsp_tac =
   234 val apply_rsp_tac =
   239   Subgoal.FOCUS (fn {concl, asms, context,...} =>
   235   Subgoal.FOCUS (fn {concl, asms, context,...} =>
   240   let
   236   let
   241     val bare_concl = HOLogic.dest_Trueprop (term_of concl)
   237     val bare_concl = HOLogic.dest_Trueprop (term_of concl)
   242     val qt_asm = find_qt_asm (map term_of asms)
   238     val qt_asm = find_qt_asm (map term_of asms)
   243   in
   239   in
   244     case (bare_concl, qt_asm) of
   240     case (bare_concl, qt_asm) of
   245       (R2 $ (f $ x) $ (g $ y), SOME (qt_fun, qt_arg)) =>
   241       (R2 $ (f $ x) $ (g $ y), SOME (qt_fun, qt_arg)) =>
   246          if (fastype_of qt_fun) = (fastype_of f) 
   242          if (fastype_of qt_fun) = (fastype_of f)
   247          then no_tac                             
   243          then no_tac
   248          else                                    
   244          else
   249            let
   245            let
   250              val ty_x = fastype_of x
   246              val ty_x = fastype_of x
   251              val ty_b = fastype_of qt_arg
   247              val ty_b = fastype_of qt_arg
   252              val ty_f = range_type (fastype_of f) 
   248              val ty_f = range_type (fastype_of f)
   253              val thy = ProofContext.theory_of context
   249              val thy = ProofContext.theory_of context
   254              val ty_inst = map (SOME o (ctyp_of thy)) [ty_x, ty_b, ty_f]
   250              val ty_inst = map (SOME o (ctyp_of thy)) [ty_x, ty_b, ty_f]
   255              val t_inst = map (SOME o (cterm_of thy)) [R2, f, g, x, y];
   251              val t_inst = map (SOME o (cterm_of thy)) [R2, f, g, x, y];
   256              val inst_thm = Drule.instantiate' ty_inst ([NONE, NONE, NONE] @ t_inst) @{thm apply_rsp}
   252              val inst_thm = Drule.instantiate' ty_inst
       
   253                ([NONE, NONE, NONE] @ t_inst) @{thm apply_rsp}
   257            in
   254            in
   258              (rtac inst_thm THEN' quotient_tac context) 1
   255              (rtac inst_thm THEN' quotient_tac context) 1
   259            end
   256            end
   260     | _ => no_tac
   257     | _ => no_tac
   261   end)
   258   end)
   279   | _ => K no_tac
   276   | _ => K no_tac
   280 end
   277 end
   281 (* TODO: Again, can one specify more concretely        *)
   278 (* TODO: Again, can one specify more concretely        *)
   282 (* TODO: in terms of R when no_tac should be returned? *)
   279 (* TODO: in terms of R when no_tac should be returned? *)
   283 
   280 
   284 fun rep_abs_rsp_tac ctxt = 
   281 fun rep_abs_rsp_tac ctxt =
   285   SUBGOAL (fn (goal, i) =>
   282   SUBGOAL (fn (goal, i) =>
   286     case (bare_concl goal) of 
   283     case (try bare_concl goal) of
   287       (rel $ _ $ (rep $ (abs $ _))) =>
   284       SOME (rel $ _ $ (rep $ (abs $ _))) =>
   288         (let
   285         let
   289            val thy = ProofContext.theory_of ctxt;
   286           val thy = ProofContext.theory_of ctxt;
   290            val (ty_a, ty_b) = dest_fun_type (fastype_of abs);
   287           val (ty_a, ty_b) = dest_fun_type (fastype_of abs);
   291            val ty_inst = map (SOME o (ctyp_of thy)) [ty_a, ty_b];
   288           val ty_inst = map (SOME o (ctyp_of thy)) [ty_a, ty_b];
   292            val t_inst = map (SOME o (cterm_of thy)) [rel, abs, rep];
   289         in
   293            val inst_thm = Drule.instantiate' ty_inst t_inst @{thm rep_abs_rsp}
   290           case try (map (SOME o (cterm_of thy))) [rel, abs, rep] of
   294          in
   291             SOME t_inst =>
   295            (rtac inst_thm THEN' quotient_tac ctxt) i
   292               (case try (Drule.instantiate' ty_inst t_inst) @{thm rep_abs_rsp} of
   296          end
   293                 SOME inst_thm => (rtac inst_thm THEN' quotient_tac ctxt) i
   297          handle THM _ => no_tac | TYPE _ => no_tac) (* TODO: same here *)
   294               | NONE => no_tac)
       
   295           | NONE => no_tac
       
   296         end
   298     | _ => no_tac)
   297     | _ => no_tac)
   299 
   298 
   300 
   299 
   301 (* FIXME / TODO needs to be adapted *)
       
   302 (*
   300 (*
   303 To prove that the regularised theorem implies the abs/rep injected, 
   301 To prove that the regularised theorem implies the abs/rep injected,
   304 we try:
   302 we try:
   305 
   303 
   306  1) theorems 'trans2' from the appropriate Quot_Type
   304  The deterministic part:
   307  2) remove lambdas from both sides: lambda_rsp_tac
   305  -) remove lambdas from both sides
   308  3) remove Ball/Bex from the right hand side
   306  -) prove Ball/Bex/Babs equalities using ball_rsp, bex_rsp, babs_rsp
   309  4) use user-supplied RSP theorems
   307  -) prove Ball/Bex relations unfolding fun_rel_id
   310  5) remove rep_abs from the right side
   308  -) reflexivity of equality
   311  6) reflexivity of equality
   309  -) prove equality of relations using equals_rsp
   312  7) split applications of lifted type (apply_rsp)
   310  -) use user-supplied RSP theorems
   313  8) split applications of non-lifted type (cong_tac)
   311  -) solve 'relation of relations' goals using quot_rel_rsp
   314  9) apply extentionality
   312  -) remove rep_abs from the right side
   315  A) reflexivity of the relation
       
   316  B) assumption
       
   317     (Lambdas under respects may have left us some assumptions)
   313     (Lambdas under respects may have left us some assumptions)
   318  C) proving obvious higher order equalities by simplifying fun_rel
   314  Then in order:
   319     (not sure if it is still needed?)
   315  -) split applications of lifted type (apply_rsp)
   320  D) unfolding lambda on one side
   316  -) split applications of non-lifted type (cong_tac)
   321  E) simplifying (= ===> =) for simpler respectfulness
   317  -) apply extentionality
       
   318  -) assumption
       
   319  -) reflexivity of the relation
   322 *)
   320 *)
   323 
   321 
   324 
   322 
   325 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) =>
   323 fun injection_match_tac ctxt = SUBGOAL (fn (goal, i) =>
   326 (case (bare_concl goal) of
   324 (case (bare_concl goal) of
   380 
   378 
   381 fun injection_step_tac ctxt rel_refl =
   379 fun injection_step_tac ctxt rel_refl =
   382  FIRST' [
   380  FIRST' [
   383     injection_match_tac ctxt,
   381     injection_match_tac ctxt,
   384 
   382 
   385     (* R (t $ ...) (t' $ ...) ----> apply_rsp   provided type of t needs lifting *)    
   383     (* R (t $ ...) (t' $ ...) ----> apply_rsp   provided type of t needs lifting *)
   386     apply_rsp_tac ctxt THEN'
   384     apply_rsp_tac ctxt THEN'
   387                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)],
   385                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)],
   388 
   386 
   389     (* (op =) (t $ ...) (t' $ ...) ----> Cong   provided type of t does not need lifting *)
   387     (* (op =) (t $ ...) (t' $ ...) ----> Cong   provided type of t does not need lifting *)
   390     (* merge with previous tactic *)
   388     (* merge with previous tactic *)
   391     Cong_Tac.cong_tac @{thm cong} THEN'
   389     Cong_Tac.cong_tac @{thm cong} THEN'
   392                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)],
   390                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)],
   393     
   391 
   394     (* (op =) (%x...) (%y...) ----> (op =) (...) (...) *)
   392     (* (op =) (%x...) (%y...) ----> (op =) (...) (...) *)
   395     rtac @{thm ext} THEN' quot_true_tac ctxt unlam,
   393     rtac @{thm ext} THEN' quot_true_tac ctxt unlam,
   396     
   394 
   397     (* resolving with R x y assumptions *)
   395     (* resolving with R x y assumptions *)
   398     atac,
   396     atac,
   399     
   397 
   400     (* reflexivity of the basic relations *)
   398     (* reflexivity of the basic relations *)
   401     (* R ... ... *)
   399     (* R ... ... *)
   402     resolve_tac rel_refl]
   400     resolve_tac rel_refl]
   403 
   401 
   404 fun injection_tac ctxt =
   402 fun injection_tac ctxt =
   405 let
   403 let
   406   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   404   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   407 in
   405 in
   408   simp_tac ((mk_minimal_ss ctxt) addsimps (id_simps_get ctxt)) (* HACK? *) 
   406   injection_step_tac ctxt rel_refl
   409   THEN' injection_step_tac ctxt rel_refl
       
   410 end
   407 end
   411 
   408 
   412 fun all_injection_tac ctxt =
   409 fun all_injection_tac ctxt =
   413   REPEAT_ALL_NEW (injection_tac ctxt)
   410   REPEAT_ALL_NEW (injection_tac ctxt)
   414 
   411 
   415 
   412 
   416 (***************************)
   413 
   417 (* Cleaning of the Theorem *)
   414 (** Cleaning of the Theorem **)
   418 (***************************)
   415 
   419 
   416 (* expands all fun_maps, except in front of the bound variables listed in xs *)
   420 (* expands all fun_maps, except in front of the bound *)
       
   421 (* variables listed in xs                             *)
       
   422 fun fun_map_simple_conv xs ctrm =
   417 fun fun_map_simple_conv xs ctrm =
   423   case (term_of ctrm) of
   418   case (term_of ctrm) of
   424     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   419     ((Const (@{const_name "fun_map"}, _) $ _ $ _) $ h $ _) =>
   425         if (member (op=) xs h) 
   420         if (member (op=) xs h)
   426         then Conv.all_conv ctrm
   421         then Conv.all_conv ctrm
   427         else Conv.rewr_conv @{thm fun_map.simps[THEN eq_reflection]} ctrm 
   422         else Conv.rewr_conv @{thm fun_map.simps[THEN eq_reflection]} ctrm 
   428   | _ => Conv.all_conv ctrm
   423   | _ => Conv.all_conv ctrm
   429 
   424 
   430 fun fun_map_conv xs ctxt ctrm =
   425 fun fun_map_conv xs ctxt ctrm =
   459   val _ $ (Abs (_, _, g)) = t;
   454   val _ $ (Abs (_, _, g)) = t;
   460 in
   455 in
   461   (f, Abs ("x", T, mk_abs u 0 g))
   456   (f, Abs ("x", T, mk_abs u 0 g))
   462 end
   457 end
   463 
   458 
   464 (* Simplifies a redex using the 'lambda_prs' theorem.        *)
   459 (* Simplifies a redex using the 'lambda_prs' theorem.
   465 (* First instantiates the types and known subterms.          *)
   460    First instantiates the types and known subterms.
   466 (* Then solves the quotient assumptions to get Rep2 and Abs1 *)
   461    Then solves the quotient assumptions to get Rep2 and Abs1
   467 (* Finally instantiates the function f using make_inst       *)
   462    Finally instantiates the function f using make_inst
   468 (* If Rep2 is an identity then the pattern is simpler and    *)
   463    If Rep2 is an identity then the pattern is simpler and
   469 (* make_inst_id is used                                      *)
   464    make_inst_id is used *)
   470 fun lambda_prs_simple_conv ctxt ctrm =
   465 fun lambda_prs_simple_conv ctxt ctrm =
   471   case (term_of ctrm) of
   466   case (term_of ctrm) of
   472    (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) =>
   467     (Const (@{const_name fun_map}, _) $ r1 $ a2) $ (Abs _) =>
   473      (let
   468       let
   474        val thy = ProofContext.theory_of ctxt
   469         val thy = ProofContext.theory_of ctxt
   475        val (ty_b, ty_a) = dest_fun_type (fastype_of r1)
   470         val (ty_b, ty_a) = dest_fun_type (fastype_of r1)
   476        val (ty_c, ty_d) = dest_fun_type (fastype_of a2)
   471         val (ty_c, ty_d) = dest_fun_type (fastype_of a2)
   477        val tyinst = map (SOME o (ctyp_of thy)) [ty_a, ty_b, ty_c, ty_d]
   472         val tyinst = map (SOME o (ctyp_of thy)) [ty_a, ty_b, ty_c, ty_d]
   478        val tinst = [NONE, NONE, SOME (cterm_of thy r1), NONE, SOME (cterm_of thy a2)]
   473         val tinst = [NONE, NONE, SOME (cterm_of thy r1), NONE, SOME (cterm_of thy a2)]
   479        val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs[THEN eq_reflection]}
   474         val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs[THEN eq_reflection]}
   480        val te = solve_quotient_assm ctxt (solve_quotient_assm ctxt lpi)
   475         val te = solve_quotient_assm ctxt (solve_quotient_assm ctxt lpi)
   481        val ts = MetaSimplifier.rewrite_rule (id_simps_get ctxt) te
   476         val ts = MetaSimplifier.rewrite_rule (id_simps_get ctxt) te
   482        val (insp, inst) = 
   477         val (insp, inst) =
   483               if ty_c = ty_d 
   478           if ty_c = ty_d
   484               then make_inst_id (term_of (Thm.lhs_of ts)) (term_of ctrm)
   479           then make_inst_id (term_of (Thm.lhs_of ts)) (term_of ctrm)
   485               else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm)
   480           else make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm)
   486        val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts
   481         val ti = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts
   487      in
   482       in
   488        Conv.rewr_conv ti ctrm
   483         Conv.rewr_conv ti ctrm
   489      end
   484       end
   490      handle _ => Conv.all_conv ctrm) (* TODO: another catch all - can this be improved? *)
       
   491   | _ => Conv.all_conv ctrm
   485   | _ => Conv.all_conv ctrm
   492 
       
   493 
   486 
   494 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   487 fun lambda_prs_conv ctxt = More_Conv.top_conv lambda_prs_simple_conv ctxt
   495 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   488 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
   496 
   489 
   497 
   490 
   498 (* 1. folding of definitions and preservation lemmas;  *)
   491 (* Cleaning consists of:
   499 (*    and simplification with                          *)
   492  1. folding of definitions and preservation lemmas;
   500 (*    thm babs_prs all_prs ex_prs                      *)
   493     and simplification with babs_prs all_prs ex_prs
   501 (*                                                     *) 
   494 
   502 (* 2. unfolding of ---> in front of everything, except *)
   495  2. unfolding of ---> in front of everything, except
   503 (*    bound variables (this prevents lambda_prs from   *)
   496     bound variables
   504 (*    becoming stuck)                                  *)
   497     (this prevents lambda_prs from becoming stuck)
   505 (*    thm fun_map.simps                                *)
   498 
   506 (*                                                     *)
   499  3. simplification with lambda_prs
   507 (* 3. simplification with                              *)
   500 
   508 (*    thm lambda_prs                                   *)
   501  4. simplification with Quotient_abs_rep Quotient_rel_rep id_simps
   509 (*                                                     *)
   502 
   510 (* 4. simplification with                              *)
   503  5. test for refl *)
   511 (*    thm Quotient_abs_rep Quotient_rel_rep id_simps   *) 
   504 fun clean_tac lthy =
   512 (*                                                     *)
       
   513 (* 5. test for refl                                    *)
       
   514 
       
   515 fun clean_tac_aux lthy =
       
   516 let
   505 let
   517   (* FIXME/TODO produce defs with lthy, like prs and ids *)
   506   (* FIXME/TODO produce defs with lthy, like prs and ids *)
   518   val thy = ProofContext.theory_of lthy;
   507   val thy = ProofContext.theory_of lthy;
   519   val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   508   val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
   520   (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *)
   509   (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *)
   521   val prs = prs_rules_get lthy
   510   val prs = prs_rules_get lthy
   522   val ids = id_simps_get lthy
   511   val ids = id_simps_get lthy
   523   
   512 
   524   fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
   513   fun mk_simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
   525   val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs})
   514   val ss1 = mk_simps (defs @ prs @ @{thms babs_prs all_prs ex_prs})
   526   val ss2 = mk_simps (@{thms Quotient_abs_rep Quotient_rel_rep} @ ids) 
   515   val ss2 = mk_simps (@{thms Quotient_abs_rep Quotient_rel_rep} @ ids)
   527 in
   516 in
   528   EVERY' [simp_tac ss1,
   517   EVERY' [simp_tac ss1,
   529           fun_map_tac lthy,
   518           fun_map_tac lthy,
   530           lambda_prs_tac lthy,
   519           lambda_prs_tac lthy,
   531           simp_tac ss2,
   520           simp_tac ss2,
   532           TRY o rtac refl]  
   521           TRY o rtac refl]
   533 end
   522 end
   534 
   523 
   535 fun clean_tac lthy = REPEAT o CHANGED o (clean_tac_aux lthy) (* HACK?? *)
   524 
   536 
   525 
   537 
   526 (** Tactic for Generalising Free Variables in a Goal **)
   538 (****************************************************)
   527 
   539 (* Tactic for Generalising Free Variables in a Goal *)
       
   540 (****************************************************)
       
   541 
   528 
   542 fun inst_spec ctrm =
   529 fun inst_spec ctrm =
   543    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
   530    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
   544 
   531 
   545 fun inst_spec_tac ctrms =
   532 fun inst_spec_tac ctrms =
   550 
   537 
   551 fun apply_under_Trueprop f = 
   538 fun apply_under_Trueprop f = 
   552   HOLogic.dest_Trueprop #> f #> HOLogic.mk_Trueprop
   539   HOLogic.dest_Trueprop #> f #> HOLogic.mk_Trueprop
   553 
   540 
   554 fun gen_frees_tac ctxt =
   541 fun gen_frees_tac ctxt =
   555  SUBGOAL (fn (concl, i) =>
   542   SUBGOAL (fn (concl, i) =>
   556   let
   543     let
   557     val thy = ProofContext.theory_of ctxt
   544       val thy = ProofContext.theory_of ctxt
   558     val vrs = Term.add_frees concl []
   545       val vrs = Term.add_frees concl []
   559     val cvrs = map (cterm_of thy o Free) vrs
   546       val cvrs = map (cterm_of thy o Free) vrs
   560     val concl' = apply_under_Trueprop (all_list vrs) concl
   547       val concl' = apply_under_Trueprop (all_list vrs) concl
   561     val goal = Logic.mk_implies (concl', concl)
   548       val goal = Logic.mk_implies (concl', concl)
   562     val rule = Goal.prove ctxt [] [] goal 
   549       val rule = Goal.prove ctxt [] [] goal
   563       (K (EVERY1 [inst_spec_tac (rev cvrs), atac]))
   550         (K (EVERY1 [inst_spec_tac (rev cvrs), atac]))
   564   in
   551     in
   565     rtac rule i
   552       rtac rule i
   566   end)  
   553     end)
   567 
   554 
   568 (**********************************************)
   555 
   569 (* The General Shape of the Lifting Procedure *)
   556 (** The General Shape of the Lifting Procedure **)
   570 (**********************************************)
   557 
   571 
   558 
   572 (* - A is the original raw theorem                         *)
   559 (* - A is the original raw theorem
   573 (* - B is the regularized theorem                          *)
   560  - B is the regularized theorem
   574 (* - C is the rep/abs injected version of B                *)
   561  - C is the rep/abs injected version of B
   575 (* - D is the lifted theorem                               *)
   562  - D is the lifted theorem
   576 (*                                                         *)
   563 
   577 (* - 1st prem is the regularization step                   *)
   564  - 1st prem is the regularization step
   578 (* - 2nd prem is the rep/abs injection step                *)
   565  - 2nd prem is the rep/abs injection step
   579 (* - 3rd prem is the cleaning part                         *)
   566  - 3rd prem is the cleaning part
   580 (*                                                         *)
   567 
   581 (* the Quot_True premise in 2nd records the lifted theorem *)
   568  the Quot_True premise in 2nd records the lifted theorem *)
   582 
   569 val lifting_procedure_thm =
   583 val lifting_procedure_thm = 
   570   @{lemma  "[|A;
   584    @{lemma  "[|A; 
   571               A --> B;
   585                A --> B; 
   572               Quot_True D ==> B = C;
   586                Quot_True D ==> B = C; 
   573               C = D|] ==> D"
   587                C = D|] ==> D" 
       
   588       by (simp add: Quot_True_def)}
   574       by (simp add: Quot_True_def)}
   589 
   575 
   590 fun lift_match_error ctxt str rtrm qtrm =
   576 fun lift_match_error ctxt str rtrm qtrm =
   591 let
   577 let
   592   val rtrm_str = Syntax.string_of_term ctxt rtrm
   578   val rtrm_str = Syntax.string_of_term ctxt rtrm
   593   val qtrm_str = Syntax.string_of_term ctxt qtrm
   579   val qtrm_str = Syntax.string_of_term ctxt qtrm
   594   val msg = cat_lines [enclose "[" "]" str, "The quotient theorem", qtrm_str, 
   580   val msg = cat_lines [enclose "[" "]" str, "The quotient theorem", qtrm_str, 
   595              "", "does not match with original theorem", rtrm_str]
   581     "", "does not match with original theorem", rtrm_str]
   596 in
   582 in
   597   error msg
   583   error msg
   598 end
   584 end
   599  
   585 
   600 fun procedure_inst ctxt rtrm qtrm =
   586 fun procedure_inst ctxt rtrm qtrm =
   601 let
   587 let
   602   val thy = ProofContext.theory_of ctxt
   588   val thy = ProofContext.theory_of ctxt
   603   val rtrm' = HOLogic.dest_Trueprop rtrm
   589   val rtrm' = HOLogic.dest_Trueprop rtrm
   604   val qtrm' = HOLogic.dest_Trueprop qtrm
   590   val qtrm' = HOLogic.dest_Trueprop qtrm
   605   val reg_goal = regularize_trm_chk ctxt (rtrm', qtrm')
   591   val reg_goal = regularize_trm_chk ctxt (rtrm', qtrm')
   606         handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm
   592     handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm
   607   val inj_goal = inj_repabs_trm_chk ctxt (reg_goal, qtrm')
   593   val inj_goal = inj_repabs_trm_chk ctxt (reg_goal, qtrm')
   608         handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm
   594     handle (LIFT_MATCH str) => lift_match_error ctxt str rtrm qtrm
   609 in
   595 in
   610   Drule.instantiate' []
   596   Drule.instantiate' []
   611     [SOME (cterm_of thy rtrm'),
   597     [SOME (cterm_of thy rtrm'),
   612      SOME (cterm_of thy reg_goal),
   598      SOME (cterm_of thy reg_goal),
   613      NONE,
   599      NONE,