module Cubical.Tactics.NatSolver.Solver where
open import Cubical.Foundations.Prelude
open import Cubical.Data.FinData
open import Cubical.Data.Nat
open import Cubical.Data.Nat.Order using (zero-≤)
open import Cubical.Data.Vec.Base
open import Cubical.Tactics.NatSolver.NatExpression
open import Cubical.Tactics.NatSolver.HornerForms
open import Cubical.Tactics.NatSolver.EvalHom
private
variable
ℓ : Level
module EqualityToNormalform where
open Eval
open IteratedHornerOperations
open HomomorphismProperties
normalize : {n : ℕ} → Expr n → IteratedHornerForms n
normalize {n = n} (K r) = Constant n r
normalize {n = n} (∣ k) = Variable n k
normalize (x +' y) =
(normalize x) +ₕ (normalize y)
normalize (x ·' y) =
(normalize x) ·ₕ (normalize y)
isEqualToNormalform :
{n : ℕ}
(e : Expr n) (xs : Vec ℕ n)
→ eval (normalize e) xs ≡ ⟦ e ⟧ xs
isEqualToNormalform (K r) [] = refl
isEqualToNormalform {n = ℕ.suc n} (K r) (x ∷ xs) =
eval (Constant (ℕ.suc n) r) (x ∷ xs) ≡⟨ refl ⟩
eval (0ₕ ·X+ Constant n r) (x ∷ xs) ≡⟨ refl ⟩
eval 0ₕ (x ∷ xs) · x + eval (Constant n r) xs
≡⟨ cong (λ u → u · x + eval (Constant n r) xs) (eval0H (x ∷ xs)) ⟩
0 · x + eval (Constant n r) xs
≡⟨ refl ⟩
eval (Constant n r) xs
≡⟨ isEqualToNormalform (K r) xs ⟩
r ∎
isEqualToNormalform (∣ zero) (x ∷ xs) =
eval (1ₕ ·X+ 0ₕ) (x ∷ xs) ≡⟨ refl ⟩
eval 1ₕ (x ∷ xs) · x + eval 0ₕ xs ≡⟨ cong (λ u → u · x + eval 0ₕ xs)
(eval1ₕ (x ∷ xs)) ⟩
1 · x + eval 0ₕ xs ≡⟨ cong (λ u → 1 · x + u ) (eval0H xs) ⟩
1 · x + 0 ≡⟨ +-zero _ ⟩
1 · x ≡⟨ ·-identityˡ _ ⟩
x ∎
isEqualToNormalform {n = ℕ.suc n} (∣ (suc k)) (x ∷ xs) =
eval (0ₕ ·X+ Variable n k) (x ∷ xs) ≡⟨ refl ⟩
eval 0ₕ (x ∷ xs) · x + eval (Variable n k) xs
≡⟨ cong (λ u → u · x + eval (Variable n k) xs) (eval0H (x ∷ xs)) ⟩
0 · x + eval (Variable n k) xs
≡⟨ refl ⟩
eval (Variable n k) xs
≡⟨ isEqualToNormalform (∣ k) xs ⟩
⟦ ∣ (suc k) ⟧ (x ∷ xs) ∎
isEqualToNormalform (e +' e₁) [] =
eval (normalize e +ₕ normalize e₁) []
≡⟨ +Homeval (normalize e) _ [] ⟩
eval (normalize e) []
+ eval (normalize e₁) []
≡⟨ cong (λ u → u + eval (normalize e₁) [])
(isEqualToNormalform e []) ⟩
⟦ e ⟧ []
+ eval (normalize e₁) []
≡⟨ cong (λ u → ⟦ e ⟧ [] + u) (isEqualToNormalform e₁ []) ⟩
⟦ e ⟧ [] + ⟦ e₁ ⟧ [] ∎
isEqualToNormalform (e +' e₁) (x ∷ xs) =
eval (normalize e
+ₕ normalize e₁) (x ∷ xs)
≡⟨ +Homeval (normalize e) _ (x ∷ xs) ⟩
eval (normalize e) (x ∷ xs)
+ eval (normalize e₁) (x ∷ xs)
≡⟨ cong (λ u → u + eval (normalize e₁) (x ∷ xs))
(isEqualToNormalform e (x ∷ xs)) ⟩
⟦ e ⟧ (x ∷ xs)
+ eval (normalize e₁) (x ∷ xs)
≡⟨ cong (λ u → ⟦ e ⟧ (x ∷ xs) + u)
(isEqualToNormalform e₁ (x ∷ xs)) ⟩
⟦ e ⟧ (x ∷ xs) + ⟦ e₁ ⟧ (x ∷ xs) ∎
isEqualToNormalform (e ·' e₁) [] =
eval (normalize e ·ₕ normalize e₁) []
≡⟨ ·Homeval (normalize e) _ [] ⟩
eval (normalize e) []
· eval (normalize e₁) []
≡⟨ cong (λ u → u · eval (normalize e₁) [])
(isEqualToNormalform e []) ⟩
⟦ e ⟧ []
· eval (normalize e₁) []
≡⟨ cong (λ u → ⟦ e ⟧ [] · u) (isEqualToNormalform e₁ []) ⟩
⟦ e ⟧ [] · ⟦ e₁ ⟧ [] ∎
isEqualToNormalform (e ·' e₁) (x ∷ xs) =
eval (normalize e ·ₕ normalize e₁) (x ∷ xs)
≡⟨ ·Homeval (normalize e) _ (x ∷ xs) ⟩
eval (normalize e) (x ∷ xs)
· eval (normalize e₁) (x ∷ xs)
≡⟨ cong (λ u → u · eval (normalize e₁) (x ∷ xs))
(isEqualToNormalform e (x ∷ xs)) ⟩
⟦ e ⟧ (x ∷ xs)
· eval (normalize e₁) (x ∷ xs)
≡⟨ cong (λ u → ⟦ e ⟧ (x ∷ xs) · u)
(isEqualToNormalform e₁ (x ∷ xs)) ⟩
⟦ e ⟧ (x ∷ xs) · ⟦ e₁ ⟧ (x ∷ xs) ∎
solve :
{n : ℕ} (e₁ e₂ : Expr n) (xs : Vec ℕ n)
(p : eval (normalize e₁) xs ≡ eval (normalize 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 ∎