QuotMain.thy
changeset 139 4cc5db28b1c3
parent 138 59bba5cfa248
child 140 00d141f2daa7
equal deleted inserted replaced
138:59bba5cfa248 139:4cc5db28b1c3
   409 thm VR'_def AP'_def LM'_def
   409 thm VR'_def AP'_def LM'_def
   410 term LM'
   410 term LM'
   411 term VR'
   411 term VR'
   412 term AP'
   412 term AP'
   413 
   413 
   414 
   414 section {* ATOMIZE *}
   415 text {* finite set example *}
       
   416 print_syntax
       
   417 inductive
       
   418   list_eq (infix "\<approx>" 50)
       
   419 where
       
   420   "a#b#xs \<approx> b#a#xs"
       
   421 | "[] \<approx> []"
       
   422 | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs"
       
   423 | "a#a#xs \<approx> a#xs"
       
   424 | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys"
       
   425 | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3"
       
   426 
       
   427 lemma list_eq_refl:
       
   428   shows "xs \<approx> xs"
       
   429   apply (induct xs)
       
   430    apply (auto intro: list_eq.intros)
       
   431   done
       
   432 
       
   433 lemma equiv_list_eq:
       
   434   shows "EQUIV list_eq"
       
   435   unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def
       
   436   apply(auto intro: list_eq.intros list_eq_refl)
       
   437   done
       
   438 
       
   439 quotient fset = "'a list" / "list_eq"
       
   440   apply(rule equiv_list_eq)
       
   441   done
       
   442 
       
   443 print_theorems
       
   444 
       
   445 typ "'a fset"
       
   446 thm "Rep_fset"
       
   447 
       
   448 local_setup {*
       
   449   make_const_def @{binding EMPTY} @{term "[]"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   450 *}
       
   451 
       
   452 term Nil
       
   453 term EMPTY
       
   454 thm EMPTY_def
       
   455 
       
   456 
       
   457 local_setup {*
       
   458   make_const_def @{binding INSERT} @{term "op #"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   459 *}
       
   460 
       
   461 term Cons
       
   462 term INSERT
       
   463 thm INSERT_def
       
   464 
       
   465 local_setup {*
       
   466   make_const_def @{binding UNION} @{term "op @"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   467 *}
       
   468 
       
   469 term append
       
   470 term UNION
       
   471 thm UNION_def
       
   472 
       
   473 
       
   474 thm QUOTIENT_fset
       
   475 
       
   476 thm QUOT_TYPE_I_fset.thm11
       
   477 
       
   478 
       
   479 fun
       
   480   membship :: "'a \<Rightarrow> 'a list \<Rightarrow> bool" (infix "memb" 100)
       
   481 where
       
   482   m1: "(x memb []) = False"
       
   483 | m2: "(x memb (y#xs)) = ((x=y) \<or> (x memb xs))"
       
   484 
       
   485 lemma mem_respects:
       
   486   fixes z
       
   487   assumes a: "list_eq x y"
       
   488   shows "(z memb x) = (z memb y)"
       
   489   using a by induct auto
       
   490 
       
   491 
       
   492 fun
       
   493   card1 :: "'a list \<Rightarrow> nat"
       
   494 where
       
   495   card1_nil: "(card1 []) = 0"
       
   496 | card1_cons: "(card1 (x # xs)) = (if (x memb xs) then (card1 xs) else (Suc (card1 xs)))"
       
   497 
       
   498 local_setup {*
       
   499   make_const_def @{binding card} @{term "card1"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   500 *}
       
   501 
       
   502 term card1
       
   503 term card
       
   504 thm card_def
       
   505 
       
   506 (* text {*
       
   507  Maybe make_const_def should require a theorem that says that the particular lifted function
       
   508  respects the relation. With it such a definition would be impossible:
       
   509  make_const_def @{binding CARD} @{term "length"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   510 *}*)
       
   511 
       
   512 lemma card1_rsp:
       
   513   fixes a b :: "'a list"
       
   514   assumes e: "a \<approx> b"
       
   515   shows "card1 a = card1 b"
       
   516   using e apply induct
       
   517   apply (simp_all add:mem_respects)
       
   518   done
       
   519 
       
   520 lemma card1_0:
       
   521   fixes a :: "'a list"
       
   522   shows "(card1 a = 0) = (a = [])"
       
   523   apply (induct a)
       
   524    apply (simp)
       
   525   apply (simp_all)
       
   526    apply meson
       
   527   apply (simp_all)
       
   528   done
       
   529 
       
   530 lemma not_mem_card1:
       
   531   fixes x :: "'a"
       
   532   fixes xs :: "'a list"
       
   533   shows "~(x memb xs) \<Longrightarrow> card1 (x # xs) = Suc (card1 xs)"
       
   534   by simp
       
   535 
       
   536 
       
   537 lemma mem_cons:
       
   538   fixes x :: "'a"
       
   539   fixes xs :: "'a list"
       
   540   assumes a : "x memb xs"
       
   541   shows "x # xs \<approx> xs"
       
   542   using a
       
   543   apply (induct xs)
       
   544   apply (auto intro: list_eq.intros)
       
   545   done
       
   546 
       
   547 lemma card1_suc:
       
   548   fixes xs :: "'a list"
       
   549   fixes n :: "nat"
       
   550   assumes c: "card1 xs = Suc n"
       
   551   shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)"
       
   552   using c
       
   553 apply(induct xs)
       
   554 apply (metis Suc_neq_Zero card1_0)
       
   555 apply (metis QUOT_TYPE_I_fset.R_trans QuotMain.card1_cons list_eq_refl mem_cons)
       
   556 done
       
   557 
       
   558 primrec
       
   559   fold1
       
   560 where
       
   561   "fold1 f (g :: 'a \<Rightarrow> 'b) (z :: 'b) [] = z"
       
   562 | "fold1 f g z (a # A) =
       
   563      (if ((!u v. (f u v = f v u))
       
   564       \<and> (!u v w. ((f u (f v w) = f (f u v) w))))
       
   565      then (
       
   566        if (a memb A) then (fold1 f g z A) else (f (g a) (fold1 f g z A))
       
   567      ) else z)"
       
   568 
       
   569 (* fold1_def is not usable, but: *)
       
   570 thm fold1.simps
       
   571 
       
   572 lemma cons_preserves:
       
   573   fixes z
       
   574   assumes a: "xs \<approx> ys"
       
   575   shows "(z # xs) \<approx> (z # ys)"
       
   576   using a by (rule QuotMain.list_eq.intros(5))
       
   577 
       
   578 lemma fs1_strong_cases:
       
   579   fixes X :: "'a list"
       
   580   shows "(X = []) \<or> (\<exists>a. \<exists> Y. (~(a memb Y) \<and> (X \<approx> a # Y)))"
       
   581   apply (induct X)
       
   582   apply (simp)
       
   583   apply (metis QUOT_TYPE_I_fset.thm11 list_eq_refl mem_cons QuotMain.m1)
       
   584   done
       
   585 
       
   586 local_setup {*
       
   587   make_const_def @{binding IN} @{term "membship"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   588 *}
       
   589 
       
   590 term membship
       
   591 term IN
       
   592 thm IN_def
       
   593 
       
   594 lemmas a = QUOT_TYPE.ABS_def[OF QUOT_TYPE_fset]
       
   595 thm QUOT_TYPE.thm11[OF QUOT_TYPE_fset, THEN iffD1, simplified a]
       
   596 
       
   597 lemma yy:
       
   598   shows "(False = x memb []) = (False = IN (x::nat) EMPTY)"
       
   599 unfolding IN_def EMPTY_def
       
   600 apply(rule_tac f="(op =) False" in arg_cong)
       
   601 apply(rule mem_respects)
       
   602 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
   603 apply(rule list_eq.intros)
       
   604 done
       
   605 
       
   606 lemma
       
   607   shows "IN (x::nat) EMPTY = False"
       
   608 using m1
       
   609 apply -
       
   610 apply(rule yy[THEN iffD1, symmetric])
       
   611 apply(simp)
       
   612 done
       
   613 
       
   614 lemma
       
   615   shows "((x=y) \<or> (IN x xs) = (IN (x::nat) (INSERT y xs))) =
       
   616          ((x=y) \<or> x memb REP_fset xs = x memb (y # REP_fset xs))"
       
   617 unfolding IN_def INSERT_def
       
   618 apply(rule_tac f="(op \<or>) (x=y)" in arg_cong)
       
   619 apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong)
       
   620 apply(rule mem_respects)
       
   621 apply(rule list_eq.intros(3))
       
   622 apply(unfold REP_fset_def ABS_fset_def)
       
   623 apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset])
       
   624 apply(rule list_eq_refl)
       
   625 done
       
   626 
       
   627 lemma append_respects_fst:
       
   628   assumes a : "list_eq l1 l2"
       
   629   shows "list_eq (l1 @ s) (l2 @ s)"
       
   630   using a
       
   631   apply(induct)
       
   632   apply(auto intro: list_eq.intros)
       
   633   apply(simp add: list_eq_refl)
       
   634 done
       
   635 
       
   636 lemma yyy:
       
   637   shows "
       
   638     (
       
   639      (UNION EMPTY s = s) &
       
   640      ((UNION (INSERT e s1) s2) = (INSERT e (UNION s1 s2)))
       
   641     ) = (
       
   642      ((ABS_fset ([] @ REP_fset s)) = s) &
       
   643      ((ABS_fset ((e # (REP_fset s1)) @ REP_fset s2)) = ABS_fset (e # (REP_fset s1 @ REP_fset s2)))
       
   644     )"
       
   645   unfolding UNION_def EMPTY_def INSERT_def
       
   646   apply(rule_tac f="(op &)" in arg_cong2)
       
   647   apply(rule_tac f="(op =)" in arg_cong2)
       
   648   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
       
   649   apply(rule append_respects_fst)
       
   650   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
   651   apply(rule list_eq_refl)
       
   652   apply(simp)
       
   653   apply(rule_tac f="(op =)" in arg_cong2)
       
   654   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
       
   655   apply(rule append_respects_fst)
       
   656   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
   657   apply(rule list_eq_refl)
       
   658   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
       
   659   apply(rule list_eq.intros(5))
       
   660   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
   661   apply(rule list_eq_refl)
       
   662 done
       
   663 
       
   664 lemma
       
   665   shows "
       
   666      (UNION EMPTY s = s) &
       
   667      ((UNION (INSERT e s1) s2) = (INSERT e (UNION s1 s2)))"
       
   668   apply (simp add: yyy)
       
   669   apply (simp add: QUOT_TYPE_I_fset.thm10)
       
   670   done
       
   671 
       
   672 ML {*
       
   673   fun mk_rep x = @{term REP_fset} $ x;
       
   674   fun mk_abs x = @{term ABS_fset} $ x;
       
   675   val consts = [@{const_name "Nil"}, @{const_name "Cons"},
       
   676                 @{const_name "membship"}, @{const_name "card1"},
       
   677                 @{const_name "append"}, @{const_name "fold1"}];
       
   678 *}
       
   679 
       
   680 ML {* val tm = @{term "x :: 'a list"} *}
       
   681 ML {* val ty = exchange_ty @{typ "'a list"} @{typ "'a fset"} (fastype_of tm) *}
       
   682 ML {* (fst (get_fun repF @{typ "'a list"} @{typ "'a fset"} @{context} ty)) $ tm *}
       
   683 
       
   684 ML {* val qty = @{typ "'a fset"} *}
       
   685 ML {* val tt = Type ("fun", [Type ("fun", [qty, @{typ "prop"}]), @{typ "prop"}]) *}
       
   686 ML {* val fall = Const(@{const_name all}, dummyT) *}
       
   687 
       
   688 ML {*
       
   689 fun needs_lift (rty as Type (rty_s, _)) ty =
       
   690   case ty of
       
   691     Type (s, tys) =>
       
   692       (s = rty_s) orelse (exists (needs_lift rty) tys)
       
   693   | _ => false
       
   694 
       
   695 *}
       
   696 
       
   697 ML {*
       
   698 fun build_goal_term lthy thm constructors rty qty =
       
   699   let
       
   700     fun mk_rep tm =
       
   701       let
       
   702         val ty = exchange_ty rty qty (fastype_of tm)
       
   703       in fst (get_fun repF rty qty lthy ty) $ tm end
       
   704 
       
   705     fun mk_abs tm =
       
   706       let
       
   707         val _ = tracing (Syntax.string_of_term @{context} tm)
       
   708         val _ = tracing (Syntax.string_of_typ @{context} (fastype_of tm))
       
   709         val ty = exchange_ty rty qty (fastype_of tm) in
       
   710       fst (get_fun absF rty qty lthy ty) $ tm end
       
   711 
       
   712     fun is_constructor (Const (x, _)) = member (op =) constructors x
       
   713       | is_constructor _ = false;
       
   714 
       
   715     fun build_aux lthy tm =
       
   716       case tm of
       
   717       Abs (a as (_, vty, _)) =>
       
   718       let
       
   719         val (vs, t) = Term.dest_abs a;
       
   720         val v = Free(vs, vty);
       
   721         val t' = lambda v (build_aux lthy t)
       
   722       in
       
   723       if (not (needs_lift rty (fastype_of tm))) then t'
       
   724       else mk_rep (mk_abs (
       
   725         if not (needs_lift rty vty) then t'
       
   726         else
       
   727           let
       
   728             val v' = mk_rep (mk_abs v);
       
   729             val t1 = Envir.beta_norm (t' $ v')
       
   730           in
       
   731             lambda v t1
       
   732           end
       
   733       ))
       
   734       end
       
   735     | x =>
       
   736       let
       
   737         val _ = tracing (">>" ^ Syntax.string_of_term @{context} tm)
       
   738         val (opp, tms0) = Term.strip_comb tm
       
   739         val tms = map (build_aux lthy) tms0
       
   740         val ty = fastype_of tm
       
   741       in
       
   742         if (((fst (Term.dest_Const opp)) = @{const_name Respects}) handle _ => false)
       
   743           then (list_comb (opp, (hd tms0) :: (tl tms)))
       
   744       else if (is_constructor opp andalso needs_lift rty ty) then
       
   745           mk_rep (mk_abs (list_comb (opp,tms)))
       
   746         else if ((Term.is_Free opp) andalso (length tms > 0) andalso (needs_lift rty ty)) then
       
   747             mk_rep(mk_abs(list_comb(opp,tms)))
       
   748         else if tms = [] then opp
       
   749         else list_comb(opp, tms)
       
   750       end
       
   751   in
       
   752     build_aux lthy (Thm.prop_of thm)
       
   753   end
       
   754 
       
   755 *}
       
   756 
       
   757 ML {*
       
   758 fun build_goal_term_old ctxt thm constructors rty qty mk_rep mk_abs =
       
   759   let
       
   760     fun mk_rep_abs x = mk_rep (mk_abs x);
       
   761 
       
   762     fun is_constructor (Const (x, _)) = member (op =) constructors x
       
   763       | is_constructor _ = false;
       
   764 
       
   765     fun maybe_mk_rep_abs t =
       
   766       let
       
   767         val _ = writeln ("Maybe: " ^ Syntax.string_of_term ctxt t)
       
   768       in
       
   769         if fastype_of t = rty then mk_rep_abs t else t
       
   770       end;
       
   771 
       
   772     fun is_all (Const ("all", Type("fun", [Type("fun", [ty, _]), _]))) = ty = rty
       
   773       | is_all _ = false;
       
   774 
       
   775     fun is_ex (Const ("Ex", Type("fun", [Type("fun", [ty, _]), _]))) = ty = rty
       
   776       | is_ex _ = false;
       
   777 
       
   778     fun build_aux ctxt1 tm =
       
   779       let
       
   780         val (head, args) = Term.strip_comb tm;
       
   781         val args' = map (build_aux ctxt1) args;
       
   782       in
       
   783         (case head of
       
   784           Abs (x, T, t) =>
       
   785             if T = rty then let
       
   786               val ([x'], ctxt2) = Variable.variant_fixes [x] ctxt1;
       
   787               val v = Free (x', qty);
       
   788               val t' = subst_bound (mk_rep v, t);
       
   789               val rec_term = build_aux ctxt2 t';
       
   790               val _ = tracing (Syntax.string_of_term ctxt2 t')
       
   791               val _ = tracing (Syntax.string_of_term ctxt2 (Term.lambda_name (x, v) rec_term))
       
   792             in
       
   793               Term.lambda_name (x, v) rec_term
       
   794             end else let
       
   795               val ([x'], ctxt2) = Variable.variant_fixes [x] ctxt1;
       
   796               val v = Free (x', T);
       
   797               val t' = subst_bound (v, t);
       
   798               val rec_term = build_aux ctxt2 t';
       
   799             in Term.lambda_name (x, v) rec_term end
       
   800         | _ =>  (* I assume that we never lift 'prop' since it is not of sort type *)
       
   801             if is_all head then
       
   802               list_comb (Const(@{const_name all}, dummyT), args') |> Syntax.check_term ctxt1
       
   803             else if is_ex head then
       
   804               list_comb (Const(@{const_name Ex}, dummyT), args') |> Syntax.check_term ctxt1
       
   805             else if is_constructor head then
       
   806               maybe_mk_rep_abs (list_comb (head, map maybe_mk_rep_abs args'))
       
   807             else
       
   808               maybe_mk_rep_abs (list_comb (head, args'))
       
   809         )
       
   810       end;
       
   811   in
       
   812     build_aux ctxt (Thm.prop_of thm)
       
   813   end
       
   814 *}
       
   815 
       
   816 ML {*
       
   817 fun build_goal ctxt thm cons rty qty =
       
   818   Logic.mk_equals ((Thm.prop_of thm), (build_goal_term ctxt thm cons rty qty))
       
   819 *}
       
   820 
       
   821 ML {*
       
   822   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m2}))
       
   823 *}
       
   824 
       
   825 ML {*
       
   826 cterm_of @{theory} (prop_of m1_novars);
       
   827 cterm_of @{theory} (build_goal_term @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"});
       
   828 cterm_of @{theory} (build_goal_term_old @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"} mk_rep mk_abs)
       
   829 *}
       
   830 
       
   831 
   415 
   832 text {*
   416 text {*
   833   Unabs_def converts a definition given as
   417   Unabs_def converts a definition given as
   834 
   418 
   835     c \<equiv> %x. %y. f x y
   419     c \<equiv> %x. %y. f x y
   858 in
   442 in
   859   get_conv xs new_lhs |>
   443   get_conv xs new_lhs |>
   860   singleton (ProofContext.export ctxt' ctxt)
   444   singleton (ProofContext.export ctxt' ctxt)
   861 end
   445 end
   862 *}
   446 *}
   863 
       
   864 ML {* (* Test: *) @{thm IN_def}; unabs_def @{context} @{thm IN_def} *}
       
   865 
       
   866 ML {* val fset_defs = @{thms EMPTY_def IN_def UNION_def card_def INSERT_def} *}
       
   867 ML {* val fset_defs_sym = map (fn t => symmetric (unabs_def @{context} t)) fset_defs *}
       
   868 
   447 
   869 lemma atomize_eqv[atomize]: 
   448 lemma atomize_eqv[atomize]: 
   870   shows "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)" 
   449   shows "(Trueprop A \<equiv> Trueprop B) \<equiv> (A \<equiv> B)" 
   871 proof
   450 proof
   872   assume "A \<equiv> B" 
   451   assume "A \<equiv> B" 
   884     then show "A = B" using * by auto
   463     then show "A = B" using * by auto
   885   qed
   464   qed
   886   then show "A \<equiv> B" by (rule eq_reflection)
   465   then show "A \<equiv> B" by (rule eq_reflection)
   887 qed
   466 qed
   888 
   467 
   889 (* Has all the theorems about fset plugged in. These should be parameters to the tactic *)
   468 ML {*
   890 ML {*
   469 fun atomize_thm thm =
   891   fun transconv_fset_tac' ctxt =
   470 let
   892     (LocalDefs.unfold_tac @{context} fset_defs) THEN
   471   val thm' = forall_intr_vars thm
   893     ObjectLogic.full_atomize_tac 1 THEN
   472   val thm'' = ObjectLogic.atomize (cprop_of thm')
   894     REPEAT_ALL_NEW (FIRST' [
   473 in
   895       rtac @{thm list_eq_refl},
   474   Simplifier.rewrite_rule [thm''] thm'
   896       rtac @{thm cons_preserves},
   475 end
   897       rtac @{thm mem_respects},
   476 *}
   898       rtac @{thm card1_rsp},
   477 
   899       rtac @{thm QUOT_TYPE_I_fset.R_trans2},
   478 
   900       CHANGED o (simp_tac ((Simplifier.context ctxt HOL_ss) addsimps @{thms QUOT_TYPE_I_fset.REP_ABS_rsp})),
   479 section {* REGULARIZE *}
   901       Cong_Tac.cong_tac @{thm cong},
       
   902       rtac @{thm ext}
       
   903     ]) 1
       
   904 *}
       
   905 
       
   906 ML {*
       
   907   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1}))
       
   908   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
   909   val cgoal = cterm_of @{theory} goal
       
   910   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
   911 *}
       
   912 
       
   913 (*notation ( output) "prop" ("#_" [1000] 1000) *)
       
   914 notation ( output) "Trueprop" ("#_" [1000] 1000)
       
   915 
       
   916 
       
   917 prove {* (Thm.term_of cgoal2) *}
       
   918   apply (tactic {* transconv_fset_tac' @{context} *})
       
   919   done
       
   920 
       
   921 thm length_append (* Not true but worth checking that the goal is correct *)
       
   922 ML {*
       
   923   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm length_append}))
       
   924   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
   925   val cgoal = cterm_of @{theory} goal
       
   926   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
   927 *}
       
   928 prove {* Thm.term_of cgoal2 *}
       
   929   apply (tactic {* transconv_fset_tac' @{context} *})
       
   930   sorry
       
   931 
       
   932 thm m2
       
   933 ML {*
       
   934   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m2}))
       
   935   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
   936   val cgoal = cterm_of @{theory} goal
       
   937   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
   938 *}
       
   939 prove {* Thm.term_of cgoal2 *}
       
   940   apply (tactic {* transconv_fset_tac' @{context} *})
       
   941   done
       
   942 
       
   943 thm list_eq.intros(4)
       
   944 ML {*
       
   945   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list_eq.intros(4)}))
       
   946   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
   947   val cgoal = cterm_of @{theory} goal
       
   948   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
   949   val cgoal3 = Thm.rhs_of (MetaSimplifier.rewrite true @{thms QUOT_TYPE_I_fset.thm10} cgoal2)
       
   950 *}
       
   951 
       
   952 (* It is the same, but we need a name for it. *)
       
   953 prove zzz : {* Thm.term_of cgoal3 *}
       
   954   apply (tactic {* transconv_fset_tac' @{context} *})
       
   955   done
       
   956 
       
   957 (*lemma zzz' :
       
   958   "(REP_fset (INSERT a (INSERT a (ABS_fset xs))) \<approx> REP_fset (INSERT a (ABS_fset xs)))"
       
   959   using list_eq.intros(4) by (simp only: zzz)
       
   960 
       
   961 thm QUOT_TYPE_I_fset.REPS_same
       
   962 ML {* val zzz'' = MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.REPS_same} @{thm zzz'} *}
       
   963 *)
       
   964 
       
   965 thm list_eq.intros(5)
       
   966 ML {*
       
   967   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list_eq.intros(5)}))
       
   968   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
   969   val cgoal = cterm_of @{theory} goal
       
   970   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
       
   971 *}
       
   972 prove {* Thm.term_of cgoal2 *}
       
   973   apply (tactic {* transconv_fset_tac' @{context} *})
       
   974   done
       
   975 
       
   976 section {* handling quantifiers - regularize *}
       
   977 
   480 
   978 text {* tyRel takes a type and builds a relation that a quantifier over this
   481 text {* tyRel takes a type and builds a relation that a quantifier over this
   979   type needs to respect. *}
   482   type needs to respect. *}
   980 ML {*
   483 ML {*
   981 fun tyRel ty rty rel lthy =
   484 fun tyRel ty rty rel lthy =
  1005 where
   508 where
  1006   "(x \<in> p) \<Longrightarrow> (Babs p m x = m x)"
   509   "(x \<in> p) \<Longrightarrow> (Babs p m x = m x)"
  1007 (* TODO: Consider defining it with an "if"; sth like:
   510 (* TODO: Consider defining it with an "if"; sth like:
  1008    Babs p m = \<lambda>x. if x \<in> p then m x else undefined
   511    Babs p m = \<lambda>x. if x \<in> p then m x else undefined
  1009 *)
   512 *)
       
   513 
       
   514 ML {*
       
   515 fun needs_lift (rty as Type (rty_s, _)) ty =
       
   516   case ty of
       
   517     Type (s, tys) =>
       
   518       (s = rty_s) orelse (exists (needs_lift rty) tys)
       
   519   | _ => false
       
   520 
       
   521 *}
  1010 
   522 
  1011 ML {*
   523 ML {*
  1012 (* trm \<Rightarrow> new_trm *)
   524 (* trm \<Rightarrow> new_trm *)
  1013 fun regularise trm rty rel lthy =
   525 fun regularise trm rty rel lthy =
  1014   case trm of
   526   case trm of
  1185 ML {*  
   697 ML {*  
  1186   cterm_of @{theory} (regularise @{term "All (P::trm \<Rightarrow> bool)"} @{typ "trm"} @{term "RR"} @{context});
   698   cterm_of @{theory} (regularise @{term "All (P::trm \<Rightarrow> bool)"} @{typ "trm"} @{term "RR"} @{context});
  1187   cterm_of @{theory} (my_reg @{term "RR"} @{term "All (P::trm \<Rightarrow> bool)"})
   699   cterm_of @{theory} (my_reg @{term "RR"} @{term "All (P::trm \<Rightarrow> bool)"})
  1188 *}
   700 *}
  1189 
   701 
  1190 ML {*
   702 (*fun prove_reg trm \<Rightarrow> thm (we might need some facts to do this)
  1191 fun atomize_thm thm =
   703   trm == new_trm
  1192 let
   704 *)
  1193   val thm' = forall_intr_vars thm
   705 
  1194   val thm'' = ObjectLogic.atomize (cprop_of thm')
   706 section {* TRANSCONV *}
  1195 in
   707 
  1196   Simplifier.rewrite_rule [thm''] thm'
   708 
  1197 end
   709 ML {*
  1198 *}
   710 fun build_goal_term lthy thm constructors rty qty =
       
   711   let
       
   712     fun mk_rep tm =
       
   713       let
       
   714         val ty = exchange_ty rty qty (fastype_of tm)
       
   715       in fst (get_fun repF rty qty lthy ty) $ tm end
       
   716 
       
   717     fun mk_abs tm =
       
   718       let
       
   719         val _ = tracing (Syntax.string_of_term @{context} tm)
       
   720         val _ = tracing (Syntax.string_of_typ @{context} (fastype_of tm))
       
   721         val ty = exchange_ty rty qty (fastype_of tm) in
       
   722       fst (get_fun absF rty qty lthy ty) $ tm end
       
   723 
       
   724     fun is_constructor (Const (x, _)) = member (op =) constructors x
       
   725       | is_constructor _ = false;
       
   726 
       
   727     fun build_aux lthy tm =
       
   728       case tm of
       
   729       Abs (a as (_, vty, _)) =>
       
   730       let
       
   731         val (vs, t) = Term.dest_abs a;
       
   732         val v = Free(vs, vty);
       
   733         val t' = lambda v (build_aux lthy t)
       
   734       in
       
   735       if (not (needs_lift rty (fastype_of tm))) then t'
       
   736       else mk_rep (mk_abs (
       
   737         if not (needs_lift rty vty) then t'
       
   738         else
       
   739           let
       
   740             val v' = mk_rep (mk_abs v);
       
   741             val t1 = Envir.beta_norm (t' $ v')
       
   742           in
       
   743             lambda v t1
       
   744           end
       
   745       ))
       
   746       end
       
   747     | x =>
       
   748       let
       
   749         val _ = tracing (">>" ^ Syntax.string_of_term @{context} tm)
       
   750         val (opp, tms0) = Term.strip_comb tm
       
   751         val tms = map (build_aux lthy) tms0
       
   752         val ty = fastype_of tm
       
   753       in
       
   754         if (((fst (Term.dest_Const opp)) = @{const_name Respects}) handle _ => false)
       
   755           then (list_comb (opp, (hd tms0) :: (tl tms)))
       
   756       else if (is_constructor opp andalso needs_lift rty ty) then
       
   757           mk_rep (mk_abs (list_comb (opp,tms)))
       
   758         else if ((Term.is_Free opp) andalso (length tms > 0) andalso (needs_lift rty ty)) then
       
   759             mk_rep(mk_abs(list_comb(opp,tms)))
       
   760         else if tms = [] then opp
       
   761         else list_comb(opp, tms)
       
   762       end
       
   763   in
       
   764     build_aux lthy (Thm.prop_of thm)
       
   765   end
       
   766 *}
       
   767 
       
   768 ML {*
       
   769 fun build_goal ctxt thm cons rty qty =
       
   770   Logic.mk_equals ((Thm.prop_of thm), (build_goal_term ctxt thm cons rty qty))
       
   771 *}
       
   772 
       
   773 
       
   774 
       
   775 
       
   776 
       
   777 text {* finite set example *}
       
   778 print_syntax
       
   779 inductive
       
   780   list_eq (infix "\<approx>" 50)
       
   781 where
       
   782   "a#b#xs \<approx> b#a#xs"
       
   783 | "[] \<approx> []"
       
   784 | "xs \<approx> ys \<Longrightarrow> ys \<approx> xs"
       
   785 | "a#a#xs \<approx> a#xs"
       
   786 | "xs \<approx> ys \<Longrightarrow> a#xs \<approx> a#ys"
       
   787 | "\<lbrakk>xs1 \<approx> xs2; xs2 \<approx> xs3\<rbrakk> \<Longrightarrow> xs1 \<approx> xs3"
       
   788 
       
   789 lemma list_eq_refl:
       
   790   shows "xs \<approx> xs"
       
   791   apply (induct xs)
       
   792    apply (auto intro: list_eq.intros)
       
   793   done
       
   794 
       
   795 lemma equiv_list_eq:
       
   796   shows "EQUIV list_eq"
       
   797   unfolding EQUIV_REFL_SYM_TRANS REFL_def SYM_def TRANS_def
       
   798   apply(auto intro: list_eq.intros list_eq_refl)
       
   799   done
       
   800 
       
   801 quotient fset = "'a list" / "list_eq"
       
   802   apply(rule equiv_list_eq)
       
   803   done
       
   804 
       
   805 print_theorems
       
   806 
       
   807 typ "'a fset"
       
   808 thm "Rep_fset"
       
   809 
       
   810 local_setup {*
       
   811   make_const_def @{binding EMPTY} @{term "[]"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   812 *}
       
   813 
       
   814 term Nil
       
   815 term EMPTY
       
   816 thm EMPTY_def
       
   817 
       
   818 
       
   819 local_setup {*
       
   820   make_const_def @{binding INSERT} @{term "op #"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   821 *}
       
   822 
       
   823 term Cons
       
   824 term INSERT
       
   825 thm INSERT_def
       
   826 
       
   827 local_setup {*
       
   828   make_const_def @{binding UNION} @{term "op @"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   829 *}
       
   830 
       
   831 term append
       
   832 term UNION
       
   833 thm UNION_def
       
   834 
       
   835 
       
   836 thm QUOTIENT_fset
       
   837 
       
   838 thm QUOT_TYPE_I_fset.thm11
       
   839 
       
   840 
       
   841 fun
       
   842   membship :: "'a \<Rightarrow> 'a list \<Rightarrow> bool" (infix "memb" 100)
       
   843 where
       
   844   m1: "(x memb []) = False"
       
   845 | m2: "(x memb (y#xs)) = ((x=y) \<or> (x memb xs))"
       
   846 
       
   847 lemma mem_respects:
       
   848   fixes z
       
   849   assumes a: "list_eq x y"
       
   850   shows "(z memb x) = (z memb y)"
       
   851   using a by induct auto
       
   852 
       
   853 
       
   854 fun
       
   855   card1 :: "'a list \<Rightarrow> nat"
       
   856 where
       
   857   card1_nil: "(card1 []) = 0"
       
   858 | card1_cons: "(card1 (x # xs)) = (if (x memb xs) then (card1 xs) else (Suc (card1 xs)))"
       
   859 
       
   860 local_setup {*
       
   861   make_const_def @{binding card} @{term "card1"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   862 *}
       
   863 
       
   864 term card1
       
   865 term card
       
   866 thm card_def
       
   867 
       
   868 (* text {*
       
   869  Maybe make_const_def should require a theorem that says that the particular lifted function
       
   870  respects the relation. With it such a definition would be impossible:
       
   871  make_const_def @{binding CARD} @{term "length"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   872 *}*)
       
   873 
       
   874 lemma card1_rsp:
       
   875   fixes a b :: "'a list"
       
   876   assumes e: "a \<approx> b"
       
   877   shows "card1 a = card1 b"
       
   878   using e apply induct
       
   879   apply (simp_all add:mem_respects)
       
   880   done
       
   881 
       
   882 lemma card1_0:
       
   883   fixes a :: "'a list"
       
   884   shows "(card1 a = 0) = (a = [])"
       
   885   apply (induct a)
       
   886    apply (simp)
       
   887   apply (simp_all)
       
   888    apply meson
       
   889   apply (simp_all)
       
   890   done
       
   891 
       
   892 lemma not_mem_card1:
       
   893   fixes x :: "'a"
       
   894   fixes xs :: "'a list"
       
   895   shows "~(x memb xs) \<Longrightarrow> card1 (x # xs) = Suc (card1 xs)"
       
   896   by simp
       
   897 
       
   898 
       
   899 lemma mem_cons:
       
   900   fixes x :: "'a"
       
   901   fixes xs :: "'a list"
       
   902   assumes a : "x memb xs"
       
   903   shows "x # xs \<approx> xs"
       
   904   using a
       
   905   apply (induct xs)
       
   906   apply (auto intro: list_eq.intros)
       
   907   done
       
   908 
       
   909 lemma card1_suc:
       
   910   fixes xs :: "'a list"
       
   911   fixes n :: "nat"
       
   912   assumes c: "card1 xs = Suc n"
       
   913   shows "\<exists>a ys. ~(a memb ys) \<and> xs \<approx> (a # ys)"
       
   914   using c
       
   915 apply(induct xs)
       
   916 apply (metis Suc_neq_Zero card1_0)
       
   917 apply (metis QUOT_TYPE_I_fset.R_trans QuotMain.card1_cons list_eq_refl mem_cons)
       
   918 done
       
   919 
       
   920 primrec
       
   921   fold1
       
   922 where
       
   923   "fold1 f (g :: 'a \<Rightarrow> 'b) (z :: 'b) [] = z"
       
   924 | "fold1 f g z (a # A) =
       
   925      (if ((!u v. (f u v = f v u))
       
   926       \<and> (!u v w. ((f u (f v w) = f (f u v) w))))
       
   927      then (
       
   928        if (a memb A) then (fold1 f g z A) else (f (g a) (fold1 f g z A))
       
   929      ) else z)"
       
   930 
       
   931 (* fold1_def is not usable, but: *)
       
   932 thm fold1.simps
       
   933 
       
   934 lemma cons_preserves:
       
   935   fixes z
       
   936   assumes a: "xs \<approx> ys"
       
   937   shows "(z # xs) \<approx> (z # ys)"
       
   938   using a by (rule QuotMain.list_eq.intros(5))
       
   939 
       
   940 lemma fs1_strong_cases:
       
   941   fixes X :: "'a list"
       
   942   shows "(X = []) \<or> (\<exists>a. \<exists> Y. (~(a memb Y) \<and> (X \<approx> a # Y)))"
       
   943   apply (induct X)
       
   944   apply (simp)
       
   945   apply (metis QUOT_TYPE_I_fset.thm11 list_eq_refl mem_cons QuotMain.m1)
       
   946   done
       
   947 
       
   948 local_setup {*
       
   949   make_const_def @{binding IN} @{term "membship"} NoSyn @{typ "'a list"} @{typ "'a fset"} #> snd
       
   950 *}
       
   951 
       
   952 term membship
       
   953 term IN
       
   954 thm IN_def
       
   955 
       
   956 lemmas a = QUOT_TYPE.ABS_def[OF QUOT_TYPE_fset]
       
   957 thm QUOT_TYPE.thm11[OF QUOT_TYPE_fset, THEN iffD1, simplified a]
       
   958 
       
   959 lemma yy:
       
   960   shows "(False = x memb []) = (False = IN (x::nat) EMPTY)"
       
   961 unfolding IN_def EMPTY_def
       
   962 apply(rule_tac f="(op =) False" in arg_cong)
       
   963 apply(rule mem_respects)
       
   964 apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
   965 apply(rule list_eq.intros)
       
   966 done
       
   967 
       
   968 lemma
       
   969   shows "IN (x::nat) EMPTY = False"
       
   970 using m1
       
   971 apply -
       
   972 apply(rule yy[THEN iffD1, symmetric])
       
   973 apply(simp)
       
   974 done
       
   975 
       
   976 lemma
       
   977   shows "((x=y) \<or> (IN x xs) = (IN (x::nat) (INSERT y xs))) =
       
   978          ((x=y) \<or> x memb REP_fset xs = x memb (y # REP_fset xs))"
       
   979 unfolding IN_def INSERT_def
       
   980 apply(rule_tac f="(op \<or>) (x=y)" in arg_cong)
       
   981 apply(rule_tac f="(op =) (x memb REP_fset xs)" in arg_cong)
       
   982 apply(rule mem_respects)
       
   983 apply(rule list_eq.intros(3))
       
   984 apply(unfold REP_fset_def ABS_fset_def)
       
   985 apply(simp only: QUOT_TYPE.REP_ABS_rsp[OF QUOT_TYPE_fset])
       
   986 apply(rule list_eq_refl)
       
   987 done
       
   988 
       
   989 lemma append_respects_fst:
       
   990   assumes a : "list_eq l1 l2"
       
   991   shows "list_eq (l1 @ s) (l2 @ s)"
       
   992   using a
       
   993   apply(induct)
       
   994   apply(auto intro: list_eq.intros)
       
   995   apply(simp add: list_eq_refl)
       
   996 done
       
   997 
       
   998 lemma yyy:
       
   999   shows "
       
  1000     (
       
  1001      (UNION EMPTY s = s) &
       
  1002      ((UNION (INSERT e s1) s2) = (INSERT e (UNION s1 s2)))
       
  1003     ) = (
       
  1004      ((ABS_fset ([] @ REP_fset s)) = s) &
       
  1005      ((ABS_fset ((e # (REP_fset s1)) @ REP_fset s2)) = ABS_fset (e # (REP_fset s1 @ REP_fset s2)))
       
  1006     )"
       
  1007   unfolding UNION_def EMPTY_def INSERT_def
       
  1008   apply(rule_tac f="(op &)" in arg_cong2)
       
  1009   apply(rule_tac f="(op =)" in arg_cong2)
       
  1010   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
       
  1011   apply(rule append_respects_fst)
       
  1012   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
  1013   apply(rule list_eq_refl)
       
  1014   apply(simp)
       
  1015   apply(rule_tac f="(op =)" in arg_cong2)
       
  1016   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
       
  1017   apply(rule append_respects_fst)
       
  1018   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
  1019   apply(rule list_eq_refl)
       
  1020   apply(simp only: QUOT_TYPE_I_fset.thm11[symmetric])
       
  1021   apply(rule list_eq.intros(5))
       
  1022   apply(simp only: QUOT_TYPE_I_fset.REP_ABS_rsp)
       
  1023   apply(rule list_eq_refl)
       
  1024 done
       
  1025 
       
  1026 lemma
       
  1027   shows "
       
  1028      (UNION EMPTY s = s) &
       
  1029      ((UNION (INSERT e s1) s2) = (INSERT e (UNION s1 s2)))"
       
  1030   apply (simp add: yyy)
       
  1031   apply (simp add: QUOT_TYPE_I_fset.thm10)
       
  1032   done
       
  1033 
       
  1034 ML {*
       
  1035   fun mk_rep x = @{term REP_fset} $ x;
       
  1036   fun mk_abs x = @{term ABS_fset} $ x;
       
  1037   val consts = [@{const_name "Nil"}, @{const_name "Cons"},
       
  1038                 @{const_name "membship"}, @{const_name "card1"},
       
  1039                 @{const_name "append"}, @{const_name "fold1"}];
       
  1040 *}
       
  1041 
       
  1042 ML {* val tm = @{term "x :: 'a list"} *}
       
  1043 ML {* val ty = exchange_ty @{typ "'a list"} @{typ "'a fset"} (fastype_of tm) *}
       
  1044 ML {* (fst (get_fun repF @{typ "'a list"} @{typ "'a fset"} @{context} ty)) $ tm *}
       
  1045 
       
  1046 ML {* val qty = @{typ "'a fset"} *}
       
  1047 ML {* val tt = Type ("fun", [Type ("fun", [qty, @{typ "prop"}]), @{typ "prop"}]) *}
       
  1048 ML {* val fall = Const(@{const_name all}, dummyT) *}
       
  1049 
       
  1050 ML {* val fset_defs = @{thms EMPTY_def IN_def UNION_def card_def INSERT_def} *}
       
  1051 ML {* val fset_defs_sym = map (fn t => symmetric (unabs_def @{context} t)) fset_defs *}
       
  1052 
       
  1053 
       
  1054 
       
  1055 ML {*
       
  1056   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m2}))
       
  1057 *}
       
  1058 
       
  1059 ML {*
       
  1060 cterm_of @{theory} (prop_of m1_novars);
       
  1061 cterm_of @{theory} (build_goal_term @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"});
       
  1062 *}
       
  1063 
       
  1064 
       
  1065 (* Has all the theorems about fset plugged in. These should be parameters to the tactic *)
       
  1066 ML {*
       
  1067   fun transconv_fset_tac' ctxt =
       
  1068     (LocalDefs.unfold_tac @{context} fset_defs) THEN
       
  1069     ObjectLogic.full_atomize_tac 1 THEN
       
  1070     REPEAT_ALL_NEW (FIRST' [
       
  1071       rtac @{thm list_eq_refl},
       
  1072       rtac @{thm cons_preserves},
       
  1073       rtac @{thm mem_respects},
       
  1074       rtac @{thm card1_rsp},
       
  1075       rtac @{thm QUOT_TYPE_I_fset.R_trans2},
       
  1076       CHANGED o (simp_tac ((Simplifier.context ctxt HOL_ss) addsimps @{thms QUOT_TYPE_I_fset.REP_ABS_rsp})),
       
  1077       Cong_Tac.cong_tac @{thm cong},
       
  1078       rtac @{thm ext}
       
  1079     ]) 1
       
  1080 *}
       
  1081 
       
  1082 ML {*
       
  1083   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m1}))
       
  1084   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
  1085   val cgoal = cterm_of @{theory} goal
       
  1086   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
  1087 *}
       
  1088 
       
  1089 (*notation ( output) "prop" ("#_" [1000] 1000) *)
       
  1090 notation ( output) "Trueprop" ("#_" [1000] 1000)
       
  1091 
       
  1092 
       
  1093 prove {* (Thm.term_of cgoal2) *}
       
  1094   apply (tactic {* transconv_fset_tac' @{context} *})
       
  1095   done
       
  1096 
       
  1097 thm length_append (* Not true but worth checking that the goal is correct *)
       
  1098 ML {*
       
  1099   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm length_append}))
       
  1100   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
  1101   val cgoal = cterm_of @{theory} goal
       
  1102   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
  1103 *}
       
  1104 prove {* Thm.term_of cgoal2 *}
       
  1105   apply (tactic {* transconv_fset_tac' @{context} *})
       
  1106   sorry
       
  1107 
       
  1108 thm m2
       
  1109 ML {*
       
  1110   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm m2}))
       
  1111   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
  1112   val cgoal = cterm_of @{theory} goal
       
  1113   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
  1114 *}
       
  1115 prove {* Thm.term_of cgoal2 *}
       
  1116   apply (tactic {* transconv_fset_tac' @{context} *})
       
  1117   done
       
  1118 
       
  1119 thm list_eq.intros(4)
       
  1120 ML {*
       
  1121   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list_eq.intros(4)}))
       
  1122   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
  1123   val cgoal = cterm_of @{theory} goal
       
  1124   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite false fset_defs_sym cgoal)
       
  1125   val cgoal3 = Thm.rhs_of (MetaSimplifier.rewrite true @{thms QUOT_TYPE_I_fset.thm10} cgoal2)
       
  1126 *}
       
  1127 
       
  1128 (* It is the same, but we need a name for it. *)
       
  1129 prove zzz : {* Thm.term_of cgoal3 *}
       
  1130   apply (tactic {* transconv_fset_tac' @{context} *})
       
  1131   done
       
  1132 
       
  1133 (*lemma zzz' :
       
  1134   "(REP_fset (INSERT a (INSERT a (ABS_fset xs))) \<approx> REP_fset (INSERT a (ABS_fset xs)))"
       
  1135   using list_eq.intros(4) by (simp only: zzz)
       
  1136 
       
  1137 thm QUOT_TYPE_I_fset.REPS_same
       
  1138 ML {* val zzz'' = MetaSimplifier.rewrite_rule @{thms QUOT_TYPE_I_fset.REPS_same} @{thm zzz'} *}
       
  1139 *)
       
  1140 
       
  1141 thm list_eq.intros(5)
       
  1142 ML {*
       
  1143   val m1_novars = snd(no_vars ((Context.Theory @{theory}), @{thm list_eq.intros(5)}))
       
  1144   val goal = build_goal @{context} m1_novars consts @{typ "'a list"} @{typ "'a fset"}
       
  1145   val cgoal = cterm_of @{theory} goal
       
  1146   val cgoal2 = Thm.rhs_of (MetaSimplifier.rewrite true fset_defs_sym cgoal)
       
  1147 *}
       
  1148 prove {* Thm.term_of cgoal2 *}
       
  1149   apply (tactic {* transconv_fset_tac' @{context} *})
       
  1150   done
       
  1151 
  1199 
  1152 
  1200 thm list.induct
  1153 thm list.induct
  1201 lemma list_induct_hol4:
  1154 lemma list_induct_hol4:
  1202   fixes P :: "'a list \<Rightarrow> bool"
  1155   fixes P :: "'a list \<Rightarrow> bool"
  1203   assumes "((P []) \<and> (\<forall>t. (P t) \<longrightarrow> (\<forall>h. (P (h # t)))))"
  1156   assumes "((P []) \<and> (\<forall>t. (P t) \<longrightarrow> (\<forall>h. (P (h # t)))))"
  1204   shows "(\<forall>l. (P l))"
  1157   shows "(\<forall>l. (P l))"
  1205   sorry
  1158   sorry
  1206 
  1159 
  1207 ML {* atomize_thm @{thm list_induct_hol4} *}
  1160 ML {* atomize_thm @{thm list_induct_hol4} *}
  1208 
  1161 
  1209 (*fun prove_reg trm \<Rightarrow> thm (we might need some facts to do this)
       
  1210   trm == new_trm
       
  1211 *)
       
  1212 
  1162 
  1213 ML {* val li = Thm.freezeT (atomize_thm @{thm list_induct_hol4}) *}
  1163 ML {* val li = Thm.freezeT (atomize_thm @{thm list_induct_hol4}) *}
  1214 
  1164 
  1215 prove list_induct_r: {*
  1165 prove list_induct_r: {*
  1216  Logic.mk_implies
  1166  Logic.mk_implies
  1364 ML_prf {* val f_abs_c = map (cterm_of @{theory}) f_abs *}
  1314 ML_prf {* val f_abs_c = map (cterm_of @{theory}) f_abs *}
  1365 ML_prf {* val insts = l ~~ f_abs_c *}
  1315 ML_prf {* val insts = l ~~ f_abs_c *}
  1366 ML_prf {* val t = Thm.lift_rule (hd (cprems_of (Isar.goal ()))) @{thm "APPLY_RSP_II" } *}
  1316 ML_prf {* val t = Thm.lift_rule (hd (cprems_of (Isar.goal ()))) @{thm "APPLY_RSP_II" } *}
  1367 ML_prf {* Toplevel.program (fn () => cterm_instantiate insts t) *}
  1317 ML_prf {* Toplevel.program (fn () => cterm_instantiate insts t) *}
  1368 
  1318 
  1369 ML_prf {* Toplevel.program (fn () => Drule.instantiate' [] [SOME f_abs_c, SOME f_abs_c] t) *}
       
  1370 
  1319 
  1371 
  1320 
  1372 
  1321 
  1373 .
  1322 .
  1374 (*  FAILS: t2 = Drule.instantiate m @{thm "APPLY_RSP_II" }; rtac t2 1 *)
  1323 (*  FAILS: t2 = Drule.instantiate m @{thm "APPLY_RSP_II" }; rtac t2 1 *)