|    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  | 
|    147 (* Throws now an exception:              *) |    148 (* Throws now an exception:              *) | 
|    148 (* declare [[map "option" = (bla, blu)]] *) |    149 (* declare [[map "option" = (bla, blu)]] *) | 
|    149  |    150  | 
|    150 lemmas [quotient_thm] = |    151 lemmas [quotient_thm] = | 
|    151   fun_quotient prod_quotient |    152   fun_quotient prod_quotient | 
|    264        s = s' andalso  |    265        s = s' andalso  | 
|    265        if (length tys = length tys')  |    266        if (length tys = length tys')  | 
|    266        then (List.all matches_typ (tys ~~ tys'))  |    267        then (List.all matches_typ (tys ~~ tys'))  | 
|    267        else false |    268        else false | 
|    268   | _ => false |    269   | _ => false | 
|    269 *} |    270  | 
|    270  |         | 
|    271 ML {* |         | 
|    272 fun matches_term (trm, trm') =  |    271 fun matches_term (trm, trm') =  | 
|    273    case (trm, trm') of  |    272    case (trm, trm') of  | 
|    274      (_, Var _) => true |    273      (_, Var _) => true | 
|    275    | (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') | 
|    276    | (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') | 
|    614         val (y, s) = Term.dest_abs (x, T, t) |    611         val (y, s) = Term.dest_abs (x, T, t) | 
|    615         val (_, s') = Term.dest_abs (x', T', t') |    612         val (_, s') = Term.dest_abs (x', T', t') | 
|    616         val yvar = Free (y, T) |    613         val yvar = Free (y, T) | 
|    617         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')) | 
|    618       in |    615       in | 
|    619         if rty = qty  |    616         if rty = qty then result | 
|    620         then result |         | 
|    621         else mk_repabs lthy (rty, qty) result |    617         else mk_repabs lthy (rty, qty) result | 
|    622       end |    618       end | 
|    623  |    619  | 
|    624   | (t $ s, t' $ s') =>   |    620   | (t $ s, t' $ s') =>   | 
|    625        (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')) | 
|    626  |    622  | 
|    627   | (Free (_, T), Free (_, T')) =>  |    623   | (Free (_, T), Free (_, T')) =>  | 
|    628         if T = T'  |    624         if T = T' then rtrm  | 
|    629         then rtrm  |         | 
|    630         else mk_repabs lthy (T, T') rtrm |    625         else mk_repabs lthy (T, T') rtrm | 
|    631  |    626  | 
|    632   | (_, Const (@{const_name "op ="}, _)) => rtrm |    627   | (_, Const (@{const_name "op ="}, _)) => rtrm | 
|    633  |    628  | 
|    634     (* 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 *) | 
|    635   | (_, Const (_, T')) => |    630   | (_, Const (_, T')) => | 
|    636       let |    631       let | 
|    637         val rty = fastype_of rtrm |    632         val rty = fastype_of rtrm | 
|    638       in  |    633       in  | 
|    639         if rty = T'                     |    634         if rty = T' then rtrm | 
|    640         then rtrm |         | 
|    641         else mk_repabs lthy (rty, T') rtrm |    635         else mk_repabs lthy (rty, T') rtrm | 
|    642       end    |    636       end    | 
|    643    |    637    | 
|    644   | _ => raise (LIFT_MATCH "injection") |    638   | _ => raise (LIFT_MATCH "injection") | 
|    645 *} |    639 *} | 
|    649 ML {* |    643 ML {* | 
|    650 fun quotient_tac ctxt = |    644 fun quotient_tac ctxt = | 
|    651   REPEAT_ALL_NEW (FIRST' |    645   REPEAT_ALL_NEW (FIRST' | 
|    652     [rtac @{thm identity_quotient}, |    646     [rtac @{thm identity_quotient}, | 
|    653      resolve_tac (quotient_rules_get ctxt)]) |    647      resolve_tac (quotient_rules_get ctxt)]) | 
|    654 *} |    648  | 
|    655  |         | 
|    656 (* solver for the simplifier *) |         | 
|    657 ML {* |         | 
|    658 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |    649 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) | 
|    659 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 | 
|    660 *} |    651 *} | 
|    661  |    652  | 
|    662 ML {* |    653 ML {* | 
|    938   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) |    929   val rel_refl = map (OF1 @{thm equivp_reflp}) (equiv_rules_get ctxt) | 
|    939   val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt) |    930   val trans2 = map (OF1 @{thm equals_rsp}) (quotient_rules_get ctxt) | 
|    940 in |    931 in | 
|    941   inj_repabs_step_tac ctxt rel_refl trans2 |    932   inj_repabs_step_tac ctxt rel_refl trans2 | 
|    942 end |    933 end | 
|    943 *} |    934  | 
|    944  |         | 
|    945 ML {* |         | 
|    946 fun all_inj_repabs_tac ctxt = |    935 fun all_inj_repabs_tac ctxt = | 
|    947   REPEAT_ALL_NEW (inj_repabs_tac ctxt) |    936   REPEAT_ALL_NEW (inj_repabs_tac ctxt) | 
|    948 (* if this is too slow we can inline the code above *) |    937 *} | 
|    949 *} |    938  | 
|    950  |    939 section {* Cleaning of the Theorem *} | 
|    951 section {* Cleaning of the theorem *} |         | 
|    952  |    940  | 
|    953 ML {* |    941 ML {* | 
|    954 fun make_inst lhs t = |    942 fun make_inst lhs t = | 
|    955   let |    943   let | 
|    956     val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs; |    944     val _ $ (Abs (_, _, (f as Var (_, Type ("fun", [T, _]))) $ u)) = lhs; | 
|   1032 (* 1. conversion (is not a pattern) *) |   1020 (* 1. conversion (is not a pattern) *) | 
|   1033 thm lambda_prs |   1021 thm lambda_prs | 
|   1034 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *) |   1022 (* 2. folding of definitions: (rep ---> abs) oldConst == newconst *) | 
|   1035 (*    and simplification with                                     *) |   1023 (*    and simplification with                                     *) | 
|   1036 thm all_prs ex_prs  |   1024 thm all_prs ex_prs  | 
|   1037 (* 3. simplification with id_simps and *) |   1025 (* 3. simplification with *) | 
|   1038 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep |   1026 thm fun_map.simps Quotient_abs_rep Quotient_rel_rep id_simps | 
|   1039 (* 4. Test for refl *) |   1027 (* 4. Test for refl *) | 
|   1040  |   1028  | 
|   1041 ML {* |   1029 ML {* | 
|   1042 fun clean_tac lthy = |   1030 fun clean_tac lthy = | 
|   1043   let |   1031   let | 
|   1044     val thy = ProofContext.theory_of lthy; |   1032     val thy = ProofContext.theory_of lthy; | 
|   1045     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) | 
|   1046       (* FIXME: shouldn't the definitions already be varified? *) |   1034       (* FIXME: why is the Thm.varifyT needed: example where it fails is LamEx *) | 
|   1047     val thms1 = @{thms all_prs ex_prs} @ defs |   1035     val thms1 = @{thms all_prs ex_prs} @ defs | 
|   1048     val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy) |   1036     val thms2 = @{thms eq_reflection[OF fun_map.simps]} @ (id_simps_get lthy) | 
|   1049                 @ @{thms Quotient_abs_rep Quotient_rel_rep}  |   1037                 @ @{thms Quotient_abs_rep Quotient_rel_rep}  | 
|   1050     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 | 
|   1051   in |   1039   in | 
|   1153       (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i |   1141       (rtac rule THEN' RANGE [rtac rthm', K all_tac, rtac quot_weak]) i | 
|   1154     end) |   1142     end) | 
|   1155 *} |   1143 *} | 
|   1156  |   1144  | 
|   1157 ML {* |   1145 ML {* | 
|   1158 (* automated tactics *) |   1146 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) | 
|         |   1147  | 
|         |   1148 fun WARN (tac, msg) i st = | 
|         |   1149  case Seq.pull ((SOLVES' tac) i st) of | 
|         |   1150      NONE    => (warning msg; Seq.single st) | 
|         |   1151    | seqcell => Seq.make (fn () => seqcell) | 
|         |   1152  | 
|         |   1153 fun RANGE_WARN xs = RANGE (map WARN xs) | 
|         |   1154 *} | 
|         |   1155  | 
|         |   1156 ML {* | 
|   1159 fun lift_tac ctxt rthm = |   1157 fun lift_tac ctxt rthm = | 
|   1160   procedure_tac ctxt rthm |   1158   procedure_tac ctxt rthm | 
|   1161   THEN' RANGE [regularize_tac ctxt, |   1159   THEN' RANGE_WARN [(regularize_tac ctxt,     "Regularize proof failed."), | 
|   1162                all_inj_repabs_tac ctxt, |   1160                     (all_inj_repabs_tac ctxt, "Injection proof failed."), | 
|   1163                clean_tac ctxt] |   1161                     (clean_tac ctxt,          "Cleaning proof failed.")] | 
|   1164 *} |   1162 *} | 
|   1165  |   1163  | 
|   1166 end |   1164 end | 
|   1167  |   1165  |