{-# OPTIONS --safe #-} module Cubical.Tactics.CommRingSolver.EvalHom where open import Cubical.Foundations.Prelude open import Cubical.Data.Nat using (ℕ) open import Cubical.Data.Int.Base hiding (_+_ ; _·_ ; -_) open import Cubical.Data.FinData open import Cubical.Data.Vec open import Cubical.Data.Bool open import Cubical.Relation.Nullary.Base open import Cubical.Tactics.CommRingSolver.Utility open import Cubical.Tactics.CommRingSolver.RawAlgebra open import Cubical.Tactics.CommRingSolver.IntAsRawRing open import Cubical.Tactics.CommRingSolver.HornerForms open import Cubical.Tactics.CommRingSolver.HornerEval open import Cubical.Algebra.CommRing open import Cubical.Algebra.Ring private variable ℓ : Level module HomomorphismProperties (R : CommRing ℓ) where private νR = CommRing→RawℤAlgebra R open CommRingStr (snd R) open RingTheory (CommRing→Ring R) open IteratedHornerOperations νR EvalHom+0 : {n : ℕ} (P : IteratedHornerForms νR n) (xs : Vec ⟨ νR ⟩ n) → eval (0ₕ +ₕ P) xs ≡ eval P xs EvalHom+0 {n = ℕ.zero} (const x) [] = cong (scalar R) (+Ridℤ x) EvalHom+0 {n = ℕ.suc _} P xs = refl Eval0H : {n : ℕ} (xs : Vec ⟨ νR ⟩ n) → eval {A = νR} 0ₕ xs ≡ 0r Eval0H [] = refl Eval0H (x ∷ xs) = refl Eval1ₕ : {n : ℕ} (xs : Vec ⟨ νR ⟩ n) → eval {A = νR} 1ₕ xs ≡ 1r Eval1ₕ [] = refl Eval1ₕ (x ∷ xs) = eval 1ₕ (x ∷ xs) ≡⟨ refl ⟩ eval (0H ·X+ 1ₕ) (x ∷ xs) ≡⟨ combineCasesEval R 0H 1ₕ x xs ⟩ eval {A = νR} 0H (x ∷ xs) · x + eval 1ₕ xs ≡⟨ cong (λ u → u · x + eval 1ₕ xs) (Eval0H (x ∷ xs)) ⟩ 0r · x + eval 1ₕ xs ≡⟨ cong (λ u → 0r · x + u) (Eval1ₕ xs) ⟩ 0r · x + 1r ≡⟨ cong (λ u → u + 1r) (0LeftAnnihilates _) ⟩ 0r + 1r ≡⟨ +IdL _ ⟩ 1r ∎ -EvalDist : {n : ℕ} (P : IteratedHornerForms νR n) (xs : Vec ⟨ νR ⟩ n) → eval (-ₕ P) xs ≡ - eval P xs -EvalDist (const x) [] = -DistScalar R x -EvalDist 0H xs = eval (-ₕ 0H) xs ≡⟨ Eval0H xs ⟩ 0r ≡⟨ sym 0Selfinverse ⟩ - 0r ≡⟨ cong -_ (sym (Eval0H xs)) ⟩ - eval 0H xs ∎ -EvalDist (P ·X+ Q) (x ∷ xs) = eval (-ₕ (P ·X+ Q)) (x ∷ xs) ≡⟨ refl ⟩ eval ((-ₕ P) ·X+ (-ₕ Q)) (x ∷ xs) ≡⟨ combineCasesEval R (-ₕ P) (-ₕ Q) x xs ⟩ (eval (-ₕ P) (x ∷ xs)) · x + eval (-ₕ Q) xs ≡⟨ cong (λ u → u · x + eval (-ₕ Q) xs) (-EvalDist P _) ⟩ (- eval P (x ∷ xs)) · x + eval (-ₕ Q) xs ≡⟨ cong (λ u → (- eval P (x ∷ xs)) · x + u) (-EvalDist Q _) ⟩ (- eval P (x ∷ xs)) · x + - eval Q xs ≡[ i ]⟨ -DistL· (eval P (x ∷ xs)) x i + - eval Q xs ⟩ - ((eval P (x ∷ xs)) · x) + (- eval Q xs) ≡⟨ -Dist _ _ ⟩ - ((eval P (x ∷ xs)) · x + eval Q xs) ≡[ i ]⟨ - combineCasesEval R P Q x xs (~ i) ⟩ - eval (P ·X+ Q) (x ∷ xs) ∎ combineCases+ : {n : ℕ} (P Q : IteratedHornerForms νR (ℕ.suc n)) (r s : IteratedHornerForms νR n) (x : fst R) (xs : Vec (fst R) n) → eval ((P ·X+ r) +ₕ (Q ·X+ s)) (x ∷ xs) ≡ eval ((P +ₕ Q) ·X+ (r +ₕ s)) (x ∷ xs) combineCases+ {n = n} P Q r s x xs with (isZero νR (P +ₕ Q) and isZero νR (r +ₕ s)) ≟ true ... | yes p = compute+ₕEvalBothZero R n P Q r s x xs p ... | no p = compute+ₕEvalNotBothZero R n P Q r s x xs (¬true→false _ p) +Homeval : {n : ℕ} (P Q : IteratedHornerForms νR n) (xs : Vec ⟨ νR ⟩ n) → eval (P +ₕ Q) xs ≡ (eval P xs) + (eval Q xs) +Homeval (const x) (const y) [] = +HomScalar R x y +Homeval 0H Q xs = eval (0H +ₕ Q) xs ≡⟨ refl ⟩ eval Q xs ≡⟨ sym (+IdL _) ⟩ 0r + eval Q xs ≡⟨ cong (λ u → u + eval Q xs) (sym (Eval0H xs)) ⟩ eval 0H xs + eval Q xs ∎ +Homeval (P ·X+ Q) 0H xs = eval ((P ·X+ Q) +ₕ 0H) xs ≡⟨ refl ⟩ eval (P ·X+ Q) xs ≡⟨ sym (+IdR _) ⟩ eval (P ·X+ Q) xs + 0r ≡⟨ cong (λ u → eval (P ·X+ Q) xs + u) (sym (Eval0H xs)) ⟩ eval (P ·X+ Q) xs + eval 0H xs ∎ +Homeval (P ·X+ Q) (S ·X+ T) (x ∷ xs) = eval ((P ·X+ Q) +ₕ (S ·X+ T)) (x ∷ xs) ≡⟨ combineCases+ P S Q T x xs ⟩ eval ((P +ₕ S) ·X+ (Q +ₕ T)) (x ∷ xs) ≡⟨ combineCasesEval R (P +ₕ S) (Q +ₕ T) x xs ⟩ (eval (P +ₕ S) (x ∷ xs)) · x + eval (Q +ₕ T) xs ≡⟨ cong (λ u → (eval (P +ₕ S) (x ∷ xs)) · x + u) (+Homeval Q T xs) ⟩ (eval (P +ₕ S) (x ∷ xs)) · x + (eval Q xs + eval T xs) ≡⟨ cong (λ u → u · x + (eval Q xs + eval T xs)) (+Homeval P S (x ∷ xs)) ⟩ (eval P (x ∷ xs) + eval S (x ∷ xs)) · x + (eval Q xs + eval T xs) ≡⟨ cong (λ u → u + (eval Q xs + eval T xs)) (·DistL+ _ _ _) ⟩ (eval P (x ∷ xs)) · x + (eval S (x ∷ xs)) · x + (eval Q xs + eval T xs) ≡⟨ +ShufflePairs _ _ _ _ ⟩ ((eval P (x ∷ xs)) · x + eval Q xs) + ((eval S (x ∷ xs)) · x + eval T xs) ≡[ i ]⟨ combineCasesEval R P Q x xs (~ i) + combineCasesEval R S T x xs (~ i) ⟩ eval (P ·X+ Q) (x ∷ xs) + eval (S ·X+ T) (x ∷ xs) ∎ ⋆Homeval : {n : ℕ} (r : IteratedHornerForms νR n) (P : IteratedHornerForms νR (ℕ.suc n)) (x : ⟨ νR ⟩) (xs : Vec ⟨ νR ⟩ n) → eval (r ⋆ P) (x ∷ xs) ≡ eval r xs · eval P (x ∷ xs) ⋆0LeftAnnihilates : {n : ℕ} (P : IteratedHornerForms νR (ℕ.suc n)) (xs : Vec ⟨ νR ⟩ (ℕ.suc n)) → eval (0ₕ ⋆ P) xs ≡ 0r ⋆0LeftAnnihilates 0H xs = Eval0H xs ⋆0LeftAnnihilates {n = ℕ.zero} (P ·X+ Q) (x ∷ xs) = refl ⋆0LeftAnnihilates {n = ℕ.suc _} (P ·X+ Q) (x ∷ xs) = refl ⋆isZeroLeftAnnihilates : {n : ℕ} (r : IteratedHornerForms νR n) (P : IteratedHornerForms νR (ℕ.suc n)) (xs : Vec ⟨ νR ⟩ (ℕ.suc n)) → isZero νR r ≡ true → eval (r ⋆ P) xs ≡ 0r ⋆isZeroLeftAnnihilates r P xs isZero-r = evalIsZero R (r ⋆ P) xs (isZeroPresLeft⋆ r P isZero-r) ·0LeftAnnihilates : {n : ℕ} (P : IteratedHornerForms νR n) (xs : Vec ⟨ νR ⟩ n) → eval (0ₕ ·ₕ P) xs ≡ 0r ·0LeftAnnihilates (const x) xs = eval (const _) xs ≡⟨ Eval0H xs ⟩ 0r ∎ ·0LeftAnnihilates 0H xs = Eval0H xs ·0LeftAnnihilates (P ·X+ P₁) xs = Eval0H xs ·isZeroLeftAnnihilates : {n : ℕ} (P Q : IteratedHornerForms νR n) (xs : Vec (fst R) n) → isZero νR P ≡ true → eval (P ·ₕ Q) xs ≡ 0r ·isZeroLeftAnnihilates P Q xs isZeroP = evalIsZero R (P ·ₕ Q) xs (isZeroPresLeft·ₕ P Q isZeroP) ·Homeval : {n : ℕ} (P Q : IteratedHornerForms νR n) (xs : Vec ⟨ νR ⟩ n) → eval (P ·ₕ Q) xs ≡ (eval P xs) · (eval Q xs) combineCases⋆ : {n : ℕ} (x : fst R) (xs : Vec (fst R) n) → (r : IteratedHornerForms νR n) → (P : IteratedHornerForms νR (ℕ.suc n)) → (Q : IteratedHornerForms νR n) → eval (r ⋆ (P ·X+ Q)) (x ∷ xs) ≡ eval ((r ⋆ P) ·X+ (r ·ₕ Q)) (x ∷ xs) combineCases⋆ x xs r P Q with isZero νR r ≟ true ... | yes p = eval (r ⋆ (P ·X+ Q)) (x ∷ xs) ≡⟨ ⋆isZeroLeftAnnihilates r (P ·X+ Q) (x ∷ xs) p ⟩ 0r ≡⟨ someCalculation R ⟩ 0r · x + 0r ≡⟨ step1 ⟩ eval (r ⋆ P) (x ∷ xs) · x + eval (r ·ₕ Q) xs ≡⟨ sym (combineCasesEval R (r ⋆ P) (r ·ₕ Q) x xs) ⟩ eval ((r ⋆ P) ·X+ (r ·ₕ Q)) (x ∷ xs) ∎ where step1 : 0r · x + 0r ≡ eval (r ⋆ P) (x ∷ xs) · x + eval (r ·ₕ Q) xs step1 i = ⋆isZeroLeftAnnihilates r P (x ∷ xs) p (~ i) · x + ·isZeroLeftAnnihilates r Q xs p (~ i) ... | no p with isZero νR r ... | true = byAbsurdity (p refl) ... | false = refl ⋆Homeval r 0H x xs = eval (r ⋆ 0H) (x ∷ xs) ≡⟨ refl ⟩ 0r ≡⟨ sym (0RightAnnihilates _) ⟩ eval r xs · 0r ≡⟨ refl ⟩ eval r xs · eval {A = νR} 0H (x ∷ xs) ∎ ⋆Homeval r (P ·X+ Q) x xs = eval (r ⋆ (P ·X+ Q)) (x ∷ xs) ≡⟨ combineCases⋆ x xs r P Q ⟩ eval ((r ⋆ P) ·X+ (r ·ₕ Q)) (x ∷ xs) ≡⟨ combineCasesEval R (r ⋆ P) (r ·ₕ Q) x xs ⟩ (eval (r ⋆ P) (x ∷ xs)) · x + eval (r ·ₕ Q) xs ≡⟨ cong (λ u → u · x + eval (r ·ₕ Q) xs) (⋆Homeval r P x xs) ⟩ (eval r xs · eval P (x ∷ xs)) · x + eval (r ·ₕ Q) xs ≡⟨ cong (λ u → (eval r xs · eval P (x ∷ xs)) · x + u) (·Homeval r Q xs) ⟩ (eval r xs · eval P (x ∷ xs)) · x + eval r xs · eval Q xs ≡⟨ cong (λ u → u + eval r xs · eval Q xs) (sym (·Assoc _ _ _)) ⟩ eval r xs · (eval P (x ∷ xs) · x) + eval r xs · eval Q xs ≡⟨ sym (·DistR+ _ _ _) ⟩ eval r xs · ((eval P (x ∷ xs) · x) + eval Q xs) ≡[ i ]⟨ eval r xs · combineCasesEval R P Q x xs (~ i) ⟩ eval r xs · eval (P ·X+ Q) (x ∷ xs) ∎ lemmaForCombineCases· : {n : ℕ} (Q : IteratedHornerForms νR n) (P S : IteratedHornerForms νR (ℕ.suc n)) (xs : Vec (fst R) (ℕ.suc n)) → isZero νR (P ·ₕ S) ≡ true → eval ((P ·X+ Q) ·ₕ S) xs ≡ eval (Q ⋆ S) xs lemmaForCombineCases· Q P S xs isZeroProd with isZero νR (P ·ₕ S) ... | true = refl ... | false = byBoolAbsurdity isZeroProd combineCases· : {n : ℕ} (Q : IteratedHornerForms νR n) (P S : IteratedHornerForms νR (ℕ.suc n)) (xs : Vec (fst R) (ℕ.suc n)) → eval ((P ·X+ Q) ·ₕ S) xs ≡ eval (((P ·ₕ S) ·X+ 0ₕ) +ₕ (Q ⋆ S)) xs combineCases· Q P S (x ∷ xs) with isZero νR (P ·ₕ S) ≟ true ... | yes p = eval ((P ·X+ Q) ·ₕ S) (x ∷ xs) ≡⟨ lemmaForCombineCases· Q P S (x ∷ xs) p ⟩ eval (Q ⋆ S) (x ∷ xs) ≡⟨ sym (+IdL _) ⟩ 0r + eval (Q ⋆ S) (x ∷ xs) ≡⟨ step1 ⟩ eval ((P ·ₕ S) ·X+ 0ₕ) (x ∷ xs) + eval (Q ⋆ S) (x ∷ xs) ≡⟨ step2 ⟩ eval (((P ·ₕ S) ·X+ 0ₕ) +ₕ (Q ⋆ S)) (x ∷ xs) ∎ where lemma = eval ((P ·ₕ S) ·X+ 0ₕ) (x ∷ xs) ≡⟨ combineCasesEval R (P ·ₕ S) 0ₕ x xs ⟩ eval (P ·ₕ S) (x ∷ xs) · x + eval 0ₕ xs ≡[ i ]⟨ evalIsZero R (P ·ₕ S) (x ∷ xs) p i · x + Eval0H xs i ⟩ 0r · x + 0r ≡⟨ sym (someCalculation R) ⟩ 0r ∎ step1 : _ ≡ _ step1 i = lemma (~ i) + eval (Q ⋆ S) (x ∷ xs) step2 = sym (+Homeval ((P ·ₕ S) ·X+ 0ₕ) (Q ⋆ S) (x ∷ xs)) ... | no p with isZero νR (P ·ₕ S) ... | true = byAbsurdity (p refl) ... | false = refl ·Homeval (const x) (const y) [] = ·HomScalar R x y ·Homeval 0H Q xs = eval (0H ·ₕ Q) xs ≡⟨ Eval0H xs ⟩ 0r ≡⟨ sym (0LeftAnnihilates _) ⟩ 0r · eval Q xs ≡⟨ cong (λ u → u · eval Q xs) (sym (Eval0H xs)) ⟩ eval 0H xs · eval Q xs ∎ ·Homeval (P ·X+ Q) S (x ∷ xs) = eval ((P ·X+ Q) ·ₕ S) (x ∷ xs) ≡⟨ combineCases· Q P S (x ∷ xs) ⟩ eval (((P ·ₕ S) ·X+ 0ₕ) +ₕ (Q ⋆ S)) (x ∷ xs) ≡⟨ +Homeval ((P ·ₕ S) ·X+ 0ₕ) (Q ⋆ S) (x ∷ xs) ⟩ eval ((P ·ₕ S) ·X+ 0ₕ) (x ∷ xs) + eval (Q ⋆ S) (x ∷ xs) ≡⟨ cong (λ u → u + eval (Q ⋆ S) (x ∷ xs)) (combineCasesEval R (P ·ₕ S) 0ₕ x xs) ⟩ (eval (P ·ₕ S) (x ∷ xs) · x + eval 0ₕ xs) + eval (Q ⋆ S) (x ∷ xs) ≡⟨ cong (λ u → u + eval (Q ⋆ S) (x ∷ xs)) ((eval (P ·ₕ S) (x ∷ xs) · x + eval 0ₕ xs) ≡⟨ cong (λ u → eval (P ·ₕ S) (x ∷ xs) · x + u) (Eval0H xs) ⟩ (eval (P ·ₕ S) (x ∷ xs) · x + 0r) ≡⟨ +IdR _ ⟩ (eval (P ·ₕ S) (x ∷ xs) · x) ≡⟨ cong (λ u → u · x) (·Homeval P S (x ∷ xs)) ⟩ ((eval P (x ∷ xs) · eval S (x ∷ xs)) · x) ≡⟨ sym (·Assoc _ _ _) ⟩ (eval P (x ∷ xs) · (eval S (x ∷ xs) · x)) ≡⟨ cong (λ u → eval P (x ∷ xs) · u) (·Comm _ _) ⟩ (eval P (x ∷ xs) · (x · eval S (x ∷ xs))) ≡⟨ ·Assoc _ _ _ ⟩ (eval P (x ∷ xs) · x) · eval S (x ∷ xs) ∎) ⟩ (eval P (x ∷ xs) · x) · eval S (x ∷ xs) + eval (Q ⋆ S) (x ∷ xs) ≡⟨ cong (λ u → (eval P (x ∷ xs) · x) · eval S (x ∷ xs) + u) (⋆Homeval Q S x xs) ⟩ (eval P (x ∷ xs) · x) · eval S (x ∷ xs) + eval Q xs · eval S (x ∷ xs) ≡⟨ sym (·DistL+ _ _ _) ⟩ ((eval P (x ∷ xs) · x) + eval Q xs) · eval S (x ∷ xs) ≡⟨ cong (λ u → u · eval S (x ∷ xs)) (sym (combineCasesEval R P Q x xs)) ⟩ eval (P ·X+ Q) (x ∷ xs) · eval S (x ∷ xs) ∎