src/HOL/Tools/TFL/rules.ML
changeset 41164 6854e9a40edc
parent 38801 319a28dd3564
child 41225 bd4ecd48c21f
equal deleted inserted replaced
41163:3f21a269780e 41164:6854e9a40edc
    55 end;
    55 end;
    56 
    56 
    57 structure Rules: RULES =
    57 structure Rules: RULES =
    58 struct
    58 struct
    59 
    59 
    60 structure S = USyntax;
    60 fun RULES_ERR func mesg = Utils.ERR {module = "Rules", func = func, mesg = mesg};
    61 structure U = Utils;
    61 
    62 structure D = Dcterm;
    62 
    63 
    63 fun cconcl thm = Dcterm.drop_prop (#prop (Thm.crep_thm thm));
    64 
    64 fun chyps thm = map Dcterm.drop_prop (#hyps (Thm.crep_thm thm));
    65 fun RULES_ERR func mesg = U.ERR {module = "Rules", func = func, mesg = mesg};
       
    66 
       
    67 
       
    68 fun cconcl thm = D.drop_prop (#prop (Thm.crep_thm thm));
       
    69 fun chyps thm = map D.drop_prop (#hyps (Thm.crep_thm thm));
       
    70 
    65 
    71 fun dest_thm thm =
    66 fun dest_thm thm =
    72   let val {prop,hyps,...} = Thm.rep_thm thm
    67   let val {prop,hyps,...} = Thm.rep_thm thm
    73   in (map HOLogic.dest_Trueprop hyps, HOLogic.dest_Trueprop prop) end
    68   in (map HOLogic.dest_Trueprop hyps, HOLogic.dest_Trueprop prop) end
    74   handle TERM _ => raise RULES_ERR "dest_thm" "missing Trueprop";
    69   handle TERM _ => raise RULES_ERR "dest_thm" "missing Trueprop";
    93     val ctm1_eq = Thm.reflexive ctm1;
    88     val ctm1_eq = Thm.reflexive ctm1;
    94   in Thm.equal_elim (Thm.transitive ctm2_eq ctm1_eq) thm end
    89   in Thm.equal_elim (Thm.transitive ctm2_eq ctm1_eq) thm end
    95   handle THM (msg, _, _) => raise RULES_ERR "ALPHA" msg;
    90   handle THM (msg, _, _) => raise RULES_ERR "ALPHA" msg;
    96 
    91 
    97 fun rbeta th =
    92 fun rbeta th =
    98   (case D.strip_comb (cconcl th) of
    93   (case Dcterm.strip_comb (cconcl th) of
    99     (_, [l, r]) => Thm.transitive th (Thm.beta_conversion false r)
    94     (_, [l, r]) => Thm.transitive th (Thm.beta_conversion false r)
   100   | _ => raise RULES_ERR "rbeta" "");
    95   | _ => raise RULES_ERR "rbeta" "");
   101 
    96 
   102 
    97 
   103 (*----------------------------------------------------------------------------
    98 (*----------------------------------------------------------------------------
   106  * Assumptions get stuck on the meta-language assumption list. Implications
   101  * Assumptions get stuck on the meta-language assumption list. Implications
   107  * are in the object language, so discharging an assumption "A" from theorem
   102  * are in the object language, so discharging an assumption "A" from theorem
   108  * "B" results in something that looks like "A --> B".
   103  * "B" results in something that looks like "A --> B".
   109  *---------------------------------------------------------------------------*)
   104  *---------------------------------------------------------------------------*)
   110 
   105 
   111 fun ASSUME ctm = Thm.assume (D.mk_prop ctm);
   106 fun ASSUME ctm = Thm.assume (Dcterm.mk_prop ctm);
   112 
   107 
   113 
   108 
   114 (*---------------------------------------------------------------------------
   109 (*---------------------------------------------------------------------------
   115  * Implication in TFL is -->. Meta-language implication (==>) is only used
   110  * Implication in TFL is -->. Meta-language implication (==>) is only used
   116  * in the implementation of some of the inference rules below.
   111  * in the implementation of some of the inference rules below.
   117  *---------------------------------------------------------------------------*)
   112  *---------------------------------------------------------------------------*)
   118 fun MP th1 th2 = th2 RS (th1 RS mp)
   113 fun MP th1 th2 = th2 RS (th1 RS mp)
   119   handle THM (msg, _, _) => raise RULES_ERR "MP" msg;
   114   handle THM (msg, _, _) => raise RULES_ERR "MP" msg;
   120 
   115 
   121 (*forces the first argument to be a proposition if necessary*)
   116 (*forces the first argument to be a proposition if necessary*)
   122 fun DISCH tm thm = Thm.implies_intr (D.mk_prop tm) thm COMP impI
   117 fun DISCH tm thm = Thm.implies_intr (Dcterm.mk_prop tm) thm COMP impI
   123   handle THM (msg, _, _) => raise RULES_ERR "DISCH" msg;
   118   handle THM (msg, _, _) => raise RULES_ERR "DISCH" msg;
   124 
   119 
   125 fun DISCH_ALL thm = fold_rev DISCH (#hyps (Thm.crep_thm thm)) thm;
   120 fun DISCH_ALL thm = fold_rev DISCH (#hyps (Thm.crep_thm thm)) thm;
   126 
   121 
   127 
   122 
   129  let fun check tm = P (#t (Thm.rep_cterm tm))
   124  let fun check tm = P (#t (Thm.rep_cterm tm))
   130  in  fold_rev (fn tm => fn th => if check tm then DISCH tm th else th) (chyps thm) thm
   125  in  fold_rev (fn tm => fn th => if check tm then DISCH tm th else th) (chyps thm) thm
   131  end;
   126  end;
   132 
   127 
   133 fun UNDISCH thm =
   128 fun UNDISCH thm =
   134    let val tm = D.mk_prop (#1 (D.dest_imp (cconcl thm)))
   129    let val tm = Dcterm.mk_prop (#1 (Dcterm.dest_imp (cconcl thm)))
   135    in Thm.implies_elim (thm RS mp) (ASSUME tm) end
   130    in Thm.implies_elim (thm RS mp) (ASSUME tm) end
   136    handle U.ERR _ => raise RULES_ERR "UNDISCH" ""
   131    handle Utils.ERR _ => raise RULES_ERR "UNDISCH" ""
   137      | THM _ => raise RULES_ERR "UNDISCH" "";
   132      | THM _ => raise RULES_ERR "UNDISCH" "";
   138 
   133 
   139 fun PROVE_HYP ath bth = MP (DISCH (cconcl ath) bth) ath;
   134 fun PROVE_HYP ath bth = MP (DISCH (cconcl ath) bth) ath;
   140 
   135 
   141 fun IMP_TRANS th1 th2 = th2 RS (th1 RS Thms.imp_trans)
   136 fun IMP_TRANS th1 th2 = th2 RS (th1 RS Thms.imp_trans)
   150   handle THM (msg, _, _) => raise RULES_ERR "CONJUNCT1" msg;
   145   handle THM (msg, _, _) => raise RULES_ERR "CONJUNCT1" msg;
   151 
   146 
   152 fun CONJUNCT2 thm = thm RS conjunct2
   147 fun CONJUNCT2 thm = thm RS conjunct2
   153   handle THM (msg, _, _) => raise RULES_ERR "CONJUNCT2" msg;
   148   handle THM (msg, _, _) => raise RULES_ERR "CONJUNCT2" msg;
   154 
   149 
   155 fun CONJUNCTS th = CONJUNCTS (CONJUNCT1 th) @ CONJUNCTS (CONJUNCT2 th) handle U.ERR _ => [th];
   150 fun CONJUNCTS th = CONJUNCTS (CONJUNCT1 th) @ CONJUNCTS (CONJUNCT2 th) handle Utils.ERR _ => [th];
   156 
   151 
   157 fun LIST_CONJ [] = raise RULES_ERR "LIST_CONJ" "empty list"
   152 fun LIST_CONJ [] = raise RULES_ERR "LIST_CONJ" "empty list"
   158   | LIST_CONJ [th] = th
   153   | LIST_CONJ [th] = th
   159   | LIST_CONJ (th :: rst) = MP (MP (conjI COMP (impI RS impI)) th) (LIST_CONJ rst)
   154   | LIST_CONJ (th :: rst) = MP (MP (conjI COMP (impI RS impI)) th) (LIST_CONJ rst)
   160       handle THM (msg, _, _) => raise RULES_ERR "LIST_CONJ" msg;
   155       handle THM (msg, _, _) => raise RULES_ERR "LIST_CONJ" msg;
   166 local val thy = Thm.theory_of_thm disjI1
   161 local val thy = Thm.theory_of_thm disjI1
   167       val prop = Thm.prop_of disjI1
   162       val prop = Thm.prop_of disjI1
   168       val [P,Q] = OldTerm.term_vars prop
   163       val [P,Q] = OldTerm.term_vars prop
   169       val disj1 = Thm.forall_intr (Thm.cterm_of thy Q) disjI1
   164       val disj1 = Thm.forall_intr (Thm.cterm_of thy Q) disjI1
   170 in
   165 in
   171 fun DISJ1 thm tm = thm RS (Thm.forall_elim (D.drop_prop tm) disj1)
   166 fun DISJ1 thm tm = thm RS (Thm.forall_elim (Dcterm.drop_prop tm) disj1)
   172   handle THM (msg, _, _) => raise RULES_ERR "DISJ1" msg;
   167   handle THM (msg, _, _) => raise RULES_ERR "DISJ1" msg;
   173 end;
   168 end;
   174 
   169 
   175 local val thy = Thm.theory_of_thm disjI2
   170 local val thy = Thm.theory_of_thm disjI2
   176       val prop = Thm.prop_of disjI2
   171       val prop = Thm.prop_of disjI2
   177       val [P,Q] = OldTerm.term_vars prop
   172       val [P,Q] = OldTerm.term_vars prop
   178       val disj2 = Thm.forall_intr (Thm.cterm_of thy P) disjI2
   173       val disj2 = Thm.forall_intr (Thm.cterm_of thy P) disjI2
   179 in
   174 in
   180 fun DISJ2 tm thm = thm RS (Thm.forall_elim (D.drop_prop tm) disj2)
   175 fun DISJ2 tm thm = thm RS (Thm.forall_elim (Dcterm.drop_prop tm) disj2)
   181   handle THM (msg, _, _) => raise RULES_ERR "DISJ2" msg;
   176   handle THM (msg, _, _) => raise RULES_ERR "DISJ2" msg;
   182 end;
   177 end;
   183 
   178 
   184 
   179 
   185 (*----------------------------------------------------------------------------
   180 (*----------------------------------------------------------------------------
   193 
   188 
   194 fun EVEN_ORS thms =
   189 fun EVEN_ORS thms =
   195   let fun blue ldisjs [] _ = []
   190   let fun blue ldisjs [] _ = []
   196         | blue ldisjs (th::rst) rdisjs =
   191         | blue ldisjs (th::rst) rdisjs =
   197             let val tail = tl rdisjs
   192             let val tail = tl rdisjs
   198                 val rdisj_tl = D.list_mk_disj tail
   193                 val rdisj_tl = Dcterm.list_mk_disj tail
   199             in fold_rev DISJ2 ldisjs (DISJ1 th rdisj_tl)
   194             in fold_rev DISJ2 ldisjs (DISJ1 th rdisj_tl)
   200                :: blue (ldisjs @ [cconcl th]) rst tail
   195                :: blue (ldisjs @ [cconcl th]) rst tail
   201             end handle U.ERR _ => [fold_rev DISJ2 ldisjs th]
   196             end handle Utils.ERR _ => [fold_rev DISJ2 ldisjs th]
   202    in blue [] thms (map cconcl thms) end;
   197    in blue [] thms (map cconcl thms) end;
   203 
   198 
   204 
   199 
   205 (*----------------------------------------------------------------------------
   200 (*----------------------------------------------------------------------------
   206  *
   201  *
   210  *
   205  *
   211  *---------------------------------------------------------------------------*)
   206  *---------------------------------------------------------------------------*)
   212 
   207 
   213 fun DISJ_CASES th1 th2 th3 =
   208 fun DISJ_CASES th1 th2 th3 =
   214   let
   209   let
   215     val c = D.drop_prop (cconcl th1);
   210     val c = Dcterm.drop_prop (cconcl th1);
   216     val (disj1, disj2) = D.dest_disj c;
   211     val (disj1, disj2) = Dcterm.dest_disj c;
   217     val th2' = DISCH disj1 th2;
   212     val th2' = DISCH disj1 th2;
   218     val th3' = DISCH disj2 th3;
   213     val th3' = DISCH disj2 th3;
   219   in
   214   in
   220     th3' RS (th2' RS (th1 RS Thms.tfl_disjE))
   215     th3' RS (th2' RS (th1 RS Thms.tfl_disjE))
   221       handle THM (msg, _, _) => raise RULES_ERR "DISJ_CASES" msg
   216       handle THM (msg, _, _) => raise RULES_ERR "DISJ_CASES" msg
   251 fun DISJ_CASESL disjth thl =
   246 fun DISJ_CASESL disjth thl =
   252    let val c = cconcl disjth
   247    let val c = cconcl disjth
   253        fun eq th atm = exists (fn t => HOLogic.dest_Trueprop t
   248        fun eq th atm = exists (fn t => HOLogic.dest_Trueprop t
   254                                        aconv term_of atm)
   249                                        aconv term_of atm)
   255                               (#hyps(rep_thm th))
   250                               (#hyps(rep_thm th))
   256        val tml = D.strip_disj c
   251        val tml = Dcterm.strip_disj c
   257        fun DL th [] = raise RULES_ERR "DISJ_CASESL" "no cases"
   252        fun DL th [] = raise RULES_ERR "DISJ_CASESL" "no cases"
   258          | DL th [th1] = PROVE_HYP th th1
   253          | DL th [th1] = PROVE_HYP th th1
   259          | DL th [th1,th2] = DISJ_CASES th th1 th2
   254          | DL th [th1,th2] = DISJ_CASES th th1 th2
   260          | DL th (th1::rst) =
   255          | DL th (th1::rst) =
   261             let val tm = #2(D.dest_disj(D.drop_prop(cconcl th)))
   256             let val tm = #2 (Dcterm.dest_disj (Dcterm.drop_prop(cconcl th)))
   262              in DISJ_CASES th th1 (DL (ASSUME tm) rst) end
   257              in DISJ_CASES th th1 (DL (ASSUME tm) rst) end
   263    in DL disjth (organize eq tml thl)
   258    in DL disjth (organize eq tml thl)
   264    end;
   259    end;
   265 
   260 
   266 
   261 
   277 fun SPEC tm thm =
   272 fun SPEC tm thm =
   278    let val gspec' = instantiate ([(cTV, Thm.ctyp_of_term tm)], []) gspec
   273    let val gspec' = instantiate ([(cTV, Thm.ctyp_of_term tm)], []) gspec
   279    in thm RS (Thm.forall_elim tm gspec') end
   274    in thm RS (Thm.forall_elim tm gspec') end
   280 end;
   275 end;
   281 
   276 
   282 fun SPEC_ALL thm = fold SPEC (#1(D.strip_forall(cconcl thm))) thm;
   277 fun SPEC_ALL thm = fold SPEC (#1 (Dcterm.strip_forall(cconcl thm))) thm;
   283 
   278 
   284 val ISPEC = SPEC
   279 val ISPEC = SPEC
   285 val ISPECL = fold ISPEC;
   280 val ISPECL = fold ISPEC;
   286 
   281 
   287 (* Not optimized! Too complicated. *)
   282 (* Not optimized! Too complicated. *)
   321   in GENL vlist thm
   316   in GENL vlist thm
   322   end;
   317   end;
   323 
   318 
   324 
   319 
   325 fun MATCH_MP th1 th2 =
   320 fun MATCH_MP th1 th2 =
   326    if (D.is_forall (D.drop_prop(cconcl th1)))
   321    if (Dcterm.is_forall (Dcterm.drop_prop(cconcl th1)))
   327    then MATCH_MP (th1 RS spec) th2
   322    then MATCH_MP (th1 RS spec) th2
   328    else MP th1 th2;
   323    else MP th1 th2;
   329 
   324 
   330 
   325 
   331 (*----------------------------------------------------------------------------
   326 (*----------------------------------------------------------------------------
   343  *
   338  *
   344  *---------------------------------------------------------------------------*)
   339  *---------------------------------------------------------------------------*)
   345 
   340 
   346 fun CHOOSE (fvar, exth) fact =
   341 fun CHOOSE (fvar, exth) fact =
   347   let
   342   let
   348     val lam = #2 (D.dest_comb (D.drop_prop (cconcl exth)))
   343     val lam = #2 (Dcterm.dest_comb (Dcterm.drop_prop (cconcl exth)))
   349     val redex = D.capply lam fvar
   344     val redex = Dcterm.capply lam fvar
   350     val thy = Thm.theory_of_cterm redex
   345     val thy = Thm.theory_of_cterm redex
   351     val t$u = Thm.term_of redex
   346     val t$u = Thm.term_of redex
   352     val residue = Thm.cterm_of thy (Term.betapply (t, u))
   347     val residue = Thm.cterm_of thy (Term.betapply (t, u))
   353   in
   348   in
   354     GEN fvar (DISCH residue fact) RS (exth RS Thms.choose_thm)
   349     GEN fvar (DISCH residue fact) RS (exth RS Thms.choose_thm)
   362 fun EXISTS (template,witness) thm =
   357 fun EXISTS (template,witness) thm =
   363    let val thy = Thm.theory_of_thm thm
   358    let val thy = Thm.theory_of_thm thm
   364        val prop = Thm.prop_of thm
   359        val prop = Thm.prop_of thm
   365        val P' = cterm_of thy P
   360        val P' = cterm_of thy P
   366        val x' = cterm_of thy x
   361        val x' = cterm_of thy x
   367        val abstr = #2 (D.dest_comb template)
   362        val abstr = #2 (Dcterm.dest_comb template)
   368    in
   363    in
   369    thm RS (cterm_instantiate[(P',abstr), (x',witness)] exI)
   364    thm RS (cterm_instantiate[(P',abstr), (x',witness)] exI)
   370      handle THM (msg, _, _) => raise RULES_ERR "EXISTS" msg
   365      handle THM (msg, _, _) => raise RULES_ERR "EXISTS" msg
   371    end
   366    end
   372 end;
   367 end;
   378  *    A |- ?v1...v_n. M
   373  *    A |- ?v1...v_n. M
   379  *
   374  *
   380  *---------------------------------------------------------------------------*)
   375  *---------------------------------------------------------------------------*)
   381 
   376 
   382 fun EXISTL vlist th =
   377 fun EXISTL vlist th =
   383   fold_rev (fn v => fn thm => EXISTS(D.mk_exists(v,cconcl thm), v) thm)
   378   fold_rev (fn v => fn thm => EXISTS(Dcterm.mk_exists(v,cconcl thm), v) thm)
   384            vlist th;
   379            vlist th;
   385 
   380 
   386 
   381 
   387 (*----------------------------------------------------------------------------
   382 (*----------------------------------------------------------------------------
   388  *
   383  *
   395 
   390 
   396 fun IT_EXISTS blist th =
   391 fun IT_EXISTS blist th =
   397    let val thy = Thm.theory_of_thm th
   392    let val thy = Thm.theory_of_thm th
   398        val tych = cterm_of thy
   393        val tych = cterm_of thy
   399        val blist' = map (pairself Thm.term_of) blist
   394        val blist' = map (pairself Thm.term_of) blist
   400        fun ex v M  = cterm_of thy (S.mk_exists{Bvar=v,Body = M})
   395        fun ex v M  = cterm_of thy (USyntax.mk_exists{Bvar=v,Body = M})
   401 
   396 
   402   in
   397   in
   403   fold_rev (fn (b as (r1,r2)) => fn thm =>
   398   fold_rev (fn (b as (r1,r2)) => fn thm =>
   404         EXISTS(ex r2 (subst_free [b]
   399         EXISTS(ex r2 (subst_free [b]
   405                    (HOLogic.dest_Trueprop(Thm.prop_of thm))), tych r1)
   400                    (HOLogic.dest_Trueprop(Thm.prop_of thm))), tych r1)
   441  *                  TERMINATION CONDITION EXTRACTION
   436  *                  TERMINATION CONDITION EXTRACTION
   442  *---------------------------------------------------------------------------*)
   437  *---------------------------------------------------------------------------*)
   443 
   438 
   444 
   439 
   445 (* Object language quantifier, i.e., "!" *)
   440 (* Object language quantifier, i.e., "!" *)
   446 fun Forall v M = S.mk_forall{Bvar=v, Body=M};
   441 fun Forall v M = USyntax.mk_forall{Bvar=v, Body=M};
   447 
   442 
   448 
   443 
   449 (* Fragile: it's a cong if it is not "R y x ==> cut f R x y = f y" *)
   444 (* Fragile: it's a cong if it is not "R y x ==> cut f R x y = f y" *)
   450 fun is_cong thm =
   445 fun is_cong thm =
   451   case (Thm.prop_of thm)
   446   case (Thm.prop_of thm)
   456 
   451 
   457 fun dest_equal(Const ("==",_) $
   452 fun dest_equal(Const ("==",_) $
   458                (Const (@{const_name Trueprop},_) $ lhs)
   453                (Const (@{const_name Trueprop},_) $ lhs)
   459                $ (Const (@{const_name Trueprop},_) $ rhs)) = {lhs=lhs, rhs=rhs}
   454                $ (Const (@{const_name Trueprop},_) $ rhs)) = {lhs=lhs, rhs=rhs}
   460   | dest_equal(Const ("==",_) $ lhs $ rhs)  = {lhs=lhs, rhs=rhs}
   455   | dest_equal(Const ("==",_) $ lhs $ rhs)  = {lhs=lhs, rhs=rhs}
   461   | dest_equal tm = S.dest_eq tm;
   456   | dest_equal tm = USyntax.dest_eq tm;
   462 
   457 
   463 fun get_lhs tm = #lhs(dest_equal (HOLogic.dest_Trueprop tm));
   458 fun get_lhs tm = #lhs(dest_equal (HOLogic.dest_Trueprop tm));
   464 
   459 
   465 fun dest_all used (Const("all",_) $ (a as Abs _)) = S.dest_abs used a
   460 fun dest_all used (Const("all",_) $ (a as Abs _)) = USyntax.dest_abs used a
   466   | dest_all _ _ = raise RULES_ERR "dest_all" "not a !!";
   461   | dest_all _ _ = raise RULES_ERR "dest_all" "not a !!";
   467 
   462 
   468 val is_all = can (dest_all []);
   463 val is_all = can (dest_all []);
   469 
   464 
   470 fun strip_all used fm =
   465 fun strip_all used fm =
   503   | get (ant::rst,n,L) =
   498   | get (ant::rst,n,L) =
   504       case (list_break_all ant)
   499       case (list_break_all ant)
   505         of ([],_) => get (rst, n+1,L)
   500         of ([],_) => get (rst, n+1,L)
   506          | (vlist,body) =>
   501          | (vlist,body) =>
   507             let val eq = Logic.strip_imp_concl body
   502             let val eq = Logic.strip_imp_concl body
   508                 val (f,args) = S.strip_comb (get_lhs eq)
   503                 val (f,args) = USyntax.strip_comb (get_lhs eq)
   509                 val (vstrl,_) = S.strip_abs f
   504                 val (vstrl,_) = USyntax.strip_abs f
   510                 val names  =
   505                 val names  =
   511                   Name.variant_list (OldTerm.add_term_names(body, [])) (map (#1 o dest_Free) vstrl)
   506                   Name.variant_list (OldTerm.add_term_names(body, [])) (map (#1 o dest_Free) vstrl)
   512             in get (rst, n+1, (names,n)::L) end
   507             in get (rst, n+1, (names,n)::L) end
   513             handle TERM _ => get (rst, n+1, L)
   508             handle TERM _ => get (rst, n+1, L)
   514               | U.ERR _ => get (rst, n+1, L);
   509               | Utils.ERR _ => get (rst, n+1, L);
   515 
   510 
   516 (* Note: Thm.rename_params_rule counts from 1, not 0 *)
   511 (* Note: Thm.rename_params_rule counts from 1, not 0 *)
   517 fun rename thm =
   512 fun rename thm =
   518   let val thy = Thm.theory_of_thm thm
   513   let val thy = Thm.theory_of_thm thm
   519       val tych = cterm_of thy
   514       val tych = cterm_of thy
   527 (*---------------------------------------------------------------------------
   522 (*---------------------------------------------------------------------------
   528  * Beta-conversion to the rhs of an equation (taken from hol90/drule.sml)
   523  * Beta-conversion to the rhs of an equation (taken from hol90/drule.sml)
   529  *---------------------------------------------------------------------------*)
   524  *---------------------------------------------------------------------------*)
   530 
   525 
   531 fun list_beta_conv tm =
   526 fun list_beta_conv tm =
   532   let fun rbeta th = Thm.transitive th (Thm.beta_conversion false (#2(D.dest_eq(cconcl th))))
   527   let fun rbeta th = Thm.transitive th (Thm.beta_conversion false (#2(Dcterm.dest_eq(cconcl th))))
   533       fun iter [] = Thm.reflexive tm
   528       fun iter [] = Thm.reflexive tm
   534         | iter (v::rst) = rbeta (Thm.combination(iter rst) (Thm.reflexive v))
   529         | iter (v::rst) = rbeta (Thm.combination(iter rst) (Thm.reflexive v))
   535   in iter  end;
   530   in iter  end;
   536 
   531 
   537 
   532 
   551 
   546 
   552 (*---------------------------------------------------------------------------
   547 (*---------------------------------------------------------------------------
   553  * General abstraction handlers, should probably go in USyntax.
   548  * General abstraction handlers, should probably go in USyntax.
   554  *---------------------------------------------------------------------------*)
   549  *---------------------------------------------------------------------------*)
   555 fun mk_aabs (vstr, body) =
   550 fun mk_aabs (vstr, body) =
   556   S.mk_abs {Bvar = vstr, Body = body}
   551   USyntax.mk_abs {Bvar = vstr, Body = body}
   557   handle U.ERR _ => S.mk_pabs {varstruct = vstr, body = body};
   552   handle Utils.ERR _ => USyntax.mk_pabs {varstruct = vstr, body = body};
   558 
   553 
   559 fun list_mk_aabs (vstrl,tm) =
   554 fun list_mk_aabs (vstrl,tm) =
   560     fold_rev (fn vstr => fn tm => mk_aabs(vstr,tm)) vstrl tm;
   555     fold_rev (fn vstr => fn tm => mk_aabs(vstr,tm)) vstrl tm;
   561 
   556 
   562 fun dest_aabs used tm =
   557 fun dest_aabs used tm =
   563    let val ({Bvar,Body}, used') = S.dest_abs used tm
   558    let val ({Bvar,Body}, used') = USyntax.dest_abs used tm
   564    in (Bvar, Body, used') end
   559    in (Bvar, Body, used') end
   565    handle U.ERR _ =>
   560    handle Utils.ERR _ =>
   566      let val {varstruct, body, used} = S.dest_pabs used tm
   561      let val {varstruct, body, used} = USyntax.dest_pabs used tm
   567      in (varstruct, body, used) end;
   562      in (varstruct, body, used) end;
   568 
   563 
   569 fun strip_aabs used tm =
   564 fun strip_aabs used tm =
   570    let val (vstr, body, used') = dest_aabs used tm
   565    let val (vstr, body, used') = dest_aabs used tm
   571        val (bvs, core, used'') = strip_aabs used' body
   566        val (bvs, core, used'') = strip_aabs used' body
   572    in (vstr::bvs, core, used'') end
   567    in (vstr::bvs, core, used'') end
   573    handle U.ERR _ => ([], tm, used);
   568    handle Utils.ERR _ => ([], tm, used);
   574 
   569 
   575 fun dest_combn tm 0 = (tm,[])
   570 fun dest_combn tm 0 = (tm,[])
   576   | dest_combn tm n =
   571   | dest_combn tm n =
   577      let val {Rator,Rand} = S.dest_comb tm
   572      let val {Rator,Rand} = USyntax.dest_comb tm
   578          val (f,rands) = dest_combn Rator (n-1)
   573          val (f,rands) = dest_combn Rator (n-1)
   579      in (f,Rand::rands)
   574      in (f,Rand::rands)
   580      end;
   575      end;
   581 
   576 
   582 
   577 
   583 
   578 
   584 
   579 
   585 local fun dest_pair M = let val {fst,snd} = S.dest_pair M in (fst,snd) end
   580 local fun dest_pair M = let val {fst,snd} = USyntax.dest_pair M in (fst,snd) end
   586       fun mk_fst tm =
   581       fun mk_fst tm =
   587           let val ty as Type(@{type_name Product_Type.prod}, [fty,sty]) = type_of tm
   582           let val ty as Type(@{type_name Product_Type.prod}, [fty,sty]) = type_of tm
   588           in  Const ("Product_Type.fst", ty --> fty) $ tm  end
   583           in  Const ("Product_Type.fst", ty --> fty) $ tm  end
   589       fun mk_snd tm =
   584       fun mk_snd tm =
   590           let val ty as Type(@{type_name Product_Type.prod}, [fty,sty]) = type_of tm
   585           let val ty as Type(@{type_name Product_Type.prod}, [fty,sty]) = type_of tm
   608  * an occurrences of the tuple, they aren't "free" (which is thus probably
   603  * an occurrences of the tuple, they aren't "free" (which is thus probably
   609  *  the wrong word to use).
   604  *  the wrong word to use).
   610  *---------------------------------------------------------------------------*)
   605  *---------------------------------------------------------------------------*)
   611 
   606 
   612 fun VSTRUCT_ELIM tych a vstr th =
   607 fun VSTRUCT_ELIM tych a vstr th =
   613   let val L = S.free_vars_lr vstr
   608   let val L = USyntax.free_vars_lr vstr
   614       val bind1 = tych (HOLogic.mk_Trueprop (HOLogic.mk_eq(a,vstr)))
   609       val bind1 = tych (HOLogic.mk_Trueprop (HOLogic.mk_eq(a,vstr)))
   615       val thm1 = Thm.implies_intr bind1 (SUBS [SYM(Thm.assume bind1)] th)
   610       val thm1 = Thm.implies_intr bind1 (SUBS [SYM(Thm.assume bind1)] th)
   616       val thm2 = forall_intr_list (map tych L) thm1
   611       val thm2 = forall_intr_list (map tych L) thm1
   617       val thm3 = forall_elim_list (XFILL tych a vstr) thm2
   612       val thm3 = forall_elim_list (XFILL tych a vstr) thm2
   618   in refl RS
   613   in refl RS
   639   let val (f,args) = dest_combn M n
   634   let val (f,args) = dest_combn M n
   640       val dummy = dest_aabs used f
   635       val dummy = dest_aabs used f
   641   in (strip_aabs used f,args)
   636   in (strip_aabs used f,args)
   642   end;
   637   end;
   643 
   638 
   644 fun pbeta_redex M n = can (U.C (dest_pbeta_redex []) n) M;
   639 fun pbeta_redex M n = can (Utils.C (dest_pbeta_redex []) n) M;
   645 
   640 
   646 fun dest_impl tm =
   641 fun dest_impl tm =
   647   let val ants = Logic.strip_imp_prems tm
   642   let val ants = Logic.strip_imp_prems tm
   648       val eq = Logic.strip_imp_concl tm
   643       val eq = Logic.strip_imp_concl tm
   649   in (ants,get_lhs eq)
   644   in (ants,get_lhs eq)
   650   end;
   645   end;
   651 
   646 
   652 fun restricted t = is_some (S.find_term
   647 fun restricted t = is_some (USyntax.find_term
   653                             (fn (Const(@{const_name Recdef.cut},_)) =>true | _ => false)
   648                             (fn (Const(@{const_name Recdef.cut},_)) =>true | _ => false)
   654                             t)
   649                             t)
   655 
   650 
   656 fun CONTEXT_REWRITE_RULE (func, G, cut_lemma, congs) th =
   651 fun CONTEXT_REWRITE_RULE (func, G, cut_lemma, congs) th =
   657  let val globals = func::G
   652  let val globals = func::G
   673                      val ants = map tych (Logic.strip_imp_prems imp)
   668                      val ants = map tych (Logic.strip_imp_prems imp)
   674                      val eq = Logic.strip_imp_concl imp
   669                      val eq = Logic.strip_imp_concl imp
   675                      val lhs = tych(get_lhs eq)
   670                      val lhs = tych(get_lhs eq)
   676                      val ss' = Simplifier.add_prems (map ASSUME ants) ss
   671                      val ss' = Simplifier.add_prems (map ASSUME ants) ss
   677                      val lhs_eq_lhs1 = MetaSimplifier.rewrite_cterm (false,true,false) (prover used) ss' lhs
   672                      val lhs_eq_lhs1 = MetaSimplifier.rewrite_cterm (false,true,false) (prover used) ss' lhs
   678                        handle U.ERR _ => Thm.reflexive lhs
   673                        handle Utils.ERR _ => Thm.reflexive lhs
   679                      val dummy = print_thms "proven:" [lhs_eq_lhs1]
   674                      val dummy = print_thms "proven:" [lhs_eq_lhs1]
   680                      val lhs_eq_lhs2 = implies_intr_list ants lhs_eq_lhs1
   675                      val lhs_eq_lhs2 = implies_intr_list ants lhs_eq_lhs1
   681                      val lhs_eeq_lhs2 = lhs_eq_lhs2 RS meta_eq_to_obj_eq
   676                      val lhs_eeq_lhs2 = lhs_eq_lhs2 RS meta_eq_to_obj_eq
   682                   in
   677                   in
   683                   lhs_eeq_lhs2 COMP thm
   678                   lhs_eeq_lhs2 COMP thm
   691                   val tych = cterm_of thy
   686                   val tych = cterm_of thy
   692                   val ants1 = map tych (Logic.strip_imp_prems imp_body1)
   687                   val ants1 = map tych (Logic.strip_imp_prems imp_body1)
   693                   val eq1 = Logic.strip_imp_concl imp_body1
   688                   val eq1 = Logic.strip_imp_concl imp_body1
   694                   val Q = get_lhs eq1
   689                   val Q = get_lhs eq1
   695                   val QeqQ1 = pbeta_reduce (tych Q)
   690                   val QeqQ1 = pbeta_reduce (tych Q)
   696                   val Q1 = #2(D.dest_eq(cconcl QeqQ1))
   691                   val Q1 = #2(Dcterm.dest_eq(cconcl QeqQ1))
   697                   val ss' = Simplifier.add_prems (map ASSUME ants1) ss
   692                   val ss' = Simplifier.add_prems (map ASSUME ants1) ss
   698                   val Q1eeqQ2 = MetaSimplifier.rewrite_cterm (false,true,false) (prover used') ss' Q1
   693                   val Q1eeqQ2 = MetaSimplifier.rewrite_cterm (false,true,false) (prover used') ss' Q1
   699                                 handle U.ERR _ => Thm.reflexive Q1
   694                                 handle Utils.ERR _ => Thm.reflexive Q1
   700                   val Q2 = #2 (Logic.dest_equals (Thm.prop_of Q1eeqQ2))
   695                   val Q2 = #2 (Logic.dest_equals (Thm.prop_of Q1eeqQ2))
   701                   val Q3 = tych(list_comb(list_mk_aabs(vstrl,Q2),vstrl))
   696                   val Q3 = tych(list_comb(list_mk_aabs(vstrl,Q2),vstrl))
   702                   val Q2eeqQ3 = Thm.symmetric(pbeta_reduce Q3 RS eq_reflection)
   697                   val Q2eeqQ3 = Thm.symmetric(pbeta_reduce Q3 RS eq_reflection)
   703                   val thA = Thm.transitive(QeqQ1 RS eq_reflection) Q1eeqQ2
   698                   val thA = Thm.transitive(QeqQ1 RS eq_reflection) Q1eeqQ2
   704                   val QeeqQ3 = Thm.transitive thA Q2eeqQ3 handle THM _ =>
   699                   val QeeqQ3 = Thm.transitive thA Q2eeqQ3 handle THM _ =>
   706                                 RS ((thA RS meta_eq_to_obj_eq) RS trans))
   701                                 RS ((thA RS meta_eq_to_obj_eq) RS trans))
   707                                 RS eq_reflection
   702                                 RS eq_reflection
   708                   val impth = implies_intr_list ants1 QeeqQ3
   703                   val impth = implies_intr_list ants1 QeeqQ3
   709                   val impth1 = impth RS meta_eq_to_obj_eq
   704                   val impth1 = impth RS meta_eq_to_obj_eq
   710                   (* Need to abstract *)
   705                   (* Need to abstract *)
   711                   val ant_th = U.itlist2 (PGEN tych) args vstrl impth1
   706                   val ant_th = Utils.itlist2 (PGEN tych) args vstrl impth1
   712               in ant_th COMP thm
   707               in ant_th COMP thm
   713               end
   708               end
   714              fun q_eliminate (thm,imp,thy) =
   709              fun q_eliminate (thm,imp,thy) =
   715               let val (vlist, imp_body, used') = strip_all used imp
   710               let val (vlist, imp_body, used') = strip_all used imp
   716                   val (ants,Q) = dest_impl imp_body
   711                   val (ants,Q) = dest_impl imp_body
   720                  let val tych = cterm_of thy
   715                  let val tych = cterm_of thy
   721                      val ants1 = map tych ants
   716                      val ants1 = map tych ants
   722                      val ss' = MetaSimplifier.add_prems (map ASSUME ants1) ss
   717                      val ss' = MetaSimplifier.add_prems (map ASSUME ants1) ss
   723                      val Q_eeq_Q1 = MetaSimplifier.rewrite_cterm
   718                      val Q_eeq_Q1 = MetaSimplifier.rewrite_cterm
   724                         (false,true,false) (prover used') ss' (tych Q)
   719                         (false,true,false) (prover used') ss' (tych Q)
   725                       handle U.ERR _ => Thm.reflexive (tych Q)
   720                       handle Utils.ERR _ => Thm.reflexive (tych Q)
   726                      val lhs_eeq_lhs2 = implies_intr_list ants1 Q_eeq_Q1
   721                      val lhs_eeq_lhs2 = implies_intr_list ants1 Q_eeq_Q1
   727                      val lhs_eq_lhs2 = lhs_eeq_lhs2 RS meta_eq_to_obj_eq
   722                      val lhs_eq_lhs2 = lhs_eeq_lhs2 RS meta_eq_to_obj_eq
   728                      val ant_th = forall_intr_list(map tych vlist)lhs_eq_lhs2
   723                      val ant_th = forall_intr_list(map tych vlist)lhs_eq_lhs2
   729                  in
   724                  in
   730                  ant_th COMP thm
   725                  ant_th COMP thm
   738                      then uq_eliminate (thm, imp, Thm.theory_of_thm thm)
   733                      then uq_eliminate (thm, imp, Thm.theory_of_thm thm)
   739                      else q_eliminate (thm, imp, Thm.theory_of_thm thm))
   734                      else q_eliminate (thm, imp, Thm.theory_of_thm thm))
   740                             (* Assume that the leading constant is ==,   *)
   735                             (* Assume that the leading constant is ==,   *)
   741                 | _ => thm  (* if it is not a ==>                        *)
   736                 | _ => thm  (* if it is not a ==>                        *)
   742          in SOME(eliminate (rename thm)) end
   737          in SOME(eliminate (rename thm)) end
   743          handle U.ERR _ => NONE    (* FIXME handle THM as well?? *)
   738          handle Utils.ERR _ => NONE    (* FIXME handle THM as well?? *)
   744 
   739 
   745         fun restrict_prover ss thm =
   740         fun restrict_prover ss thm =
   746           let val dummy = say "restrict_prover:"
   741           let val dummy = say "restrict_prover:"
   747               val cntxt = rev(Simplifier.prems_of_ss ss)
   742               val cntxt = rev(Simplifier.prems_of_ss ss)
   748               val dummy = print_thms "cntxt:" cntxt
   743               val dummy = print_thms "cntxt:" cntxt
   763               fun is_func (Const (name,_)) = (name = func_name)
   758               fun is_func (Const (name,_)) = (name = func_name)
   764                 | is_func _                = false
   759                 | is_func _                = false
   765               val rcontext = rev cntxt
   760               val rcontext = rev cntxt
   766               val cncl = HOLogic.dest_Trueprop o Thm.prop_of
   761               val cncl = HOLogic.dest_Trueprop o Thm.prop_of
   767               val antl = case rcontext of [] => []
   762               val antl = case rcontext of [] => []
   768                          | _   => [S.list_mk_conj(map cncl rcontext)]
   763                          | _   => [USyntax.list_mk_conj(map cncl rcontext)]
   769               val TC = genl(S.list_mk_imp(antl, A))
   764               val TC = genl(USyntax.list_mk_imp(antl, A))
   770               val dummy = print_cterm "func:" (cterm_of thy func)
   765               val dummy = print_cterm "func:" (cterm_of thy func)
   771               val dummy = print_cterm "TC:" (cterm_of thy (HOLogic.mk_Trueprop TC))
   766               val dummy = print_cterm "TC:" (cterm_of thy (HOLogic.mk_Trueprop TC))
   772               val dummy = tc_list := (TC :: !tc_list)
   767               val dummy = tc_list := (TC :: !tc_list)
   773               val nestedp = is_some (S.find_term is_func TC)
   768               val nestedp = is_some (USyntax.find_term is_func TC)
   774               val dummy = if nestedp then say "nested" else say "not_nested"
   769               val dummy = if nestedp then say "nested" else say "not_nested"
   775               val th' = if nestedp then raise RULES_ERR "solver" "nested function"
   770               val th' = if nestedp then raise RULES_ERR "solver" "nested function"
   776                         else let val cTC = cterm_of thy
   771                         else let val cTC = cterm_of thy
   777                                               (HOLogic.mk_Trueprop TC)
   772                                               (HOLogic.mk_Trueprop TC)
   778                              in case rcontext of
   773                              in case rcontext of
   780                                | _ => MP (SPEC_ALL (ASSUME cTC))
   775                                | _ => MP (SPEC_ALL (ASSUME cTC))
   781                                          (LIST_CONJ rcontext)
   776                                          (LIST_CONJ rcontext)
   782                              end
   777                              end
   783               val th'' = th' RS thm
   778               val th'' = th' RS thm
   784           in SOME (th'')
   779           in SOME (th'')
   785           end handle U.ERR _ => NONE    (* FIXME handle THM as well?? *)
   780           end handle Utils.ERR _ => NONE    (* FIXME handle THM as well?? *)
   786     in
   781     in
   787     (if (is_cong thm) then cong_prover else restrict_prover) ss thm
   782     (if (is_cong thm) then cong_prover else restrict_prover) ss thm
   788     end
   783     end
   789     val ctm = cprop_of th
   784     val ctm = cprop_of th
   790     val names = OldTerm.add_term_names (term_of ctm, [])
   785     val names = OldTerm.add_term_names (term_of ctm, [])