src/HOL/Tools/groebner.ML
changeset 67149 e61557884799
parent 63211 0bec0d1d9998
child 67230 b2800da9eb8a
equal deleted inserted replaced
67148:d24dcac5eb4c 67149:e61557884799
   325   resolve_proof vars h end;
   325   resolve_proof vars h end;
   326 
   326 
   327 (* Produce Strong Nullstellensatz certificate for a power of pol.            *)
   327 (* Produce Strong Nullstellensatz certificate for a power of pol.            *)
   328 
   328 
   329 fun grobner_strong vars pols pol =
   329 fun grobner_strong vars pols pol =
   330     let val vars' = @{cterm "True"}::vars
   330     let val vars' = \<^cterm>\<open>True\<close>::vars
   331         val grob_z = [(@1, 1::(map (K 0) vars))]
   331         val grob_z = [(@1, 1::(map (K 0) vars))]
   332         val grob_1 = [(@1, (map (K 0) vars'))]
   332         val grob_1 = [(@1, (map (K 0) vars'))]
   333         fun augment p= map (fn (c,m) => (c,0::m)) p
   333         fun augment p= map (fn (c,m) => (c,0::m)) p
   334         val pols' = map augment pols
   334         val pols' = map augment pols
   335         val pol' = augment pol
   335         val pol' = augment pol
   347 (* Overall parametrized universal procedure for (semi)rings.                 *)
   347 (* Overall parametrized universal procedure for (semi)rings.                 *)
   348 (* We return an ideal_conv and the actual ring prover.                       *)
   348 (* We return an ideal_conv and the actual ring prover.                       *)
   349 
   349 
   350 fun refute_disj rfn tm =
   350 fun refute_disj rfn tm =
   351  case Thm.term_of tm of
   351  case Thm.term_of tm of
   352   Const(@{const_name HOL.disj},_)$_$_ =>
   352   Const(\<^const_name>\<open>HOL.disj\<close>,_)$_$_ =>
   353    Drule.compose
   353    Drule.compose
   354     (refute_disj rfn (Thm.dest_arg tm), 2,
   354     (refute_disj rfn (Thm.dest_arg tm), 2,
   355       Drule.compose (refute_disj rfn (Thm.dest_arg1 tm), 2, disjE))
   355       Drule.compose (refute_disj rfn (Thm.dest_arg1 tm), 2, disjE))
   356   | _ => rfn tm ;
   356   | _ => rfn tm ;
   357 
   357 
   358 val notnotD = @{thm notnotD};
   358 val notnotD = @{thm notnotD};
   359 fun mk_binop ct x y = Thm.apply (Thm.apply ct x) y
   359 fun mk_binop ct x y = Thm.apply (Thm.apply ct x) y
   360 
   360 
   361 fun is_neg t =
   361 fun is_neg t =
   362     case Thm.term_of t of
   362     case Thm.term_of t of
   363       (Const(@{const_name Not},_)$_) => true
   363       (Const(\<^const_name>\<open>Not\<close>,_)$_) => true
   364     | _  => false;
   364     | _  => false;
   365 fun is_eq t =
   365 fun is_eq t =
   366  case Thm.term_of t of
   366  case Thm.term_of t of
   367  (Const(@{const_name HOL.eq},_)$_$_) => true
   367  (Const(\<^const_name>\<open>HOL.eq\<close>,_)$_$_) => true
   368 | _  => false;
   368 | _  => false;
   369 
   369 
   370 fun end_itlist f l =
   370 fun end_itlist f l =
   371   case l of
   371   case l of
   372         []     => error "end_itlist"
   372         []     => error "end_itlist"
   383  end;
   383  end;
   384 
   384 
   385 val strip_exists =
   385 val strip_exists =
   386  let fun h (acc, t) =
   386  let fun h (acc, t) =
   387       case Thm.term_of t of
   387       case Thm.term_of t of
   388        Const (@{const_name Ex}, _) $ Abs _ =>
   388        Const (\<^const_name>\<open>Ex\<close>, _) $ Abs _ =>
   389         h (Thm.dest_abs NONE (Thm.dest_arg t) |>> (fn v => v::acc))
   389         h (Thm.dest_abs NONE (Thm.dest_arg t) |>> (fn v => v::acc))
   390      | _ => (acc,t)
   390      | _ => (acc,t)
   391  in fn t => h ([],t)
   391  in fn t => h ([],t)
   392  end;
   392  end;
   393 
   393 
   394 fun is_forall t =
   394 fun is_forall t =
   395  case Thm.term_of t of
   395  case Thm.term_of t of
   396   (Const(@{const_name All},_)$Abs(_,_,_)) => true
   396   (Const(\<^const_name>\<open>All\<close>,_)$Abs(_,_,_)) => true
   397 | _ => false;
   397 | _ => false;
   398 
   398 
   399 val mk_object_eq = fn th => th COMP meta_eq_to_obj_eq;
   399 val mk_object_eq = fn th => th COMP meta_eq_to_obj_eq;
   400 val nnf_simps = @{thms nnf_simps};
   400 val nnf_simps = @{thms nnf_simps};
   401 
   401 
   410 fun initial_conv ctxt =
   410 fun initial_conv ctxt =
   411   Simplifier.rewrite (put_simpset initial_ss ctxt);
   411   Simplifier.rewrite (put_simpset initial_ss ctxt);
   412 
   412 
   413 val specl = fold_rev (fn x => fn th => Thm.instantiate' [] [SOME x] (th RS spec));
   413 val specl = fold_rev (fn x => fn th => Thm.instantiate' [] [SOME x] (th RS spec));
   414 
   414 
   415 val cTrp = @{cterm "Trueprop"};
   415 val cTrp = \<^cterm>\<open>Trueprop\<close>;
   416 val cConj = @{cterm HOL.conj};
   416 val cConj = \<^cterm>\<open>HOL.conj\<close>;
   417 val (cNot,false_tm) = (@{cterm "Not"}, @{cterm "False"});
   417 val (cNot,false_tm) = (\<^cterm>\<open>Not\<close>, \<^cterm>\<open>False\<close>);
   418 val assume_Trueprop = Thm.apply cTrp #> Thm.assume;
   418 val assume_Trueprop = Thm.apply cTrp #> Thm.assume;
   419 val list_mk_conj = list_mk_binop cConj;
   419 val list_mk_conj = list_mk_binop cConj;
   420 val conjs = list_dest_binop cConj;
   420 val conjs = list_dest_binop cConj;
   421 val mk_neg = Thm.apply cNot;
   421 val mk_neg = Thm.apply cNot;
   422 
   422 
   436  end;
   436  end;
   437 
   437 
   438   (* FIXME : copied from cqe.ML -- complex QE*)
   438   (* FIXME : copied from cqe.ML -- complex QE*)
   439 fun conjuncts ct =
   439 fun conjuncts ct =
   440  case Thm.term_of ct of
   440  case Thm.term_of ct of
   441   @{term HOL.conj}$_$_ => (Thm.dest_arg1 ct)::(conjuncts (Thm.dest_arg ct))
   441   \<^term>\<open>HOL.conj\<close>$_$_ => (Thm.dest_arg1 ct)::(conjuncts (Thm.dest_arg ct))
   442 | _ => [ct];
   442 | _ => [ct];
   443 
   443 
   444 fun fold1 f = foldr1 (uncurry f);
   444 fun fold1 f = foldr1 (uncurry f);
   445 
   445 
   446 fun mk_conj_tab th =
   446 fun mk_conj_tab th =
   447  let fun h acc th =
   447  let fun h acc th =
   448    case Thm.prop_of th of
   448    case Thm.prop_of th of
   449    @{term "Trueprop"}$(@{term HOL.conj}$_$_) =>
   449    \<^term>\<open>Trueprop\<close>$(\<^term>\<open>HOL.conj\<close>$_$_) =>
   450      h (h acc (th RS conjunct2)) (th RS conjunct1)
   450      h (h acc (th RS conjunct2)) (th RS conjunct1)
   451   | @{term "Trueprop"}$p => (p,th)::acc
   451   | \<^term>\<open>Trueprop\<close>$p => (p,th)::acc
   452 in fold (Termtab.insert Thm.eq_thm) (h [] th) Termtab.empty end;
   452 in fold (Termtab.insert Thm.eq_thm) (h [] th) Termtab.empty end;
   453 
   453 
   454 fun is_conj (@{term HOL.conj}$_$_) = true
   454 fun is_conj (\<^term>\<open>HOL.conj\<close>$_$_) = true
   455   | is_conj _ = false;
   455   | is_conj _ = false;
   456 
   456 
   457 fun prove_conj tab cjs =
   457 fun prove_conj tab cjs =
   458  case cjs of
   458  case cjs of
   459    [c] => if is_conj (Thm.term_of c) then prove_conj tab (conjuncts c) else tab c
   459    [c] => if is_conj (Thm.term_of c) then prove_conj tab (conjuncts c) else tab c
   460  | c::cs => conjI OF [prove_conj tab [c], prove_conj tab cs];
   460  | c::cs => conjI OF [prove_conj tab [c], prove_conj tab cs];
   461 
   461 
   462 fun conj_ac_rule eq =
   462 fun conj_ac_rule eq =
   463  let
   463  let
   464   val (l,r) = Thm.dest_equals eq
   464   val (l,r) = Thm.dest_equals eq
   465   val ctabl = mk_conj_tab (Thm.assume (Thm.apply @{cterm Trueprop} l))
   465   val ctabl = mk_conj_tab (Thm.assume (Thm.apply \<^cterm>\<open>Trueprop\<close> l))
   466   val ctabr = mk_conj_tab (Thm.assume (Thm.apply @{cterm Trueprop} r))
   466   val ctabr = mk_conj_tab (Thm.assume (Thm.apply \<^cterm>\<open>Trueprop\<close> r))
   467   fun tabl c = the (Termtab.lookup ctabl (Thm.term_of c))
   467   fun tabl c = the (Termtab.lookup ctabl (Thm.term_of c))
   468   fun tabr c = the (Termtab.lookup ctabr (Thm.term_of c))
   468   fun tabr c = the (Termtab.lookup ctabr (Thm.term_of c))
   469   val thl  = prove_conj tabl (conjuncts r) |> implies_intr_hyps
   469   val thl  = prove_conj tabl (conjuncts r) |> implies_intr_hyps
   470   val thr  = prove_conj tabr (conjuncts l) |> implies_intr_hyps
   470   val thr  = prove_conj tabr (conjuncts l) |> implies_intr_hyps
   471   val eqI = Thm.instantiate' [] [SOME l, SOME r] @{thm iffI}
   471   val eqI = Thm.instantiate' [] [SOME l, SOME r] @{thm iffI}
   473 
   473 
   474  (* END FIXME.*)
   474  (* END FIXME.*)
   475 
   475 
   476    (* Conversion for the equivalence of existential statements where
   476    (* Conversion for the equivalence of existential statements where
   477       EX quantifiers are rearranged differently *)
   477       EX quantifiers are rearranged differently *)
   478 fun ext ctxt T = Thm.cterm_of ctxt (Const (@{const_name Ex}, (T --> @{typ bool}) --> @{typ bool}))
   478 fun ext ctxt T = Thm.cterm_of ctxt (Const (\<^const_name>\<open>Ex\<close>, (T --> \<^typ>\<open>bool\<close>) --> \<^typ>\<open>bool\<close>))
   479 fun mk_ex ctxt v t = Thm.apply (ext ctxt (Thm.typ_of_cterm v)) (Thm.lambda v t)
   479 fun mk_ex ctxt v t = Thm.apply (ext ctxt (Thm.typ_of_cterm v)) (Thm.lambda v t)
   480 
   480 
   481 fun choose v th th' = case Thm.concl_of th of
   481 fun choose v th th' = case Thm.concl_of th of
   482   @{term Trueprop} $ (Const(@{const_name Ex},_)$_) =>
   482   \<^term>\<open>Trueprop\<close> $ (Const(\<^const_name>\<open>Ex\<close>,_)$_) =>
   483    let
   483    let
   484     val p = (funpow 2 Thm.dest_arg o Thm.cprop_of) th
   484     val p = (funpow 2 Thm.dest_arg o Thm.cprop_of) th
   485     val T = (hd o Thm.dest_ctyp o Thm.ctyp_of_cterm) p
   485     val T = (hd o Thm.dest_ctyp o Thm.ctyp_of_cterm) p
   486     val th0 = Conv.fconv_rule (Thm.beta_conversion true)
   486     val th0 = Conv.fconv_rule (Thm.beta_conversion true)
   487         (Thm.instantiate' [SOME T] [SOME p, (SOME o Thm.dest_arg o Thm.cprop_of) th'] exE)
   487         (Thm.instantiate' [SOME T] [SOME p, (SOME o Thm.dest_arg o Thm.cprop_of) th'] exE)
   488     val pv = (Thm.rhs_of o Thm.beta_conversion true)
   488     val pv = (Thm.rhs_of o Thm.beta_conversion true)
   489           (Thm.apply @{cterm Trueprop} (Thm.apply p v))
   489           (Thm.apply \<^cterm>\<open>Trueprop\<close> (Thm.apply p v))
   490     val th1 = Thm.forall_intr v (Thm.implies_intr pv th')
   490     val th1 = Thm.forall_intr v (Thm.implies_intr pv th')
   491    in Thm.implies_elim (Thm.implies_elim th0 th) th1  end
   491    in Thm.implies_elim (Thm.implies_elim th0 th) th1  end
   492 | _ => error ""  (* FIXME ? *)
   492 | _ => error ""  (* FIXME ? *)
   493 
   493 
   494 fun simple_choose ctxt v th =
   494 fun simple_choose ctxt v th =
   495    choose v (Thm.assume ((Thm.apply @{cterm Trueprop} o mk_ex ctxt v)
   495    choose v (Thm.assume ((Thm.apply \<^cterm>\<open>Trueprop\<close> o mk_ex ctxt v)
   496     (Thm.dest_arg (hd (Thm.chyps_of th))))) th
   496     (Thm.dest_arg (hd (Thm.chyps_of th))))) th
   497 
   497 
   498 
   498 
   499  fun mkexi v th =
   499  fun mkexi v th =
   500   let
   500   let
   507  fun ex_eq_conv ctxt t =
   507  fun ex_eq_conv ctxt t =
   508   let
   508   let
   509   val (p0,q0) = Thm.dest_binop t
   509   val (p0,q0) = Thm.dest_binop t
   510   val (vs',P) = strip_exists p0
   510   val (vs',P) = strip_exists p0
   511   val (vs,_) = strip_exists q0
   511   val (vs,_) = strip_exists q0
   512    val th = Thm.assume (Thm.apply @{cterm Trueprop} P)
   512    val th = Thm.assume (Thm.apply \<^cterm>\<open>Trueprop\<close> P)
   513    val th1 = implies_intr_hyps (fold (simple_choose ctxt) vs' (fold mkexi vs th))
   513    val th1 = implies_intr_hyps (fold (simple_choose ctxt) vs' (fold mkexi vs th))
   514    val th2 = implies_intr_hyps (fold (simple_choose ctxt) vs (fold mkexi vs' th))
   514    val th2 = implies_intr_hyps (fold (simple_choose ctxt) vs (fold mkexi vs' th))
   515    val p = (Thm.dest_arg o Thm.dest_arg1 o Thm.cprop_of) th1
   515    val p = (Thm.dest_arg o Thm.dest_arg1 o Thm.cprop_of) th1
   516    val q = (Thm.dest_arg o Thm.dest_arg o Thm.cprop_of) th1
   516    val q = (Thm.dest_arg o Thm.dest_arg o Thm.cprop_of) th1
   517   in Thm.implies_elim (Thm.implies_elim (Thm.instantiate' [] [SOME p, SOME q] iffI) th1) th2
   517   in Thm.implies_elim (Thm.implies_elim (Thm.instantiate' [] [SOME p, SOME q] iffI) th1) th2
   521 
   521 
   522  fun getname v = case Thm.term_of v of
   522  fun getname v = case Thm.term_of v of
   523   Free(s,_) => s
   523   Free(s,_) => s
   524  | Var ((s,_),_) => s
   524  | Var ((s,_),_) => s
   525  | _ => "x"
   525  | _ => "x"
   526  fun mk_eq s t = Thm.apply (Thm.apply @{cterm "op == :: bool => _"} s) t
   526  fun mk_eq s t = Thm.apply (Thm.apply \<^cterm>\<open>op \<equiv> :: bool \<Rightarrow> _\<close> s) t
   527  fun mk_exists ctxt v th = Drule.arg_cong_rule (ext ctxt (Thm.typ_of_cterm v))
   527  fun mk_exists ctxt v th = Drule.arg_cong_rule (ext ctxt (Thm.typ_of_cterm v))
   528    (Thm.abstract_rule (getname v) v th)
   528    (Thm.abstract_rule (getname v) v th)
   529  fun simp_ex_conv ctxt =
   529  fun simp_ex_conv ctxt =
   530    Simplifier.rewrite (put_simpset HOL_basic_ss ctxt addsimps @{thms simp_thms(39)})
   530    Simplifier.rewrite (put_simpset HOL_basic_ss ctxt addsimps @{thms simp_thms(39)})
   531 
   531 
   550     map Thm.dest_fun2 [add_pat, mul_pat, pow_pat];
   550     map Thm.dest_fun2 [add_pat, mul_pat, pow_pat];
   551 
   551 
   552   val (ring_sub_tm, ring_neg_tm) =
   552   val (ring_sub_tm, ring_neg_tm) =
   553     (case r_ops of
   553     (case r_ops of
   554      [sub_pat, neg_pat] => (Thm.dest_fun2 sub_pat, Thm.dest_fun neg_pat)
   554      [sub_pat, neg_pat] => (Thm.dest_fun2 sub_pat, Thm.dest_fun neg_pat)
   555     |_  => (@{cterm "True"}, @{cterm "True"}));
   555     |_  => (\<^cterm>\<open>True\<close>, \<^cterm>\<open>True\<close>));
   556 
   556 
   557   val (field_div_tm, field_inv_tm) =
   557   val (field_div_tm, field_inv_tm) =
   558     (case f_ops of
   558     (case f_ops of
   559        [div_pat, inv_pat] => (Thm.dest_fun2 div_pat, Thm.dest_fun inv_pat)
   559        [div_pat, inv_pat] => (Thm.dest_fun2 div_pat, Thm.dest_fun inv_pat)
   560      | _ => (@{cterm "True"}, @{cterm "True"}));
   560      | _ => (\<^cterm>\<open>True\<close>, \<^cterm>\<open>True\<close>));
   561 
   561 
   562   val [idom_thm, neq_thm] = idom;
   562   val [idom_thm, neq_thm] = idom;
   563   val [idl_sub, idl_add0] =
   563   val [idl_sub, idl_add0] =
   564      if length ideal = 2 then ideal else [eq_commute, eq_commute]
   564      if length ideal = 2 then ideal else [eq_commute, eq_commute]
   565   fun ring_dest_neg t =
   565   fun ring_dest_neg t =
   651  in (vars,map (grobify_equation vars) cjs)
   651  in (vars,map (grobify_equation vars) cjs)
   652  end;
   652  end;
   653 
   653 
   654 val holify_polynomial =
   654 val holify_polynomial =
   655  let fun holify_varpow (v,n) =
   655  let fun holify_varpow (v,n) =
   656   if n = 1 then v else ring_mk_pow v (Numeral.mk_cnumber @{ctyp nat} n)  (* FIXME *)
   656   if n = 1 then v else ring_mk_pow v (Numeral.mk_cnumber \<^ctyp>\<open>nat\<close> n)  (* FIXME *)
   657  fun holify_monomial vars (c,m) =
   657  fun holify_monomial vars (c,m) =
   658   let val xps = map holify_varpow (filter (fn (_,n) => n <> 0) (vars ~~ m))
   658   let val xps = map holify_varpow (filter (fn (_,n) => n <> 0) (vars ~~ m))
   659    in end_itlist ring_mk_mul (mk_const c :: xps)
   659    in end_itlist ring_mk_mul (mk_const c :: xps)
   660   end
   660   end
   661  fun holify_polynomial vars p =
   661  fun holify_polynomial vars p =
   735 fun ring ctxt tm =
   735 fun ring ctxt tm =
   736  let
   736  let
   737   fun mk_forall x p =
   737   fun mk_forall x p =
   738     let
   738     let
   739       val T = Thm.typ_of_cterm x;
   739       val T = Thm.typ_of_cterm x;
   740       val all = Thm.cterm_of ctxt (Const (@{const_name All}, (T --> @{typ bool}) --> @{typ bool}))
   740       val all = Thm.cterm_of ctxt (Const (\<^const_name>\<open>All\<close>, (T --> \<^typ>\<open>bool\<close>) --> \<^typ>\<open>bool\<close>))
   741     in Thm.apply all (Thm.lambda x p) end
   741     in Thm.apply all (Thm.lambda x p) end
   742   val avs = Drule.cterm_add_frees tm []
   742   val avs = Drule.cterm_add_frees tm []
   743   val P' = fold mk_forall avs tm
   743   val P' = fold mk_forall avs tm
   744   val th1 = initial_conv ctxt (mk_neg P')
   744   val th1 = initial_conv ctxt (mk_neg P')
   745   val (evs,bod) = strip_exists(concl th1) in
   745   val (evs,bod) = strip_exists(concl th1) in
   817    end
   817    end
   818  in
   818  in
   819  fun unwind_polys_conv ctxt tm =
   819  fun unwind_polys_conv ctxt tm =
   820  let
   820  let
   821   val (vars,bod) = strip_exists tm
   821   val (vars,bod) = strip_exists tm
   822   val cjs = striplist (dest_binary @{cterm HOL.conj}) bod
   822   val cjs = striplist (dest_binary \<^cterm>\<open>HOL.conj\<close>) bod
   823   val th1 = (the (get_first (try (isolate_variable vars)) cjs)
   823   val th1 = (the (get_first (try (isolate_variable vars)) cjs)
   824              handle Option.Option => raise CTERM ("unwind_polys_conv",[tm]))
   824              handle Option.Option => raise CTERM ("unwind_polys_conv",[tm]))
   825   val eq = Thm.lhs_of th1
   825   val eq = Thm.lhs_of th1
   826   val bod' = list_mk_binop @{cterm HOL.conj} (eq::(remove op aconvc eq cjs))
   826   val bod' = list_mk_binop \<^cterm>\<open>HOL.conj\<close> (eq::(remove op aconvc eq cjs))
   827   val th2 = conj_ac_rule (mk_eq bod bod')
   827   val th2 = conj_ac_rule (mk_eq bod bod')
   828   val th3 =
   828   val th3 =
   829     Thm.transitive th2
   829     Thm.transitive th2
   830       (Drule.binop_cong_rule @{cterm HOL.conj} th1
   830       (Drule.binop_cong_rule \<^cterm>\<open>HOL.conj\<close> th1
   831         (Thm.reflexive (Thm.dest_arg (Thm.rhs_of th2))))
   831         (Thm.reflexive (Thm.dest_arg (Thm.rhs_of th2))))
   832   val v = Thm.dest_arg1(Thm.dest_arg1(Thm.rhs_of th3))
   832   val v = Thm.dest_arg1(Thm.dest_arg1(Thm.rhs_of th3))
   833   val th4 = Conv.fconv_rule (Conv.arg_conv (simp_ex_conv ctxt)) (mk_exists ctxt v th3)
   833   val th4 = Conv.fconv_rule (Conv.arg_conv (simp_ex_conv ctxt)) (mk_exists ctxt v th3)
   834   val th5 = ex_eq_conv ctxt (mk_eq tm (fold (mk_ex ctxt) (remove op aconvc v vars) (Thm.lhs_of th4)))
   834   val th5 = ex_eq_conv ctxt (mk_eq tm (fold (mk_ex ctxt) (remove op aconvc v vars) (Thm.lhs_of th4)))
   835  in Thm.transitive th5 (fold (mk_exists ctxt) (remove op aconvc v vars) th4)
   835  in Thm.transitive th5 (fold (mk_exists ctxt) (remove op aconvc v vars) th4)
   888 end;
   888 end;
   889 
   889 
   890 
   890 
   891 fun find_term bounds tm =
   891 fun find_term bounds tm =
   892   (case Thm.term_of tm of
   892   (case Thm.term_of tm of
   893     Const (@{const_name HOL.eq}, T) $ _ $ _ =>
   893     Const (\<^const_name>\<open>HOL.eq\<close>, T) $ _ $ _ =>
   894       if domain_type T = HOLogic.boolT then find_args bounds tm
   894       if domain_type T = HOLogic.boolT then find_args bounds tm
   895       else Thm.dest_arg tm
   895       else Thm.dest_arg tm
   896   | Const (@{const_name Not}, _) $ _ => find_term bounds (Thm.dest_arg tm)
   896   | Const (\<^const_name>\<open>Not\<close>, _) $ _ => find_term bounds (Thm.dest_arg tm)
   897   | Const (@{const_name All}, _) $ _ => find_body bounds (Thm.dest_arg tm)
   897   | Const (\<^const_name>\<open>All\<close>, _) $ _ => find_body bounds (Thm.dest_arg tm)
   898   | Const (@{const_name Ex}, _) $ _ => find_body bounds (Thm.dest_arg tm)
   898   | Const (\<^const_name>\<open>Ex\<close>, _) $ _ => find_body bounds (Thm.dest_arg tm)
   899   | Const (@{const_name HOL.conj}, _) $ _ $ _ => find_args bounds tm
   899   | Const (\<^const_name>\<open>HOL.conj\<close>, _) $ _ $ _ => find_args bounds tm
   900   | Const (@{const_name HOL.disj}, _) $ _ $ _ => find_args bounds tm
   900   | Const (\<^const_name>\<open>HOL.disj\<close>, _) $ _ $ _ => find_args bounds tm
   901   | Const (@{const_name HOL.implies}, _) $ _ $ _ => find_args bounds tm
   901   | Const (\<^const_name>\<open>HOL.implies\<close>, _) $ _ $ _ => find_args bounds tm
   902   | @{term "op ==>"} $_$_ => find_args bounds tm
   902   | \<^term>\<open>op \<Longrightarrow>\<close> $_$_ => find_args bounds tm
   903   | Const("op ==",_)$_$_ => find_args bounds tm
   903   | Const("op ==",_)$_$_ => find_args bounds tm  (* FIXME proper const name *)
   904   | @{term Trueprop}$_ => find_term bounds (Thm.dest_arg tm)
   904   | \<^term>\<open>Trueprop\<close>$_ => find_term bounds (Thm.dest_arg tm)
   905   | _ => raise TERM ("find_term", []))
   905   | _ => raise TERM ("find_term", []))
   906 and find_args bounds tm =
   906 and find_args bounds tm =
   907   let val (t, u) = Thm.dest_binop tm
   907   let val (t, u) = Thm.dest_binop tm
   908   in (find_term bounds t handle TERM _ => find_term bounds u) end
   908   in (find_term bounds t handle TERM _ => find_term bounds u) end
   909 and find_body bounds b =
   909 and find_body bounds b =
   923           dest_const (mk_const (Thm.ctyp_of_cterm tm)) (ring_eq_conv ctxt)
   923           dest_const (mk_const (Thm.ctyp_of_cterm tm)) (ring_eq_conv ctxt)
   924           (Semiring_Normalizer.semiring_normalize_wrapper ctxt res)))
   924           (Semiring_Normalizer.semiring_normalize_wrapper ctxt res)))
   925 
   925 
   926 fun presimplify ctxt add_thms del_thms =
   926 fun presimplify ctxt add_thms del_thms =
   927   asm_full_simp_tac (put_simpset HOL_basic_ss ctxt
   927   asm_full_simp_tac (put_simpset HOL_basic_ss ctxt
   928     addsimps (Named_Theorems.get ctxt @{named_theorems algebra})
   928     addsimps (Named_Theorems.get ctxt \<^named_theorems>\<open>algebra\<close>)
   929     delsimps del_thms addsimps add_thms);
   929     delsimps del_thms addsimps add_thms);
   930 
   930 
   931 fun ring_tac add_ths del_ths ctxt =
   931 fun ring_tac add_ths del_ths ctxt =
   932   Object_Logic.full_atomize_tac ctxt
   932   Object_Logic.full_atomize_tac ctxt
   933   THEN' presimplify ctxt add_ths del_ths
   933   THEN' presimplify ctxt add_ths del_ths
   941         | CTERM _ => no_tac
   941         | CTERM _ => no_tac
   942         | THM _ => no_tac);
   942         | THM _ => no_tac);
   943 
   943 
   944 local
   944 local
   945  fun lhs t = case Thm.term_of t of
   945  fun lhs t = case Thm.term_of t of
   946   Const(@{const_name HOL.eq},_)$_$_ => Thm.dest_arg1 t
   946   Const(\<^const_name>\<open>HOL.eq\<close>,_)$_$_ => Thm.dest_arg1 t
   947  | _=> raise CTERM ("ideal_tac - lhs",[t])
   947  | _=> raise CTERM ("ideal_tac - lhs",[t])
   948  fun exitac _ NONE = no_tac
   948  fun exitac _ NONE = no_tac
   949    | exitac ctxt (SOME y) =
   949    | exitac ctxt (SOME y) =
   950       resolve_tac ctxt [Thm.instantiate' [SOME (Thm.ctyp_of_cterm y)] [NONE,SOME y] exI] 1
   950       resolve_tac ctxt [Thm.instantiate' [SOME (Thm.ctyp_of_cterm y)] [NONE,SOME y] exI] 1
   951 
   951