Quot/QuotMain.thy
changeset 618 8dfae5d97387
parent 616 20b8585ad1e0
child 621 c10a46fa0de9
equal deleted inserted replaced
617:ca37f4b6457c 618:8dfae5d97387
   142 (* the auxiliary data for the quotient types *)
   142 (* the auxiliary data for the quotient types *)
   143 use "quotient_info.ML"
   143 use "quotient_info.ML"
   144 
   144 
   145 declare [[map * = (prod_fun, prod_rel)]]
   145 declare [[map * = (prod_fun, prod_rel)]]
   146 declare [[map "fun" = (fun_map, fun_rel)]]
   146 declare [[map "fun" = (fun_map, fun_rel)]]
   147 (* FIXME: This should throw an exception:
   147 
   148 declare [[map "option" = (bla, blu)]]
   148 (* Throws now an exception:              *)
   149 *)
   149 (* declare [[map "option" = (bla, blu)]] *)
   150 
   150 
   151 (* identity quotient is not here as it has to be applied first *)
       
   152 lemmas [quotient_thm] =
   151 lemmas [quotient_thm] =
   153   fun_quotient prod_quotient
   152   fun_quotient prod_quotient
   154 
   153 
   155 lemmas [quotient_rsp] =
   154 lemmas [quotient_rsp] =
   156   quot_rel_rsp pair_rsp
   155   quot_rel_rsp pair_rsp
   158 (* fun_map is not here since equivp is not true *)
   157 (* fun_map is not here since equivp is not true *)
   159 (* TODO: option, ... *)
   158 (* TODO: option, ... *)
   160 lemmas [quotient_equiv] =
   159 lemmas [quotient_equiv] =
   161   identity_equivp prod_equivp
   160   identity_equivp prod_equivp
   162 
   161 
   163 ML {* maps_lookup @{theory} "*" *}
       
   164 ML {* maps_lookup @{theory} "fun" *}
       
   165 
       
   166 
       
   167 (* definition of the quotient types *)
   162 (* definition of the quotient types *)
   168 (* FIXME: should be called quotient_typ.ML *)
   163 (* FIXME: should be called quotient_typ.ML *)
   169 use "quotient.ML"
   164 use "quotient.ML"
   170 
   165 
   171 
       
   172 (* lifting of constants *)
   166 (* lifting of constants *)
   173 use "quotient_def.ML"
   167 use "quotient_def.ML"
   174 
   168 
   175 section {* Simset setup *}
   169 section {* Simset setup *}
   176 
   170 
   177 (* since HOL_basic_ss is too "big", we need to set up *)
   171 (* Since HOL_basic_ss is too "big" for us, *)
   178 (* our own minimal simpset                            *)
   172 (* we set up our own minimal simpset.      *)
   179 ML {*
   173 ML {*
   180 fun  mk_minimal_ss ctxt =
   174 fun  mk_minimal_ss ctxt =
   181   Simplifier.context ctxt empty_ss
   175   Simplifier.context ctxt empty_ss
   182     setsubgoaler asm_simp_tac
   176     setsubgoaler asm_simp_tac
   183     setmksimps (mksimps [])
   177     setmksimps (mksimps [])
   184 *}
   178 *}
   185 
   179 
   186 ML {*
   180 ML {*
   187 (* TODO/FIXME not needed anymore? *)
   181 fun OF1 thm1 thm2 = thm2 RS thm1
   188 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac)
   182 *}
   189 *}
   183 
   190 
   184 section {* Atomize Infrastructure *}
   191 section {* atomize *}
       
   192 
   185 
   193 lemma atomize_eqv[atomize]:
   186 lemma atomize_eqv[atomize]:
   194   shows "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)"
   187   shows "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)"
   195 proof
   188 proof
   196   assume "A \<equiv> B"
   189   assume "A \<equiv> B"
   218 in
   211 in
   219   @{thm equal_elim_rule1} OF [thm'', thm']
   212   @{thm equal_elim_rule1} OF [thm'', thm']
   220 end
   213 end
   221 *}
   214 *}
   222 
   215 
   223 section {* infrastructure about id *}
   216 section {* Infrastructure about id *}
       
   217 
       
   218 print_attributes
   224 
   219 
   225 (* TODO: think where should this be *)
   220 (* TODO: think where should this be *)
   226 lemma prod_fun_id: "prod_fun id id \<equiv> id"
   221 lemma prod_fun_id: "prod_fun id id \<equiv> id"
   227   by (rule eq_reflection) (simp add: prod_fun_def)
   222   by (rule eq_reflection) (simp add: prod_fun_def)
   228 
   223 
   229 (* FIXME: make it a list and add map_id to it *)
   224 lemmas [id_simps] = 
   230 lemmas id_simps =
       
   231   fun_map_id[THEN eq_reflection]
   225   fun_map_id[THEN eq_reflection]
   232   id_apply[THEN eq_reflection]
   226   id_apply[THEN eq_reflection]
   233   id_def[THEN eq_reflection,symmetric]
   227   id_def[THEN eq_reflection,symmetric]
   234   prod_fun_id
   228   prod_fun_id
   235 
       
   236 ML {*
       
   237 fun simp_ids thm =
       
   238   MetaSimplifier.rewrite_rule @{thms id_simps} thm
       
   239 *}
       
   240 
   229 
   241 section {* Debugging infrastructure for testing tactics *}
   230 section {* Debugging infrastructure for testing tactics *}
   242 
   231 
   243 ML {*
   232 ML {*
   244 fun my_print_tac ctxt s i thm =
   233 fun my_print_tac ctxt s i thm =
   263 end
   252 end
   264 
   253 
   265 fun NDT ctxt s tac thm = tac thm  
   254 fun NDT ctxt s tac thm = tac thm  
   266 *}
   255 *}
   267 
   256 
   268 section {* Matching of terms and types *}
   257 section {* Matching of Terms and Types *}
   269 
   258 
   270 ML {*
   259 ML {*
   271 fun matches_typ (ty, ty') =
   260 fun matches_typ (ty, ty') =
   272   case (ty, ty') of
   261   case (ty, ty') of
   273     (_, TVar _) => true
   262     (_, TVar _) => true
   276        s = s' andalso 
   265        s = s' andalso 
   277        if (length tys = length tys') 
   266        if (length tys = length tys') 
   278        then (List.all matches_typ (tys ~~ tys')) 
   267        then (List.all matches_typ (tys ~~ tys')) 
   279        else false
   268        else false
   280   | _ => false
   269   | _ => false
   281 *}
   270 
   282 
       
   283 ML {*
       
   284 fun matches_term (trm, trm') = 
   271 fun matches_term (trm, trm') = 
   285    case (trm, trm') of 
   272    case (trm, trm') of 
   286      (_, Var _) => true
   273      (_, Var _) => true
   287    | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty')
   274    | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty')
   288    | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty')
   275    | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty')
   290    | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t')
   277    | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t')
   291    | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s') 
   278    | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s') 
   292    | _ => false
   279    | _ => false
   293 *}
   280 *}
   294 
   281 
   295 section {* Infrastructure for collecting theorems for starting the lifting *}
   282 section {* Computation of the Regularize Goal *} 
   296 
       
   297 ML {*
       
   298 fun lookup_quot_data lthy qty =
       
   299   let
       
   300     val qty_name = fst (dest_Type qty)
       
   301     val SOME quotdata = quotdata_lookup lthy qty_name
       
   302     (* TODO: Should no longer be needed *)
       
   303     val rty = Logic.unvarifyT (#rtyp quotdata)
       
   304     val rel = #rel quotdata
       
   305     val rel_eqv = #equiv_thm quotdata
       
   306     val rel_refl = @{thm equivp_reflp} OF [rel_eqv]
       
   307   in
       
   308     (rty, rel, rel_refl, rel_eqv)
       
   309   end
       
   310 *}
       
   311 
       
   312 ML {*
       
   313 fun lookup_quot_thms lthy qty_name =
       
   314   let
       
   315     val thy = ProofContext.theory_of lthy;
       
   316     val trans2 = PureThy.get_thm thy ("QUOT_TYPE_I_" ^ qty_name ^ ".R_trans2")
       
   317     val reps_same = PureThy.get_thm thy ("QUOT_TYPE_I_" ^ qty_name ^ ".REPS_same")
       
   318     val absrep = PureThy.get_thm thy ("QUOT_TYPE_I_" ^ qty_name ^ ".thm10")
       
   319     val quot = PureThy.get_thm thy ("Quotient_" ^ qty_name)
       
   320   in
       
   321     (trans2, reps_same, absrep, quot)
       
   322   end
       
   323 *}
       
   324 
       
   325 section {* Regularization *} 
       
   326 
   283 
   327 (*
   284 (*
   328 Regularizing an rtrm means:
   285 Regularizing an rtrm means:
   329  - quantifiers over a type that needs lifting are replaced by
   286  - quantifiers over a type that needs lifting are replaced by
   330    bounded quantifiers, for example:
   287    bounded quantifiers, for example:
   487 
   444 
   488   | (rt, qt) =>
   445   | (rt, qt) =>
   489        raise (LIFT_MATCH "regularize (default)")
   446        raise (LIFT_MATCH "regularize (default)")
   490 *}
   447 *}
   491 
   448 
       
   449 section {* Regularize Tactic *}
       
   450 
   492 ML {*
   451 ML {*
   493 fun equiv_tac ctxt =
   452 fun equiv_tac ctxt =
   494   (K (print_tac "equiv tac")) THEN'
   453   (K (print_tac "equiv tac")) THEN'
   495   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
   454   REPEAT_ALL_NEW (resolve_tac (equiv_rules_get ctxt))
   496 *}
   455 
   497 
       
   498 ML {*
       
   499 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
   456 fun equiv_solver_tac ss = equiv_tac (Simplifier.the_context ss)
   500 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
   457 val equiv_solver = Simplifier.mk_solver' "Equivalence goal solver" equiv_solver_tac
   501 *}
   458 *}
   502 
   459 
   503 ML {*
   460 ML {*
   535   val thm2 = Drule.eta_contraction_rule (Drule.instantiate inst thmi)
   492   val thm2 = Drule.eta_contraction_rule (Drule.instantiate inst thmi)
   536 in
   493 in
   537   SOME thm2
   494   SOME thm2
   538 end
   495 end
   539 handle _ => NONE
   496 handle _ => NONE
   540 (* FIXME/TODO: what is the place where the exception can be raised: matching_prs? *)
   497 (* FIXME/TODO: what is the place where the exception is raised: matching_prs? *)
   541 *}
   498 *}
   542 
   499 
   543 ML {*
   500 ML {*
   544 fun ball_bex_range_simproc ss redex =
   501 fun ball_bex_range_simproc ss redex =
   545 let
   502 let
   558 
   515 
   559 lemma eq_imp_rel: 
   516 lemma eq_imp_rel: 
   560   shows "equivp R \<Longrightarrow> a = b \<longrightarrow> R a b"
   517   shows "equivp R \<Longrightarrow> a = b \<longrightarrow> R a b"
   561 by (simp add: equivp_reflp)
   518 by (simp add: equivp_reflp)
   562 
   519 
   563 (* FIXME/TODO: How does regularizing work? *)
   520 
   564 (* FIXME/TODO: needs to be adapted
   521 (* Regularize Tactic *)
   565 
   522 
   566 To prove that the raw theorem implies the regularised one, 
   523 (* 0. preliminary simplification step according to *)
   567 we try in order:
   524 thm ball_reg_eqv bex_reg_eqv babs_reg_eqv (* the latter of no use *)
   568 
   525     ball_reg_eqv_range bex_reg_eqv_range
   569  - Reflexivity of the relation
   526 (* 1. eliminating simple Ball/Bex instances*)
   570  - Assumption
   527 thm ball_reg_right bex_reg_left
   571  - Elimnating quantifiers on both sides of toplevel implication
   528 (* 2. monos *)
   572  - Simplifying implications on both sides of toplevel implication
   529 (* 3. commutation rules for ball and bex *)
   573  - Ball (Respects ?E) ?P = All ?P
   530 thm ball_all_comm bex_ex_comm
   574  - (\<And>x. ?R x \<Longrightarrow> ?P x \<longrightarrow> ?Q x) \<Longrightarrow> All ?P \<longrightarrow> Ball ?R ?Q
   531 (* 4. then rel-equality (which need to be instantiated to avoid loops *)
   575 
   532 thm eq_imp_rel
   576 *)
   533 (* 5. then simplification like 0 *)
       
   534 (* finally jump back to 1 *)
       
   535 
       
   536 
   577 ML {*
   537 ML {*
   578 fun regularize_tac ctxt =
   538 fun regularize_tac ctxt =
   579 let
   539 let
   580   val thy = ProofContext.theory_of ctxt
   540   val thy = ProofContext.theory_of ctxt
   581   val pat_ball = @{term "Ball (Respects (R1 ===> R2)) P"}
   541   val pat_ball = @{term "Ball (Respects (R1 ===> R2)) P"}
   584   val simpset = (mk_minimal_ss ctxt) 
   544   val simpset = (mk_minimal_ss ctxt) 
   585                        addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv}
   545                        addsimps @{thms ball_reg_eqv bex_reg_eqv babs_reg_eqv}
   586                        addsimprocs [simproc] addSolver equiv_solver
   546                        addsimprocs [simproc] addSolver equiv_solver
   587   (* TODO: Make sure that there are no list_rel, pair_rel etc involved *)
   547   (* TODO: Make sure that there are no list_rel, pair_rel etc involved *)
   588   (* can this cause loops in equiv_tac ? *)
   548   (* can this cause loops in equiv_tac ? *)
   589   val eq_eqvs = map (fn x => @{thm eq_imp_rel} OF [x]) (equiv_rules_get ctxt)
   549   val eq_eqvs = map (OF1 @{thm eq_imp_rel}) (equiv_rules_get ctxt)
   590 in
   550 in
   591   simp_tac simpset THEN'
   551   simp_tac simpset THEN'
   592   REPEAT_ALL_NEW (CHANGED o FIRST' [
   552   REPEAT_ALL_NEW (CHANGED o FIRST' [
   593     rtac @{thm ball_reg_right},
   553     resolve_tac @{thms ball_reg_right bex_reg_left},
   594     rtac @{thm bex_reg_left},
       
   595     resolve_tac (Inductive.get_monos ctxt),
   554     resolve_tac (Inductive.get_monos ctxt),
   596     rtac @{thm ball_all_comm},
   555     resolve_tac @{thms ball_all_comm bex_ex_comm},
   597     rtac @{thm bex_ex_comm},
       
   598     resolve_tac eq_eqvs,  
   556     resolve_tac eq_eqvs,  
   599     (* should be equivalent to the above, but causes loops:   *) 
       
   600     (* rtac @{thm eq_imp_rel} THEN' SOLVES' (equiv_tac ctxt), *)
       
   601     (* the culprit is aslread rtac @{thm eq_imp_rel}          *)
       
   602     simp_tac simpset])
   557     simp_tac simpset])
   603 end
   558 end
   604 *}
   559 *}
   605 
   560 
   606 section {* Injections of rep and abses *}
   561 section {* Calculation of the Injected Goal *}
   607 
   562 
   608 (*
   563 (*
   609 Injecting repabs means:
   564 Injecting repabs means:
   610 
   565 
   611   For abstractions:
   566   For abstractions:
   656         val (y, s) = Term.dest_abs (x, T, t)
   611         val (y, s) = Term.dest_abs (x, T, t)
   657         val (_, s') = Term.dest_abs (x', T', t')
   612         val (_, s') = Term.dest_abs (x', T', t')
   658         val yvar = Free (y, T)
   613         val yvar = Free (y, T)
   659         val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s'))
   614         val result = Term.lambda_name (y, yvar) (inj_repabs_trm lthy (s, s'))
   660       in
   615       in
   661         if rty = qty 
   616         if rty = qty then result
   662         then result
       
   663         else mk_repabs lthy (rty, qty) result
   617         else mk_repabs lthy (rty, qty) result
   664       end
   618       end
   665 
   619 
   666   | (t $ s, t' $ s') =>  
   620   | (t $ s, t' $ s') =>  
   667        (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s'))
   621        (inj_repabs_trm lthy (t, t')) $ (inj_repabs_trm lthy (s, s'))
   668 
   622 
   669   | (Free (_, T), Free (_, T')) => 
   623   | (Free (_, T), Free (_, T')) => 
   670         if T = T' 
   624         if T = T' then rtrm 
   671         then rtrm 
       
   672         else mk_repabs lthy (T, T') rtrm
   625         else mk_repabs lthy (T, T') rtrm
   673 
   626 
   674   | (_, Const (@{const_name "op ="}, _)) => rtrm
   627   | (_, Const (@{const_name "op ="}, _)) => rtrm
   675 
   628 
   676     (* FIXME: check here that rtrm is the corresponding definition for the const *)
   629     (* FIXME: check here that rtrm is the corresponding definition for the const *)
   677   | (_, Const (_, T')) =>
   630   | (_, Const (_, T')) =>
   678       let
   631       let
   679         val rty = fastype_of rtrm
   632         val rty = fastype_of rtrm
   680       in 
   633       in 
   681         if rty = T'                    
   634         if rty = T' then rtrm
   682         then rtrm
       
   683         else mk_repabs lthy (rty, T') rtrm
   635         else mk_repabs lthy (rty, T') rtrm
   684       end   
   636       end   
   685   
   637   
   686   | _ => raise (LIFT_MATCH "injection")
   638   | _ => raise (LIFT_MATCH "injection")
   687 *}
   639 *}
   688 
   640 
   689 section {* RepAbs Injection Tactic *}
   641 section {* Injection Tactic *}
   690 
   642 
   691 ML {*
   643 ML {*
   692 fun quotient_tac ctxt =
   644 fun quotient_tac ctxt =
   693   REPEAT_ALL_NEW (FIRST'
   645   REPEAT_ALL_NEW (FIRST'
   694     [rtac @{thm identity_quotient},
   646     [rtac @{thm identity_quotient},
   695      resolve_tac (quotient_rules_get ctxt)])
   647      resolve_tac (quotient_rules_get ctxt)])
   696 *}
   648 
   697 
       
   698 (* solver for the simplifier *)
       
   699 ML {*
       
   700 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
   649 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss)
   701 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
   650 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac
   702 *}
   651 *}
   703 
   652 
   704 ML {*
   653 ML {*
   705 fun solve_quotient_assums ctxt thm =
   654 fun solve_quotient_assums ctxt thm =
   706   let val gl = hd (Drule.strip_imp_prems (cprop_of thm)) in
   655 let 
   707   thm OF [Goal.prove_internal [] gl (fn _ => quotient_tac ctxt 1)]
   656   val goal = hd (Drule.strip_imp_prems (cprop_of thm)) 
   708   end
   657 in
   709   handle _ => error "solve_quotient_assums failed. Maybe a quotient_thm is missing"
   658   thm OF [Goal.prove_internal [] goal (fn _ => quotient_tac ctxt 1)]
       
   659 end
       
   660 handle _ => error "solve_quotient_assums failed. Maybe a quotient_thm is missing"
   710 *}
   661 *}
   711 
   662 
   712 (* Not used *)
   663 (* Not used *)
   713 (* It proves the Quotient assumptions by calling quotient_tac *)
   664 (* It proves the Quotient assumptions by calling quotient_tac *)
   714 ML {*
   665 ML {*
   912     (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _))
   863     (Const(@{const_name Babs},_) $ (Const (@{const_name Respects}, _) $ _) $ _))
   913       => rtac @{thm babs_rsp} THEN' RANGE [quotient_tac ctxt]
   864       => rtac @{thm babs_rsp} THEN' RANGE [quotient_tac ctxt]
   914 
   865 
   915     (* reflexivity of operators arising from Cong_tac *)
   866     (* reflexivity of operators arising from Cong_tac *)
   916 | Const (@{const_name "op ="},_) $ _ $ _ 
   867 | Const (@{const_name "op ="},_) $ _ $ _ 
   917       => rtac @{thm refl} ORELSE'
   868       => rtac @{thm refl} (*ORELSE'
   918           (resolve_tac trans2 THEN' RANGE [
   869           (resolve_tac trans2 THEN' RANGE [
   919             quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)])
   870             quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)])*)
   920 
   871 
   921 (* TODO: These patterns should should be somehow combined and generalized... *)
   872 (* TODO: These patterns should should be somehow combined and generalized... *)
   922 | (Const (@{const_name fun_rel}, _) $ _ $ _) $
   873 | (Const (@{const_name fun_rel}, _) $ _ $ _) $
   923     (Const (@{const_name fun_rel}, _) $ _ $ _) $
   874     (Const (@{const_name fun_rel}, _) $ _ $ _) $
   924     (Const (@{const_name fun_rel}, _) $ _ $ _)
   875     (Const (@{const_name fun_rel}, _) $ _ $ _)
   941 | _ => error "inj_repabs_tac not a relation"
   892 | _ => error "inj_repabs_tac not a relation"
   942 ) i)
   893 ) i)
   943 *}
   894 *}
   944 
   895 
   945 ML {*
   896 ML {*
   946 fun inj_repabs_tac ctxt rel_refl trans2 =
   897 fun inj_repabs_step_tac ctxt rel_refl trans2 =
   947   (FIRST' [
   898   (FIRST' [
   948     inj_repabs_tac_match ctxt trans2,
   899     NDT ctxt "0" (inj_repabs_tac_match ctxt trans2),
   949     (* R (t $ \<dots>) (t' $ \<dots>) ----> apply_rsp   provided type of t needs lifting *)
   900     (* R (t $ \<dots>) (t' $ \<dots>) ----> apply_rsp   provided type of t needs lifting *)
       
   901     
   950     NDT ctxt "A" (apply_rsp_tac ctxt THEN'
   902     NDT ctxt "A" (apply_rsp_tac ctxt THEN'
   951                 (RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])),
   903                  RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)]),
       
   904     
       
   905     (* TODO/FIXME: I had to move this after the apply_rsp_tac - is this right *)
       
   906     NDT ctxt "B" (resolve_tac trans2 THEN' 
       
   907                  RANGE [quot_true_tac ctxt (fst o dest_bcomb), quot_true_tac ctxt (snd o dest_bcomb)]),
       
   908 
   952     (* (op =) (t $ \<dots>) (t' $ \<dots>) ----> Cong   provided type of t does not need lifting *)
   909     (* (op =) (t $ \<dots>) (t' $ \<dots>) ----> Cong   provided type of t does not need lifting *)
   953     (* merge with previous tactic *)
   910     (* merge with previous tactic *)
   954     NDT ctxt "B" (Cong_Tac.cong_tac @{thm cong} THEN'
   911     NDT ctxt "C" (Cong_Tac.cong_tac @{thm cong} THEN'
   955                 (RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])),
   912                 (RANGE [quot_true_tac ctxt (fst o dest_comb), quot_true_tac ctxt (snd o dest_comb)])),
       
   913     
   956     (* (op =) (\<lambda>x\<dots>) (\<lambda>x\<dots>) ----> (op =) (\<dots>) (\<dots>) *)
   914     (* (op =) (\<lambda>x\<dots>) (\<lambda>x\<dots>) ----> (op =) (\<dots>) (\<dots>) *)
   957     NDT ctxt "C" (rtac @{thm ext} THEN' quot_true_tac ctxt unlam),
   915     NDT ctxt "D" (rtac @{thm ext} THEN' quot_true_tac ctxt unlam),
       
   916     
   958     (* resolving with R x y assumptions *)
   917     (* resolving with R x y assumptions *)
   959     NDT ctxt "E" (atac),
   918     NDT ctxt "E" (atac),
       
   919     
   960     (* reflexivity of the basic relations *)
   920     (* reflexivity of the basic relations *)
   961     (* R \<dots> \<dots> *)
   921     (* R \<dots> \<dots> *)
   962     NDT ctxt "D" (resolve_tac rel_refl)
   922     NDT ctxt "F" (resolve_tac rel_refl)
   963     ])
   923     ])
   964 *}
   924 *}
   965 
   925 
   966 ML {*
   926 ML {*
   967 fun all_inj_repabs_tac ctxt rel_refl trans2 =
   927 fun inj_repabs_tac ctxt =
   968   REPEAT_ALL_NEW (inj_repabs_tac ctxt rel_refl trans2)
   928 let
   969 *}
   929   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt)
   970 
   930   val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt)
   971 section {* Cleaning of the theorem *}
   931 in
       
   932   inj_repabs_step_tac ctxt rel_refl trans2
       
   933 end
       
   934 
       
   935 fun all_inj_repabs_tac ctxt =
       
   936   REPEAT_ALL_NEW (inj_repabs_tac ctxt)
       
   937 *}
       
   938 
       
   939 section {* Cleaning of the Theorem *}
   972 
   940 
   973 ML {*
   941 ML {*
   974 fun make_inst lhs t =
   942 fun make_inst lhs t =
   975   let
   943   let
   976     val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs;
   944     val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs;
  1015        val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs}
   983        val lpi = Drule.instantiate' tyinst tinst @{thm lambda_prs}
  1016        val te = @{thm eq_reflection} OF [solve_quotient_assums ctxt (solve_quotient_assums ctxt lpi)]
   984        val te = @{thm eq_reflection} OF [solve_quotient_assums ctxt (solve_quotient_assums ctxt lpi)]
  1017        val _ = tracing ("te rule:\n" ^ (Syntax.string_of_term ctxt (prop_of te)));
   985        val _ = tracing ("te rule:\n" ^ (Syntax.string_of_term ctxt (prop_of te)));
  1018        val ti =
   986        val ti =
  1019          (let
   987          (let
  1020            val ts = MetaSimplifier.rewrite_rule @{thms id_simps} te
   988            val ts = MetaSimplifier.rewrite_rule (id_simps_get ctxt) te
  1021            val (insp, inst) = make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm)
   989            val (insp, inst) = make_inst (term_of (Thm.lhs_of ts)) (term_of ctrm)
  1022          in
   990          in
  1023            Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts
   991            Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) ts
  1024          end handle _ => (* TODO handle only Bind | Error "make_inst" *)
   992          end handle _ => (* TODO handle only Bind | Error "make_inst" *)
  1025          let
   993          let
  1026            val (insp, inst) = make_inst2 (term_of (Thm.lhs_of te)) (term_of ctrm)
   994            val (insp, inst) = make_inst2 (term_of (Thm.lhs_of te)) (term_of ctrm)
  1027            val td = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) te
   995            val td = Drule.instantiate ([], [(cterm_of thy insp, cterm_of thy inst)]) te
  1028          in
   996          in
  1029            MetaSimplifier.rewrite_rule @{thms id_simps} td
   997            MetaSimplifier.rewrite_rule (id_simps_get ctxt) td
  1030          end);
   998          end);
  1031        val _ = if not (Term.is_Const a2 andalso fst (dest_Const a2) = @{const_name "id"}) then
   999        val _ = if not (Term.is_Const a2 andalso fst (dest_Const a2) = @{const_name "id"}) then
  1032                   (tracing "lambda_prs";
  1000                   (tracing "lambda_prs";
  1033                    tracing ("redex:\n" ^ (Syntax.string_of_term ctxt (term_of ctrm)));
  1001                    tracing ("redex:\n" ^ (Syntax.string_of_term ctxt (term_of ctrm)));
  1034                    tracing ("lpi rule:\n" ^ (Syntax.string_of_term ctxt (prop_of lpi)));
  1002                    tracing ("lpi rule:\n" ^ (Syntax.string_of_term ctxt (prop_of lpi)));
  1047   More_Conv.top_conv lambda_prs_simple_conv
  1015   More_Conv.top_conv lambda_prs_simple_conv
  1048 
  1016 
  1049 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
  1017 fun lambda_prs_tac ctxt = CONVERSION (lambda_prs_conv ctxt)
  1050 *}
  1018 *}
  1051 
  1019 
  1052 (*
  1020 (* 1. conversion (is not a pattern) *)
  1053  Cleaning the theorem consists of three rewriting steps.
  1021 thm lambda_prs
  1054  The first two need to be done before fun_map is unfolded
  1022 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *)
  1055 
  1023 (*    and simplification with                                     *)
  1056  1) lambda_prs:
  1024 thm all_prs ex_prs 
  1057      (Rep1 ---> Abs2) (\<lambda>x. Rep2 (f (Abs1 x)))  ---->  f
  1025 (* 3. simplification with *)
  1058 
  1026 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep id_simps
  1059     Implemented as conversion since it is not a pattern.
  1027 (* 4. Test for refl *)
  1060 
       
  1061  2) all_prs (the same for exists):
       
  1062      Ball (Respects R) ((abs ---> id) f)  ---->  All f
       
  1063 
       
  1064     Rewriting with definitions from the argument defs
       
  1065      (rep ---> abs) oldConst ----> newconst
       
  1066 
       
  1067  3) Quotient_rel_rep:
       
  1068       Rel (Rep x) (Rep y)  ---->  x = y
       
  1069 
       
  1070     Quotient_abs_rep:
       
  1071       Abs (Rep x)  ---->  x
       
  1072 
       
  1073     id_simps; fun_map.simps
       
  1074 *)
       
  1075 
  1028 
  1076 ML {*
  1029 ML {*
  1077 fun clean_tac lthy =
  1030 fun clean_tac lthy =
  1078   let
  1031   let
  1079     val thy = ProofContext.theory_of lthy;
  1032     val thy = ProofContext.theory_of lthy;
  1080     val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
  1033     val defs = map (Thm.varifyT o symmetric o #def) (qconsts_dest thy)
  1081       (* FIXME: shouldn't the definitions already be varified? *)
  1034       (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *)
  1082     val thms1 = @{thms all_prs ex_prs} @ defs
  1035     val thms1 = @{thms all_prs ex_prs} @ defs
  1083     val thms2 = @{thms eq_reflection[OF fun_map.simps]} 
  1036     val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy)
  1084                 @ @{thms id_simps Quotient_abs_rep Quotient_rel_rep} 
  1037                 @ @{thms Quotient_abs_rep Quotient_rel_rep} 
  1085     fun simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
  1038     fun simps thms = (mk_minimal_ss lthy) addsimps thms addSolver quotient_solver
  1086   in
  1039   in
  1087     EVERY' [lambda_prs_tac lthy,
  1040     EVERY' [lambda_prs_tac lthy,
  1088             simp_tac (simps thms1),
  1041             simp_tac (simps thms1),
  1089             simp_tac (simps thms2),
  1042             simp_tac (simps thms2),
  1090             TRY o rtac refl]
  1043             TRY o rtac refl]
  1091   end
  1044   end
  1092 *}
  1045 *}
  1093 
  1046 
  1094 section {* Genralisation of free variables in a goal *}
  1047 section {* Tactic for genralisation of free variables in a goal *}
  1095 
  1048 
  1096 ML {*
  1049 ML {*
  1097 fun inst_spec ctrm =
  1050 fun inst_spec ctrm =
  1098    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
  1051    Drule.instantiate' [SOME (ctyp_of_term ctrm)] [NONE, SOME ctrm] @{thm spec}
  1099 
  1052 
  1119   in
  1072   in
  1120     rtac rule i
  1073     rtac rule i
  1121   end)  
  1074   end)  
  1122 *}
  1075 *}
  1123 
  1076 
  1124 section {* General outline of the lifting procedure *}
  1077 section {* General Shape of the Lifting Procedure *}
  1125 
  1078 
  1126 (* - A is the original raw theorem          *)
  1079 (* - A is the original raw theorem          *)
  1127 (* - B is the regularized theorem           *)
  1080 (* - B is the regularized theorem           *)
  1128 (* - C is the rep/abs injected version of B *) 
  1081 (* - C is the rep/abs injected version of B *) 
  1129 (* - D is the lifted theorem                *)
  1082 (* - D is the lifted theorem                *)
  1136   assumes a: "A"
  1089   assumes a: "A"
  1137   and     b: "A \<longrightarrow> B"
  1090   and     b: "A \<longrightarrow> B"
  1138   and     c: "B = C"
  1091   and     c: "B = C"
  1139   and     d: "C = D"
  1092   and     d: "C = D"
  1140   shows   "D"
  1093   shows   "D"
  1141   using a b c d
  1094 using a b c d
  1142   by simp
  1095 by simp
  1143 
  1096 
  1144 ML {*
  1097 ML {*
  1145 fun lift_match_error ctxt fun_str rtrm qtrm =
  1098 fun lift_match_error ctxt fun_str rtrm qtrm =
  1146 let
  1099 let
  1147   val rtrm_str = Syntax.string_of_term ctxt rtrm
  1100   val rtrm_str = Syntax.string_of_term ctxt rtrm
  1160   val rtrm' = HOLogic.dest_Trueprop rtrm
  1113   val rtrm' = HOLogic.dest_Trueprop rtrm
  1161   val qtrm' = HOLogic.dest_Trueprop qtrm
  1114   val qtrm' = HOLogic.dest_Trueprop qtrm
  1162   val reg_goal = 
  1115   val reg_goal = 
  1163         Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm')
  1116         Syntax.check_term ctxt (regularize_trm ctxt rtrm' qtrm')
  1164         handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm
  1117         handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm
  1165   val _ = warning "Regularization done."
       
  1166   val inj_goal = 
  1118   val inj_goal = 
  1167         Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm'))
  1119         Syntax.check_term ctxt (inj_repabs_trm ctxt (reg_goal, qtrm'))
  1168         handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm
  1120         handle (LIFT_MATCH s) => lift_match_error ctxt s rtrm qtrm
  1169   val _ = warning "RepAbs Injection done."
       
  1170 in
  1121 in
  1171   Drule.instantiate' []
  1122   Drule.instantiate' []
  1172     [SOME (cterm_of thy rtrm'),
  1123     [SOME (cterm_of thy rtrm'),
  1173      SOME (cterm_of thy reg_goal),
  1124      SOME (cterm_of thy reg_goal),
  1174      SOME (cterm_of thy inj_goal)] @{thm lifting_procedure}
  1125      SOME (cterm_of thy inj_goal)] @{thm lifting_procedure}
  1175 end
  1126 end
  1176 *}
  1127 *}
  1177 
  1128 
  1178 (* Left for debugging *)
  1129 ML {*
  1179 ML {*
  1130 (* the tactic leaves three subgoals to be proved *)
  1180 fun procedure_tac ctxt rthm =
  1131 fun procedure_tac ctxt rthm =
  1181   ObjectLogic.full_atomize_tac
  1132   ObjectLogic.full_atomize_tac
  1182   THEN' gen_frees_tac ctxt
  1133   THEN' gen_frees_tac ctxt
  1183   THEN' CSUBGOAL (fn (gl, i) =>
  1134   THEN' CSUBGOAL (fn (goal, i) =>
  1184     let
  1135     let
  1185       val rthm' = atomize_thm rthm
  1136       val rthm' = atomize_thm rthm
  1186       val rule = procedure_inst ctxt (prop_of rthm') (term_of gl)
  1137       val rule = procedure_inst ctxt (prop_of rthm') (term_of goal)
  1187       val thm = Drule.instantiate' [] [SOME (snd (Thm.dest_comb gl))] @{thm QUOT_TRUE_i}
  1138       val bare_goal = snd (Thm.dest_comb goal)
       
  1139       val quot_weak = Drule.instantiate' [] [SOME bare_goal] @{thm QUOT_TRUE_i}
  1188     in
  1140     in
  1189       (rtac rule THEN' RANGE [rtac rthm', (fn _ => all_tac), rtac thm]) i
  1141       (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i
  1190     end)
  1142     end)
  1191 *}
  1143 *}
  1192 
  1144 
  1193 ML {*
  1145 (* automatic proofs *)
  1194 (* FIXME/TODO should only get as arguments the rthm like procedure_tac *)
  1146 ML {*
  1195 
  1147 fun SOLVES' tac = tac THEN_ALL_NEW (K no_tac)
       
  1148 
       
  1149 fun WARN (tac, msg) i st =
       
  1150  case Seq.pull ((SOLVES' tac) i st) of
       
  1151      NONE    => (warning msg; Seq.single st)
       
  1152    | seqcell => Seq.make (fn () => seqcell)
       
  1153 
       
  1154 fun RANGE_WARN xs = RANGE (map WARN xs)
       
  1155 *}
       
  1156 
       
  1157 ML {*
  1196 fun lift_tac ctxt rthm =
  1158 fun lift_tac ctxt rthm =
  1197   ObjectLogic.full_atomize_tac
  1159   procedure_tac ctxt rthm
  1198   THEN' gen_frees_tac ctxt
  1160   THEN' RANGE_WARN [(regularize_tac ctxt,     "Regularize proof failed."),
  1199   THEN' CSUBGOAL (fn (gl, i) =>
  1161                     (all_inj_repabs_tac ctxt, "Injection proof failed."),
  1200     let
  1162                     (clean_tac ctxt,          "Cleaning proof failed.")]
  1201       val rthm' = atomize_thm rthm
  1163 *}
  1202       val rule = procedure_inst ctxt (prop_of rthm') (term_of gl)
  1164 
  1203       val rel_refl = map (fn x => @{thm equivp_reflp} OF [x]) (equiv_rules_get ctxt)
  1165 end
  1204       val quotients = quotient_rules_get ctxt
  1166 
  1205       val trans2 = map (fn x => @{thm equals_rsp} OF [x]) quotients
       
  1206       val thm = Drule.instantiate' [] [SOME (snd (Thm.dest_comb gl))] @{thm QUOT_TRUE_i}
       
  1207     in
       
  1208       (rtac rule THEN'
       
  1209        RANGE [rtac rthm',
       
  1210               regularize_tac ctxt,
       
  1211               rtac thm THEN' all_inj_repabs_tac ctxt rel_refl trans2,
       
  1212               clean_tac ctxt]) i
       
  1213     end)
       
  1214 *}
       
  1215 
       
  1216 end
       
  1217