(* Title: HOL/Decision_Procs/Commutative_Ring.thy Author: Bernhard Haeupler, Stefan Berghofer, and Amine Chaieb Proving equalities in commutative rings done "right" in Isabelle/HOL. *)
section‹Proving equalities in commutative rings›
theory Commutative_Ring imports
Conversions
Algebra_Aux "HOL-Library.Code_Target_Numeral" begin
text‹Syntax of multivariate polynomials (pol) and polynomial expressions.›
datatype pol =
Pc int
| Pinj nat pol
| PX pol nat pol
datatype polex =
Var nat
| Const int
| Add polex polex
| Sub polex polex
| Mul polex polex
| Pow polex nat
| Neg polex
text‹Interpretation functions for the shadow syntax.›
context cring begin
definition in_carrier :: "'a list ==> bool" where"in_carrier xs ⟷ (∀x∈set xs. x ∈ carrier R)"
lemma in_carrier_Nil: "in_carrier []" by (simp add: in_carrier_def)
lemma in_carrier_Cons: "x ∈ carrier R ==> in_carrier xs ==> in_carrier (x # xs)" by (simp add: in_carrier_def)
lemma drop_in_carrier [simp]: "in_carrier xs ==> in_carrier (drop n xs)" using set_drop_subset [of n xs] by (auto simp add: in_carrier_def)
primrec head :: "'a list ==> 'a" where "head [] = 0"
| "head (x # xs) = x"
lemma head_closed [simp]: "in_carrier xs ==> head xs ∈ carrier R" by (cases xs) (simp_all add: in_carrier_def)
primrec Ipol :: "'a list ==> pol ==> 'a" where "Ipol l (Pc c) = «c¬"
| "Ipol l (Pinj i P) = Ipol (drop i l) P"
| "Ipol l (PX P x Q) = Ipol l P ⊗ head l [^] x ⊕ Ipol (drop 1 l) Q"
lemma Ipol_Pc: "Ipol l (Pc 0) = 0" "Ipol l (Pc 1) = 1" "Ipol l (Pc (numeral n)) = «numeral n¬" "Ipol l (Pc (- numeral n)) = ⊖«numeral n¬" by simp_all
lemma Ipol_closed [simp]: "in_carrier l ==> Ipol l p ∈ carrier R" by (induct p arbitrary: l) simp_all
primrec Ipolex :: "'a list ==> polex ==> 'a" where "Ipolex l (Var n) = head (drop n l)"
| "Ipolex l (Const i) = «i¬"
| "Ipolex l (Add P Q) = Ipolex l P ⊕ Ipolex l Q"
| "Ipolex l (Sub P Q) = Ipolex l P ⊖ Ipolex l Q"
| "Ipolex l (Mul P Q) = Ipolex l P ⊗ Ipolex l Q"
| "Ipolex l (Pow p n) = Ipolex l p [^] n"
| "Ipolex l (Neg P) = ⊖ Ipolex l P"
lemma Ipolex_Const: "Ipolex l (Const 0) = 0" "Ipolex l (Const 1) = 1" "Ipolex l (Const (numeral n)) = «numeral n¬" by simp_all
end
text‹Create polynomial normalized polynomials given normalized inputs.›
definition mkPinj :: "nat ==> pol ==> pol" where"mkPinj x P = (case P of Pc c ==> Pc c | Pinj y P ==> Pinj (x + y) P | PX p1 y p2 ==> Pinj x P)"
definition mkPX :: "pol ==> nat ==> pol ==> pol" where"mkPX P i Q = (case P of Pc c ==> if c = 0 then mkPinj 1 Q else PX P i Q | Pinj j R ==> PX P i Q | PX P2 i2 Q2 ==> if Q2 = Pc 0 then PX P2 (i + i2) Q else PX P i Q)"
text‹Defining the basic ring operations on normalized polynomials›
function add :: "pol ==> pol ==> pol" (infixl‹⟨+⟩› 65) where "Pc a ⟨+⟩ Pc b = Pc (a + b)"
| "Pc c ⟨+⟩ Pinj i P = Pinj i (P ⟨+⟩ Pc c)"
| "Pinj i P ⟨+⟩ Pc c = Pinj i (P ⟨+⟩ Pc c)"
| "Pc c ⟨+⟩ PX P i Q = PX P i (Q ⟨+⟩ Pc c)"
| "PX P i Q ⟨+⟩ Pc c = PX P i (Q ⟨+⟩ Pc c)"
| "Pinj x P ⟨+⟩ Pinj y Q = (if x = y then mkPinj x (P ⟨+⟩ Q) else (if x > y then mkPinj y (Pinj (x - y) P ⟨+⟩ Q) else mkPinj x (Pinj (y - x) Q ⟨+⟩ P)))"
| "Pinj x P ⟨+⟩ PX Q y R = (if x = 0 then P ⟨+⟩ PX Q y R else (if x = 1 then PX Q y (R ⟨+⟩ P) else PX Q y (R ⟨+⟩ Pinj (x - 1) P)))"
| "PX P x R ⟨+⟩ Pinj y Q = (if y = 0 then PX P x R ⟨+⟩ Q else (if y = 1 then PX P x (R ⟨+⟩ Q) else PX P x (R ⟨+⟩ Pinj (y - 1) Q)))"
| "PX P1 x P2 ⟨+⟩ PX Q1 y Q2 = (if x = y then mkPX (P1 ⟨+⟩ Q1) x (P2 ⟨+⟩ Q2) else (if x > y then mkPX (PX P1 (x - y) (Pc 0) ⟨+⟩ Q1) y (P2 ⟨+⟩ Q2) else mkPX (PX Q1 (y - x) (Pc 0) ⟨+⟩ P1) x (P2 ⟨+⟩ Q2)))" by pat_completeness auto terminationby (relation "measure (λ(x, y). size x + size y)") auto
function mul :: "pol ==> pol ==> pol" (infixl‹⟨*⟩› 70) where "Pc a ⟨*⟩ Pc b = Pc (a * b)"
| "Pc c ⟨*⟩ Pinj i P = (if c = 0 then Pc 0 else mkPinj i (P ⟨*⟩ Pc c))"
| "Pinj i P ⟨*⟩ Pc c = (if c = 0 then Pc 0 else mkPinj i (P ⟨*⟩ Pc c))"
| "Pc c ⟨*⟩ PX P i Q = (if c = 0 then Pc 0 else mkPX (P ⟨*⟩ Pc c) i (Q ⟨*⟩ Pc c))"
| "PX P i Q ⟨*⟩ Pc c = (if c = 0 then Pc 0 else mkPX (P ⟨*⟩ Pc c) i (Q ⟨*⟩ Pc c))"
| "Pinj x P ⟨*⟩ Pinj y Q = (if x = y then mkPinj x (P ⟨*⟩ Q) else (if x > y then mkPinj y (Pinj (x - y) P ⟨*⟩ Q) else mkPinj x (Pinj (y - x) Q ⟨*⟩ P)))"
| "Pinj x P ⟨*⟩ PX Q y R = (if x = 0 then P ⟨*⟩ PX Q y R else (if x = 1 then mkPX (Pinj x P ⟨*⟩ Q) y (R ⟨*⟩ P) else mkPX (Pinj x P ⟨*⟩ Q) y (R ⟨*⟩ Pinj (x - 1) P)))"
| "PX P x R ⟨*⟩ Pinj y Q = (if y = 0 then PX P x R ⟨*⟩ Q else (if y = 1 then mkPX (Pinj y Q ⟨*⟩ P) x (R ⟨*⟩ Q) else mkPX (Pinj y Q ⟨*⟩ P) x (R ⟨*⟩ Pinj (y - 1) Q)))"
| "PX P1 x P2 ⟨*⟩ PX Q1 y Q2 = mkPX (P1 ⟨*⟩ Q1) (x + y) (P2 ⟨*⟩ Q2) ⟨+⟩ (mkPX (P1 ⟨*⟩ mkPinj 1 Q2) x (Pc 0) ⟨+⟩ (mkPX (Q1 ⟨*⟩ mkPinj 1 P2) y (Pc 0)))" by pat_completeness auto terminationby (relation "measure (λ(x, y). size x + size y)")
(auto simp add: mkPinj_def split: pol.split)
text‹Negation› primrec neg :: "pol ==> pol" where "neg (Pc c) = Pc (- c)"
| "neg (Pinj i P) = Pinj i (neg P)"
| "neg (PX P x Q) = PX (neg P) x (neg Q)"
text‹Subtraction› definition sub :: "pol ==> pol ==> pol" (infixl‹⟨-⟩› 65) where"sub P Q = P ⟨+⟩ neg Q"
text‹Square for Fast Exponentiation› primrec sqr :: "pol ==> pol" where "sqr (Pc c) = Pc (c * c)"
| "sqr (Pinj i P) = mkPinj i (sqr P)"
| "sqr (PX A x B) = mkPX (sqr A) (x + x) (sqr B) ⟨+⟩ mkPX (Pc 2 ⟨*⟩ A ⟨*⟩ mkPinj 1 B) x (Pc 0)"
text‹Fast Exponentiation›
fun pow :: "nat ==> pol ==> pol" where pow_if [simp del]: "pow n P = (if n = 0 then Pc 1 else if even n then pow (n div 2) (sqr P) else P ⟨*⟩ pow (n div 2) (sqr P))"
lemma pow_simps [simp]: "pow 0 P = Pc 1" "pow (2 * n) P = pow n (sqr P)" "pow (Suc (2 * n)) P = P ⟨*⟩ pow n (sqr P)" by (simp_all add: pow_if)
lemma even_pow: "even n ==> pow n P = pow (n div 2) (sqr P)" by (erule evenE) simp
lemma odd_pow: "odd n ==> pow n P = P ⟨*⟩ pow (n div 2) (sqr P)" by (erule oddE) simp
text‹Normalization of polynomial expressions›
primrec norm :: "polex ==> pol" where "norm (Var n) = (if n = 0 then PX (Pc 1) 1 (Pc 0) else Pinj n (PX (Pc 1) 1 (Pc 0)))"
| "norm (Const i) = Pc i"
| "norm (Add P Q) = norm P ⟨+⟩ norm Q"
| "norm (Sub P Q) = norm P ⟨-⟩ norm Q"
| "norm (Mul P Q) = norm P ⟨*⟩ norm Q"
| "norm (Pow P n) = pow n (norm P)"
| "norm (Neg P) = neg (norm P)"
context cring begin
text‹mkPinj preserve semantics› lemma mkPinj_ci: "Ipol l (mkPinj a B) = Ipol l (Pinj a B)" by (induct B) (auto simp add: mkPinj_def algebra_simps)
text‹mkPX preserves semantics› lemma mkPX_ci: "in_carrier l ==> Ipol l (mkPX A b C) = Ipol l (PX A b C)" by (cases A) (auto simp add: mkPX_def mkPinj_ci nat_pow_mult [symmetric] m_ac)
text‹Correctness theorems for the implemented operations›
text‹Negation› lemma neg_ci: "in_carrier l ==> Ipol l (neg P) = ⊖ (Ipol l P)" by (induct P arbitrary: l) (auto simp add: minus_add l_minus)
text‹Addition› lemma add_ci: "in_carrier l ==> Ipol l (P ⟨+⟩ Q) = Ipol l P ⊕ Ipol l Q" proof (induct P Q arbitrary: l rule: add.induct) case (6 x P y Q)
consider "x < y" | "x = y" | "x > y"by arith thenshow ?case proof cases case 1 with 6 show ?thesis by (simp add: mkPinj_ci a_ac) next case 2 with 6 show ?thesis by (simp add: mkPinj_ci) next case 3 with 6 show ?thesis by (simp add: mkPinj_ci) qed next case (7 x P Q y R)
consider "x = 0" | "x = 1" | "x > 1"by arith thenshow ?case proof cases case 1 with 7 show ?thesis by simp next case 2 with 7 show ?thesis by (simp add: a_ac) next case 3 with 7 show ?thesis by (cases x) (simp_all add: a_ac) qed next case (8 P x R y Q) thenshow ?caseby (simp add: a_ac) next case (9 P1 x P2 Q1 y Q2)
consider "x = y" | d where"d + x = y" | d where"d + y = x" by atomize_elim arith thenshow ?case proof cases case 1 with 9 show ?thesis by (simp add: mkPX_ci r_distr a_ac m_ac) next case 2 with 9 show ?thesis by (auto simp add: mkPX_ci nat_pow_mult [symmetric] r_distr a_ac m_ac) next case 3 with 9 show ?thesis by (auto simp add: nat_pow_mult [symmetric] mkPX_ci r_distr a_ac m_ac) qed qed (auto simp add: a_ac m_ac)
text‹Multiplication› lemma mul_ci: "in_carrier l ==> Ipol l (P ⟨*⟩ Q) = Ipol l P ⊗ Ipol l Q" by (induct P Q arbitrary: l rule: mul.induct)
(simp_all add: mkPX_ci mkPinj_ci a_ac m_ac r_distr add_ci nat_pow_mult [symmetric])
text‹Subtraction› lemma sub_ci: "in_carrier l ==> Ipol l (P ⟨-⟩ Q) = Ipol l P ⊖ Ipol l Q" by (simp add: add_ci neg_ci sub_def minus_eq)
text‹Square› lemma sqr_ci: "in_carrier ls ==> Ipol ls (sqr P) = Ipol ls P ⊗ Ipol ls P" by (induct P arbitrary: ls)
(simp_all add: add_ci mkPinj_ci mkPX_ci mul_ci l_distr r_distr
a_ac m_ac nat_pow_mult [symmetric] of_int_2)
text‹Power› lemma pow_ci: "in_carrier ls ==> Ipol ls (pow n P) = Ipol ls P [^] n" proof (induct n arbitrary: P rule: less_induct) case (less k)
consider "k = 0" | "k > 0"by arith thenshow ?case proof cases case 1 thenshow ?thesis by simp next case 2 thenhave"k div 2 < k"by arith with less have *: "Ipol ls (pow (k div 2) (sqr P)) = Ipol ls (sqr P) [^] (k div 2)" by simp show ?thesis proof (cases "even k") case True with * ‹in_carrier ls›show ?thesis by (simp add: even_pow sqr_ci nat_pow_distrib nat_pow_mult
mult_2 [symmetric] even_two_times_div_two) next case False with * ‹in_carrier ls›show ?thesis by (simp add: odd_pow mul_ci sqr_ci nat_pow_distrib nat_pow_mult
mult_2 [symmetric] trans [OF nat_pow_Suc m_comm, symmetric]) qed qed qed
text‹Normalization preserves semantics› lemma norm_ci: "in_carrier l ==> Ipolex l Pe = Ipol l (norm Pe)" by (induct Pe) (simp_all add: add_ci sub_ci mul_ci neg_ci pow_ci)
text‹Reflection lemma: Key to the (incomplete) decision procedure› lemma norm_eq: assumes"in_carrier l" and"norm P1 = norm P2" shows"Ipolex l P1 = Ipolex l P2" proof - from assms have"Ipol l (norm P1) = Ipol l (norm P2)"by simp with assms show ?thesis by (simp only: norm_ci) qed
end
text‹Monomials›
datatype mon =
Mc int
| Minj nat mon
| MX nat mon
primrec (in cring) Imon :: "'a list ==> mon ==> 'a" where "Imon l (Mc c) = «c¬"
| "Imon l (Minj i M) = Imon (drop i l) M"
| "Imon l (MX x M) = Imon (drop 1 l) M ⊗ head l [^] x"
lemma (in cring) Imon_closed [simp]: "in_carrier l ==> Imon l m ∈ carrier R" by (induct m arbitrary: l) simp_all
definition mkMinj :: "nat ==> mon ==> mon" where"mkMinj i M = (case M of Mc c ==> Mc c | Minj j M ==> Minj (i + j) M | _ ==> Minj i M)"
definition Minj_pred :: "nat ==> mon ==> mon" where"Minj_pred i M = (if i = 1 then M else mkMinj (i - 1) M)"
primrec mkMX :: "nat ==> mon ==> mon" where "mkMX i (Mc c) = MX i (Mc c)"
| "mkMX i (Minj j M) = (if j = 0 then mkMX i M else MX i (Minj_pred j M))"
| "mkMX i (MX j M) = MX (i + j) M"
lemma (in cring) mkMinj_correct: "Imon l (mkMinj i M) = Imon l (Minj i M)" by (simp add: mkMinj_def add.commute split: mon.split)
lemma (in cring) Minj_pred_correct: "0 < i ==> Imon (drop 1 l) (Minj_pred i M) = Imon l (Minj i M)" by (simp add: Minj_pred_def mkMinj_correct)
lemma (in cring) mkMX_correct: "in_carrier l ==> Imon l (mkMX i M) = Imon l M ⊗ head l [^] i" by (induct M)
(simp_all add: Minj_pred_correct [simplified] nat_pow_mult [symmetric] m_ac split: mon.split)
fun cfactor :: "pol ==> int ==> pol × pol" where "cfactor (Pc c') c = (Pc (c' mod c), Pc (c' div c))"
| "cfactor (Pinj i P) c = (let (R, S) = cfactor P c in (mkPinj i R, mkPinj i S))"
| "cfactor (PX P i Q) c = (let (R1, S1) = cfactor P c; (R2, S2) = cfactor Q c in (mkPX R1 i R2, mkPX S1 i S2))"
lemma (in cring) cfactor_correct: "in_carrier l ==> Ipol l P = Ipol l (fst (cfactor P c)) ⊕«c¬⊗ Ipol l (snd (cfactor P c))" proof (induct P c arbitrary: l rule: cfactor.induct) case (1 c' c) show ?case by (simp add: of_int_mult [symmetric] of_int_add [symmetric] del: of_int_mult) next case (2 i P c) thenshow ?case by (simp add: mkPinj_ci split_beta) next case (3 P i Q c) from 3(1) 3(2) [OF refl prod.collapse] 3(3) show ?case by (simp add: mkPX_ci r_distr a_ac m_ac split_beta) qed
fun mfactor :: "pol ==> mon ==> pol × pol" where "mfactor P (Mc c) = (if c = 1 then (Pc 0, P) else cfactor P c)"
| "mfactor (Pc d) M = (Pc d, Pc 0)"
| "mfactor (Pinj i P) (Minj j M) = (if i = j then let (R, S) = mfactor P M in (mkPinj i R, mkPinj i S) else if i < j then let (R, S) = mfactor P (Minj (j - i) M) in (mkPinj i R, mkPinj i S) else (Pinj i P, Pc 0))"
| "mfactor (Pinj i P) (MX j M) = (Pinj i P, Pc 0)"
| "mfactor (PX P i Q) (Minj j M) = (if j = 0 then mfactor (PX P i Q) M else let (R1, S1) = mfactor P (Minj j M); (R2, S2) = mfactor Q (Minj_pred j M) in (mkPX R1 i R2, mkPX S1 i S2))"
| "mfactor (PX P i Q) (MX j M) = (if i = j then let (R, S) = mfactor P (mkMinj 1 M) in (mkPX R i Q, S) else if i < j then let (R, S) = mfactor P (MX (j - i) M) in (mkPX R i Q, S) else let (R, S) = mfactor P (mkMinj 1 M) in (mkPX R i Q, mkPX S (i - j) (Pc 0)))"
lemma (in cring) mfactor_correct: "in_carrier l ==> Ipol l P = Ipol l (fst (mfactor P M)) ⊕ Imon l M ⊗ Ipol l (snd (mfactor P M))" proof (induct P M arbitrary: l rule: mfactor_induct) case (Mc P c) thenshow ?case by (simp add: cfactor_correct) next case (Pc_Minj d i M) thenshow ?case by simp next case (Pc_MX d i M) thenshow ?case by simp next case (Pinj_Minj i P j M) thenshow ?case by (simp add: mkPinj_ci split_beta) next case (Pinj_MX i P j M) thenshow ?case by simp next case (PX_Minj P i Q j M) from PX_Minj(1,2) PX_Minj(3) [OF _ refl prod.collapse] PX_Minj(4) show ?case by (simp add: mkPX_ci Minj_pred_correct [simplified] r_distr a_ac m_ac split_beta) next case (PX_MX P i Q j M) from‹in_carrier l› have eq1: "(Imon (drop (Suc 0) l) M ⊗ head l [^] (j - i)) ⊗ Ipol l (snd (mfactor P (MX (j - i) M))) ⊗ head l [^] i = Imon (drop (Suc 0) l) M ⊗ Ipol l (snd (mfactor P (MX (j - i) M))) ⊗ (head l [^] (j - i) ⊗ head l [^] i)" by (simp add: m_ac) from‹in_carrier l› have eq2: "(Imon (drop (Suc 0) l) M ⊗ head l [^] j) ⊗ (Ipol l (snd (mfactor P (mkMinj (Suc 0) M))) ⊗ head l [^] (i - j)) = Imon (drop (Suc 0) l) M ⊗ Ipol l (snd (mfactor P (mkMinj (Suc 0) M))) ⊗ (head l [^] (i - j) ⊗ head l [^] j)" by (simp add: m_ac) from PX_MX ‹in_carrier l›show ?case by (simp add: mkPX_ci mkMinj_correct l_distr eq1 eq2 split_beta nat_pow_mult)
(simp add: a_ac m_ac) qed
primrec mon_of_pol :: "pol ==> mon option" where "mon_of_pol (Pc c) = Some (Mc c)"
| "mon_of_pol (Pinj i P) = (case mon_of_pol P of None ==> None | Some M ==> Some (mkMinj i M))"
| "mon_of_pol (PX P i Q) = (if Q = Pc 0 then (case mon_of_pol P of None ==> None | Some M ==> Some (mkMX i M)) else None)"
lemma (in cring) mon_of_pol_correct: assumes"in_carrier l" and"mon_of_pol P = Some M" shows"Ipol l P = Imon l M" using assms proof (induct P arbitrary: M l) case (PX P1 i P2) from PX(1,3,4) show ?case by (auto simp add: mkMinj_correct mkMX_correct split: if_split_asm option.split_asm) qed (auto simp add: mkMinj_correct split: option.split_asm)
fun (in cring) Ipolex_polex_list :: "'a list ==> (polex × polex) list ==> bool" where "Ipolex_polex_list l [] = True"
| "Ipolex_polex_list l ((P, Q) # pps) = ((Ipolex l P = Ipolex l Q) ∧ Ipolex_polex_list l pps)"
fun (in cring) Imon_pol_list :: "'a list ==> (mon × pol) list ==> bool" where "Imon_pol_list l [] = True"
| "Imon_pol_list l ((M, P) # mps) = ((Imon l M = Ipol l P) ∧ Imon_pol_list l mps)"
fun mk_monpol_list :: "(polex × polex) list ==> (mon × pol) list" where "mk_monpol_list [] = []"
| "mk_monpol_list ((P, Q) # pps) = (case mon_of_pol (norm P) of None ==> mk_monpol_list pps | Some M ==> (M, norm Q) # mk_monpol_list pps)"
lemma (in cring) mk_monpol_list_correct: "in_carrier l ==> Ipolex_polex_list l pps ==> Imon_pol_list l (mk_monpol_list pps)" by (induct pps rule: mk_monpol_list.induct)
(auto split: option.split simp add: norm_ci [symmetric] mon_of_pol_correct [symmetric])
definition ponesubst :: "pol ==> mon ==> pol ==> pol option" where"ponesubst P1 M P2 = (let (Q, R) = mfactor P1 M in (case R of Pc c ==> if c = 0 then None else Some (add Q (mul P2 R)) | _ ==> Some (add Q (mul P2 R))))"
fun pnsubst1 :: "pol ==> mon ==> pol ==> nat ==> pol" where"pnsubst1 P1 M P2 n = (case ponesubst P1 M P2 of None ==> P1 | Some P3 ==> if n = 0 then P3 else pnsubst1 P3 M P2 (n - 1))"
lemma pnsubst1_0 [simp]: "pnsubst1 P1 M P2 0 = (case ponesubst P1 M P2 of None ==> P1 | Some P3 ==> P3)" by (simp split: option.split)
lemma pnsubst1_Suc [simp]: "pnsubst1 P1 M P2 (Suc n) = (case ponesubst P1 M P2 of None ==> P1 | Some P3 ==> pnsubst1 P3 M P2 n)" by (simp split: option.split)
declare pnsubst1.simps [simp del]
definition pnsubst :: "pol ==> mon ==> pol ==> nat ==> pol option" where"pnsubst P1 M P2 n = (case ponesubst P1 M P2 of None ==> None | Some P3 ==> Some (pnsubst1 P3 M P2 n))"
fun psubstl1 :: "pol ==> (mon × pol) list ==> nat ==> pol" where "psubstl1 P1 [] n = P1"
| "psubstl1 P1 ((M, P2) # mps) n = psubstl1 (pnsubst1 P1 M P2 n) mps n"
fun psubstl :: "pol ==> (mon × pol) list ==> nat ==> pol option" where "psubstl P1 [] n = None"
| "psubstl P1 ((M, P2) # mps) n = (case pnsubst P1 M P2 n of None ==> psubstl P1 mps n | Some P3 ==> Some (psubstl1 P3 mps n))"
fun pnsubstl :: "pol ==> (mon × pol) list ==> nat ==> nat ==> pol" where"pnsubstl P1 mps m n = (case psubstl P1 mps n of None ==> P1 | Some P3 ==> if m = 0 then P3 else pnsubstl P3 mps (m - 1) n)"
lemma pnsubstl_0 [simp]: "pnsubstl P1 mps 0 n = (case psubstl P1 mps n of None ==> P1 | Some P3 ==> P3)" by (simp split: option.split)
lemma pnsubstl_Suc [simp]: "pnsubstl P1 mps (Suc m) n = (case psubstl P1 mps n of None ==> P1 | Some P3 ==> pnsubstl P3 mps m n)" by (simp split: option.split)
declare pnsubstl.simps [simp del]
lemma (in cring) ponesubst_correct: "in_carrier l ==> ponesubst P1 M P2 = Some P3 ==> Imon l M = Ipol l P2 ==> Ipol l P1 = Ipol l P3" by (auto simp add: ponesubst_def split_beta mfactor_correct [of l P1 M]
add_ci mul_ci split: pol.split_asm if_split_asm)
lemma (in cring) pnsubst1_correct: "in_carrier l ==> Imon l M = Ipol l P2 ==> Ipol l (pnsubst1 P1 M P2 n) = Ipol l P1" by (induct n arbitrary: P1)
(simp_all add: ponesubst_correct split: option.split)
lemma (in cring) pnsubst_correct: "in_carrier l ==> pnsubst P1 M P2 n = Some P3 ==> Imon l M = Ipol l P2 ==> Ipol l P1 = Ipol l P3" by (auto simp add: pnsubst_def
pnsubst1_correct ponesubst_correct split: option.split_asm)
lemma (in cring) psubstl1_correct: "in_carrier l ==> Imon_pol_list l mps ==> Ipol l (psubstl1 P1 mps n) = Ipol l P1" by (induct P1 mps n rule: psubstl1.induct) (simp_all add: pnsubst1_correct)
lemma (in cring) psubstl_correct: "in_carrier l ==> psubstl P1 mps n = Some P2 ==> Imon_pol_list l mps ==> Ipol l P1 = Ipol l P2" by (induct P1 mps n rule: psubstl.induct)
(auto simp add: psubstl1_correct pnsubst_correct split: option.split_asm)
lemma (in cring) pnsubstl_correct: "in_carrier l ==> Imon_pol_list l mps ==> Ipol l (pnsubstl P1 mps m n) = Ipol l P1" by (induct m arbitrary: P1)
(simp_all add: psubstl_correct split: option.split)
lemma (in cring) norm_subst_correct: "in_carrier l ==> Ipolex_polex_list l pps ==> Ipolex l P = Ipol l (pnsubstl (norm P) (mk_monpol_list pps) m n)" by (simp add: pnsubstl_correct mk_monpol_list_correct norm_ci)
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.