\import Algebra.Group
\import Algebra.Monoid
\import Algebra.Ordered
\import Algebra.StrictlyOrdered
\import Algebra.Pointed
\import Algebra.Ring
\import Algebra.Solver
\import Arith.Int
\import Data.List
{-
\func \infixl 7 *n (n : Nat) (a : E) : E \elim n
| 0 => zro
| suc n => n *n a + a
\func \infixl 7 *i (n : Int) (a : E) : E \elim n
| pos n => n *n a
| neg (suc n) => suc n *n negative a
-}
-- TODO[server2]: Finish this
\func LinearSolverModel (A : LinearlyOrderedAbGroup) : SolverModel A \cowith
| Term => Term Int
| NF => NF Int
| normalize => normalize
| interpret => {?}
| interpretNF => {?}
| interpretNF-consistent => {?}
\where {
\data Term (C : \Set) (n : Nat)
| coef C (Term C n)
| var (Fin n)
| :zro
| :negative (Term C n)
| \infixl 6 :+ (t s : Term C n)
\func NF (C : \Set) (n : Nat) => List (\Sigma (Fin n) C)
\func mulNF {C : Monoid} {n : Nat} (c : C) (l : NF C n) : NF C n
=> map (\lam s => (s.1, c * s.2)) l
\func normalize {C : Ring} {n : Nat} (t : Term C n) : NF C n \elim t
| coef c t => mulNF c (normalize t)
| var v => (v,1) :: nil
| :zro => nil
| :negative t => mulNF -1 (normalize t)
| t :+ s => normalize t ++ normalize s
{-
\func interpret (env : Array A) (t : Term Int env.len) : A \elim t
| coef c t => c A.*i interpret env t
| var j => env j
| :zro => 0
| :negative t => negative (interpret env t)
| :+ t s => interpret env t + interpret env s
\func mulCoef (c : C) (l : List (Fin env.len)) : R \elim l
| nil => alg c
| l => \case decideEq c 1 \with {
| yes _ => MonoidSolverModel.interpretNF env l
| no _ => alg c * MonoidSolverModel.interpretNF env l
}
\func interpretNF (env : Array A) (l : NF Int env.len) : A \elim l
| nil => 0
| x :: l => {?}
-}
}