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 =  | 
   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:  | 
   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   | 
  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   | 
         |