{-# OPTIONS --safe #-}
module Cubical.Tactics.CommRingSolver.HornerEval where
open import Cubical.Foundations.Prelude
open import Cubical.Data.Nat using (ℕ)
open import Cubical.Data.Int hiding (_+_ ; _·_ ; -_)
open import Cubical.Data.Vec
open import Cubical.Data.Bool
open import Cubical.Relation.Nullary.Base using (¬_; yes; no)
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.Algebra.CommRing
open import Cubical.Algebra.Ring
private
variable
ℓ ℓ' : Level
eval : {A : RawAlgebra ℤAsRawRing ℓ'}
{n : ℕ} (P : IteratedHornerForms A n)
→ Vec ⟨ A ⟩ n → ⟨ A ⟩
eval {A = A} (const r) [] = RawAlgebra.scalar A r
eval {A = A} 0H (_ ∷ _) = RawAlgebra.0r A
eval {A = A} (P ·X+ Q) (x ∷ xs) =
let open RawAlgebra A
P' = (eval P (x ∷ xs))
Q' = eval Q xs
in if (isZero A P)
then Q'
else P' · x + Q'
module _ (R : CommRing ℓ) where
private
νR = CommRing→RawℤAlgebra R
open CommRingStr (snd R)
open RingTheory (CommRing→Ring R)
open IteratedHornerOperations νR
someCalculation : {x : fst R} → _ ≡ _
someCalculation {x = x} =
0r ≡⟨ sym (+IdR 0r) ⟩
0r + 0r ≡[ i ]⟨ 0LeftAnnihilates x (~ i) + 0r ⟩
0r · x + 0r ∎
evalIsZero : {n : ℕ} (P : IteratedHornerForms νR n)
→ (l : Vec (fst R) n)
→ isZero νR P ≡ true
→ eval P l ≡ 0r
evalIsZero (const (pos ℕ.zero)) [] isZeroP = refl
evalIsZero (const (pos (ℕ.suc n))) [] isZeroP = byBoolAbsurdity isZeroP
evalIsZero (const (negsuc _)) [] isZeroP = byBoolAbsurdity isZeroP
evalIsZero 0H (x ∷ xs) _ = refl
evalIsZero {n = ℕ.suc n} (P ·X+ Q) (x ∷ xs) isZeroPandQ with isZero νR P
... | true = eval Q xs ≡⟨ evalIsZero Q xs isZeroQ ⟩
0r ∎
where isZeroQ = snd (extractFromAnd _ _ isZeroPandQ)
... | false = byBoolAbsurdity isZeroP
where isZeroP = isZeroPandQ
computeEvalSummandIsZero :
{n : ℕ}
(P : IteratedHornerForms νR (ℕ.suc n))
(Q : IteratedHornerForms νR n)
→ (xs : Vec (fst R) n)
→ (x : (fst R))
→ isZero νR P ≡ true
→ eval (P ·X+ Q) (x ∷ xs) ≡ eval Q xs
computeEvalSummandIsZero P Q xs x isZeroP with isZero νR P
... | true = refl
... | false = byBoolAbsurdity isZeroP
computeEvalNotZero :
{n : ℕ}
(P : IteratedHornerForms νR (ℕ.suc n))
(Q : IteratedHornerForms νR n)
→ (xs : Vec (fst R) n)
→ (x : (fst R))
→ ¬ (isZero νR P ≡ true)
→ eval (P ·X+ Q) (x ∷ xs) ≡ (eval P (x ∷ xs)) · x + eval Q xs
computeEvalNotZero P Q xs x notZeroP with isZero νR P
... | true = byBoolAbsurdity (sym (¬true→false true notZeroP))
... | false = refl
combineCasesEval :
{n : ℕ} (P : IteratedHornerForms νR (ℕ.suc n)) (Q : IteratedHornerForms νR n)
(x : (fst R)) (xs : Vec (fst R) n)
→ eval (P ·X+ Q) (x ∷ xs)
≡ (eval P (x ∷ xs)) · x + eval Q xs
combineCasesEval P Q x xs with isZero νR P ≟ true
... | yes p =
eval (P ·X+ Q) (x ∷ xs) ≡⟨ computeEvalSummandIsZero P Q xs x p ⟩
eval Q xs ≡⟨ sym (+IdL _) ⟩
0r + eval Q xs ≡[ i ]⟨ 0LeftAnnihilates x (~ i) + eval Q xs ⟩
0r · x + eval Q xs ≡[ i ]⟨ (evalIsZero P (x ∷ xs) p (~ i)) · x + eval Q xs ⟩
(eval P (x ∷ xs)) · x + eval Q xs ∎
... | no p = computeEvalNotZero P Q xs x p
compute+ₕEvalBothZero :
(n : ℕ) (P Q : IteratedHornerForms νR (ℕ.suc n))
(r s : IteratedHornerForms νR n)
(x : (fst R)) (xs : Vec (fst R) n)
→ (isZero νR (P +ₕ Q) and isZero νR (r +ₕ s)) ≡ true
→ eval ((P ·X+ r) +ₕ (Q ·X+ s)) (x ∷ xs) ≡ eval ((P +ₕ Q) ·X+ (r +ₕ s)) (x ∷ xs)
compute+ₕEvalBothZero n P Q r s x xs bothZero with isZero νR (P +ₕ Q) and isZero νR (r +ₕ s) | bothZero
... | true | p =
eval {A = νR} 0H (x ∷ xs) ≡⟨ refl ⟩
0r ≡⟨ someCalculation ⟩
0r · x + 0r ≡⟨ step1 ⟩
(eval (P +ₕ Q) (x ∷ xs)) · x + eval (r +ₕ s) xs ≡⟨ step2 ⟩
eval ((P +ₕ Q) ·X+ (r +ₕ s)) (x ∷ xs) ∎
where step1 : 0r · x + 0r ≡ (eval (P +ₕ Q) (x ∷ xs)) · x + eval (r +ₕ s) xs
step1 i = (evalIsZero (P +ₕ Q) (x ∷ xs) (fst (extractFromAnd _ _ (bothZero))) (~ i)) · x
+ (evalIsZero (r +ₕ s) xs (snd (extractFromAnd _ _ (bothZero))) (~ i))
step2 = sym (combineCasesEval (P +ₕ Q) (r +ₕ s) x xs)
... | false | p = byBoolAbsurdity p
compute+ₕEvalNotBothZero :
(n : ℕ) (P Q : IteratedHornerForms νR (ℕ.suc n))
(r s : IteratedHornerForms νR n)
(x : (fst R)) (xs : Vec (fst R) n)
→ (isZero νR (P +ₕ Q) and isZero νR (r +ₕ s)) ≡ false
→ eval ((P ·X+ r) +ₕ (Q ·X+ s)) (x ∷ xs) ≡ eval ((P +ₕ Q) ·X+ (r +ₕ s)) (x ∷ xs)
compute+ₕEvalNotBothZero n P Q r s _ _ notBothZero
with isZero νR (P +ₕ Q) and isZero νR (r +ₕ s) | notBothZero
... | true | p = byBoolAbsurdity (sym p)
... | false | p = refl