QuotMain.thy
changeset 46 e801b929216b
parent 45 d98224cafb86
child 47 6a51704204e5
equal deleted inserted replaced
45:d98224cafb86 46:e801b929216b
    75 apply(subst thm11[symmetric])
    75 apply(subst thm11[symmetric])
    76 apply(simp add: equiv[simplified EQUIV_def])
    76 apply(simp add: equiv[simplified EQUIV_def])
    77 done
    77 done
    78 
    78 
    79 lemma R_trans:
    79 lemma R_trans:
    80   assumes ab: "R a b"
    80   assumes ab: "R a b" 
    81   and     bc: "R b c"
    81   and     bc: "R b c" 
    82   shows "R a c"
    82   shows "R a c"
    83 proof -
    83 proof -
    84   have tr: "TRANS R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp
    84   have tr: "TRANS R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp
    85   moreover have ab: "R a b" by fact
    85   moreover have ab: "R a b" by fact
    86   moreover have bc: "R b c" by fact
    86   moreover have bc: "R b c" by fact
    87   ultimately show "R a c" unfolding TRANS_def by blast
    87   ultimately show "R a c" unfolding TRANS_def by blast
    88 qed
    88 qed
    89 
    89 
    90 lemma R_sym:
    90 lemma R_sym:
    91   assumes ab: "R a b"
    91   assumes ab: "R a b" 
    92   shows "R b a"
    92   shows "R b a"
    93 proof -
    93 proof -
    94   have re: "SYM R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp
    94   have re: "SYM R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp
    95   then show "R b a" using ab unfolding SYM_def by blast
    95   then show "R b a" using ab unfolding SYM_def by blast
    96 qed
    96 qed
    97 
    97 
    98 lemma R_trans2:
    98 lemma R_trans2: 
    99   assumes ac: "R a c"
    99   assumes ac: "R a c" 
   100   and     bd: "R b d"
   100   and     bd: "R b d"
   101   shows "R a b = R c d"
   101   shows "R a b = R c d"
   102 proof
   102 proof
   103   assume "R a b"
   103   assume "R a b"
   104   then have "R b a" using R_sym by blast
   104   then have "R b a" using R_sym by blast
   149   val [x, c] = [("x", ty), ("c", ty --> @{typ bool})]
   149   val [x, c] = [("x", ty), ("c", ty --> @{typ bool})]
   150                |> Variable.variant_frees lthy [rel]
   150                |> Variable.variant_frees lthy [rel]
   151                |> map Free
   151                |> map Free
   152 in
   152 in
   153   lambda c
   153   lambda c
   154     (HOLogic.exists_const ty $
   154     (HOLogic.exists_const ty $ 
   155        lambda x (HOLogic.mk_eq (c, (rel $ x))))
   155        lambda x (HOLogic.mk_eq (c, (rel $ x))))
   156 end
   156 end
   157 
   157 
   158 
   158 
   159 (* makes the new type definitions and proves non-emptyness*)
   159 (* makes the new type definitions and proves non-emptyness*)
   160 fun typedef_make (qty_name, rel, ty) lthy =
   160 fun typedef_make (qty_name, rel, ty) lthy =
   161 let
   161 let  
   162   val typedef_tac =
   162   val typedef_tac =
   163      EVERY1 [rewrite_goal_tac @{thms mem_def},
   163      EVERY1 [rewrite_goal_tac @{thms mem_def},
   164              rtac @{thm exI},
   164              rtac @{thm exI}, 
   165              rtac @{thm exI},
   165              rtac @{thm exI}, 
   166              rtac @{thm refl}]
   166              rtac @{thm refl}]
   167 in
   167 in
   168   LocalTheory.theory_result
   168   LocalTheory.theory_result
   169     (Typedef.add_typedef false NONE
   169     (Typedef.add_typedef false NONE
   170        (qty_name, map fst (Term.add_tfreesT ty []), NoSyn)
   170        (qty_name, map fst (Term.add_tfreesT ty []), NoSyn)
   215   val typedef_quotient_thm_tac =
   215   val typedef_quotient_thm_tac =
   216     EVERY1 [K (rewrite_goals_tac [abs_def, rep_def]),
   216     EVERY1 [K (rewrite_goals_tac [abs_def, rep_def]),
   217             rtac @{thm QUOT_TYPE.QUOTIENT},
   217             rtac @{thm QUOT_TYPE.QUOTIENT},
   218             rtac quot_type_thm]
   218             rtac quot_type_thm]
   219 in
   219 in
   220   Goal.prove lthy [] [] goal
   220   Goal.prove lthy [] [] goal 
   221     (K typedef_quotient_thm_tac)
   221     (K typedef_quotient_thm_tac)
   222 end
   222 end
   223 *}
   223 *}
   224 
   224 
   225 text {* two wrappers for define and note *}
   225 text {* two wrappers for define and note *}
   322 datatype trm =
   322 datatype trm =
   323   var  "nat"
   323   var  "nat"
   324 | app  "trm" "trm"
   324 | app  "trm" "trm"
   325 | lam  "nat" "trm"
   325 | lam  "nat" "trm"
   326 
   326 
   327 axiomatization
   327 axiomatization 
   328   RR :: "trm \<Rightarrow> trm \<Rightarrow> bool"
   328   RR :: "trm \<Rightarrow> trm \<Rightarrow> bool" 
   329 where
   329 where
   330   r_eq: "EQUIV RR"
   330   r_eq: "EQUIV RR"
   331 
   331 
   332 local_setup {*
   332 local_setup {*
   333   typedef_main (@{binding "qtrm"}, @{term "RR"}, @{typ trm}, @{thm r_eq}) #> snd
   333   typedef_main (@{binding "qtrm"}, @{term "RR"}, @{typ trm}, @{thm r_eq}) #> snd
   395   (type T = typ_info Symtab.table
   395   (type T = typ_info Symtab.table
   396    val empty = Symtab.empty
   396    val empty = Symtab.empty
   397    val extend = I
   397    val extend = I
   398    fun merge _ = Symtab.merge (K true))
   398    fun merge _ = Symtab.merge (K true))
   399 in
   399 in
   400  val lookup = Symtab.lookup o Data.get
   400   val lookup = Symtab.lookup o Data.get
   401  fun update k v = Data.map (Symtab.update (k, v))
   401   fun update k v = Data.map (Symtab.update (k, v))
   402 end
   402 end
   403 *}
   403 *}
   404 
   404 
   405 (* mapfuns for some standard types *)
   405 (* mapfuns for some standard types *)
   406 setup {*
   406 setup {*
   410 *}
   410 *}
   411 
   411 
   412 ML {* lookup (Context.Proof @{context}) @{type_name list} *}
   412 ML {* lookup (Context.Proof @{context}) @{type_name list} *}
   413 
   413 
   414 ML {*
   414 ML {*
   415 datatype abs_or_rep = abs | rep
   415 datatype flag = absF | repF
   416 
   416 
   417 fun get_fun abs_or_rep rty qty lthy ty =
   417 fun get_fun flag rty qty lthy ty =
   418 let
   418 let
   419   val qty_name = Long_Name.base_name (fst (dest_Type qty))
   419   val qty_name = Long_Name.base_name (fst (dest_Type qty))
   420 
   420 
   421   fun get_fun_aux s fs_tys =
   421   fun get_fun_aux s fs_tys =
   422   let
   422   let
   429    (case (lookup (Context.Proof lthy) s) of
   429    (case (lookup (Context.Proof lthy) s) of
   430       SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty))
   430       SOME info => (list_comb (Const (#mapfun info, ftys ---> oty --> nty), fs), (oty, nty))
   431     | NONE      => raise ERROR ("no map association for type " ^ s))
   431     | NONE      => raise ERROR ("no map association for type " ^ s))
   432   end
   432   end
   433 
   433 
   434   fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty))
   434   fun get_const absF = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty))
   435     | get_const rep = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty))
   435     | get_const repF = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty))
   436 
   436 
   437   fun mk_identity ty = Abs ("x", ty, Bound 0)
   437   fun mk_identity ty = Abs ("x", ty, Bound 0)
   438 
   438 
   439 in
   439 in
   440   if ty = qty
   440   if ty = qty
   441   then (get_const abs_or_rep)
   441   then (get_const flag)
   442   else (case ty of
   442   else (case ty of
   443           TFree _ => (mk_identity ty, (ty, ty))
   443           TFree _ => (mk_identity ty, (ty, ty))
   444         | Type (_, []) => (mk_identity ty, (ty, ty))
   444         | Type (_, []) => (mk_identity ty, (ty, ty))
   445         | Type (s, tys) => get_fun_aux s (map (get_fun abs_or_rep rty qty lthy) tys)
   445         | Type (s, tys) => get_fun_aux s (map (get_fun flag rty qty lthy) tys)
   446         | _ => raise ERROR ("no type variables")
   446         | _ => raise ERROR ("no type variables")
   447        )
   447        )
   448 end
   448 end
   449 *}
   449 *}
   450 
   450 
   451 ML {*
   451 ML {*
   452   get_fun rep @{typ t} @{typ qt} @{context} @{typ "t * nat"}
   452   get_fun repF @{typ t} @{typ qt} @{context} @{typ "t * nat"}
   453   |> fst
   453   |> fst
   454   |> Syntax.string_of_term @{context}
   454   |> Syntax.string_of_term @{context}
   455   |> writeln
   455   |> writeln
   456 *}
   456 *}
   457 
   457 
       
   458 ML {*
       
   459   get_fun absF @{typ t} @{typ qt} @{context} @{typ "t * nat"}
       
   460   |> fst
       
   461   |> Syntax.string_of_term @{context}
       
   462   |> writeln
       
   463 *}
   458 
   464 
   459 text {* produces the definition for a lifted constant *}
   465 text {* produces the definition for a lifted constant *}
   460 ML {*
   466 ML {*
   461 fun get_const_def nconst oconst rty qty lthy =
   467 fun get_const_def nconst oconst rty qty lthy =
   462 let
   468 let
   465 
   471 
   466   val fresh_args = arg_tys |> map (pair "x")
   472   val fresh_args = arg_tys |> map (pair "x")
   467                            |> Variable.variant_frees lthy [nconst, oconst]
   473                            |> Variable.variant_frees lthy [nconst, oconst]
   468                            |> map Free
   474                            |> map Free
   469 
   475 
   470   val rep_fns = map (fst o get_fun rep rty qty lthy) arg_tys
   476   val rep_fns = map (fst o get_fun repF rty qty lthy) arg_tys
   471   val abs_fn  = (fst o get_fun abs rty qty lthy) res_ty
   477   val abs_fn  = (fst o get_fun absF rty qty lthy) res_ty
   472 
   478 
   473 in
   479 in
   474   map (op $) (rep_fns ~~ fresh_args)
   480   map (op $) (rep_fns ~~ fresh_args)
   475   |> curry list_comb oconst
   481   |> curry list_comb oconst
   476   |> curry (op $) abs_fn
   482   |> curry (op $) abs_fn
   478 end
   484 end
   479 *}
   485 *}
   480 
   486 
   481 ML {*
   487 ML {*
   482 fun exchange_ty rty qty ty =
   488 fun exchange_ty rty qty ty =
   483   if ty = rty
   489   if ty = rty 
   484   then qty
   490   then qty
   485   else
   491   else
   486     (case ty of
   492     (case ty of
   487        Type (s, tys) => Type (s, map (exchange_ty rty qty) tys)
   493        Type (s, tys) => Type (s, map (exchange_ty rty qty) tys)
   488       | _ => ty
   494       | _ => ty
   557 | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs"
   563 | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs"
   558 | "a#a#xs \<approx> a#xs"
   564 | "a#a#xs \<approx> a#xs"
   559 | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys"
   565 | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys"
   560 | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3"
   566 | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3"
   561 
   567 
   562 lemma list_eq_refl:
   568 lemma list_eq_sym:
   563   shows "xs \<approx> xs"
   569   shows "xs \<approx> xs"
   564   apply (induct xs)
   570   apply (induct xs)
   565    apply (auto intro: list_eq.intros)
   571    apply (auto intro: list_eq.intros)
   566   done
   572   done
   567 
   573 
   568 lemma equiv_list_eq:
   574 lemma equiv_list_eq:
   569   shows "EQUIV list_eq"
   575   shows "EQUIV list_eq"
   570   unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def
   576   unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def
   571   apply(auto intro: list_eq.intros list_eq_refl)
   577   apply(auto intro: list_eq.intros list_eq_sym)
   572   done
   578   done
   573 
   579 
   574 local_setup {*
   580 local_setup {*
   575   typedef_main (@{binding "fset"}, @{term "list_eq"}, @{typ "'a list"}, @{thm "equiv_list_eq"}) #> snd
   581   typedef_main (@{binding "fset"}, @{term "list_eq"}, @{typ "'a list"}, @{thm "equiv_list_eq"}) #> snd
   576 *}
   582 *}
   672 lemma mem_cons:
   678 lemma mem_cons:
   673   fixes x :: "'a"
   679   fixes x :: "'a"
   674   fixes xs :: "'a list"
   680   fixes xs :: "'a list"
   675   assumes a : "x memb xs"
   681   assumes a : "x memb xs"
   676   shows "x # xs \<approx> xs"
   682   shows "x # xs \<approx> xs"
   677   using a
   683   using a 
   678   apply (induct xs)
   684   apply (induct xs)
   679   apply (auto intro: list_eq.intros)
   685   apply (auto intro: list_eq.intros)
   680   done
   686   done
   681 
   687 
   682 lemma card1_suc:
   688 lemma card1_suc:
   683   fixes xs :: "'a list"
   689   fixes xs :: "'a list"
   684   fixes n :: "nat"
   690   fixes n :: "nat"
   685   assumes c: "card1 xs = Suc n"
   691   assumes c: "card1 xs = Suc n"
   686   shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)"
   692   shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)"
   687   using c
   693   using c 
   688 apply(induct xs)
   694 apply(induct xs)
   689 apply (metis Suc_neq_Zero card1_0)
   695 apply (metis Suc_neq_Zero card1_0)
   690 apply (metis QUOT_TYPE_I_fset.R_trans QuotMain.card1_cons list_eq_refl mem_cons)
   696 apply (metis QUOT_TYPE_I_fset.R_trans QuotMain.card1_cons list_eq_sym mem_cons)
   691 done
   697 done
   692 
   698 
   693 lemma cons_preserves:
   699 lemma cons_preserves:
   694   fixes z
   700   fixes z
   695   assumes a: "xs \<approx> ys"
   701   assumes a: "xs \<approx> ys"
   696   shows "(z # xs) \<approx> (z # ys)"
   702   shows "(z # xs) \<approx> (z # ys)"
   697   using a by (rule QuotMain.list_eq.intros(5))
   703   using a by (rule QuotMain.list_eq.intros(5))
   698 
   704 
   699 
   705 
   700 text {*
   706 text {*
   701   Unlam_def converts a definition given as
   707   Unlam_def converts a definition given as 
   702 
   708 
   703     c \<equiv> %x. %y. f x y
   709     c \<equiv> %x. %y. f x y
   704 
   710 
   705   to a theorem of the form
   711   to a theorem of the form 
   706 
   712    
   707     c x y \<equiv> f x y
   713     c x y \<equiv> f x y 
   708 
   714 
   709   This function is needed to rewrite the right-hand
   715   This function is needed to rewrite the right-hand
   710   side to the left-hand side.
   716   side to the left-hand side.
   711 *}
   717 *}
   712 
   718 
   765 apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong)
   771 apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong)
   766 apply(rule mem_respects)
   772 apply(rule mem_respects)
   767 apply(rule list_eq.intros(3))
   773 apply(rule list_eq.intros(3))
   768 apply(unfold REP_fset_def ABS_fset_def)
   774 apply(unfold REP_fset_def ABS_fset_def)
   769 apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset])
   775 apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset])
   770 apply(rule list_eq_refl)
   776 apply(rule list_eq_sym)
   771 done
   777 done
   772 
   778 
   773 lemma append_respects_fst:
   779 lemma append_respects_fst:
   774   assumes a : "list_eq l1 l2"
   780   assumes a : "list_eq l1 l2"
   775   shows "list_eq (l1 @ s) (l2 @ s)"
   781   shows "list_eq (l1 @ s) (l2 @ s)"
   776   using a
   782   using a
   777   apply(induct)
   783   apply(induct)
   778   apply(auto intro: list_eq.intros)
   784   apply(auto intro: list_eq.intros)
   779   apply(simp add: list_eq_refl)
   785   apply(simp add: list_eq_sym)
   780 done
   786 done
   781 
   787 
   782 lemma yyy:
   788 lemma yyy:
   783   shows "
   789   shows "
   784     (
   790     (
   792   apply(rule_tac f="(op &)" in arg_cong2)
   798   apply(rule_tac f="(op &)" in arg_cong2)
   793   apply(rule_tac f="(op =)" in arg_cong2)
   799   apply(rule_tac f="(op =)" in arg_cong2)
   794   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
   800   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
   795   apply(rule append_respects_fst)
   801   apply(rule append_respects_fst)
   796   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
   802   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
   797   apply(rule list_eq_refl)
   803   apply(rule list_eq_sym)
   798   apply(simp)
   804   apply(simp)
   799   apply(rule_tac f="(op =)" in arg_cong2)
   805   apply(rule_tac f="(op =)" in arg_cong2)
   800   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
   806   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
   801   apply(rule append_respects_fst)
   807   apply(rule append_respects_fst)
   802   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
   808   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
   803   apply(rule list_eq_refl)
   809   apply(rule list_eq_sym)
   804   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
   810   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
   805   apply(rule list_eq.intros(5))
   811   apply(rule list_eq.intros(5))
   806   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
   812   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
   807   apply(rule list_eq_refl)
   813   apply(rule list_eq_sym)
   808 done
   814 done
   809 
   815 
   810 lemma
   816 lemma
   811   shows "
   817   shows "
   812      (UNION EMPTY s = s) &
   818      (UNION EMPTY s = s) &
   815   apply (simp add: QUOT_TYPE_I_fset.thm10)
   821   apply (simp add: QUOT_TYPE_I_fset.thm10)
   816   done
   822   done
   817 
   823 
   818 ML {*
   824 ML {*
   819   fun mk_rep_abs x = @{term REP_fset} $ (@{term ABS_fset} $ x)
   825   fun mk_rep_abs x = @{term REP_fset} $ (@{term ABS_fset} $ x)
   820   val consts = [@{const_name "Nil"}, @{const_name "append"},
   826   val consts = [@{const_name "Nil"}, @{const_name "append"}, 
   821                 @{const_name "Cons"}, @{const_name "membship"},
   827                 @{const_name "Cons"}, @{const_name "membship"}, 
   822                 @{const_name "card1"}]
   828                 @{const_name "card1"}]
   823 *}
   829 *}
   824 
   830 
   825 ML {*
   831 ML {*
   826 fun build_goal ctxt thm constructors lifted_type mk_rep_abs =
   832 fun build_goal ctxt thm constructors qty mk_rep_abs =
   827   let
   833 let
   828     fun is_constructor (Const (x, _)) = member (op =) constructors x
   834     fun is_const (Const (x, t)) = x mem constructors
   829       | is_constructor _ = false;
   835       | is_const _ = false
   830 
   836   
   831     fun maybe_mk_rep_abs t =
   837     fun maybe_mk_rep_abs t =
   832       let
   838     let
   833         val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t)
   839       val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t)
   834       in
   840     in
   835         if type_of t = lifted_type then mk_rep_abs t else t
   841       if type_of t = qty then mk_rep_abs t else t
   836       end;
   842     end
   837 
   843     handle TYPE _ => t
   838     fun build_aux ctxt1 tm =
   844   
   839       let
   845     fun build_aux (Abs (s, t, tr)) = (Abs (s, t, build_aux tr))
   840         val (head, args) = Term.strip_comb tm;
   846       | build_aux (f $ a) =
   841         val args' = map (build_aux ctxt1) args;
       
   842       in
       
   843         (case head of
       
   844           Abs (x, T, t) =>
       
   845             let
       
   846               val ([x'], ctxt2) = Variable.variant_fixes [x] ctxt1;
       
   847               val v = Free (x', T);
       
   848               val t' = subst_bound (v, t);
       
   849               val rec_term = build_aux ctxt2 t';
       
   850             in Term.lambda_name (x, v) rec_term end
       
   851         | _ =>
       
   852             if is_constructor head then
       
   853               maybe_mk_rep_abs (list_comb (head, map maybe_mk_rep_abs args'))
       
   854             else list_comb (head, args'))
       
   855       end;
       
   856 
       
   857     val concl2 = Thm.prop_of thm;
       
   858   in
       
   859     Logic.mk_equals (build_aux ctxt concl2, concl2)
       
   860   end
       
   861 *}
       
   862 
       
   863 ML {*
       
   864 fun build_goal' ctxt thm constructors lifted_type mk_rep_abs =
       
   865   let
       
   866     fun is_const (Const (x, t)) = member (op =) constructors x
       
   867       | is_const _ = false
       
   868 
       
   869     fun maybe_mk_rep_abs t =
       
   870       let
       
   871         val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t)
       
   872       in
       
   873         if type_of t = lifted_type then mk_rep_abs t else t
       
   874       end
       
   875 (*      handle TYPE _ => t*)
       
   876     fun build_aux ctxt1 (Abs (x, T, t)) =
       
   877           let
       
   878             val ([x'], ctxt2) = Variable.variant_fixes [x] ctxt1;
       
   879             val v = Free (x', T);
       
   880             val t' = subst_bound (v, t);
       
   881             val rec_term = build_aux ctxt2 t';
       
   882           in Term.lambda_name (x, v) rec_term end
       
   883       | build_aux ctxt1 (f $ a) =
       
   884           let
   847           let
   885             val (f, args) = strip_comb (f $ a)
   848             val (f, args) = strip_comb (f $ a)
   886             val _ = writeln (Syntax.string_of_term ctxt f)
   849             val _ = writeln (Syntax.string_of_term ctxt f)
   887            in
   850            in
   888             if is_const f then
   851             (if is_const f then maybe_mk_rep_abs (list_comb (f, (map maybe_mk_rep_abs (map build_aux args))))
   889               maybe_mk_rep_abs
   852             else list_comb ((build_aux f), (map build_aux args)))
   890                 (list_comb (f, map maybe_mk_rep_abs (map (build_aux ctxt1) args)))
       
   891             else list_comb (build_aux ctxt1 f, map (build_aux ctxt1) args)
       
   892           end
   853           end
   893       | build_aux _ x =
   854       | build_aux x =
   894           if is_const x then maybe_mk_rep_abs x else x
   855           if is_const x then maybe_mk_rep_abs x else x
   895 
   856     
   896     val concl2 = term_of (#prop (crep_thm thm))
   857     val concl2 = prop_of thm
   897   in
   858 in
   898   Logic.mk_equals (build_aux ctxt concl2, concl2)
   859   Logic.mk_equals ((build_aux concl2), concl2)
   899 end *}
   860 end *}
   900 
   861 
       
   862 thm EMPTY_def IN_def UNION_def
       
   863 
       
   864 ML {* val emptyt = symmetric (unlam_def  @{context} @{thm EMPTY_def}) *}
       
   865 ML {* val in_t =   symmetric (unlam_def  @{context} @{thm IN_def}) *}
       
   866 ML {* val uniont = symmetric (unlam_def @{context}  @{thm UNION_def}) *}
       
   867 ML {* val cardt =  symmetric (unlam_def @{context}  @{thm card_def}) *}
       
   868 ML {* val insertt =  symmetric (unlam_def @{context} @{thm INSERT_def}) *}
   901 ML {* val fset_defs = @{thms EMPTY_def IN_def UNION_def card_def INSERT_def} *}
   869 ML {* val fset_defs = @{thms EMPTY_def IN_def UNION_def card_def INSERT_def} *}
   902 ML {* val fset_defs_sym = map (fn t => symmetric (unlam_def @{context} t)) fset_defs *}
   870 ML {* val fset_defs_sym = [emptyt, in_t, uniont, cardt, insertt] *}
   903 
   871 
   904 ML {*
   872 ML {*
   905   fun dest_cbinop t =
   873   fun dest_cbinop t =
   906     let
   874     let
   907       val (t2, rhs) = Thm.dest_comb t;
   875       val (t2, rhs) = Thm.dest_comb t;
   913 
   881 
   914 ML {*
   882 ML {*
   915   fun dest_ceq t =
   883   fun dest_ceq t =
   916     let
   884     let
   917       val (bop, pair) = dest_cbinop t;
   885       val (bop, pair) = dest_cbinop t;
   918       val (bop_s, _) = Term.dest_Const (Thm.term_of bop);
   886      val (bop_s, _) = Term.dest_Const (Thm.term_of bop);
   919     in
   887     in
   920       if bop_s = "op =" then pair else (raise CTERM ("Not an equality", [t]))
   888       if bop_s = "op =" then pair else (raise CTERM ("Not an equality", [t]))
   921     end
   889     end
   922 *}
   890 *}
   923 
   891 
   930     Drule.instantiate' [SOME cT,SOME cT,SOME @{ctyp bool}] [NONE,NONE,NONE,NONE,SOME (@{cpat "op ="})] @{thm arg_cong2}
   898     Drule.instantiate' [SOME cT,SOME cT,SOME @{ctyp bool}] [NONE,NONE,NONE,NONE,SOME (@{cpat "op ="})] @{thm arg_cong2}
   931   )
   899   )
   932 *}
   900 *}
   933 
   901 
   934 ML {*
   902 ML {*
   935   fun split_binop_conv t =
   903   fun foo_conv t =
   936     let
   904     let
   937       val (lhs, rhs) = dest_ceq t;
   905       val (lhs, rhs) = dest_ceq t;
   938       val (bop, _) = dest_cbinop lhs;
   906       val (bop, _) = dest_cbinop lhs;
   939       val [clT, cr2] = bop |> Thm.ctyp_of_term |> Thm.dest_ctyp;
   907       val [clT, cr2] = bop |> Thm.ctyp_of_term |> Thm.dest_ctyp;
   940       val [cmT, crT] = Thm.dest_ctyp cr2;
   908       val [cmT, crT] = Thm.dest_ctyp cr2;
   941     in
   909     in
   942       Drule.instantiate' [SOME clT, SOME cmT, SOME crT] [NONE, NONE, NONE, NONE, SOME bop] @{thm arg_cong2}
   910       Drule.instantiate' [SOME clT,SOME cmT,SOME crT] [NONE,NONE,NONE,NONE,SOME bop] @{thm arg_cong2}
   943     end
   911     end
   944 *}
   912 *}
   945 
   913 
   946 ML {*
   914 ML {*
   947   fun split_arg_conv t =
   915   fun foo_tac n thm =
   948     let
       
   949       val (lhs, rhs) = dest_ceq t;
       
   950       val (lop, larg) = Thm.dest_comb lhs;
       
   951       val [caT, crT] = lop |> Thm.ctyp_of_term |> Thm.dest_ctyp;
       
   952     in
       
   953       Drule.instantiate' [SOME caT, SOME crT] [NONE, NONE, SOME lop] @{thm arg_cong}
       
   954     end
       
   955 *}
       
   956 
       
   957 ML {*
       
   958   fun split_binop_tac n thm =
       
   959     let
   916     let
   960       val concl = Thm.cprem_of thm n;
   917       val concl = Thm.cprem_of thm n;
   961       val (_, cconcl) = Thm.dest_comb concl;
   918       val (_, cconcl) = Thm.dest_comb concl;
   962       val rewr = split_binop_conv cconcl;
   919       val rewr = foo_conv cconcl;
       
   920 (*      val _ = tracing (Display.string_of_thm @{context} rewr)
       
   921       val _ = tracing (Display.string_of_thm @{context} thm)*)
   963     in
   922     in
   964       rtac rewr n thm
   923       rtac rewr n thm
   965     end
   924     end
   966       handle CTERM _ => Seq.empty
   925       handle CTERM _ => Seq.empty
   967 *}
   926 *}
   968 
   927 
   969 ML {*
       
   970   fun split_arg_tac n thm =
       
   971     let
       
   972       val concl = Thm.cprem_of thm n;
       
   973       val (_, cconcl) = Thm.dest_comb concl;
       
   974       val rewr = split_arg_conv cconcl;
       
   975     in
       
   976       rtac rewr n thm
       
   977     end
       
   978       handle CTERM _ => Seq.empty
       
   979 *}
       
   980 
       
   981 (* Has all the theorems about fset plugged in. These should be parameters to the tactic *)
   928 (* Has all the theorems about fset plugged in. These should be parameters to the tactic *)
   982 
   929 
   983 lemma trueprop_cong:
   930 lemma trueprop_cong:
   984   shows "(a \<equiv> b) \<Longrightarrow> (Trueprop a \<equiv> Trueprop b)"
   931   shows "(a \<equiv> b) \<Longrightarrow> (Trueprop a \<equiv> Trueprop b)"
   985   by auto
   932   by auto
   986 
   933 
   987 
       
   988 thm QUOT_TYPE_I_fset.R_trans2
       
   989 ML {*
   934 ML {*
   990   fun foo_tac' ctxt =
   935   fun foo_tac' ctxt =
   991     REPEAT_ALL_NEW (FIRST' [
   936     REPEAT_ALL_NEW (FIRST' [
   992 (*      rtac @{thm trueprop_cong},*)
   937       rtac @{thm trueprop_cong},
   993       rtac @{thm list_eq_refl},
   938       rtac @{thm list_eq_sym},
   994       rtac @{thm cons_preserves},
   939       rtac @{thm cons_preserves},
   995       rtac @{thm mem_respects},
   940       rtac @{thm mem_respects},
   996       rtac @{thm card1_rsp},
       
   997       rtac @{thm QUOT_TYPE_I_fset.R_trans2},
   941       rtac @{thm QUOT_TYPE_I_fset.R_trans2},
   998       CHANGED o (simp_tac ((Simplifier.context ctxt HOL_ss) addsimps @{thms QUOT_TYPE_I_fset.REP_ABS_rsp})),
   942       CHANGED o (simp_tac ((Simplifier.context ctxt HOL_ss) addsimps @{thms QUOT_TYPE_I_fset.REP_ABS_rsp})),
   999       DatatypeAux.cong_tac,
   943       foo_tac,
  1000       rtac @{thm ext},
       
  1001       rtac @{thm eq_reflection},
       
  1002       CHANGED o (ObjectLogic.full_atomize_tac)
   944       CHANGED o (ObjectLogic.full_atomize_tac)
  1003     ])
   945     ])
  1004 *}
   946 *}
  1005 
   947 
  1006 ML {*
   948 ML {*
  1007   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1}))
   949   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm m1}))
  1008   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
   950   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1009   val cgoal = cterm_of @{theory} goal
   951   val cgoal = cterm_of @{theory} goal
  1010   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
   952   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1011 *}
   953 *}
  1012 
   954 
  1013 (*notation ( output) "prop" ("#_" [1000] 1000) *)
   955 (*notation ( output) "prop" ("#_" [1000] 1000) *)
  1014 notation ( output) "Trueprop" ("#_" [1000] 1000)
   956 notation ( output) "Trueprop" ("#_" [1000] 1000)
  1015 
       
  1016 lemma atomize_eqv [atomize]: "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)"
       
  1017   (is "?rhs \<equiv> ?lhs")
       
  1018 proof
       
  1019   assume "PROP ?lhs" then show "PROP ?rhs" by unfold
       
  1020 next
       
  1021   assume *: "PROP ?rhs"
       
  1022   have "A = B"
       
  1023   proof (cases A)
       
  1024     case True
       
  1025     with * have B by unfold
       
  1026     with `A` show ?thesis by simp
       
  1027   next
       
  1028     case False
       
  1029     with * have "~ B" by auto
       
  1030     with `~ A` show ?thesis by simp
       
  1031   qed
       
  1032   then show "PROP ?lhs" by (rule eq_reflection)
       
  1033 qed
       
  1034 
       
  1035 
   957 
  1036 prove {* (Thm.term_of cgoal2) *}
   958 prove {* (Thm.term_of cgoal2) *}
  1037   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
   959   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1038   apply (tactic {* foo_tac' @{context} 1 *})
   960   apply (tactic {* foo_tac' @{context} 1 *})
  1039   done
   961   done
  1040 
   962 
  1041 thm length_append (* Not true but worth checking that the goal is correct *)
   963 thm length_append (* Not true but worth checking that the goal is correct *)
  1042 ML {*
   964 ML {*
  1043   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm length_append}))
   965   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm length_append}))
  1044   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
   966   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1045   val cgoal = cterm_of @{theory} goal
   967   val cgoal = cterm_of @{theory} goal
  1046   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
   968   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1047 *}
   969 *}
  1048 prove {* Thm.term_of cgoal2 *}
   970 prove {* Thm.term_of cgoal2 *}
  1050   apply (tactic {* foo_tac' @{context} 1 *})
   972   apply (tactic {* foo_tac' @{context} 1 *})
  1051   sorry
   973   sorry
  1052 
   974 
  1053 thm m2
   975 thm m2
  1054 ML {*
   976 ML {*
  1055   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m2}))
   977   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm m2}))
  1056   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
   978   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1057   val cgoal = cterm_of @{theory} goal
   979   val cgoal = cterm_of @{theory} goal
  1058   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
   980   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1059 *}
   981 *}
  1060 prove {* Thm.term_of cgoal2 *}
   982 prove {* Thm.term_of cgoal2 *}
  1062   apply (tactic {* foo_tac' @{context} 1 *})
   984   apply (tactic {* foo_tac' @{context} 1 *})
  1063   done
   985   done
  1064 
   986 
  1065 thm list_eq.intros(4)
   987 thm list_eq.intros(4)
  1066 ML {*
   988 ML {*
  1067   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list_eq.intros(4)}))
   989   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm list_eq.intros(4)}))
  1068   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
   990   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1069   val cgoal = cterm_of @{theory} goal
   991   val cgoal = cterm_of @{theory} goal
  1070   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
   992   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1071   val cgoal3 = Thm.rhs_of (MetaSimplifier.rewrite true @{thms QUOT_TYPE_I_fset.thm10} cgoal2)
   993   val cgoal3 = Thm.rhs_of (MetaSimplifier.rewrite true @{thms QUOT_TYPE_I_fset.thm10} cgoal2)
  1072 *}
   994 *}
  1088   using list_eq.intros(4) by (simp only: zzz)
  1010   using list_eq.intros(4) by (simp only: zzz)
  1089 
  1011 
  1090 thm QUOT_TYPE_I_fset.REPS_same
  1012 thm QUOT_TYPE_I_fset.REPS_same
  1091 ML {* val zzz'' = MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.REPS_same} @{thm zzz'} *}
  1013 ML {* val zzz'' = MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.REPS_same} @{thm zzz'} *}
  1092 
  1014 
       
  1015 ML Drule.instantiate'
       
  1016 ML {* zzz'' *}
       
  1017 text {*
       
  1018   A variable export will still be necessary in the end, but this is already the final theorem.
       
  1019 *}
       
  1020 ML {*
       
  1021   Toplevel.program (fn () =>
       
  1022     MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.thm10} (
       
  1023       Drule.instantiate' [] [NONE,SOME (@{cpat "REP_fset x"})] zzz''
       
  1024     )
       
  1025   )
       
  1026 *}
       
  1027 
       
  1028 
  1093 thm list_eq.intros(5)
  1029 thm list_eq.intros(5)
  1094 ML {*
  1030 ML {*
  1095   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list_eq.intros(5)}))
  1031   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm list_eq.intros(5)}))
  1096   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1032   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1097 *}
  1033 *}
  1098 ML {*
  1034 ML {*
  1099   val cgoal =
  1035   val cgoal = 
  1100     Toplevel.program (fn () =>
  1036     Toplevel.program (fn () =>
  1101       cterm_of @{theory} goal
  1037       cterm_of @{theory} goal
  1102     )
  1038     )
  1103 *}
  1039 *}
  1104 ML {*
  1040 ML {*
  1105   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
  1041   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1106 *}
  1042 *}
  1107 prove {* Thm.term_of cgoal2 *}
  1043 prove {* Thm.term_of cgoal2 *}
  1108   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1044   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1109   apply (tactic {* foo_tac' @{context} 1 *})
  1045   apply (tactic {* foo_tac' @{context} 1 *})
  1110   done
  1046   done
  1111 
  1047 
  1112 thm list.induct
  1048 thm list.induct
       
  1049 ML {* Logic.list_implies ((Thm.prems_of @{thm list.induct}), (Thm.concl_of @{thm list.induct})) *}
  1113 
  1050 
  1114 ML {*
  1051 ML {*
  1115   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm list.induct}))
  1052   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm list.induct}))
  1116 *}
  1053 *}
  1117 ML {*
  1054 ML {*
  1120       build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1057       build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1121     )
  1058     )
  1122 *}
  1059 *}
  1123 ML {*
  1060 ML {*
  1124   val cgoal = cterm_of @{theory} goal
  1061   val cgoal = cterm_of @{theory} goal
  1125 *}
  1062   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1126 ML {*
  1063 *}
  1127   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
  1064 ML fset_defs_sym
  1128 *}
       
  1129 
       
  1130 prove {* (Thm.term_of cgoal2) *}
  1065 prove {* (Thm.term_of cgoal2) *}
  1131   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1066   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1132   apply (tactic {* foo_tac' @{context} 1 *})
  1067   apply (atomize(full))
       
  1068   apply (rule_tac trueprop_cong)
       
  1069   apply (atomize(full))
       
  1070   apply (tactic {* foo_tac' @{context} 1 *}) 
       
  1071   apply (rule_tac f = "P" in arg_cong)
  1133   sorry
  1072   sorry
  1134 
  1073 
  1135 ML {*
       
  1136   fun lift_theorem_fset_aux thm lthy =
       
  1137     let
       
  1138       val ((_, [novars]), lthy2) = Variable.import true [thm] lthy;
       
  1139       val goal = build_goal @{context} novars consts @{typ "'a list"} mk_rep_abs;
       
  1140       val cgoal = cterm_of @{theory} goal;
       
  1141       val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal);
       
  1142       val tac = (LocalDefs.unfold_tac @{context} fset_defs) THEN (foo_tac' @{context}) 1;
       
  1143       val cthm = Goal.prove_internal [] cgoal2 (fn _ => tac);
       
  1144       val nthm = MetaSimplifier.rewrite_rule [symmetric cthm] (snd (no_vars (Context.Theory @{theory}, thm)))
       
  1145       val nthm2 = MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.REPS_same QUOT_TYPE_I_fset.thm10} nthm;
       
  1146       val [nthm3] = ProofContext.export lthy2 lthy [nthm2]
       
  1147     in
       
  1148       nthm3
       
  1149     end
       
  1150 *}
       
  1151 
       
  1152 ML {* lift_theorem_fset_aux @{thm m1} @{context} *}
       
  1153 
       
  1154 ML {*
       
  1155   fun lift_theorem_fset name thm lthy =
       
  1156     let
       
  1157       val lifted_thm = lift_theorem_fset_aux thm lthy;
       
  1158       val (_, lthy2) = note_thm (name, lifted_thm) lthy;
       
  1159     in
       
  1160       lthy2
       
  1161     end;
       
  1162 *}
       
  1163 
       
  1164 local_setup {* lift_theorem_fset @{binding "m1_lift"} @{thm m1} *}
       
  1165 local_setup {* lift_theorem_fset @{binding "leqi4_lift"} @{thm list_eq.intros(4)} *}
       
  1166 local_setup {* lift_theorem_fset @{binding "leqi5_lift"} @{thm list_eq.intros(5)} *}
       
  1167 local_setup {* lift_theorem_fset @{binding "m2_lift"} @{thm m2} *}
       
  1168 
       
  1169 thm m1_lift
       
  1170 thm leqi4_lift
       
  1171 thm leqi5_lift
       
  1172 thm m2_lift
       
  1173 
       
  1174 ML Drule.instantiate'
       
  1175 text {*
       
  1176   We lost the schematic variable again :(.
       
  1177   Another variable export will still be necessary...
       
  1178 *}
       
  1179 ML {*
       
  1180   Toplevel.program (fn () =>
       
  1181     MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.thm10} (
       
  1182       Drule.instantiate' [] [NONE, NONE, SOME (@{cpat "REP_fset x"})] @{thm m2_lift}
       
  1183     )
       
  1184   )
       
  1185 *}
       
  1186 
       
  1187 thm leqi4_lift
       
  1188 ML {*
       
  1189   val (nam, typ) = (hd (Term.add_vars (term_of (#prop (crep_thm @{thm leqi4_lift}))) []))
       
  1190   val (_, l) = dest_Type typ
       
  1191   val t = Type ("QuotMain.fset", l)
       
  1192   val v = Var (nam, t)
       
  1193   val cv = cterm_of @{theory} ((term_of @{cpat "REP_fset"}) $ v)
       
  1194 *}
       
  1195 
       
  1196 ML {*
       
  1197 term_of (#prop (crep_thm @{thm sym}))
       
  1198 *}
       
  1199 
       
  1200 ML {*
       
  1201   Toplevel.program (fn () =>
       
  1202     MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.thm10} (
       
  1203       Drule.instantiate' [] [NONE, SOME (cv)] @{thm leqi4_lift}
       
  1204     )
       
  1205   )
       
  1206 *}
       
  1207 
       
  1208 
       
  1209 
       
  1210 
       
  1211 
       
  1212 ML {* MRS *}
       
  1213 thm card1_suc
  1074 thm card1_suc
  1214 
  1075 
  1215 ML {*
  1076 ML {*
  1216   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm card1_suc}))
  1077   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm card1_suc}))
  1217 *}
  1078 *}
  1218 ML {*
  1079 ML {*
  1219   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1080   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1220 *}
  1081 *}
  1221 ML {*
  1082 ML {*
  1222   val cgoal = cterm_of @{theory} goal
  1083   val cgoal = cterm_of @{theory} goal
  1223   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
  1084   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1224 *}
  1085 *}
  1225 ML {* @{term "\<exists>x. P x"} *}
       
  1226 ML {*  Thm.bicompose *}
       
  1227 prove {* (Thm.term_of cgoal2) *}
  1086 prove {* (Thm.term_of cgoal2) *}
  1228   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1087   apply (tactic {* LocalDefs.unfold_tac @{context} fset_defs *} )
  1229   apply (tactic {* foo_tac' @{context} 1 *})
  1088 
  1230 
  1089 
  1231 
  1090 
  1232 (*
  1091 (*
  1233 datatype obj1 =
  1092 datatype obj1 =
  1234   OVAR1 "string"
  1093   OVAR1 "string"