|    253 end |    253 end | 
|    254  |    254  | 
|    255 fun NDT ctxt s tac thm = tac thm   |    255 fun NDT ctxt s tac thm = tac thm   | 
|    256 *} |    256 *} | 
|    257  |    257  | 
|         |    258 section {* Matching of terms and types *} | 
|         |    259  | 
|         |    260 ML {* | 
|         |    261 fun matches_typ (ty, ty') = | 
|         |    262   case (ty, ty') of | 
|         |    263     (_, TVar _) => true | 
|         |    264   | (TFree x, TFree x') => x = x' | 
|         |    265   | (Type (s, tys), Type (s', tys')) =>  | 
|         |    266        s = s' andalso  | 
|         |    267        if (length tys = length tys')  | 
|         |    268        then (List.all matches_typ (tys ~~ tys'))  | 
|         |    269        else false | 
|         |    270   | _ => false | 
|         |    271 *} | 
|         |    272 ML {* | 
|         |    273 fun matches_term (trm, trm') =  | 
|         |    274    case (trm, trm') of  | 
|         |    275      (_, Var _) => true | 
|         |    276    | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty') | 
|         |    277    | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty') | 
|         |    278    | (Bound i, Bound j) => i = j | 
|         |    279    | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t') | 
|         |    280    | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s')  | 
|         |    281    | _ => false | 
|         |    282 *} | 
|    258  |    283  | 
|    259 section {* Infrastructure for collecting theorems for starting the lifting *} |    284 section {* Infrastructure for collecting theorems for starting the lifting *} | 
|    260  |    285  | 
|    261 ML {* |    286 ML {* | 
|    262 fun lookup_quot_data lthy qty = |    287 fun lookup_quot_data lthy qty = | 
|    342              (* FIXME: check that the types correspond to each other? *) |    367              (* FIXME: check that the types correspond to each other? *) | 
|    343 end |    368 end | 
|    344 *} |    369 *} | 
|    345  |    370  | 
|    346 ML {* |    371 ML {* | 
|    347 fun matches_typ (ty, ty') = |         | 
|    348   case (ty, ty') of |         | 
|    349     (_, TVar _) => true |         | 
|    350   | (TFree x, TFree x') => x = x' |         | 
|    351   | (Type (s, tys), Type (s', tys')) =>  |         | 
|    352        s = s' andalso  |         | 
|    353        if (length tys = length tys')  |         | 
|    354        then (List.all matches_typ (tys ~~ tys'))  |         | 
|    355        else false |         | 
|    356   | _ => false |         | 
|    357 *} |         | 
|    358 ML {* |         | 
|    359 fun matches_term (trm, trm') =  |         | 
|    360    case (trm, trm') of  |         | 
|    361      (_, Var _) => true |         | 
|    362    | (Const (s, ty), Const (s', ty')) => s = s' andalso matches_typ (ty, ty') |         | 
|    363    | (Free (x, ty), Free (x', ty')) => x = x' andalso matches_typ (ty, ty') |         | 
|    364    | (Bound i, Bound j) => i = j |         | 
|    365    | (Abs (_, T, t), Abs (_, T', t')) => matches_typ (T, T') andalso matches_term (t, t') |         | 
|    366    | (t $ s, t' $ s') => matches_term (t, t') andalso matches_term (s, s')  |         | 
|    367    | _ => false |         | 
|    368 *} |         | 
|    369  |         | 
|    370 ML {* |         | 
|    371 val mk_babs = Const (@{const_name Babs}, dummyT) |    372 val mk_babs = Const (@{const_name Babs}, dummyT) | 
|    372 val mk_ball = Const (@{const_name Ball}, dummyT) |    373 val mk_ball = Const (@{const_name Ball}, dummyT) | 
|    373 val mk_bex  = Const (@{const_name Bex}, dummyT) |    374 val mk_bex  = Const (@{const_name Bex}, dummyT) | 
|    374 val mk_resp = Const (@{const_name Respects}, dummyT) |    375 val mk_resp = Const (@{const_name Respects}, dummyT) | 
|    375 *} |    376 *} | 
|    755   | _ => raise (LIFT_MATCH "injection") |    756   | _ => raise (LIFT_MATCH "injection") | 
|    756 *} |    757 *} | 
|    757  |    758  | 
|    758 section {* RepAbs Injection Tactic *} |    759 section {* RepAbs Injection Tactic *} | 
|    759  |    760  | 
|    760 (* Not used anymore *) |         | 
|    761 (* FIXME/TODO: do not handle everything *) |         | 
|    762 ML {* |         | 
|    763 fun instantiate_tac thm =  |         | 
|    764   Subgoal.FOCUS (fn {concl, ...} => |         | 
|    765   let |         | 
|    766     val pat = Drule.strip_imp_concl (cprop_of thm) |         | 
|    767     val insts = Thm.first_order_match (pat, concl) |         | 
|    768   in |         | 
|    769     rtac (Drule.instantiate insts thm) 1 |         | 
|    770   end |         | 
|    771   handle _ => no_tac) |         | 
|    772 *} |         | 
|    773  |         | 
|    774 ML {* |    761 ML {* | 
|    775 fun quotient_tac ctxt = |    762 fun quotient_tac ctxt = | 
|    776   REPEAT_ALL_NEW (FIRST' |    763   REPEAT_ALL_NEW (FIRST' | 
|    777     [rtac @{thm identity_quotient}, |    764     [rtac @{thm identity_quotient}, | 
|    778      resolve_tac (quotient_rules_get ctxt)]) |    765      resolve_tac (quotient_rules_get ctxt)]) | 
|    780  |    767  | 
|    781 (* solver for the simplifier *) |    768 (* solver for the simplifier *) | 
|    782 ML {* |    769 ML {* | 
|    783 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) |    770 fun quotient_solver_tac ss = quotient_tac (Simplifier.the_context ss) | 
|    784 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac |    771 val quotient_solver = Simplifier.mk_solver' "Quotient goal solver" quotient_solver_tac | 
|         |    772 *} | 
|         |    773  | 
|         |    774 ML {* | 
|         |    775 fun solve_quotient_assums ctxt thm = | 
|         |    776   let val gl = hd (Drule.strip_imp_prems (cprop_of thm)) in | 
|         |    777   thm OF [Goal.prove_internal [] gl (fn _ => quotient_tac ctxt 1)] | 
|         |    778   end | 
|         |    779   handle _ => error "solve_quotient_assums" | 
|         |    780 *} | 
|         |    781  | 
|         |    782 (* It proves the Quotient assumptions by calling quotient_tac *) | 
|         |    783 ML {* | 
|         |    784 fun solve_quotient_assum i ctxt thm = | 
|         |    785   let | 
|         |    786     val tac = | 
|         |    787       (compose_tac (false, thm, i)) THEN_ALL_NEW | 
|         |    788       (quotient_tac ctxt); | 
|         |    789     val gc = Drule.strip_imp_concl (cprop_of thm); | 
|         |    790   in | 
|         |    791     Goal.prove_internal [] gc (fn _ => tac 1) | 
|         |    792   end | 
|         |    793   handle _ => error "solve_quotient_assum" | 
|    785 *} |    794 *} | 
|    786  |    795  | 
|    787 definition |    796 definition | 
|    788   "QUOT_TRUE x \<equiv> True" |    797   "QUOT_TRUE x \<equiv> True" | 
|    789  |    798  | 
|    800     | SOME _ => error "find_qt_asm: no pair" |    809     | SOME _ => error "find_qt_asm: no pair" | 
|    801     | NONE => error "find_qt_asm: no assumption" |    810     | NONE => error "find_qt_asm: no assumption" | 
|    802   end |    811   end | 
|    803 *} |    812 *} | 
|    804  |    813  | 
|    805 (* It proves the Quotient assumptions by calling quotient_tac *) |    814 (* | 
|    806 ML {* |    815 To prove that the regularised theorem implies the abs/rep injected,  | 
|    807 fun solve_quotient_assum i ctxt thm = |    816 we try: | 
|    808   let |    817  | 
|    809     val tac = |    818  1) theorems 'trans2' from the appropriate QUOT_TYPE | 
|    810       (compose_tac (false, thm, i)) THEN_ALL_NEW |    819  2) remove lambdas from both sides: lambda_rsp_tac | 
|    811       (quotient_tac ctxt); |    820  3) remove Ball/Bex from the right hand side | 
|    812     val gc = Drule.strip_imp_concl (cprop_of thm); |    821  4) use user-supplied RSP theorems | 
|    813   in |    822  5) remove rep_abs from the right side | 
|    814     Goal.prove_internal [] gc (fn _ => tac 1) |    823  6) reflexivity of equality | 
|    815   end |    824  7) split applications of lifted type (apply_rsp) | 
|    816   handle _ => error "solve_quotient_assum" |    825  8) split applications of non-lifted type (cong_tac) | 
|    817 *} |    826  9) apply extentionality | 
|    818  |    827  A) reflexivity of the relation | 
|    819 ML {* |    828  B) assumption | 
|    820 fun solve_quotient_assums ctxt thm = |    829     (Lambdas under respects may have left us some assumptions) | 
|    821   let val gl = hd (Drule.strip_imp_prems (cprop_of thm)) in |    830  C) proving obvious higher order equalities by simplifying fun_rel | 
|    822   thm OF [Goal.prove_internal [] gl (fn _ => quotient_tac ctxt 1)] |    831     (not sure if it is still needed?) | 
|    823   end |    832  D) unfolding lambda on one side | 
|    824   handle _ => error "solve_quotient_assums" |    833  E) simplifying (= ===> =) for simpler respectfulness | 
|         |    834  | 
|         |    835 *) | 
|         |    836  | 
|         |    837 lemma quot_true_dests: | 
|         |    838   shows QT_all: "QUOT_TRUE (All P) \<Longrightarrow> QUOT_TRUE P" | 
|         |    839   and   QT_ex:  "QUOT_TRUE (Ex P) \<Longrightarrow> QUOT_TRUE P" | 
|         |    840   and   QT_lam: "QUOT_TRUE (\<lambda>x. P x) \<Longrightarrow> (\<And>x. QUOT_TRUE  (P x))" | 
|         |    841   and   QT_ext: "(\<And>x. QUOT_TRUE (a x) \<Longrightarrow> f x = g x) \<Longrightarrow> (QUOT_TRUE a \<Longrightarrow> f = g)" | 
|         |    842 apply(simp_all add: QUOT_TRUE_def ext) | 
|         |    843 done | 
|         |    844  | 
|         |    845 lemma QUOT_TRUE_i: "(QUOT_TRUE (a :: bool) \<Longrightarrow> P) \<Longrightarrow> P" | 
|         |    846 by (simp add: QUOT_TRUE_def) | 
|         |    847  | 
|         |    848 lemma QUOT_TRUE_imp: "QUOT_TRUE a \<equiv> QUOT_TRUE b" | 
|         |    849 by (simp add: QUOT_TRUE_def) | 
|         |    850  | 
|         |    851 ML {* | 
|         |    852 fun quot_true_conv1 ctxt fnctn ctrm = | 
|         |    853   case (term_of ctrm) of | 
|         |    854     (Const (@{const_name QUOT_TRUE}, _) $ x) => | 
|         |    855     let | 
|         |    856       val fx = fnctn x; | 
|         |    857       val thy = ProofContext.theory_of ctxt; | 
|         |    858       val cx = cterm_of thy x; | 
|         |    859       val cfx = cterm_of thy fx; | 
|         |    860       val cxt = ctyp_of thy (fastype_of x); | 
|         |    861       val cfxt = ctyp_of thy (fastype_of fx); | 
|         |    862       val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QUOT_TRUE_imp} | 
|         |    863     in | 
|         |    864       Conv.rewr_conv thm ctrm | 
|         |    865     end | 
|         |    866 *} | 
|         |    867  | 
|         |    868 ML {* | 
|         |    869 fun quot_true_conv ctxt fnctn ctrm = | 
|         |    870   case (term_of ctrm) of | 
|         |    871     (Const (@{const_name QUOT_TRUE}, _) $ _) => | 
|         |    872       quot_true_conv1 ctxt fnctn ctrm | 
|         |    873   | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm | 
|         |    874   | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm | 
|         |    875   | _ => Conv.all_conv ctrm | 
|         |    876 *} | 
|         |    877  | 
|         |    878 ML {* | 
|         |    879 fun quot_true_tac ctxt fnctn = CONVERSION | 
|         |    880     ((Conv.params_conv ~1 (fn ctxt => | 
|         |    881        (Conv.prems_conv ~1 (quot_true_conv ctxt fnctn)))) ctxt) | 
|         |    882 *} | 
|         |    883  | 
|         |    884 ML {* fun dest_comb (f $ a) = (f, a) *} | 
|         |    885 ML {* fun dest_bcomb ((_ $ l) $ r) = (l, r) *} | 
|         |    886 (* TODO: Can this be done easier? *) | 
|         |    887 ML {* | 
|         |    888 fun unlam t = | 
|         |    889   case t of | 
|         |    890     (Abs a) => snd (Term.dest_abs a) | 
|         |    891   | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) | 
|         |    892 *} | 
|         |    893  | 
|         |    894 ML {* | 
|         |    895 fun dest_fun_type (Type("fun", [T, S])) = (T, S) | 
|         |    896   | dest_fun_type _ = error "dest_fun_type" | 
|         |    897 *} | 
|         |    898  | 
|         |    899 ML {* | 
|         |    900 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl | 
|    825 *} |    901 *} | 
|    826  |    902  | 
|    827 ML {* |    903 ML {* | 
|    828 val apply_rsp_tac = |    904 val apply_rsp_tac = | 
|    829   Subgoal.FOCUS (fn {concl, asms, context,...} => |    905   Subgoal.FOCUS (fn {concl, asms, context,...} => | 
|    847           end |    923           end | 
|    848         end |    924         end | 
|    849         handle ERROR "find_qt_asm: no pair" => no_tac) |    925         handle ERROR "find_qt_asm: no pair" => no_tac) | 
|    850     | _ => no_tac) |    926     | _ => no_tac) | 
|    851 *} |    927 *} | 
|    852  |         | 
|    853 ML {* |    928 ML {* | 
|    854 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) |    929 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac) | 
|    855 *} |         | 
|    856  |         | 
|    857 (* |         | 
|    858 To prove that the regularised theorem implies the abs/rep injected,  |         | 
|    859 we try: |         | 
|    860  |         | 
|    861  1) theorems 'trans2' from the appropriate QUOT_TYPE |         | 
|    862  2) remove lambdas from both sides: lambda_rsp_tac |         | 
|    863  3) remove Ball/Bex from the right hand side |         | 
|    864  4) use user-supplied RSP theorems |         | 
|    865  5) remove rep_abs from the right side |         | 
|    866  6) reflexivity of equality |         | 
|    867  7) split applications of lifted type (apply_rsp) |         | 
|    868  8) split applications of non-lifted type (cong_tac) |         | 
|    869  9) apply extentionality |         | 
|    870  A) reflexivity of the relation |         | 
|    871  B) assumption |         | 
|    872     (Lambdas under respects may have left us some assumptions) |         | 
|    873  C) proving obvious higher order equalities by simplifying fun_rel |         | 
|    874     (not sure if it is still needed?) |         | 
|    875  D) unfolding lambda on one side |         | 
|    876  E) simplifying (= ===> =) for simpler respectfulness |         | 
|    877  |         | 
|    878 *) |         | 
|    879  |         | 
|    880 lemma quot_true_dests: |         | 
|    881   shows QT_all: "QUOT_TRUE (All P) \<Longrightarrow> QUOT_TRUE P" |         | 
|    882   and   QT_ex:  "QUOT_TRUE (Ex P) \<Longrightarrow> QUOT_TRUE P" |         | 
|    883   and   QT_lam: "QUOT_TRUE (\<lambda>x. P x) \<Longrightarrow> (\<And>x. QUOT_TRUE  (P x))" |         | 
|    884   and   QT_ext: "(\<And>x. QUOT_TRUE (a x) \<Longrightarrow> f x = g x) \<Longrightarrow> (QUOT_TRUE a \<Longrightarrow> f = g)" |         | 
|    885 apply(simp_all add: QUOT_TRUE_def ext) |         | 
|    886 done |         | 
|    887  |         | 
|    888 lemma QUOT_TRUE_i: "(QUOT_TRUE (a :: bool) \<Longrightarrow> P) \<Longrightarrow> P" |         | 
|    889 by (simp add: QUOT_TRUE_def) |         | 
|    890  |         | 
|    891 lemma QUOT_TRUE_imp: "QUOT_TRUE a \<equiv> QUOT_TRUE b" |         | 
|    892 by (simp add: QUOT_TRUE_def) |         | 
|    893  |         | 
|    894 ML {* |         | 
|    895 fun quot_true_conv1 ctxt fnctn ctrm = |         | 
|    896   case (term_of ctrm) of |         | 
|    897     (Const (@{const_name QUOT_TRUE}, _) $ x) => |         | 
|    898     let |         | 
|    899       val fx = fnctn x; |         | 
|    900       val thy = ProofContext.theory_of ctxt; |         | 
|    901       val cx = cterm_of thy x; |         | 
|    902       val cfx = cterm_of thy fx; |         | 
|    903       val cxt = ctyp_of thy (fastype_of x); |         | 
|    904       val cfxt = ctyp_of thy (fastype_of fx); |         | 
|    905       val thm = Drule.instantiate' [SOME cxt, SOME cfxt] [SOME cx, SOME cfx] @{thm QUOT_TRUE_imp} |         | 
|    906     in |         | 
|    907       Conv.rewr_conv thm ctrm |         | 
|    908     end |         | 
|    909 *} |         | 
|    910  |         | 
|    911 ML {* |         | 
|    912 fun quot_true_conv ctxt fnctn ctrm = |         | 
|    913   case (term_of ctrm) of |         | 
|    914     (Const (@{const_name QUOT_TRUE}, _) $ _) => |         | 
|    915       quot_true_conv1 ctxt fnctn ctrm |         | 
|    916   | _ $ _ => Conv.comb_conv (quot_true_conv ctxt fnctn) ctrm |         | 
|    917   | Abs _ => Conv.abs_conv (fn (_, ctxt) => quot_true_conv ctxt fnctn) ctxt ctrm |         | 
|    918   | _ => Conv.all_conv ctrm |         | 
|    919 *} |         | 
|    920  |         | 
|    921 ML {* |         | 
|    922 fun quot_true_tac ctxt fnctn = CONVERSION |         | 
|    923     ((Conv.params_conv ~1 (fn ctxt => |         | 
|    924        (Conv.prems_conv ~1 (quot_true_conv ctxt fnctn)))) ctxt) |         | 
|    925 *} |         | 
|    926  |         | 
|    927 ML {* fun dest_comb (f $ a) = (f, a) *} |         | 
|    928 ML {* fun dest_bcomb ((_ $ l) $ r) = (l, r) *} |         | 
|    929 (* TODO: Can this be done easier? *) |         | 
|    930 ML {* |         | 
|    931 fun unlam t = |         | 
|    932   case t of |         | 
|    933     (Abs a) => snd (Term.dest_abs a) |         | 
|    934   | _ => unlam (Abs("", domain_type (fastype_of t), (incr_boundvars 1 t) $ (Bound 0))) |         | 
|    935 *} |         | 
|    936  |         | 
|    937 ML {* |         | 
|    938 fun dest_fun_type (Type("fun", [T, S])) = (T, S) |         | 
|    939   | dest_fun_type _ = error "dest_fun_type" |         | 
|    940 *} |         | 
|    941  |         | 
|    942 ML {* |         | 
|    943 val bare_concl = HOLogic.dest_Trueprop o Logic.strip_assums_concl |         | 
|    944 *} |    930 *} | 
|    945  |    931  | 
|    946 ML {* |    932 ML {* | 
|    947 fun rep_abs_rsp_tac ctxt = |    933 fun rep_abs_rsp_tac ctxt = | 
|    948   SUBGOAL (fn (goal, i) => |    934   SUBGOAL (fn (goal, i) => |