{-# OPTIONS --without-K --safe #-} module Polynomial.Simple.Solver where open import Polynomial.Expr public open import Polynomial.Simple.AlmostCommutativeRing public hiding (-raw-almostCommutative⟶) open import Data.Vec hiding (_⊛_) open import Algebra.Solver.Ring.AlmostCommutativeRing using (-raw-almostCommutative⟶) open import Polynomial.Parameters open import Function open import Data.Maybe open import Data.Vec.N-ary open import Data.Bool using (Bool; true; false; T; if_then_else_) open import Data.Empty using (⊥-elim) module Ops {ℓ₁ ℓ₂} (ring : AlmostCommutativeRing ℓ₁ ℓ₂) where open AlmostCommutativeRing ring zero-homo : ∀ x → T (is-just (0≟ x)) → 0# ≈ x zero-homo x _ with 0≟ x zero-homo x _ | just p = p zero-homo x () | nothing homo : Homomorphism ℓ₁ ℓ₁ ℓ₂ homo = record { coeffs = record { coeffs = AlmostCommutativeRing.rawRing ring ; Zero-C = λ x → is-just (0≟ x) } ; ring = record { isAlmostCommutativeRing = record { isCommutativeSemiring = isCommutativeSemiring ; -‿cong = -‿cong ; -‿*-distribˡ = -‿*-distribˡ ; -‿+-comm = -‿+-comm } } ; morphism = -raw-almostCommutative⟶ _ ; Zero-C⟶Zero-R = zero-homo } ⟦_⟧ : ∀ {n} → Expr Carrier n → Vec Carrier n → Carrier ⟦ Κ x ⟧ ρ = x ⟦ Ι x ⟧ ρ = lookup ρ x ⟦ x ⊕ y ⟧ ρ = ⟦ x ⟧ ρ + ⟦ y ⟧ ρ ⟦ x ⊗ y ⟧ ρ = ⟦ x ⟧ ρ * ⟦ y ⟧ ρ ⟦ ⊝ x ⟧ ρ = - ⟦ x ⟧ ρ ⟦ x ⊛ i ⟧ ρ = ⟦ x ⟧ ρ ^ i open import Polynomial.NormalForm.Definition (Homomorphism.coeffs homo) open import Polynomial.NormalForm.Operations (Homomorphism.coeffs homo) norm : ∀ {n} → Expr Carrier n → Poly n norm = go where go : ∀ {n} → Expr Carrier n → Poly n go (Κ x) = κ x go (Ι x) = ι x go (x ⊕ y) = go x ⊞ go y go (x ⊗ y) = go x ⊠ go y go (⊝ x) = ⊟ go x go (x ⊛ i) = go x ⊡ i ⟦_⇓⟧ : ∀ {n} → Expr Carrier n → Vec Carrier n → Carrier ⟦ expr ⇓⟧ = ⟦ norm expr ⟧ₚ where open import Polynomial.NormalForm.Semantics homo renaming (⟦_⟧ to ⟦_⟧ₚ) correct : ∀ {n} (expr : Expr Carrier n) ρ → ⟦ expr ⇓⟧ ρ ≈ ⟦ expr ⟧ ρ correct {n = n} = go where open import Polynomial.Homomorphism homo go : ∀ (expr : Expr Carrier n) ρ → ⟦ expr ⇓⟧ ρ ≈ ⟦ expr ⟧ ρ go (Κ x) ρ = κ-hom x ρ go (Ι x) ρ = ι-hom x ρ go (x ⊕ y) ρ = ⊞-hom (norm x) (norm y) ρ ⟨ trans ⟩ (go x ρ ⟨ +-cong ⟩ go y ρ) go (x ⊗ y) ρ = ⊠-hom (norm x) (norm y) ρ ⟨ trans ⟩ (go x ρ ⟨ *-cong ⟩ go y ρ) go (⊝ x) ρ = ⊟-hom (norm x) ρ ⟨ trans ⟩ -‿cong (go x ρ) go (x ⊛ i) ρ = ⊡-hom (norm x) i ρ ⟨ trans ⟩ pow-cong i (go x ρ) open import Relation.Binary.Reflection setoid Ι ⟦_⟧ ⟦_⇓⟧ correct public open import Data.Nat using (ℕ) open import Data.Product solve : ∀ {ℓ₁ ℓ₂} → (ring : AlmostCommutativeRing ℓ₁ ℓ₂) → (n : ℕ) → (f : N-ary n (Expr (AlmostCommutativeRing.Carrier ring) n) (Expr (AlmostCommutativeRing.Carrier ring) n × Expr (AlmostCommutativeRing.Carrier ring) n)) → Eqʰ n (AlmostCommutativeRing._≈_ ring) (curryⁿ (Ops.⟦_⇓⟧ ring (proj₁ (Ops.close ring n f)))) (curryⁿ (Ops.⟦_⇓⟧ ring (proj₂ (Ops.close ring n f)))) → Eq n (AlmostCommutativeRing._≈_ ring) (curryⁿ (Ops.⟦_⟧ ring (proj₁ (Ops.close ring n f)))) (curryⁿ (Ops.⟦_⟧ ring (proj₂ (Ops.close ring n f)))) solve ring = solve′ where open Ops ring renaming (solve to solve′) {-# INLINE solve #-} _⊜_ : ∀ {ℓ₁ ℓ₂} → (ring : AlmostCommutativeRing ℓ₁ ℓ₂) → (n : ℕ) → Expr (AlmostCommutativeRing.Carrier ring) n → Expr (AlmostCommutativeRing.Carrier ring) n → Expr (AlmostCommutativeRing.Carrier ring) n × Expr (AlmostCommutativeRing.Carrier ring) n _⊜_ _ _ = _,_ {-# INLINE _⊜_ #-}