QuotMain.thy
changeset 44 f078dbf557b7
parent 43 e51af8bace65
parent 41 72d63aa8af68
child 45 d98224cafb86
equal deleted inserted replaced
43:e51af8bace65 44:f078dbf557b7
   113   then show "R a b" using R_sym by blast
   113   then show "R a b" using R_sym by blast
   114 qed
   114 qed
   115 
   115 
   116 lemma REPS_same:
   116 lemma REPS_same:
   117   shows "R (REP a) (REP b) \<equiv> (a = b)"
   117   shows "R (REP a) (REP b) \<equiv> (a = b)"
   118   apply (rule eq_reflection)
   118 proof -
   119 proof
   119   have "R (REP a) (REP b) = (a = b)"
   120   assume as: "R (REP a) (REP b)"
   120   proof
   121   from rep_prop
   121     assume as: "R (REP a) (REP b)"
   122   obtain x y
   122     from rep_prop
   123     where eqs: "Rep a = R x" "Rep b = R y" by blast
   123     obtain x y
   124   from eqs have "R (Eps (R x)) (Eps (R y))" using as unfolding REP_def by simp
   124       where eqs: "Rep a = R x" "Rep b = R y" by blast
   125   then have "R x (Eps (R y))" using lem9 by simp
   125     from eqs have "R (Eps (R x)) (Eps (R y))" using as unfolding REP_def by simp
   126   then have "R (Eps (R y)) x" using R_sym by blast
   126     then have "R x (Eps (R y))" using lem9 by simp
   127   then have "R y x" using lem9 by simp
   127     then have "R (Eps (R y)) x" using R_sym by blast
   128   then have "R x y" using R_sym by blast
   128     then have "R y x" using lem9 by simp
   129   then have "ABS x = ABS y" using thm11 by simp
   129     then have "R x y" using R_sym by blast
   130   then have "Abs (Rep a) = Abs (Rep b)" using eqs unfolding ABS_def by simp
   130     then have "ABS x = ABS y" using thm11 by simp
   131   then show "a = b" using rep_inverse by simp
   131     then have "Abs (Rep a) = Abs (Rep b)" using eqs unfolding ABS_def by simp
   132 next
   132     then show "a = b" using rep_inverse by simp
   133   assume ab: "a = b"
   133   next
   134   have "REFL R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp
   134     assume ab: "a = b"
   135   then show "R (REP a) (REP b)" unfolding REFL_def using ab by auto
   135     have "REFL R" using equiv EQUIV_REFL_SYM_TRANS[of R] by simp
       
   136     then show "R (REP a) (REP b)" unfolding REFL_def using ab by auto
       
   137   qed
       
   138   then show "R (REP a) (REP b) \<equiv> (a = b)" by simp
   136 qed
   139 qed
   137 
   140 
   138 end
   141 end
   139 
   142 
   140 section {* type definition for the quotient type *}
   143 section {* type definition for the quotient type *}
   146   val [x, c] = [("x", ty), ("c", ty --> @{typ bool})]
   149   val [x, c] = [("x", ty), ("c", ty --> @{typ bool})]
   147                |> Variable.variant_frees lthy [rel]
   150                |> Variable.variant_frees lthy [rel]
   148                |> map Free
   151                |> map Free
   149 in
   152 in
   150   lambda c
   153   lambda c
   151     (HOLogic.mk_exists
   154     (HOLogic.exists_const ty $ 
   152        ("x", ty, HOLogic.mk_eq (c, (rel $ x))))
   155        lambda x (HOLogic.mk_eq (c, (rel $ x))))
   153 end
   156 end
   154 *}
   157 
   155 
   158 
   156 ML {*
       
   157 (* makes the new type definitions and proves non-emptyness*)
   159 (* makes the new type definitions and proves non-emptyness*)
   158 fun typedef_make (qty_name, rel, ty) lthy =
   160 fun typedef_make (qty_name, rel, ty) lthy =
   159 let
   161 let  
   160   val typedef_tac =
   162   val typedef_tac =
   161      EVERY1 [rewrite_goal_tac @{thms mem_def},
   163      EVERY1 [rewrite_goal_tac @{thms mem_def},
   162              rtac @{thm exI},
   164              rtac @{thm exI}, 
   163              rtac @{thm exI},
   165              rtac @{thm exI}, 
   164              rtac @{thm refl}]
   166              rtac @{thm refl}]
   165 in
   167 in
   166   LocalTheory.theory_result
   168   LocalTheory.theory_result
   167     (Typedef.add_typedef false NONE
   169     (Typedef.add_typedef false NONE
   168        (qty_name, map fst (Term.add_tfreesT ty []), NoSyn)
   170        (qty_name, map fst (Term.add_tfreesT ty []), NoSyn)
   169          (typedef_term rel ty lthy)
   171          (typedef_term rel ty lthy)
   170            NONE typedef_tac) lthy
   172            NONE typedef_tac) lthy
   171 end
   173 end
   172 *}
   174 
   173 
   175 
   174 ML {*
   176 (* tactic to prove the QUOT_TYPE theorem for the new type *)
   175 (* proves the QUOT_TYPE theorem for the new type *)
       
   176 fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) =
   177 fun typedef_quot_type_tac equiv_thm (typedef_info: Typedef.info) =
   177 let
   178 let
   178   val rep_thm = #Rep typedef_info
   179   val rep_thm = #Rep typedef_info
   179   val rep_inv = #Rep_inverse typedef_info
   180   val rep_inv = #Rep_inverse typedef_info
   180   val abs_inv = #Abs_inverse typedef_info
   181   val abs_inv = #Abs_inverse typedef_info
   190           rtac rep_inv,
   191           rtac rep_inv,
   191           rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl},
   192           rtac abs_inv_simpd, rtac @{thm exI}, rtac @{thm refl},
   192           rtac rep_inj]
   193           rtac rep_inj]
   193 end
   194 end
   194 
   195 
       
   196 
   195 fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy =
   197 fun typedef_quot_type_thm (rel, abs, rep, equiv_thm, typedef_info) lthy =
   196 let
   198 let
   197   val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT)
   199   val quot_type_const = Const (@{const_name "QUOT_TYPE"}, dummyT)
   198   val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep)
   200   val goal = HOLogic.mk_Trueprop (quot_type_const $ rel $ abs $ rep)
   199              |> Syntax.check_term lthy
   201              |> Syntax.check_term lthy
   200 in
   202 in
   201   Goal.prove lthy [] [] goal
   203   Goal.prove lthy [] [] goal
   202     (K (typedef_quot_type_tac equiv_thm typedef_info))
   204     (K (typedef_quot_type_tac equiv_thm typedef_info))
   203 end
   205 end
   204 *}
   206 
   205 
   207 
   206 ML {*
   208 (* proves the quotient theorem *)
   207 fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy =
   209 fun typedef_quotient_thm (rel, abs, rep, abs_def, rep_def, quot_type_thm) lthy =
   208 let
   210 let
   209   val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT)
   211   val quotient_const = Const (@{const_name "QUOTIENT"}, dummyT)
   210   val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep)
   212   val goal = HOLogic.mk_Trueprop (quotient_const $ rel $ abs $ rep)
   211              |> Syntax.check_term lthy
   213              |> Syntax.check_term lthy
   213   val typedef_quotient_thm_tac =
   215   val typedef_quotient_thm_tac =
   214     EVERY1 [K (rewrite_goals_tac [abs_def, rep_def]),
   216     EVERY1 [K (rewrite_goals_tac [abs_def, rep_def]),
   215             rtac @{thm QUOT_TYPE.QUOTIENT},
   217             rtac @{thm QUOT_TYPE.QUOTIENT},
   216             rtac quot_type_thm]
   218             rtac quot_type_thm]
   217 in
   219 in
   218   Goal.prove lthy [] [] goal
   220   Goal.prove lthy [] [] goal 
   219     (K typedef_quotient_thm_tac)
   221     (K typedef_quotient_thm_tac)
   220 end
   222 end
   221 *}
   223 *}
   222 
   224 
   223 text {* two wrappers for define and note *}
   225 text {* two wrappers for define and note *}
   320 datatype trm =
   322 datatype trm =
   321   var  "nat"
   323   var  "nat"
   322 | app  "trm" "trm"
   324 | app  "trm" "trm"
   323 | lam  "nat" "trm"
   325 | lam  "nat" "trm"
   324 
   326 
   325 axiomatization
   327 axiomatization 
   326   RR :: "trm \<Rightarrow> trm \<Rightarrow> bool"
   328   RR :: "trm \<Rightarrow> trm \<Rightarrow> bool" 
   327 where
   329 where
   328   r_eq: "EQUIV RR"
   330   r_eq: "EQUIV RR"
   329 
   331 
   330 local_setup {*
   332 local_setup {*
   331   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
   424     val nty = Type (s, ntys)
   426     val nty = Type (s, ntys)
   425     val ftys = map (op -->) tys
   427     val ftys = map (op -->) tys
   426   in
   428   in
   427    (case (lookup (Context.Proof lthy) s) of
   429    (case (lookup (Context.Proof lthy) s) of
   428       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))
   429     | NONE => raise ERROR ("no map association for type " ^ s))
   431     | NONE      => raise ERROR ("no map association for type " ^ s))
   430   end
   432   end
   431 
   433 
   432   fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty))
   434   fun get_const abs = (Const ("QuotMain.ABS_" ^ qty_name, rty --> qty), (rty, qty))
   433     | get_const rep = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty))
   435     | get_const rep = (Const ("QuotMain.REP_" ^ qty_name, qty --> rty), (qty, rty))
       
   436 
       
   437   fun mk_identity ty = Abs ("x", ty, Bound 0)
       
   438 
   434 in
   439 in
   435   if ty = qty
   440   if ty = qty
   436   then (get_const abs_or_rep)
   441   then (get_const abs_or_rep)
   437   else (case ty of
   442   else (case ty of
   438           TFree _ => (Abs ("x", ty, Bound 0), (ty, ty))
   443           TFree _ => (mk_identity ty, (ty, ty))
   439         | Type (_, []) => (Abs ("x", ty, Bound 0), (ty, ty))
   444         | Type (_, []) => (mk_identity ty, (ty, ty))
   440         | 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 abs_or_rep rty qty lthy) tys)
   441         | _ => raise ERROR ("no variables")
   446         | _ => raise ERROR ("no type variables")
   442        )
   447        )
   443 end
   448 end
   444 *}
   449 *}
   445 
   450 
   446 ML {*
   451 ML {*
   449   |> Syntax.string_of_term @{context}
   454   |> Syntax.string_of_term @{context}
   450   |> writeln
   455   |> writeln
   451 *}
   456 *}
   452 
   457 
   453 
   458 
       
   459 text {* produces the definition for a lifted constant *}
   454 ML {*
   460 ML {*
   455 fun get_const_def nconst oconst rty qty lthy =
   461 fun get_const_def nconst oconst rty qty lthy =
   456 let
   462 let
   457   val ty = fastype_of nconst
   463   val ty = fastype_of nconst
   458   val (arg_tys, res_ty) = strip_type ty
   464   val (arg_tys, res_ty) = strip_type ty
   472 end
   478 end
   473 *}
   479 *}
   474 
   480 
   475 ML {*
   481 ML {*
   476 fun exchange_ty rty qty ty =
   482 fun exchange_ty rty qty ty =
   477   if ty = rty then qty
   483   if ty = rty 
       
   484   then qty
   478   else
   485   else
   479     (case ty of
   486     (case ty of
   480        Type (s, tys) => Type (s, map (exchange_ty rty qty) tys)
   487        Type (s, tys) => Type (s, map (exchange_ty rty qty) tys)
   481       | _ => ty)
   488       | _ => ty
       
   489     )
   482 *}
   490 *}
   483 
   491 
   484 ML {*
   492 ML {*
   485 fun make_const_def nconst_bname oconst mx rty qty lthy =
   493 fun make_const_def nconst_bname oconst mx rty qty lthy =
   486 let
   494 let
   492   make_def (nconst_bname, mx, def_trm) lthy
   500   make_def (nconst_bname, mx, def_trm) lthy
   493 end
   501 end
   494 *}
   502 *}
   495 
   503 
   496 local_setup {*
   504 local_setup {*
   497   make_const_def @{binding VR} @{term "vr"} NoSyn @{typ "t"} @{typ "qt"} #> snd
   505   make_const_def @{binding VR} @{term "vr"} NoSyn @{typ "t"} @{typ "qt"} #> snd #>
   498 *}
   506   make_const_def @{binding AP} @{term "ap"} NoSyn @{typ "t"} @{typ "qt"} #> snd #>
   499 
       
   500 local_setup {*
       
   501   make_const_def @{binding AP} @{term "ap"} NoSyn @{typ "t"} @{typ "qt"} #> snd
       
   502 *}
       
   503 
       
   504 local_setup {*
       
   505   make_const_def @{binding LM} @{term "lm"} NoSyn @{typ "t"} @{typ "qt"} #> snd
   507   make_const_def @{binding LM} @{term "lm"} NoSyn @{typ "t"} @{typ "qt"} #> snd
   506 *}
   508 *}
   507 
   509 
   508 thm VR_def
   510 term vr
   509 thm AP_def
   511 term ap
   510 thm LM_def
   512 term lm
       
   513 thm VR_def AP_def LM_def
   511 term LM
   514 term LM
   512 term VR
   515 term VR
   513 term AP
   516 term AP
   514 
   517 
   515 
   518 
   528 *}
   531 *}
   529 
   532 
   530 print_theorems
   533 print_theorems
   531 
   534 
   532 local_setup {*
   535 local_setup {*
   533   make_const_def @{binding VR'} @{term "vr'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
   536   make_const_def @{binding VR'} @{term "vr'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd #>
   534 *}
   537   make_const_def @{binding AP'} @{term "ap'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd #>
   535 
       
   536 local_setup {*
       
   537   make_const_def @{binding AP'} @{term "ap'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
       
   538 *}
       
   539 
       
   540 local_setup {*
       
   541   make_const_def @{binding LM'} @{term "lm'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
   538   make_const_def @{binding LM'} @{term "lm'"} NoSyn @{typ "'a t'"} @{typ "'a qt'"} #> snd
   542 *}
   539 *}
   543 
   540 
   544 thm VR'_def
   541 term vr'
   545 thm AP'_def
   542 term ap'
   546 thm LM'_def
   543 term ap'
       
   544 thm VR'_def AP'_def LM'_def
   547 term LM'
   545 term LM'
   548 term VR'
   546 term VR'
   549 term AP'
   547 term AP'
   550 
   548 
   551 
   549 
   642 
   640 
   643 (* text {*
   641 (* text {*
   644  Maybe make_const_def should require a theorem that says that the particular lifted function
   642  Maybe make_const_def should require a theorem that says that the particular lifted function
   645  respects the relation. With it such a definition would be impossible:
   643  respects the relation. With it such a definition would be impossible:
   646  make_const_def @{binding CARD} @{term "length"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
   644  make_const_def @{binding CARD} @{term "length"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
   647 *} *)
   645 *}*)
   648 
   646 
   649 lemma card1_rsp:
   647 lemma card1_rsp:
   650   fixes a b :: "'a list"
   648   fixes a b :: "'a list"
   651   assumes e: "a \<approx> b"
   649   assumes e: "a \<approx> b"
   652   shows "card1 a = card1 b"
   650   shows "card1 a = card1 b"
   674 lemma mem_cons:
   672 lemma mem_cons:
   675   fixes x :: "'a"
   673   fixes x :: "'a"
   676   fixes xs :: "'a list"
   674   fixes xs :: "'a list"
   677   assumes a : "x memb xs"
   675   assumes a : "x memb xs"
   678   shows "x # xs \<approx> xs"
   676   shows "x # xs \<approx> xs"
   679   using a apply (induct xs)
   677   using a 
   680   apply (simp_all)
   678   apply (induct xs)
   681   apply (meson)
   679   apply (auto intro: list_eq.intros)
   682   apply (simp_all add: list_eq.intros(4))
   680   done
   683   proof -
       
   684     fix a :: "'a"
       
   685     fix xs :: "'a list"
       
   686     assume a1 : "x # xs \<approx> xs"
       
   687     assume a2 : "x memb xs"
       
   688     have a3 : "x # a # xs \<approx> a # x # xs" using list_eq.intros(1)[of "x"] by blast
       
   689     have a4 : "a # x # xs \<approx> a # xs" using a1 list_eq.intros(5)[of "x # xs" "xs"] by simp
       
   690     then show "x # a # xs \<approx> a # xs" using a3 list_eq.intros(6) by blast
       
   691   qed
       
   692 
   681 
   693 lemma card1_suc:
   682 lemma card1_suc:
   694   fixes xs :: "'a list"
   683   fixes xs :: "'a list"
   695   fixes n :: "nat"
   684   fixes n :: "nat"
   696   assumes c: "card1 xs = Suc n"
   685   assumes c: "card1 xs = Suc n"
   697   shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)"
   686   shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)"
   698   using c apply (induct xs)
   687   using c 
   699    apply (simp)
   688 apply(induct xs)
   700 (*  apply (rule allI)*)
   689 apply (metis Suc_neq_Zero card1_0)
   701   proof -
   690 apply (metis QUOT_TYPE_I_fset.R_trans QuotMain.card1_cons list_eq_sym mem_cons)
   702     fix a :: "'a"
   691 done
   703     fix xs :: "'a list"
       
   704     fix n :: "nat"
       
   705     assume a1: "card1 xs = Suc n \<Longrightarrow> \<exists>a ys. \<not> a memb ys \<and> xs \<approx> a # ys"
       
   706     assume a2: "card1 (a # xs) = Suc n"
       
   707     from a1 a2 show "\<exists>aa ys. \<not> aa memb ys \<and> a # xs \<approx> aa # ys"
       
   708     apply -
       
   709     apply (rule True_or_False [of "a memb xs", THEN disjE])
       
   710     apply (simp_all add: card1_cons if_True simp_thms)
       
   711   proof -
       
   712     assume a1: "\<exists>a ys. \<not> a memb ys \<and> xs \<approx> a # ys"
       
   713     assume a2: "card1 xs = Suc n"
       
   714     assume a3: "a memb xs"
       
   715     from a1 obtain b ys where a5: "\<not> b memb ys \<and> xs \<approx> b # ys" by blast
       
   716     from a2 a3 a5 show "\<exists>aa ys. \<not> aa memb ys \<and> a # xs \<approx> aa # ys"
       
   717     apply -
       
   718     apply (rule_tac x = "b" in exI)
       
   719     apply (rule_tac x = "ys" in exI)
       
   720     apply (simp_all)
       
   721   proof -
       
   722     assume a1: "a memb xs"
       
   723     assume a2: "\<not> b memb ys \<and> xs \<approx> b # ys"
       
   724     then have a3: "xs \<approx> b # ys" by simp
       
   725     have "a # xs \<approx> xs" using a1 mem_cons[of "a" "xs"] by simp
       
   726     then show "a # xs \<approx> b # ys" using a3 list_eq.intros(6) by blast
       
   727   qed
       
   728 next
       
   729   assume a2: "\<not> a memb xs"
       
   730   from a2 show "\<exists>aa ys. \<not> aa memb ys \<and> a # xs \<approx> aa # ys"
       
   731     apply -
       
   732     apply (rule_tac x = "a" in exI)
       
   733     apply (rule_tac x = "xs" in exI)
       
   734     apply (simp)
       
   735     apply (rule list_eq_refl)
       
   736     done
       
   737   qed
       
   738 qed
       
   739 
   692 
   740 lemma cons_preserves:
   693 lemma cons_preserves:
   741   fixes z
   694   fixes z
   742   assumes a: "xs \<approx> ys"
   695   assumes a: "xs \<approx> ys"
   743   shows "(z # xs) \<approx> (z # ys)"
   696   shows "(z # xs) \<approx> (z # ys)"
   744   using a by (rule QuotMain.list_eq.intros(5))
   697   using a by (rule QuotMain.list_eq.intros(5))
   745 
   698 
   746 
   699 
   747 text {*
   700 text {*
   748   unlam_def converts a definition theorem given as 'a = \lambda x. \lambda y. f (x y)'
   701   Unlam_def converts a definition given as 
   749   to a theorem 'a x y = f (x, y)'. These are needed to rewrite right-to-left.
   702 
       
   703     c \<equiv> %x. %y. f x y
       
   704 
       
   705   to a theorem of the form 
       
   706    
       
   707     c x y \<equiv> f x y 
       
   708 
       
   709   This function is needed to rewrite the right-hand
       
   710   side to the left-hand side.
   750 *}
   711 *}
   751 
   712 
   752 ML {*
   713 ML {*
   753 fun unlam_def_aux orig_ctxt ctxt t =
   714 fun unlam_def_aux orig_ctxt ctxt t =
   754   let val rhs = Thm.rhs_of t in
   715   let val rhs = Thm.rhs_of t in
   854   apply (simp add: QUOT_TYPE_I_fset.thm10)
   815   apply (simp add: QUOT_TYPE_I_fset.thm10)
   855   done
   816   done
   856 
   817 
   857 ML {*
   818 ML {*
   858   fun mk_rep_abs x = @{term REP_fset} $ (@{term ABS_fset} $ x)
   819   fun mk_rep_abs x = @{term REP_fset} $ (@{term ABS_fset} $ x)
   859   val consts = [@{const_name "Nil"}, @{const_name "append"}, @{const_name "Cons"}, @{const_name "membship"}, @{const_name "card1"}]
   820   val consts = [@{const_name "Nil"}, @{const_name "append"}, 
   860 *}
   821                 @{const_name "Cons"}, @{const_name "membship"}, 
   861 
   822                 @{const_name "card1"}]
   862 ML lambda
   823 *}
   863 
   824 
   864 ML {*
   825 ML {*
   865 fun build_goal ctxt thm constructors lifted_type mk_rep_abs =
   826 fun build_goal ctxt thm constructors lifted_type mk_rep_abs =
   866   let
   827   let
   867     fun is_constructor (Const (x, _)) = member (op =) constructors x
   828     fun is_constructor (Const (x, _)) = member (op =) constructors x
   902 ML {*
   863 ML {*
   903 fun build_goal' ctxt thm constructors lifted_type mk_rep_abs =
   864 fun build_goal' ctxt thm constructors lifted_type mk_rep_abs =
   904   let
   865   let
   905     fun is_const (Const (x, t)) = member (op =) constructors x
   866     fun is_const (Const (x, t)) = member (op =) constructors x
   906       | is_const _ = false
   867       | is_const _ = false
       
   868   
   907     fun maybe_mk_rep_abs t =
   869     fun maybe_mk_rep_abs t =
   908       let
   870       let
   909         val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t)
   871         val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t)
   910       in
   872       in
   911         if type_of t = lifted_type then mk_rep_abs t else t
   873         if type_of t = lifted_type then mk_rep_abs t else t
   928                 (list_comb (f, map maybe_mk_rep_abs (map (build_aux ctxt1) args)))
   890                 (list_comb (f, map maybe_mk_rep_abs (map (build_aux ctxt1) args)))
   929             else list_comb (build_aux ctxt1 f, map (build_aux ctxt1) args)
   891             else list_comb (build_aux ctxt1 f, map (build_aux ctxt1) args)
   930           end
   892           end
   931       | build_aux _ x =
   893       | build_aux _ x =
   932           if is_const x then maybe_mk_rep_abs x else x
   894           if is_const x then maybe_mk_rep_abs x else x
       
   895     
   933     val concl2 = term_of (#prop (crep_thm thm))
   896     val concl2 = term_of (#prop (crep_thm thm))
   934   in
   897   in
   935   Logic.mk_equals (build_aux ctxt concl2, concl2)
   898   Logic.mk_equals (build_aux ctxt concl2, concl2)
   936 end *}
   899 end *}
   937 
   900 
   955       val (bop_s, _) = Term.dest_Const (Thm.term_of bop);
   918       val (bop_s, _) = Term.dest_Const (Thm.term_of bop);
   956     in
   919     in
   957       if bop_s = "op =" then pair else (raise CTERM ("Not an equality", [t]))
   920       if bop_s = "op =" then pair else (raise CTERM ("Not an equality", [t]))
   958     end
   921     end
   959 *}
   922 *}
       
   923 
   960 ML Thm.instantiate
   924 ML Thm.instantiate
   961 ML {*@{thm arg_cong2}*}
   925 ML {*@{thm arg_cong2}*}
   962 ML {*@{thm arg_cong2[of _ _ _ _ "op ="]} *}
   926 ML {*@{thm arg_cong2[of _ _ _ _ "op ="]} *}
   963 ML {* val cT = @{cpat "op ="} |> Thm.ctyp_of_term |> Thm.dest_ctyp |> hd *}
   927 ML {* val cT = @{cpat "op ="} |> Thm.ctyp_of_term |> Thm.dest_ctyp |> hd *}
   964 ML {*
   928 ML {*
   965   Toplevel.program (fn () =>
   929   Toplevel.program (fn () =>
   966     Drule.instantiate' [SOME cT, SOME cT, SOME @{ctyp bool}] [NONE, NONE, NONE, NONE, SOME (@{cpat "op ="})] @{thm arg_cong2}
   930     Drule.instantiate' [SOME cT,SOME cT,SOME @{ctyp bool}] [NONE,NONE,NONE,NONE,SOME (@{cpat "op ="})] @{thm arg_cong2}
   967   )
   931   )
   968 *}
   932 *}
   969 
   933 
   970 ML {*
   934 ML {*
   971   fun split_binop_conv t =
   935   fun split_binop_conv t =
   972     let
   936     let
   973       val _ = tracing (Syntax.string_of_term @{context} (term_of t))
       
   974       val (lhs, rhs) = dest_ceq t;
   937       val (lhs, rhs) = dest_ceq t;
   975       val (bop, _) = dest_cbinop lhs;
   938       val (bop, _) = dest_cbinop lhs;
   976       val [clT, cr2] = bop |> Thm.ctyp_of_term |> Thm.dest_ctyp;
   939       val [clT, cr2] = bop |> Thm.ctyp_of_term |> Thm.dest_ctyp;
   977       val [cmT, crT] = Thm.dest_ctyp cr2;
   940       val [cmT, crT] = Thm.dest_ctyp cr2;
   978     in
   941     in
  1039       CHANGED o (ObjectLogic.full_atomize_tac)
  1002       CHANGED o (ObjectLogic.full_atomize_tac)
  1040     ])
  1003     ])
  1041 *}
  1004 *}
  1042 
  1005 
  1043 ML {*
  1006 ML {*
       
  1007 <<<<<<< variant A
  1044   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1}))
  1008   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1}))
  1045   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1009   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
       
  1010 >>>>>>> variant B
       
  1011   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm m1}))
       
  1012   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
       
  1013 ####### Ancestor
       
  1014   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1}))
       
  1015   val goal = build_goal m1_novars consts @{typ "'a list"} mk_rep_abs
       
  1016 ======= end
  1046   val cgoal = cterm_of @{theory} goal
  1017   val cgoal = cterm_of @{theory} goal
  1047   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1018   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
  1048 *}
  1019 *}
  1049 
  1020 
  1050 (*notation ( output) "prop" ("#_" [1000] 1000) *)
  1021 (*notation ( output) "prop" ("#_" [1000] 1000) *)
  1151   done
  1122   done
  1152 
  1123 
  1153 thm list.induct
  1124 thm list.induct
  1154 
  1125 
  1155 ML {*
  1126 ML {*
  1156   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list.induct}))
  1127   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm list.induct}))
  1157 *}
  1128 *}
  1158 ML {*
  1129 ML {*
  1159   val goal =
  1130   val goal =
  1160     Toplevel.program (fn () =>
  1131     Toplevel.program (fn () =>
  1161       build_goal m1_novars consts @{typ "'a list"} mk_rep_abs
  1132       build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1162     )
  1133     )
  1163 *}
  1134 *}
  1164 ML {*
  1135 ML {*
  1165   val cgoal = cterm_of @{theory} goal
  1136   val cgoal = cterm_of @{theory} goal
  1166 *}
  1137 *}
  1252 
  1223 
  1253 ML {* MRS *}
  1224 ML {* MRS *}
  1254 thm card1_suc
  1225 thm card1_suc
  1255 
  1226 
  1256 ML {*
  1227 ML {*
  1257   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm card1_suc}))
  1228   val m1_novars = snd(no_vars ((Context.Theory @{theory}),@{thm card1_suc}))
  1258 *}
  1229 *}
  1259 ML {*
  1230 ML {*
  1260   val goal = build_goal m1_novars consts @{typ "'a list"} mk_rep_abs
  1231   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} mk_rep_abs
  1261 *}
  1232 *}
  1262 ML {*
  1233 ML {*
  1263   val cgoal = cterm_of @{theory} goal
  1234   val cgoal = cterm_of @{theory} goal
  1264   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
  1235   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
  1265 *}
  1236 *}