lemma (in field) peval_closed [simp]: "in_carrier xs \ peval xs e \ carrier R" "in_carrier xs \ peval xs (PExpr1 e1) \ carrier R" "in_carrier xs \ peval xs (PExpr2 e2) \ carrier R" by (induct e and e1 and e2) simp_all
definition npepow :: "pexpr \ nat \ pexpr" where"npepow e n =
(if n = 0 then PExpr1 (PCnst 1)
else if n = 1 then e
else
(case e of
PExpr1 (PCnst c) ==> PExpr1 (PCnst (c ^ n))
| _ ==> PExpr2 (PPow e n)))"
lemma (in field) npepow_correct: "in_carrier xs \ peval xs (npepow e n) = peval xs (PExpr2 (PPow e n))" by (cases e rule: pexpr_cases) (simp_all add: npepow_def)
fun npemul :: "pexpr \ pexpr \ pexpr" where"npemul x y =
(case x of
PExpr1 (PCnst c) ==> if c = 0 then x
else if c = 1 then y else
(case y of
PExpr1 (PCnst d) ==> PExpr1 (PCnst (c * d))
| _ ==> PExpr2 (PMul x y))
| PExpr2 (PPow e1 n) ==>
(case y of
PExpr2 (PPow e2 m) ==> if n = m then npepow (npemul e1 e2) n
else PExpr2 (PMul x y)
| PExpr1 (PCnst d) ==> if d = 0 then y
else if d = 1 then x
else PExpr2 (PMul x y)
| _ ==> PExpr2 (PMul x y))
| _ ==>
(case y of
PExpr1 (PCnst d) ==> if d = 0 then y
else if d = 1 then x
else PExpr2 (PMul x y)
| _ ==> PExpr2 (PMul x y)))"
lemma (in field) npemul_correct: "in_carrier xs \ peval xs (npemul e1 e2) = peval xs (PExpr2 (PMul e1 e2))" proof (induct e1 e2 rule: npemul.induct) case (1 x y) thenshow ?case proof (cases x y rule: pexpr_cases2) case (PPow_PPow e n e' m) thenshow ?thesis by (simp del: npemul.simps add: 1 npepow_correct nat_pow_distrib
npemul.simps [of "PExpr2 (PPow e n)""PExpr2 (PPow e' m)"]) qed simp_all qed
declare npemul.simps [simp del]
definition npeadd :: "pexpr \ pexpr \ pexpr" where"npeadd x y =
(case x of
PExpr1 (PCnst c) ==> if c = 0 then y
else
(case y of
PExpr1 (PCnst d) ==> PExpr1 (PCnst (c + d))
| _ ==> PExpr1 (PAdd x y))
| _ ==>
(case y of
PExpr1 (PCnst d) ==> if d = 0 then x
else PExpr1 (PAdd x y)
| _ ==> PExpr1 (PAdd x y)))"
definition npesub :: "pexpr \ pexpr \ pexpr" where"npesub x y =
(case y of
PExpr1 (PCnst d) ==> if d = 0 then x
else
(case x of
PExpr1 (PCnst c) ==> PExpr1 (PCnst (c - d))
| _ ==> PExpr1 (PSub x y))
| _ ==>
(case x of
PExpr1 (PCnst c) ==> if c = 0 then PExpr1 (PNeg y)
else PExpr1 (PSub x y)
| _ ==> PExpr1 (PSub x y)))"
definition npeneg :: "pexpr \ pexpr" where"npeneg e =
(case e of
PExpr1 (PCnst c) ==> PExpr1 (PCnst (- c))
| _ ==> PExpr1 (PNeg e))"
lemma (in field) npeneg_correct: "peval xs (npeneg e) = peval xs (PExpr1 (PNeg e))" by (cases e rule: pexpr_cases) (simp_all add: npeneg_def)
lemma option_pair_cases [case_names None Some]: obtains (None) "x = None" | (Some) p q where"x = Some (p, q)" proof (cases x) case None thenshow ?thesis by (rule that) next case (Some r) thenshow ?thesis by (cases r, simp) (rule that) qed
fun isin :: "pexpr \ nat \ pexpr \ nat \ (nat \ pexpr) option" where "isin e n (PExpr2 (PMul e1 e2)) m =
(case isin e n e1 m of
Some (k, e3) ==> if k = 0 then Some (0, npemul e3 (npepow e2 m))
else
(case isin e k e2 m of
Some (l, e4) ==> Some (l, npemul e3 e4)
| None ==> Some (k, npemul e3 (npepow e2 m)))
| None ==>
(case isin e n e2 m of
Some (k, e3) ==> Some (k, npemul (npepow e1 m) e3)
| None ==> None))"
| "isin e n (PExpr2 (PPow e' k)) m =
(if k = 0 then None else isin e n e' (k * m))"
| "isin (PExpr1 e) n (PExpr1 e') m =
(if e = e' then if n โฅ m then Some (n - m, PExpr1 (PCnst 1))
else Some (0, npepow (PExpr1 e) (m - n))
else None)"
| "isin (PExpr2 e) n (PExpr1 e') m = None"
lemma (in field) isin_correct: assumes"in_carrier xs" and"isin e n e' m = Some (p, e'')" shows"peval xs (PExpr2 (PPow e' m)) = peval xs (PExpr2 (PMul (PExpr2 (PPow e (n - p))) e''))" and"p \ n" using assms by (induct e n e' m arbitrary: p e'' rule: isin.induct)
(force
simp add:
nat_pow_distrib nat_pow_pow nat_pow_mult m_ac
npemul_correct npepow_correct
split: option.split_asm prod.split_asm if_split_asm)+
lemma (in field) isin_correct': "in_carrier xs \ isin e n e' 1 = Some (p, e'') \
peval xs e' = peval xs e [^] (n - p) \ peval xs e''" "in_carrier xs \ isin e n e' 1 = Some (p, e'') \ p \ n" using isin_correct [where m = 1] by simp_all
fun split_aux :: "pexpr \ nat \ pexpr \ pexpr \ pexpr \ pexpr" where "split_aux (PExpr2 (PMul e1 e2)) n e =
(let
(left1, common1, right1) = split_aux e1 n e;
(left2, common2, right2) = split_aux e2 n right1 in (npemul left1 left2, npemul common1 common2, right2))"
| "split_aux (PExpr2 (PPow e' m)) n e =
(if m = 0 then (PExpr1 (PCnst 1), PExpr1 (PCnst 1), e)
else split_aux e' (m * n) e)"
| "split_aux (PExpr1 e') n e =
(case isin (PExpr1 e') n e 1 of
Some (m, e'') ==>
(if m = 0 then (PExpr1 (PCnst 1), npepow (PExpr1 e') n, e'')
else (npepow (PExpr1 e') m, npepow (PExpr1 e') (n - m), e''))
| None ==> (npepow (PExpr1 e') n, PExpr1 (PCnst 1), e))"
lemma split_aux_induct [case_names 1 2 3]: assumes I1: "\e1 e2 n e. P e1 n e \ P e2 n (snd (snd (split_aux e1 n e))) \
P (PExpr2 (PMul e1 e2)) n e" and I2: "\e' m n e. (m \ 0 \ P e' (m * n) e) \ P (PExpr2 (PPow e' m)) n e" and I3: "\e' n e. P (PExpr1 e') n e" shows"P x y z" proof (induct x y z rule: split_aux.induct) case 1 from 1(1) 1(2) [OF refl prod.collapse prod.collapse] show ?caseby (rule I1) next case 2 thenshow ?caseby (rule I2) next case 3 thenshow ?caseby (rule I3) qed
ML โน signature FIELD_TAC =
sig structure Field_Simps:
sig
type T
val get: Context.generic -> T
val put: T -> Context.generic -> Context.generic
val map: (T -> T) -> Context.generic -> Context.generic end
val eq_field_simps:
(term * (thm list * thm list * thm list * thm * thm)) *
(term * (thm list * thm list * thm list * thm * thm)) -> bool
val field_tac: bool -> Proof.context -> int -> tactic end
structure Field_Tac : FIELD_TAC =
struct
open Ring_Tac;
fun field_struct ๐โนRing.ring.add _ _ for R _ _โบ = SOME R
| field_struct ๐โนRing.a_minus _ _ for R _ _โบ = SOME R
| field_struct ๐โนGroup.monoid.mult _ _ for R _ _โบ = SOME R
| field_struct ๐โนRing.a_inv _ _ for R _โบ = SOME R
| field_struct ๐โนGroup.pow _ _ _ for R _ _โบ = SOME R
| field_struct ๐โนAlgebra_Aux.m_div _ _for R _ _โบ = SOME R
| field_struct ๐โนRing.ring.zero _ _ for Rโบ = SOME R
| field_struct ๐โนGroup.monoid.one _ _ for Rโบ = SOME R
| field_struct ๐โนAlgebra_Aux.of_integer _ _ for R _โบ = SOME R
| field_struct _ = NONE;
fun reif_fexpr vs ๐โนRing.ring.add _ _ for _ a bโบ = ๐โนFAdd forโนreif_fexpr vs aโบโนreif_fexpr vs bโบโบ
| reif_fexpr vs ๐โนRing.a_minus _ _ for _ a bโบ = ๐โนFSub forโนreif_fexpr vs aโบโนreif_fexpr vs bโบโบ
| reif_fexpr vs ๐โนGroup.monoid.mult _ _ for _ a bโบ = ๐โนFMul forโนreif_fexpr vs aโบโนreif_fexpr vs bโบโบ
| reif_fexpr vs ๐โนRing.a_inv _ _ for _ aโบ = ๐โนFNeg forโนreif_fexpr vs aโบโบ
| reif_fexpr vs ๐โนGroup.pow _ _ _ for _ a nโบ = ๐โนFPow forโนreif_fexpr vs aโบ nโบ
| reif_fexpr vs ๐โนAlgebra_Aux.m_div _ _ for _ a bโบ = ๐โนFDiv forโนreif_fexpr vs aโบโนreif_fexpr vs bโบโบ
| reif_fexpr vs (Free x) = ๐โนFVar forโนHOLogic.mk_number HOLogic.natT (find_index (equal x) vs)โบโบ
| reif_fexpr vs ๐โนRing.ring.zero _ _ for _โบ = ๐โนFCnst 0โบ
| reif_fexpr vs ๐โนGroup.monoid.one _ _ for _โบ = ๐โนFCnst 1โบ
| reif_fexpr vs ๐โนAlgebra_Aux.of_integer _ _ for _ nโบ = ๐โนFCnst for nโบ
| reif_fexpr _ _ = error "reif_fexpr: bad expression";
fun reif_fexpr' vs \<^Const_>\plus _ for a b\ = \<^Const>\FAdd for \reif_fexpr' vs aโบโนreif_fexpr' vs b\\
| reif_fexpr' vs \<^Const_>\minus _ for a b\ = \<^Const>\FSub for \reif_fexpr' vs aโบโนreif_fexpr' vs b\\
| reif_fexpr' vs \<^Const_>\times _ for a b\ = \<^Const>\FMul for \reif_fexpr' vs aโบโนreif_fexpr' vs b\\
| reif_fexpr' vs \<^Const_>\uminus _ for a\ = \<^Const>\FNeg for \reif_fexpr' vs aโบโบ
| reif_fexpr' vs \<^Const_>\power _ for a n\ = \<^Const>\FPow for \reif_fexpr' vs aโบ nโบ
| reif_fexpr' vs \<^Const_>\divide _ for a b\ = \<^Const>\FDiv for \reif_fexpr' vs aโบโนreif_fexpr' vs b\\
| reif_fexpr' vs (Free x) = ๐โนFVar forโนHOLogic.mk_number HOLogic.natT (find_index (equal x) vs)โบโบ
| reif_fexpr' vs \<^Const_>\zero_class.zero _\ = \<^term>\FCnst 0\
| reif_fexpr' vs \<^Const_>\one_class.one _\ = \<^term>\FCnst 1\
| reif_fexpr' vs \<^Const_>\numeral _ for b\ = \<^Const>\FCnst for \<^Const>\numeral \<^Type>\int\ for b\\
| reif_fexpr' _ _ = error "reif_fexpr: bad expression";
structure Field_Simps = Generic_Data
(struct
type T = (term * (thm list * thm list * thm list * thm * thm)) Net.net
val empty = Net.empty
val merge = Net.merge eq_field_simps end);
fun get_field_simps ctxt optcT t =
(case get_matching_rules ctxt (Field_Simps.get (Context.Proof ctxt)) t of
SOME (ths1, ths2, ths3, th4, th) => let val tr = Thm.transfer' ctxt #>
(case optcT of NONE => I | SOME cT => inst [cT] [] #> norm) in (map tr ths1, map tr ths2, map tr ths3, tr th4, tr th) end
| NONE => error "get_field_simps: lookup failed");
fun nth_el_conv (_, _, _, nth_el_Cons, _) = let
val a = type_of_eqn nth_el_Cons;
val If_conv_a = If_conv a;
fun conv ys n = (case strip_app ys of
(๐โนConsโบ, [x, xs]) =>
transitive'
(inst [] [x, xs, n] nth_el_Cons)
(If_conv_a (args2 nat_eq_conv) Thm.reflexive
(cong2' conv Thm.reflexive (args2 nat_minus_conv)))) in conv end;
fun feval_conv (rls as
([feval_simps_1, feval_simps_2, feval_simps_3,
feval_simps_4, feval_simps_5, feval_simps_6,
feval_simps_7, feval_simps_8, feval_simps_9,
feval_simps_10, feval_simps_11],
_, _, _, _)) = let
val nth_el_conv' = nth_el_conv rls;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfรคltig zusammengestellt. Es wird jedoch weder Vollstรคndigkeit, noch Richtigkeit,
noch Qualitรคt der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.