{-# OPTIONS --safe #-} module Cubical.Algebra.RingSolver.CommRingSolver where open import Cubical.Foundations.Prelude open import Cubical.Data.FinData open import Cubical.Data.Nat using (ℕ) open import Cubical.Data.Nat.Order using (zero-≤) open import Cubical.Data.Vec.Base open import Cubical.Algebra.CommRing open import Cubical.Algebra.Ring open import Cubical.Algebra.RingSolver.RawAlgebra renaming (⟨_⟩ to ⟨_⟩ᵣ) open import Cubical.Algebra.RingSolver.AlgebraExpression open import Cubical.Algebra.RingSolver.IntAsRawRing open import Cubical.Algebra.RingSolver.CommRingHornerForms open import Cubical.Algebra.RingSolver.CommRingEvalHom open import Cubical.Algebra.RingSolver.CommRingHornerEval private variable ℓ : Level module EqualityToNormalform (R : CommRing ℓ) where νR = CommRing→RawℤAlgebra R open CommRingStr (snd R) open RingTheory (CommRing→Ring R) open Eval ℤAsRawRing νR open IteratedHornerOperations νR open HomomorphismProperties R ℤExpr : (n : ℕ) → Type _ ℤExpr = Expr ℤAsRawRing (fst R) normalize : (n : ℕ) → ℤExpr n → IteratedHornerForms νR n normalize n (K r) = Constant n νR r normalize n (∣ k) = Variable n νR k normalize n (x +' y) = (normalize n x) +ₕ (normalize n y) normalize n (x ·' y) = (normalize n x) ·ₕ (normalize n y) normalize n (-' x) = -ₕ (normalize n x) isEqualToNormalform : (n : ℕ) (e : ℤExpr n) (xs : Vec (fst R) n) → eval n (normalize n e) xs ≡ ⟦ e ⟧ xs isEqualToNormalform ℕ.zero (K r) [] = refl isEqualToNormalform (ℕ.suc n) (K r) (x ∷ xs) = eval (ℕ.suc n) (Constant (ℕ.suc n) νR r) (x ∷ xs) ≡⟨ refl ⟩ eval (ℕ.suc n) (0ₕ ·X+ Constant n νR r) (x ∷ xs) ≡⟨ combineCasesEval R 0ₕ (Constant n νR r) x xs ⟩ eval (ℕ.suc n) 0ₕ (x ∷ xs) · x + eval n (Constant n νR r) xs ≡⟨ cong (λ u → u · x + eval n (Constant n νR r) xs) (Eval0H _ (x ∷ xs)) ⟩ 0r · x + eval n (Constant n νR r) xs ≡⟨ cong (λ u → u + eval n (Constant n νR r) xs) (0LeftAnnihilates _) ⟩ 0r + eval n (Constant n νR r) xs ≡⟨ +Lid _ ⟩ eval n (Constant n νR r) xs ≡⟨ isEqualToNormalform n (K r) xs ⟩ _ ∎ isEqualToNormalform (ℕ.suc n) (∣ zero) (x ∷ xs) = eval (ℕ.suc n) (1ₕ ·X+ 0ₕ) (x ∷ xs) ≡⟨ combineCasesEval R 1ₕ 0ₕ x xs ⟩ eval (ℕ.suc n) 1ₕ (x ∷ xs) · x + eval n 0ₕ xs ≡⟨ cong (λ u → u · x + eval n 0ₕ xs) (Eval1ₕ _ (x ∷ xs)) ⟩ 1r · x + eval n 0ₕ xs ≡⟨ cong (λ u → 1r · x + u ) (Eval0H _ xs) ⟩ 1r · x + 0r ≡⟨ +Rid _ ⟩ 1r · x ≡⟨ ·Lid _ ⟩ x ∎ isEqualToNormalform (ℕ.suc n) (∣ (suc k)) (x ∷ xs) = eval (ℕ.suc n) (0ₕ ·X+ Variable n νR k) (x ∷ xs) ≡⟨ combineCasesEval R 0ₕ (Variable n νR k) x xs ⟩ eval (ℕ.suc n) 0ₕ (x ∷ xs) · x + eval n (Variable n νR k) xs ≡⟨ cong (λ u → u · x + eval n (Variable n νR k) xs) (Eval0H _ (x ∷ xs)) ⟩ 0r · x + eval n (Variable n νR k) xs ≡⟨ cong (λ u → u + eval n (Variable n νR k) xs) (0LeftAnnihilates _) ⟩ 0r + eval n (Variable n νR k) xs ≡⟨ +Lid _ ⟩ eval n (Variable n νR k) xs ≡⟨ isEqualToNormalform n (∣ k) xs ⟩ ⟦ ∣ (suc k) ⟧ (x ∷ xs) ∎ isEqualToNormalform ℕ.zero (-' e) [] = eval ℕ.zero (-ₕ (normalize ℕ.zero e)) [] ≡⟨ -EvalDist ℕ.zero (normalize ℕ.zero e) [] ⟩ - eval ℕ.zero (normalize ℕ.zero e) [] ≡⟨ cong -_ (isEqualToNormalform ℕ.zero e [] ) ⟩ - ⟦ e ⟧ [] ∎ isEqualToNormalform (ℕ.suc n) (-' e) (x ∷ xs) = eval (ℕ.suc n) (-ₕ (normalize (ℕ.suc n) e)) (x ∷ xs) ≡⟨ -EvalDist (ℕ.suc n) (normalize (ℕ.suc n) e) (x ∷ xs) ⟩ - eval (ℕ.suc n) (normalize (ℕ.suc n) e) (x ∷ xs) ≡⟨ cong -_ (isEqualToNormalform (ℕ.suc n) e (x ∷ xs) ) ⟩ - ⟦ e ⟧ (x ∷ xs) ∎ isEqualToNormalform ℕ.zero (e +' e₁) [] = eval ℕ.zero (normalize ℕ.zero e +ₕ normalize ℕ.zero e₁) [] ≡⟨ +Homeval ℕ.zero (normalize ℕ.zero e) _ [] ⟩ eval ℕ.zero (normalize ℕ.zero e) [] + eval ℕ.zero (normalize ℕ.zero e₁) [] ≡⟨ cong (λ u → u + eval ℕ.zero (normalize ℕ.zero e₁) []) (isEqualToNormalform ℕ.zero e []) ⟩ ⟦ e ⟧ [] + eval ℕ.zero (normalize ℕ.zero e₁) [] ≡⟨ cong (λ u → ⟦ e ⟧ [] + u) (isEqualToNormalform ℕ.zero e₁ []) ⟩ ⟦ e ⟧ [] + ⟦ e₁ ⟧ [] ∎ isEqualToNormalform (ℕ.suc n) (e +' e₁) (x ∷ xs) = eval (ℕ.suc n) (normalize (ℕ.suc n) e +ₕ normalize (ℕ.suc n) e₁) (x ∷ xs) ≡⟨ +Homeval (ℕ.suc n) (normalize (ℕ.suc n) e) _ (x ∷ xs) ⟩ eval (ℕ.suc n) (normalize (ℕ.suc n) e) (x ∷ xs) + eval (ℕ.suc n) (normalize (ℕ.suc n) e₁) (x ∷ xs) ≡⟨ cong (λ u → u + eval (ℕ.suc n) (normalize (ℕ.suc n) e₁) (x ∷ xs)) (isEqualToNormalform (ℕ.suc n) e (x ∷ xs)) ⟩ ⟦ e ⟧ (x ∷ xs) + eval (ℕ.suc n) (normalize (ℕ.suc n) e₁) (x ∷ xs) ≡⟨ cong (λ u → ⟦ e ⟧ (x ∷ xs) + u) (isEqualToNormalform (ℕ.suc n) e₁ (x ∷ xs)) ⟩ ⟦ e ⟧ (x ∷ xs) + ⟦ e₁ ⟧ (x ∷ xs) ∎ isEqualToNormalform ℕ.zero (e ·' e₁) [] = eval ℕ.zero (normalize ℕ.zero e ·ₕ normalize ℕ.zero e₁) [] ≡⟨ ·Homeval ℕ.zero (normalize ℕ.zero e) _ [] ⟩ eval ℕ.zero (normalize ℕ.zero e) [] · eval ℕ.zero (normalize ℕ.zero e₁) [] ≡⟨ cong (λ u → u · eval ℕ.zero (normalize ℕ.zero e₁) []) (isEqualToNormalform ℕ.zero e []) ⟩ ⟦ e ⟧ [] · eval ℕ.zero (normalize ℕ.zero e₁) [] ≡⟨ cong (λ u → ⟦ e ⟧ [] · u) (isEqualToNormalform ℕ.zero e₁ []) ⟩ ⟦ e ⟧ [] · ⟦ e₁ ⟧ [] ∎ isEqualToNormalform (ℕ.suc n) (e ·' e₁) (x ∷ xs) = eval (ℕ.suc n) (normalize (ℕ.suc n) e ·ₕ normalize (ℕ.suc n) e₁) (x ∷ xs) ≡⟨ ·Homeval (ℕ.suc n) (normalize (ℕ.suc n) e) _ (x ∷ xs) ⟩ eval (ℕ.suc n) (normalize (ℕ.suc n) e) (x ∷ xs) · eval (ℕ.suc n) (normalize (ℕ.suc n) e₁) (x ∷ xs) ≡⟨ cong (λ u → u · eval (ℕ.suc n) (normalize (ℕ.suc n) e₁) (x ∷ xs)) (isEqualToNormalform (ℕ.suc n) e (x ∷ xs)) ⟩ ⟦ e ⟧ (x ∷ xs) · eval (ℕ.suc n) (normalize (ℕ.suc n) e₁) (x ∷ xs) ≡⟨ cong (λ u → ⟦ e ⟧ (x ∷ xs) · u) (isEqualToNormalform (ℕ.suc n) e₁ (x ∷ xs)) ⟩ ⟦ e ⟧ (x ∷ xs) · ⟦ e₁ ⟧ (x ∷ xs) ∎ solve : {n : ℕ} (e₁ e₂ : ℤExpr n) (xs : Vec (fst R) n) (p : eval n (normalize n e₁) xs ≡ eval n (normalize n e₂) xs) → ⟦ e₁ ⟧ xs ≡ ⟦ e₂ ⟧ xs solve e₁ e₂ xs p = ⟦ e₁ ⟧ xs ≡⟨ sym (isEqualToNormalform _ e₁ xs) ⟩ eval _ (normalize _ e₁) xs ≡⟨ p ⟩ eval _ (normalize _ e₂) xs ≡⟨ isEqualToNormalform _ e₂ xs ⟩ ⟦ e₂ ⟧ xs ∎ ℤExpr : (R : CommRing ℓ) (n : ℕ) → _ ℤExpr R n = EqualityToNormalform.ℤExpr R n solve : (R : CommRing ℓ) {n : ℕ} (e₁ e₂ : ℤExpr R n) (xs : Vec (fst R) n) (p : eval n (EqualityToNormalform.normalize R n e₁) xs ≡ eval n (EqualityToNormalform.normalize R n e₂) xs) → _ solve R = EqualityToNormalform.solve R module VarNames3 (R : CommRing ℓ) where X1 : ℤExpr R 3 X1 = ∣ Fin.zero X2 : ℤExpr R 3 X2 = ∣ (suc Fin.zero) X3 : ℤExpr R 3 X3 = ∣ (suc (suc Fin.zero)) module VarNames4 (R : CommRing ℓ) where X1 : ℤExpr R 4 X1 = ∣ Fin.zero X2 : ℤExpr R 4 X2 = ∣ (suc Fin.zero) X3 : ℤExpr R 4 X3 = ∣ (suc (suc Fin.zero)) X4 : ℤExpr R 4 X4 = ∣ (suc (suc (suc Fin.zero))) module VarNames5 (R : CommRing ℓ) where X1 : ℤExpr R 5 X1 = ∣ Fin.zero X2 : ℤExpr R 5 X2 = ∣ (suc Fin.zero) X3 : ℤExpr R 5 X3 = ∣ (suc (suc Fin.zero)) X4 : ℤExpr R 5 X4 = ∣ (suc (suc (suc Fin.zero))) X5 : ℤExpr R 5 X5 = ∣ (suc (suc (suc (suc Fin.zero)))) module VarNames6 (R : CommRing ℓ) where X1 : ℤExpr R 6 X1 = ∣ Fin.zero X2 : ℤExpr R 6 X2 = ∣ (suc Fin.zero) X3 : ℤExpr R 6 X3 = ∣ (suc (suc Fin.zero)) X4 : ℤExpr R 6 X4 = ∣ (suc (suc (suc Fin.zero))) X5 : ℤExpr R 6 X5 = ∣ (suc (suc (suc (suc Fin.zero)))) X6 : ℤExpr R 6 X6 = ∣ (suc (suc (suc (suc (suc Fin.zero)))))