QuotMain.thy
changeset 303 991b0e53f9dc
parent 302 a840c232e04e
child 307 9aa3aba71ecc
equal deleted inserted replaced
302:a840c232e04e 303:991b0e53f9dc
   200 Regularizing a theorem means:
   200 Regularizing a theorem means:
   201  - Quantifiers over a type that needs lifting are replaced by
   201  - Quantifiers over a type that needs lifting are replaced by
   202    bounded quantifiers, for example:
   202    bounded quantifiers, for example:
   203       \<forall>x. P     \<Longrightarrow>     \<forall>x\<in>(Respects R). P
   203       \<forall>x. P     \<Longrightarrow>     \<forall>x\<in>(Respects R). P
   204  - Abstractions over a type that needs lifting are replaced
   204  - Abstractions over a type that needs lifting are replaced
   205    by bounded abstactions:
   205    by bounded abstractions:
   206       \<lambda>x. P     \<Longrightarrow>     Ball (Respects R) (\<lambda>x. P)
   206       \<lambda>x. P     \<Longrightarrow>     Ball (Respects R) (\<lambda>x. P)
   207 
   207 
   208  - Equalities over the type being lifted are replaced by
   208  - Equalities over the type being lifted are replaced by
   209    appropriate relations:
   209    appropriate relations:
   210       A = B     \<Longrightarrow>     A \<approx> B
   210       A = B     \<Longrightarrow>     A \<approx> B
   239               val tys_rel = map (fn ty => ty --> ty --> @{typ bool}) tys;
   239               val tys_rel = map (fn ty => ty --> ty --> @{typ bool}) tys;
   240               val ty_out = ty --> ty --> @{typ bool};
   240               val ty_out = ty --> ty --> @{typ bool};
   241               val tys_out = tys_rel ---> ty_out;
   241               val tys_out = tys_rel ---> ty_out;
   242             in
   242             in
   243             (case (maps_lookup (ProofContext.theory_of lthy) s) of
   243             (case (maps_lookup (ProofContext.theory_of lthy) s) of
   244                SOME (info) => list_comb (Const (#relfun info, tys_out), map (fn ty => tyRel ty rty rel lthy) tys)
   244                SOME (info) => list_comb (Const (#relfun info, tys_out),
       
   245                               map (fn ty => tyRel ty rty rel lthy) tys)
   245              | NONE  => HOLogic.eq_const ty
   246              | NONE  => HOLogic.eq_const ty
   246             )
   247             )
   247             end
   248             end
   248         | _ => HOLogic.eq_const ty)
   249         | _ => HOLogic.eq_const ty)
   249 *}
   250 *}
   339       (my_reg lthy (Const (n, dummyT)) (Logic.varifyT rty) trm)
   340       (my_reg lthy (Const (n, dummyT)) (Logic.varifyT rty) trm)
   340 *}
   341 *}
   341 
   342 
   342 (*
   343 (*
   343 ML {*
   344 ML {*
   344   text {*val r = term_of @{cpat "R::?'a list \<Rightarrow> ?'a list \<Rightarrow> bool"};*}
       
   345   val r = Free ("R", dummyT);
   345   val r = Free ("R", dummyT);
   346   val t = (my_reg @{context} r @{typ "'a list"} @{term "\<forall>(x::'b list). P x"});
   346   val t = (my_reg_inst @{context} r @{typ "'a list"} @{term "\<forall>(x::'b list). P x"});
   347   val t2 = Syntax.check_term @{context} t;
   347   val t2 = Syntax.check_term @{context} t;
   348   Toplevel.program (fn () => cterm_of @{theory} t2)
   348   cterm_of @{theory} t2
   349 *}*)
   349 *}
       
   350 *)
   350 
   351 
   351 text {* Assumes that the given theorem is atomized *}
   352 text {* Assumes that the given theorem is atomized *}
   352 ML {*
   353 ML {*
   353   fun build_regularize_goal thm rty rel lthy =
   354   fun build_regularize_goal thm rty rel lthy =
   354      Logic.mk_implies
   355      Logic.mk_implies
   355        ((prop_of thm),
   356        ((prop_of thm),
   356        (my_reg_inst lthy rel rty (prop_of thm)))
   357        (my_reg_inst lthy rel rty (prop_of thm)))
   357 *}
   358 *}
   358 
   359 
   359 lemma universal_twice: 
   360 lemma universal_twice:
   360   "(\<And>x. (P x \<longrightarrow> Q x)) \<Longrightarrow> ((\<forall>x. P x) \<longrightarrow> (\<forall>x. Q x))"
   361   assumes *: "\<And>x. (P x \<longrightarrow> Q x)"
   361 by auto
   362   shows "(\<forall>x. P x) \<longrightarrow> (\<forall>x. Q x)"
   362 
   363 using * by auto
   363 lemma implication_twice: 
   364 
   364   "(c \<longrightarrow> a) \<Longrightarrow> (a \<Longrightarrow> b \<longrightarrow> d) \<Longrightarrow> (a \<longrightarrow> b) \<longrightarrow> (c \<longrightarrow> d)"
   365 lemma implication_twice:
   365 by auto
   366   assumes a: "c \<longrightarrow> a"
   366 
   367   assumes b: "a \<Longrightarrow> b \<longrightarrow> d"
   367 (*lemma equality_twice:
   368   shows "(a \<longrightarrow> b) \<longrightarrow> (c \<longrightarrow> d)"
   368   "a = c \<Longrightarrow> b = d \<Longrightarrow> (a = b \<longrightarrow> c = d)"
   369 using a b by auto
   369 by auto*)
       
   370 
   370 
   371 ML {*
   371 ML {*
   372 fun regularize thm rty rel rel_eqv rel_refl lthy =
   372 fun regularize thm rty rel rel_eqv rel_refl lthy =
   373   let
   373   let
   374     val goal = build_regularize_goal thm rty rel lthy;
   374     val goal = build_regularize_goal thm rty rel lthy;
   381         (rtac @{thm impI} THEN' atac),
   381         (rtac @{thm impI} THEN' atac),
   382         rtac @{thm implication_twice},
   382         rtac @{thm implication_twice},
   383         EqSubst.eqsubst_tac ctxt [0]
   383         EqSubst.eqsubst_tac ctxt [0]
   384           [(@{thm equiv_res_forall} OF [rel_eqv]),
   384           [(@{thm equiv_res_forall} OF [rel_eqv]),
   385            (@{thm equiv_res_exists} OF [rel_eqv])],
   385            (@{thm equiv_res_exists} OF [rel_eqv])],
       
   386         (* For a = b \<longrightarrow> a \<approx> b *)
   386         (rtac @{thm impI} THEN' (asm_full_simp_tac HOL_ss) THEN' rtac rel_refl),
   387         (rtac @{thm impI} THEN' (asm_full_simp_tac HOL_ss) THEN' rtac rel_refl),
   387         (rtac @{thm RIGHT_RES_FORALL_REGULAR})
   388         (rtac @{thm RIGHT_RES_FORALL_REGULAR})
   388       ]);
   389       ]);
   389     val cthm = Goal.prove lthy [] [] goal
   390     val cthm = Goal.prove lthy [] [] goal
   390       (fn {context, ...} => tac context 1);
   391       (fn {context, ...} => tac context 1);
   394 *}
   395 *}
   395 
   396 
   396 section {* RepAbs injection *}
   397 section {* RepAbs injection *}
   397 (*
   398 (*
   398 
   399 
   399 Injecting RepAbs means:
   400 RepAbs injection is done in the following phases:
       
   401  1) build_repabs_term inserts rep-abs pairs in the term
       
   402  2) we prove the equality between the original theorem and this one
       
   403  3) we use Pure.equal_elim_rule1 to get the new theorem.
       
   404 
       
   405 build_repabs_term does:
   400 
   406 
   401   For abstractions:
   407   For abstractions:
   402   * If the type of the abstraction doesn't need lifting we recurse.
   408   * If the type of the abstraction doesn't need lifting we recurse.
   403   * If it does we add RepAbs around the whole term and check if the
   409   * If it does we add RepAbs around the whole term and check if the
   404     variable needs lifting.
   410     variable needs lifting.
   405     * If it doesn't then we recurse
   411     * If it doesn't then we recurse
   406     * If it does we recurse and put 'RepAbs' around all occurences
   412     * If it does we recurse and put 'RepAbs' around all occurences
   407       of the variable in the obtained subterm.
   413       of the variable in the obtained subterm. This in combination
       
   414       with the RepAbs above will let us change the type of the
       
   415       abstraction with rewriting.
   408   For applications:
   416   For applications:
   409   * If the term is 'Respects' applied to anything we leave it unchanged
   417   * If the term is 'Respects' applied to anything we leave it unchanged
   410   * If the term needs lifting and the head is a constant that we know
   418   * If the term needs lifting and the head is a constant that we know
   411     how to lift, we put a RepAbs and recurse
   419     how to lift, we put a RepAbs and recurse
   412   * If the term needs lifting and the head is a free applied to subterms
   420   * If the term needs lifting and the head is a free applied to subterms
   413     (if it is not applied we treated it in Abs branch) then we
   421     (if it is not applied we treated it in Abs branch) then we
   414     put RepAbs and recurse
   422     put RepAbs and recurse
   415   * Otherwise just recurse.
   423   * Otherwise just recurse.
   416 
   424 
   417 The injection is done in the following phases:
       
   418  1) build_repabs_term inserts rep-abs pairs in the term
       
   419  2) we prove the equality between the original theorem and this one
       
   420  3) we use Pure.equal_elim_rule1 to get the new theorem.
       
   421 
   425 
   422 To prove that the old theorem implies the new one, we first
   426 To prove that the old theorem implies the new one, we first
   423 atomize it and then try:
   427 atomize it and then try:
   424 
   428 
   425  1) theorems 'trans2' from the QUOT_TYPE
   429  1) theorems 'trans2' from the appropriate QUOT_TYPE
   426  2) remove lambdas from both sides (LAMBDA_RES_TAC)
   430  2) remove lambdas from both sides (LAMBDA_RES_TAC)
   427  3) remove Ball/Bex
   431  3) remove Ball/Bex from the right hand side
   428  4) use RSP theorems
   432  4) use user-supplied RSP theorems
   429  5) remove rep_abs from right side
   433  5) remove rep_abs from the right side
   430  6) reflexivity
   434  6) reflexivity of equality
   431  7) split applications of lifted type (apply_rsp)
   435  7) split applications of lifted type (apply_rsp)
   432  8) split applications of non-lifted type (cong_tac)
   436  8) split applications of non-lifted type (cong_tac)
   433  9) apply extentionality
   437  9) apply extentionality
   434 10) relation reflexive
   438 10) reflexivity of the relation
   435 11) assumption
   439 11) assumption
       
   440     (Lambdas under respects may have left us some assumptions)
   436 12) proving obvious higher order equalities by simplifying fun_rel
   441 12) proving obvious higher order equalities by simplifying fun_rel
   437     (not sure if still needed?)
   442     (not sure if it is still needed?)
   438 13) unfolding lambda on one side
   443 13) unfolding lambda on one side
   439 14) simplifying (= ===> =) for simpler respectfullness
   444 14) simplifying (= ===> =) for simpler respectfullness
   440 
   445 
   441 *)
   446 *)
   442 
   447 
   630 
   635 
   631 (* Needed to have a meta-equality *)
   636 (* Needed to have a meta-equality *)
   632 lemma id_def_sym: "(\<lambda>x. x) \<equiv> id"
   637 lemma id_def_sym: "(\<lambda>x. x) \<equiv> id"
   633 by (simp add: id_def)
   638 by (simp add: id_def)
   634 
   639 
       
   640 (* TODO: can be also obtained with: *)
       
   641 ML {* symmetric (eq_reflection OF @{thms id_def}) *}
       
   642 
   635 ML {*
   643 ML {*
   636 fun build_repabs_term lthy thm consts rty qty =
   644 fun build_repabs_term lthy thm consts rty qty =
   637   let
   645   let
       
   646     (* TODO: The rty and qty stored in the quotient_info should
       
   647        be varified, so this will soon not be needed *)
   638     val rty = Logic.varifyT rty;
   648     val rty = Logic.varifyT rty;
   639     val qty = Logic.varifyT qty;
   649     val qty = Logic.varifyT qty;
   640 
   650 
   641   fun mk_abs tm =
   651   fun mk_abs tm =
   642     let
   652     let
   662             else mk_repabs (
   672             else mk_repabs (
   663               if not (needs_lift rty vty) then t'
   673               if not (needs_lift rty vty) then t'
   664               else
   674               else
   665                 let
   675                 let
   666                   val v' = mk_repabs v;
   676                   val v' = mk_repabs v;
   667                   (* TODO: I believe this is not needed any more *)
   677                   (* TODO: I believe 'beta' is not needed any more *)
   668                   val t1 = Envir.beta_norm (t' $ v')
   678                   val t1 = (* Envir.beta_norm *) (t' $ v')
   669                 in
   679                 in
   670                   lambda v t1
   680                   lambda v t1
   671                 end)
   681                 end)
   672           end
   682           end
   673       | x =>
   683       | x =>
   689     repeat_eqsubst_prop lthy @{thms id_def_sym}
   699     repeat_eqsubst_prop lthy @{thms id_def_sym}
   690       (build_aux lthy (Thm.prop_of thm))
   700       (build_aux lthy (Thm.prop_of thm))
   691   end
   701   end
   692 *}
   702 *}
   693 
   703 
   694 text {* Assumes that it is given a regularized theorem *}
   704 text {* Builds provable goals for regularized theorems *}
   695 ML {*
   705 ML {*
   696 fun build_repabs_goal ctxt thm cons rty qty =
   706 fun build_repabs_goal ctxt thm cons rty qty =
   697   Logic.mk_equals ((Thm.prop_of thm), (build_repabs_term ctxt thm cons rty qty))
   707   Logic.mk_equals ((Thm.prop_of thm), (build_repabs_term ctxt thm cons rty qty))
   698 *}
   708 *}
   699 
   709 
   700 ML {*
   710 ML {*
   701 fun instantiate_tac thm = Subgoal.FOCUS (fn {concl, ...} =>
   711 fun instantiate_tac thm = Subgoal.FOCUS (fn {concl, ...} =>
   702 let
   712   let
   703   val pat = Drule.strip_imp_concl (cprop_of thm)
   713     val pat = Drule.strip_imp_concl (cprop_of thm)
   704   val insts = Thm.match (pat, concl)
   714     val insts = Thm.match (pat, concl)
   705 in
   715   in
   706   rtac (Drule.instantiate insts thm) 1
   716     rtac (Drule.instantiate insts thm) 1
   707 end
   717   end
   708 handle _ => no_tac
   718   handle _ => no_tac)
   709 )
   719 *}
       
   720 
       
   721 ML {*
       
   722 fun CHANGED' tac = (fn i => CHANGED (tac i))
   710 *}
   723 *}
   711 
   724 
   712 ML {*
   725 ML {*
   713 fun quotient_tac quot_thm =
   726 fun quotient_tac quot_thm =
   714   REPEAT_ALL_NEW (FIRST' [
   727   REPEAT_ALL_NEW (FIRST' [
   715     rtac @{thm FUN_QUOTIENT},
   728     rtac @{thm FUN_QUOTIENT},
   716     rtac quot_thm,
   729     rtac quot_thm,
   717     rtac @{thm IDENTITY_QUOTIENT},
   730     rtac @{thm IDENTITY_QUOTIENT},
   718     (
   731     (* For functional identity quotients, (op = ---> op =) *)
   719       fn i => CHANGED (simp_tac (HOL_ss addsimps @{thms FUN_MAP_I}) i) THEN
   732     CHANGED' (
   720       rtac @{thm IDENTITY_QUOTIENT} i
   733       (simp_tac (HOL_ss addsimps @{thms FUN_MAP_I})) THEN'
       
   734       rtac @{thm IDENTITY_QUOTIENT}
   721     )
   735     )
   722   ])
   736   ])
   723 *}
   737 *}
   724 
   738 
   725 ML {*
   739 ML {*
   726 fun LAMBDA_RES_TAC ctxt i st =
   740 fun LAMBDA_RES_TAC ctxt i st =
   727   (case (term_of o #concl o fst) (Subgoal.focus ctxt i st) of
   741   (case (term_of o #concl o fst) (Subgoal.focus ctxt i st) of
   728     (_ $ (_ $ (Abs(_, _, _))$(Abs(_, _, _)))) =>
   742     (_ $ (_ $ (Abs(_, _, _)) $ (Abs(_, _, _)))) =>
   729       (EqSubst.eqsubst_tac ctxt [0] @{thms FUN_REL.simps}) THEN'
   743       (EqSubst.eqsubst_tac ctxt [0] @{thms FUN_REL.simps}) THEN'
   730       (rtac @{thm allI}) THEN' (rtac @{thm allI}) THEN' (rtac @{thm impI})
   744       (rtac @{thm allI}) THEN' (rtac @{thm allI}) THEN' (rtac @{thm impI})
   731   | _ => fn _ => no_tac) i st
   745   | _ => fn _ => no_tac) i st
   732 *}
   746 *}
   733 
   747 
   747 fun APPLY_RSP_TAC rty = Subgoal.FOCUS (fn {concl, ...} =>
   761 fun APPLY_RSP_TAC rty = Subgoal.FOCUS (fn {concl, ...} =>
   748   let
   762   let
   749     val (_ $ (R $ (f $ _) $ (_ $ _))) = term_of concl;
   763     val (_ $ (R $ (f $ _) $ (_ $ _))) = term_of concl;
   750     val pat = Drule.strip_imp_concl (cprop_of @{thm APPLY_RSP});
   764     val pat = Drule.strip_imp_concl (cprop_of @{thm APPLY_RSP});
   751     val insts = Thm.match (pat, concl)
   765     val insts = Thm.match (pat, concl)
   752 in
   766   in
   753   if needs_lift rty (type_of f) then
   767     if needs_lift rty (type_of f) then
   754     rtac (Drule.instantiate insts @{thm APPLY_RSP}) 1
   768       rtac (Drule.instantiate insts @{thm APPLY_RSP}) 1
   755   else no_tac
   769     else no_tac
   756 end
   770   end
   757 handle _ => no_tac)
   771   handle _ => no_tac)
   758 *}
   772 *}
   759 
   773 
   760 ML {*
   774 ML {*
   761 val ball_rsp_tac = Subgoal.FOCUS (fn {concl, context = ctxt, ...} =>
   775 val ball_rsp_tac = Subgoal.FOCUS (fn {concl, context = ctxt, ...} =>
   762   let
   776   let
   766     ((simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))
   780     ((simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))
   767     THEN' rtac @{thm allI} THEN' rtac @{thm allI} THEN' rtac @{thm impI}
   781     THEN' rtac @{thm allI} THEN' rtac @{thm allI} THEN' rtac @{thm impI}
   768     THEN' instantiate_tac @{thm RES_FORALL_RSP} ctxt THEN'
   782     THEN' instantiate_tac @{thm RES_FORALL_RSP} ctxt THEN'
   769     (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))) 1
   783     (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))) 1
   770   end
   784   end
   771   handle _ => no_tac
   785   handle _ => no_tac)
   772   )
       
   773 *}
   786 *}
   774 
   787 
   775 ML {*
   788 ML {*
   776 val bex_rsp_tac = Subgoal.FOCUS (fn {concl, context = ctxt, ...} =>
   789 val bex_rsp_tac = Subgoal.FOCUS (fn {concl, context = ctxt, ...} =>
   777   let
   790   let
   781     ((simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))
   794     ((simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))
   782     THEN' rtac @{thm allI} THEN' rtac @{thm allI} THEN' rtac @{thm impI}
   795     THEN' rtac @{thm allI} THEN' rtac @{thm allI} THEN' rtac @{thm impI}
   783     THEN' instantiate_tac @{thm RES_EXISTS_RSP} ctxt THEN'
   796     THEN' instantiate_tac @{thm RES_EXISTS_RSP} ctxt THEN'
   784     (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))) 1
   797     (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))) 1
   785   end
   798   end
   786   handle _ => no_tac
   799   handle _ => no_tac)
   787   )
   800 *}
       
   801 
       
   802 ML {*
       
   803 fun SOLVES' tac = tac THEN_ALL_NEW (fn _ => no_tac)
   788 *}
   804 *}
   789 
   805 
   790 ML {*
   806 ML {*
   791 fun r_mk_comb_tac ctxt rty quot_thm reflex_thm trans_thm rsp_thms =
   807 fun r_mk_comb_tac ctxt rty quot_thm reflex_thm trans_thm rsp_thms =
   792   (FIRST' [
   808   (FIRST' [
   795     ball_rsp_tac ctxt,
   811     ball_rsp_tac ctxt,
   796     bex_rsp_tac ctxt,
   812     bex_rsp_tac ctxt,
   797     FIRST' (map rtac rsp_thms),
   813     FIRST' (map rtac rsp_thms),
   798     (instantiate_tac @{thm REP_ABS_RSP(1)} ctxt THEN' (RANGE [quotient_tac quot_thm])),
   814     (instantiate_tac @{thm REP_ABS_RSP(1)} ctxt THEN' (RANGE [quotient_tac quot_thm])),
   799     rtac refl,
   815     rtac refl,
   800 (*    rtac @{thm arg_cong2[of _ _ _ _ "op ="]},*)
       
   801     (APPLY_RSP_TAC rty ctxt THEN' (RANGE [quotient_tac quot_thm, quotient_tac quot_thm])),
   816     (APPLY_RSP_TAC rty ctxt THEN' (RANGE [quotient_tac quot_thm, quotient_tac quot_thm])),
   802     Cong_Tac.cong_tac @{thm cong},
   817     Cong_Tac.cong_tac @{thm cong},
   803     rtac @{thm ext},
   818     rtac @{thm ext},
   804     rtac reflex_thm,
   819     rtac reflex_thm,
   805     atac,
   820     atac,
   806     (
   821     SOLVES' (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps})),
   807      (simp_tac (HOL_ss addsimps @{thms FUN_REL.simps}))
       
   808      THEN_ALL_NEW (fn _ => no_tac)
       
   809     ),
       
   810     WEAK_LAMBDA_RES_TAC ctxt,
   822     WEAK_LAMBDA_RES_TAC ctxt,
   811     (fn i => CHANGED (asm_full_simp_tac (HOL_ss addsimps @{thms FUN_REL_EQ}) i))
   823     CHANGED' (asm_full_simp_tac (HOL_ss addsimps @{thms FUN_REL_EQ}))
   812     ])
   824     ])
   813 *}
   825 *}
   814 
   826 
   815 ML {*
   827 ML {*
   816 fun repabs lthy thm consts rty qty quot_thm reflex_thm trans_thm rsp_thms =
   828 fun repabs lthy thm consts rty qty quot_thm reflex_thm trans_thm rsp_thms =
   826 *}
   838 *}
   827 
   839 
   828 section {* Cleaning the goal *}
   840 section {* Cleaning the goal *}
   829 
   841 
   830 lemma prod_fun_id: "prod_fun id id = id"
   842 lemma prod_fun_id: "prod_fun id id = id"
   831   apply (simp add: prod_fun_def)
   843 by (simp add: prod_fun_def)
   832 done
   844 
   833 lemma map_id: "map id x = x"
   845 lemma map_id: "map id x = x"
   834   apply (induct x)
   846 by (induct x) (simp_all)
   835   apply (simp_all add: map.simps)
       
   836 done
       
   837 
   847 
   838 ML {*
   848 ML {*
   839 fun simp_ids lthy thm =
   849 fun simp_ids lthy thm =
   840   thm
   850   thm
   841   |> MetaSimplifier.rewrite_rule @{thms id_def_sym}
   851   |> MetaSimplifier.rewrite_rule @{thms id_def_sym}
   864   in
   874   in
   865     map Thm.varifyT defs_all
   875     map Thm.varifyT defs_all
   866   end
   876   end
   867 *}
   877 *}
   868 
   878 
       
   879 (* TODO: Check if it behaves properly with varifyed rty *)
   869 ML {*
   880 ML {*
   870 fun findabs_all rty tm =
   881 fun findabs_all rty tm =
   871   case tm of
   882   case tm of
   872     Abs(_, T, b) =>
   883     Abs(_, T, b) =>
   873       let
   884       let
   879   | f $ a => (findabs_all rty f) @ (findabs_all rty a)
   890   | f $ a => (findabs_all rty f) @ (findabs_all rty a)
   880   | _ => [];
   891   | _ => [];
   881 fun findabs rty tm = distinct (op =) (findabs_all rty tm)
   892 fun findabs rty tm = distinct (op =) (findabs_all rty tm)
   882 *}
   893 *}
   883 
   894 
   884 
       
   885 ML {*
   895 ML {*
   886 fun findaps_all rty tm =
   896 fun findaps_all rty tm =
   887   case tm of
   897   case tm of
   888     Abs(_, T, b) =>
   898     Abs(_, T, b) =>
   889       findaps_all rty (subst_bound ((Free ("x", T)), b))
   899       findaps_all rty (subst_bound ((Free ("x", T)), b))
   892       (if needs_lift rty T then [T] else [])
   902       (if needs_lift rty T then [T] else [])
   893   | _ => [];
   903   | _ => [];
   894 fun findaps rty tm = distinct (op =) (findaps_all rty tm)
   904 fun findaps rty tm = distinct (op =) (findaps_all rty tm)
   895 *}
   905 *}
   896 
   906 
       
   907 (* Currently useful only for LAMBDA_PRS *)
   897 ML {*
   908 ML {*
   898 fun make_simp_prs_thm lthy quot_thm thm typ =
   909 fun make_simp_prs_thm lthy quot_thm thm typ =
   899   let
   910   let
   900     val (_, [lty, rty]) = dest_Type typ;
   911     val (_, [lty, rty]) = dest_Type typ;
   901     val thy = ProofContext.theory_of lthy;
   912     val thy = ProofContext.theory_of lthy;
   934         val (a1, e1) = findallex_all rty qty f;
   945         val (a1, e1) = findallex_all rty qty f;
   935         val (a2, e2) = findallex_all rty qty a;
   946         val (a2, e2) = findallex_all rty qty a;
   936       in (a1 @ a2, e1 @ e2) end
   947       in (a1 @ a2, e1 @ e2) end
   937   | _ => ([], []);
   948   | _ => ([], []);
   938 *}
   949 *}
       
   950 
   939 ML {*
   951 ML {*
   940 fun findallex lthy rty qty tm =
   952 fun findallex lthy rty qty tm =
   941   let
   953   let
   942     val (a, e) = findallex_all rty qty tm;
   954     val (a, e) = findallex_all rty qty tm;
   943     val (ad, ed) = (map domain_type a, map domain_type e);
   955     val (ad, ed) = (map domain_type a, map domain_type e);
  1003     singleton (ProofContext.export lthy' lthy) t_id
  1015     singleton (ProofContext.export lthy' lthy) t_id
  1004   end
  1016   end
  1005 *}
  1017 *}
  1006 
  1018 
  1007 ML {*
  1019 ML {*
  1008 fun matches (ty1, ty2) =
       
  1009   Type.raw_instance (ty1, Logic.varifyT ty2);
       
  1010 
       
  1011 fun lookup_quot_data lthy qty =
  1020 fun lookup_quot_data lthy qty =
  1012   let
  1021   let
       
  1022     fun matches (ty1, ty2) =
       
  1023       Type.raw_instance (ty1, Logic.varifyT ty2);
  1013     val SOME quotdata = find_first (fn x => matches ((#qtyp x), qty)) (quotdata_lookup lthy)
  1024     val SOME quotdata = find_first (fn x => matches ((#qtyp x), qty)) (quotdata_lookup lthy)
       
  1025     (* TODO: Should no longer be needed *)
  1014     val rty = Logic.unvarifyT (#rtyp quotdata)
  1026     val rty = Logic.unvarifyT (#rtyp quotdata)
  1015     val rel = #rel quotdata
  1027     val rel = #rel quotdata
  1016     val rel_eqv = #equiv_thm quotdata
  1028     val rel_eqv = #equiv_thm quotdata
  1017     val rel_refl_pre = @{thm EQUIV_REFL} OF [rel_eqv]
  1029     val rel_refl_pre = @{thm EQUIV_REFL} OF [rel_eqv]
  1018     val rel_refl = @{thm spec} OF [MetaSimplifier.rewrite_rule [@{thm REFL_def}] rel_refl_pre]
  1030     val rel_refl = @{thm spec} OF [MetaSimplifier.rewrite_rule [@{thm REFL_def}] rel_refl_pre]