src/HOL/Decision_Procs/Commutative_Ring.thy
changeset 74397 e80c4cde6064
parent 70019 095dce9892e8
child 74561 8e6c973003c8
equal deleted inserted replaced
74396:dc73f9e6476b 74397:e80c4cde6064
   647 
   647 
   648 lemma in_carrier_trivial: "cring_class.in_carrier l"
   648 lemma in_carrier_trivial: "cring_class.in_carrier l"
   649   by (induct l) (simp_all add: cring_class.in_carrier_def carrier_class)
   649   by (induct l) (simp_all add: cring_class.in_carrier_def carrier_class)
   650 
   650 
   651 ML \<open>
   651 ML \<open>
   652 val term_of_nat = HOLogic.mk_number \<^typ>\<open>nat\<close> o @{code integer_of_nat};
   652 val term_of_nat = HOLogic.mk_number \<^Type>\<open>nat\<close> o @{code integer_of_nat};
   653 
   653 
   654 val term_of_int = HOLogic.mk_number \<^typ>\<open>int\<close> o @{code integer_of_int};
   654 val term_of_int = HOLogic.mk_number \<^Type>\<open>int\<close> o @{code integer_of_int};
   655 
   655 
   656 fun term_of_pol (@{code Pc} k) = \<^term>\<open>Pc\<close> $ term_of_int k
   656 fun term_of_pol (@{code Pc} k) = \<^Const>\<open>Pc\<close> $ term_of_int k
   657   | term_of_pol (@{code Pinj} (n, p)) = \<^term>\<open>Pinj\<close> $ term_of_nat n $ term_of_pol p
   657   | term_of_pol (@{code Pinj} (n, p)) = \<^Const>\<open>Pinj\<close> $ term_of_nat n $ term_of_pol p
   658   | term_of_pol (@{code PX} (p, n, q)) = \<^term>\<open>PX\<close> $ term_of_pol p $ term_of_nat n $ term_of_pol q;
   658   | term_of_pol (@{code PX} (p, n, q)) = \<^Const>\<open>PX\<close> $ term_of_pol p $ term_of_nat n $ term_of_pol q;
   659 
   659 
   660 local
   660 local
   661 
   661 
   662 fun pol (ctxt, ct, t) = Thm.mk_binop \<^cterm>\<open>Pure.eq :: pol \<Rightarrow> pol \<Rightarrow> prop\<close>
   662 fun pol (ctxt, ct, t) = Thm.mk_binop \<^cterm>\<open>Pure.eq :: pol \<Rightarrow> pol \<Rightarrow> prop\<close>
   663   ct (Thm.cterm_of ctxt t);
   663   ct (Thm.cterm_of ctxt t);
   740          Thm.transfer' ctxt #>
   740          Thm.transfer' ctxt #>
   741          (case optcT of NONE => I | SOME cT => inst [cT] [] #> norm)
   741          (case optcT of NONE => I | SOME cT => inst [cT] [] #> norm)
   742        in (map tr ths1, map tr ths2, map tr ths3, map tr ths4, tr th5, tr th) end
   742        in (map tr ths1, map tr ths2, map tr ths3, map tr ths4, tr th5, tr th) end
   743    | NONE => error "get_ring_simps: lookup failed");
   743    | NONE => error "get_ring_simps: lookup failed");
   744 
   744 
   745 fun ring_struct (Const (\<^const_name>\<open>Ring.ring.add\<close>, _) $ R $ _ $ _) = SOME R
   745 fun ring_struct \<^Const_>\<open>Ring.ring.add _ _ for R _ _\<close> = SOME R
   746   | ring_struct (Const (\<^const_name>\<open>Ring.a_minus\<close>, _) $ R $ _ $ _) = SOME R
   746   | ring_struct \<^Const_>\<open>Ring.a_minus _ _ for R _ _\<close> = SOME R
   747   | ring_struct (Const (\<^const_name>\<open>Group.monoid.mult\<close>, _) $ R $ _ $ _) = SOME R
   747   | ring_struct \<^Const_>\<open>Group.monoid.mult _ _ for R _ _\<close> = SOME R
   748   | ring_struct (Const (\<^const_name>\<open>Ring.a_inv\<close>, _) $ R $ _) = SOME R
   748   | ring_struct \<^Const_>\<open>Ring.a_inv _ _ for R _\<close> = SOME R
   749   | ring_struct (Const (\<^const_name>\<open>Group.pow\<close>, _) $ R $ _ $ _) = SOME R
   749   | ring_struct \<^Const_>\<open>Group.pow _ _ _ for R _ _\<close> = SOME R
   750   | ring_struct (Const (\<^const_name>\<open>Ring.ring.zero\<close>, _) $ R) = SOME R
   750   | ring_struct \<^Const_>\<open>Ring.ring.zero _ _ for R\<close> = SOME R
   751   | ring_struct (Const (\<^const_name>\<open>Group.monoid.one\<close>, _) $ R) = SOME R
   751   | ring_struct \<^Const_>\<open>Group.monoid.one _ _ for R\<close> = SOME R
   752   | ring_struct (Const (\<^const_name>\<open>Algebra_Aux.of_integer\<close>, _) $ R $ _) = SOME R
   752   | ring_struct \<^Const_>\<open>Algebra_Aux.of_integer _ _ for R _\<close> = SOME R
   753   | ring_struct _ = NONE;
   753   | ring_struct _ = NONE;
   754 
   754 
   755 fun reif_polex vs (Const (\<^const_name>\<open>Ring.ring.add\<close>, _) $ _ $ a $ b) =
   755 fun reif_polex vs \<^Const_>\<open>Ring.ring.add _ _ for _ a b\<close> =
   756       \<^const>\<open>Add\<close> $ reif_polex vs a $ reif_polex vs b
   756       \<^Const>\<open>Add for \<open>reif_polex vs a\<close> \<open>reif_polex vs b\<close>\<close>
   757   | reif_polex vs (Const (\<^const_name>\<open>Ring.a_minus\<close>, _) $ _ $ a $ b) =
   757   | reif_polex vs \<^Const_>\<open>Ring.a_minus _ _ for _ a b\<close> =
   758       \<^const>\<open>Sub\<close> $ reif_polex vs a $ reif_polex vs b
   758       \<^Const>\<open>Sub for \<open>reif_polex vs a\<close> \<open>reif_polex vs b\<close>\<close>
   759   | reif_polex vs (Const (\<^const_name>\<open>Group.monoid.mult\<close>, _) $ _ $ a $ b) =
   759   | reif_polex vs \<^Const_>\<open>Group.monoid.mult _ _ for _ a b\<close> =
   760       \<^const>\<open>Mul\<close> $ reif_polex vs a $ reif_polex vs b
   760       \<^Const>\<open>Mul for \<open>reif_polex vs a\<close> \<open>reif_polex vs b\<close>\<close>
   761   | reif_polex vs (Const (\<^const_name>\<open>Ring.a_inv\<close>, _) $ _ $ a) =
   761   | reif_polex vs \<^Const_>\<open>Ring.a_inv _ _ for _ a\<close> =
   762       \<^const>\<open>Neg\<close> $ reif_polex vs a
   762       \<^Const>\<open>Neg for \<open>reif_polex vs a\<close>\<close>
   763   | reif_polex vs (Const (\<^const_name>\<open>Group.pow\<close>, _) $ _ $ a $ n) =
   763   | reif_polex vs \<^Const_>\<open>Group.pow _ _ _ for _ a n\<close> =
   764       \<^const>\<open>Pow\<close> $ reif_polex vs a $ n
   764       \<^Const>\<open>Pow for \<open>reif_polex vs a\<close> n\<close>
   765   | reif_polex vs (Free x) =
   765   | reif_polex vs (Free x) =
   766       \<^const>\<open>Var\<close> $ HOLogic.mk_number HOLogic.natT (find_index (equal x) vs)
   766       \<^Const>\<open>Var for \<open>HOLogic.mk_number HOLogic.natT (find_index (equal x) vs)\<close>\<close>
   767   | reif_polex vs (Const (\<^const_name>\<open>Ring.ring.zero\<close>, _) $ _) =
   767   | reif_polex _ \<^Const_>\<open>Ring.ring.zero _ _ for _\<close> = \<^term>\<open>Const 0\<close>
   768       \<^term>\<open>Const 0\<close>
   768   | reif_polex _ \<^Const_>\<open>Group.monoid.one _ _ for _\<close> = \<^term>\<open>Const 1\<close>
   769   | reif_polex vs (Const (\<^const_name>\<open>Group.monoid.one\<close>, _) $ _) =
   769   | reif_polex _ \<^Const_>\<open>Algebra_Aux.of_integer _ _ for _ n\<close> = \<^Const>\<open>Const for n\<close>
   770       \<^term>\<open>Const 1\<close>
       
   771   | reif_polex vs (Const (\<^const_name>\<open>Algebra_Aux.of_integer\<close>, _) $ _ $ n) =
       
   772       \<^const>\<open>Const\<close> $ n
       
   773   | reif_polex _ _ = error "reif_polex: bad expression";
   770   | reif_polex _ _ = error "reif_polex: bad expression";
   774 
   771 
   775 fun reif_polex' vs (Const (\<^const_name>\<open>Groups.plus\<close>, _) $ a $ b) =
   772 fun reif_polex' vs \<^Const_>\<open>plus _ for a b\<close> = \<^Const>\<open>Add for \<open>reif_polex' vs a\<close> \<open>reif_polex' vs b\<close>\<close>
   776       \<^const>\<open>Add\<close> $ reif_polex' vs a $ reif_polex' vs b
   773   | reif_polex' vs \<^Const_>\<open>minus _ for a b\<close> = \<^Const>\<open>Sub for \<open>reif_polex' vs a\<close> \<open>reif_polex' vs b\<close>\<close>
   777   | reif_polex' vs (Const (\<^const_name>\<open>Groups.minus\<close>, _) $ a $ b) =
   774   | reif_polex' vs \<^Const_>\<open>times _ for a b\<close> = \<^Const>\<open>Mul for \<open>reif_polex' vs a\<close> \<open>reif_polex' vs b\<close>\<close>
   778       \<^const>\<open>Sub\<close> $ reif_polex' vs a $ reif_polex' vs b
   775   | reif_polex' vs \<^Const_>\<open>uminus _ for a\<close> = \<^Const>\<open>Neg for \<open>reif_polex' vs a\<close>\<close>
   779   | reif_polex' vs (Const (\<^const_name>\<open>Groups.times\<close>, _) $ a $ b) =
   776   | reif_polex' vs \<^Const_>\<open>power _ for a n\<close> = \<^Const>\<open>Pow for \<open>reif_polex' vs a\<close> n\<close>
   780       \<^const>\<open>Mul\<close> $ reif_polex' vs a $ reif_polex' vs b
   777   | reif_polex' vs (Free x) = \<^Const>\<open>Var for \<open>HOLogic.mk_number \<^Type>\<open>nat\<close> (find_index (equal x) vs)\<close>\<close>
   781   | reif_polex' vs (Const (\<^const_name>\<open>Groups.uminus\<close>, _) $ a) =
   778   | reif_polex' _ \<^Const_>\<open>numeral _ for b\<close> = \<^Const>\<open>Const for \<^Const>\<open>numeral \<^Type>\<open>int\<close> for b\<close>\<close>
   782       \<^const>\<open>Neg\<close> $ reif_polex' vs a
   779   | reif_polex' _ \<^Const_>\<open>zero_class.zero _\<close> = \<^term>\<open>Const 0\<close>
   783   | reif_polex' vs (Const (\<^const_name>\<open>Power.power\<close>, _) $ a $ n) =
   780   | reif_polex' _ \<^Const_>\<open>one_class.one _\<close> = \<^term>\<open>Const 1\<close>
   784       \<^const>\<open>Pow\<close> $ reif_polex' vs a $ n
   781   | reif_polex' _ t = error "reif_polex: bad expression";
   785   | reif_polex' vs (Free x) =
       
   786       \<^const>\<open>Var\<close> $ HOLogic.mk_number HOLogic.natT (find_index (equal x) vs)
       
   787   | reif_polex' vs (Const (\<^const_name>\<open>numeral\<close>, _) $ b) =
       
   788       \<^const>\<open>Const\<close> $ (@{const numeral (int)} $ b)
       
   789   | reif_polex' vs (Const (\<^const_name>\<open>zero_class.zero\<close>, _)) = \<^term>\<open>Const 0\<close>
       
   790   | reif_polex' vs (Const (\<^const_name>\<open>one_class.one\<close>, _)) = \<^term>\<open>Const 1\<close>
       
   791   | reif_polex' vs t = error "reif_polex: bad expression";
       
   792 
   782 
   793 fun head_conv (_, _, _, _, head_simp, _) ys =
   783 fun head_conv (_, _, _, _, head_simp, _) ys =
   794   (case strip_app ys of
   784   (case strip_app ys of
   795      (\<^const_name>\<open>Cons\<close>, [y, xs]) => inst [] [y, xs] head_simp);
   785      (\<^const_name>\<open>Cons\<close>, [y, xs]) => inst [] [y, xs] head_simp);
   796 
   786 
   890     val (_, _, _, [in_carrier_Nil, in_carrier_Cons], _, _) =
   880     val (_, _, _, [in_carrier_Nil, in_carrier_Cons], _, _) =
   891       get_ring_simps ctxt NONE R;
   881       get_ring_simps ctxt NONE R;
   892     val props = map fst (Facts.props (Proof_Context.facts_of ctxt)) @ maps dest_conj prems;
   882     val props = map fst (Facts.props (Proof_Context.facts_of ctxt)) @ maps dest_conj prems;
   893     val ths = map (fn p as (x, _) =>
   883     val ths = map (fn p as (x, _) =>
   894       (case find_first
   884       (case find_first
   895          ((fn Const (\<^const_name>\<open>Trueprop\<close>, _) $
   885          ((fn \<^Const_>\<open>Trueprop
   896                 (Const (\<^const_name>\<open>Set.member\<close>, _) $
   886               for \<^Const_>\<open>Set.member _ for \<open>Free (y, _)\<close> \<^Const_>\<open>carrier _ _ for S\<close>\<close>\<close> =>
   897                    Free (y, _) $ (Const (\<^const_name>\<open>carrier\<close>, _) $ S)) =>
       
   898                 x = y andalso R aconv S
   887                 x = y andalso R aconv S
   899             | _ => false) o Thm.prop_of) props of
   888             | _ => false) o Thm.prop_of) props of
   900          SOME th => th
   889          SOME th => th
   901        | NONE => error ("Variable " ^ Syntax.string_of_term ctxt (Free p) ^
   890        | NONE => error ("Variable " ^ Syntax.string_of_term ctxt (Free p) ^
   902            " not in carrier"))) xs
   891            " not in carrier"))) xs
   903   in
   892   in
   904     fold_rev (fn th1 => fn th2 => [th1, th2] MRS in_carrier_Cons)
   893     fold_rev (fn th1 => fn th2 => [th1, th2] MRS in_carrier_Cons)
   905        ths in_carrier_Nil
   894        ths in_carrier_Nil
   906   end;
   895   end;
   907 
   896 
   908 fun mk_ring T =
   897 fun mk_ring T = \<^Const>\<open>cring_class_ops T\<close>;
   909   Const (\<^const_name>\<open>cring_class_ops\<close>,
       
   910     Type (\<^type_name>\<open>partial_object_ext\<close>, [T,
       
   911       Type (\<^type_name>\<open>monoid_ext\<close>, [T,
       
   912         Type (\<^type_name>\<open>ring_ext\<close>, [T, \<^typ>\<open>unit\<close>])])]));
       
   913 
   898 
   914 val iterations = \<^cterm>\<open>1000::nat\<close>;
   899 val iterations = \<^cterm>\<open>1000::nat\<close>;
   915 val Trueprop_cong = Thm.combination (Thm.reflexive \<^cterm>\<open>Trueprop\<close>);
   900 val Trueprop_cong = Thm.combination (Thm.reflexive \<^cterm>\<open>Trueprop\<close>);
   916 
   901 
   917 fun commutative_ring_conv ctxt prems eqs ct =
   902 fun commutative_ring_conv ctxt prems eqs ct =
   924     val (R, optcT, prem', reif) = (case ring_struct (Thm.term_of ct) of
   909     val (R, optcT, prem', reif) = (case ring_struct (Thm.term_of ct) of
   925         SOME R => (R, NONE, mk_in_carrier ctxt R prems xs, reif_polex xs)
   910         SOME R => (R, NONE, mk_in_carrier ctxt R prems xs, reif_polex xs)
   926       | NONE => (mk_ring T, SOME cT, @{thm in_carrier_trivial}, reif_polex' xs));
   911       | NONE => (mk_ring T, SOME cT, @{thm in_carrier_trivial}, reif_polex' xs));
   927     val rls as (_, _, _, _, _, norm_subst_correct) = get_ring_simps ctxt optcT R;
   912     val rls as (_, _, _, _, _, norm_subst_correct) = get_ring_simps ctxt optcT R;
   928     val cxs = Thm.cterm_of ctxt (HOLogic.mk_list T (map Free xs));
   913     val cxs = Thm.cterm_of ctxt (HOLogic.mk_list T (map Free xs));
   929     val ceqs = Thm.cterm_of ctxt (HOLogic.mk_list \<^typ>\<open>polex * polex\<close>
   914     val ceqs = Thm.cterm_of ctxt (HOLogic.mk_list \<^typ>\<open>polex \<times> polex\<close>
   930       (map (HOLogic.mk_prod o apply2 reif) eqs'));
   915       (map (HOLogic.mk_prod o apply2 reif) eqs'));
   931     val cp = Thm.cterm_of ctxt (reif (Thm.term_of ct));
   916     val cp = Thm.cterm_of ctxt (reif (Thm.term_of ct));
   932     val prem = Thm.equal_elim
   917     val prem = Thm.equal_elim
   933       (Trueprop_cong (Thm.symmetric (Ipolex_polex_list_conv rls cxs ceqs)))
   918       (Trueprop_cong (Thm.symmetric (Ipolex_polex_list_conv rls cxs ceqs)))
   934       (fold_rev (fn th1 => fn th2 => [th1, th2] MRS @{thm conjI})
   919       (fold_rev (fn th1 => fn th2 => [th1, th2] MRS @{thm conjI})