module Cubical.Tactics.CommRingSolver.Examples where
open import Cubical.Foundations.Prelude
open import Cubical.Foundations.Structure
open import Cubical.Data.Int.Base hiding (_+_ ; _·_ ; _-_)
open import Cubical.Data.List
open import Cubical.Data.Nat using (ℕ; suc; zero)
open import Cubical.Algebra.CommRing
open import Cubical.Algebra.CommRing.Instances.Int
open import Cubical.Algebra.CommAlgebra
open import Cubical.Tactics.CommRingSolver
open import Cubical.Tactics.CommRingSolver.RawAlgebra using (scalar)
private
  variable
    ℓ ℓ' : Level
module TestErrors (R : CommRing ℓ) where
  open CommRingStr (snd R)
  
  
module TestWithℤ where
  open CommRingStr (ℤCommRing .snd)
  ex0 : (a b : fst ℤCommRing) → a + b ≡ b + a
  ex0 a b = solve! ℤCommRing
module Test (R : CommRing ℓ) (x y z : fst R) where
  open CommRingStr (snd R)
  _ : 0r ≡ 0r
  _ = solve! R
  _ :   1r · (1r + 0r)
      ≡ (1r · 0r) + 1r
  _ = solve! R
  _ :   1r · 0r + (1r - 1r)
      ≡ 0r - 0r
  _ = solve! R
  ex1 : x ≡ x
  ex1 = solve! R
  ex2 : (0r - 1r) · x ≡ 0r - x
  ex2 = solve! R
  ex3 : x + y ≡ y + x
  ex3 = solve! R
  ex4 : y ≡ (y - x) + x
  ex4 = solve! R
  ex5 : x ≡ (x - y) + y
  ex5 = solve! R
  ex6 : (x + y) · (x - y) ≡ x · x - y · y
  ex6 = solve! R
  
  ex7 : (x + y) · (x + y) · (x + y) · (x + y)
                ≡ x · x · x · x + (scalar R 4) · x · x · x · y + (scalar R 6) · x · x · y · y
                  + (scalar R 4) · x · y · y · y + y · y · y · y
  ex7 = solve! R
  
  ex8 : x · 0r ≡ 0r
  ex8 = solve! R
  ex9 : x · (y - z) ≡ x · y - x · z
  ex9 = solve! R
  
  pow : ℕ → fst R → fst R
  pow (suc n) x = x · (pow n x)
  pow (zero) x = 1r
  module _ (f : fst R → fst R) (n : ℕ) where
    ex10 : (x : (fst R)) → (pow n x) + 0r ≡ (pow n x)
    ex10 x = solve! R
    ex11 : (x : (fst R)) → (f x) + 0r ≡ (f x)
    ex11 x = solve! R
module _ (R : CommRing ℓ) (A : CommAlgebra R ℓ') where
  open CommRingStr ⦃...⦄
  private
    instance
      _ : CommRingStr ⟨ A ⟩ₐ
      _ = (A .fst .snd)
  
  ex12 : (x y : ⟨ A ⟩ₐ) → x + y ≡ y + x
  ex12 x y = solve! (CommAlgebra→CommRing A)
module TestInPlaceSolving (R : CommRing ℓ) where
   open CommRingStr (snd R)
   testWithOneVariabl : (x : fst R) → x + 0r ≡ 0r + x
   testWithOneVariabl x = solve! R
   testWithTwoVariables :  (x y : fst R) → x + y ≡ y + x
   testWithTwoVariables x y =
     x + y                      ≡⟨ solve! R ⟩
     y + x ∎
   testEquationalReasoning : (x : fst R) → x + 0r ≡ 0r + x
   testEquationalReasoning x =
     x + 0r                       ≡⟨ solve! R ⟩
     0r + x ∎
   testEquationalReasoning' : (x : fst R) (p : 0r + x ≡ 1r) → x + 0r ≡ 1r
   testEquationalReasoning' x p =
     x + 0r              ≡⟨ solve! R ⟩
     0r + x              ≡⟨ p ⟩
     1r ∎