module Hermod.ReCon.Integer.Polynomial.Term (
    VariableIdentifier
  , IntValue
  , IntTerm(..)
  , mul
  ) where

import           Hermod.ReCon.Common.Types (IntValue, VariableIdentifier)

-- | i, j ::= i + i | <int> · x | <int>, where <int> is an arbitrary integer
data IntTerm = IntVar IntValue VariableIdentifier | IntConst IntValue | IntSum IntTerm IntTerm deriving (Int -> IntTerm -> ShowS
[IntTerm] -> ShowS
IntTerm -> String
(Int -> IntTerm -> ShowS)
-> (IntTerm -> String) -> ([IntTerm] -> ShowS) -> Show IntTerm
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> IntTerm -> ShowS
showsPrec :: Int -> IntTerm -> ShowS
$cshow :: IntTerm -> String
show :: IntTerm -> String
$cshowList :: [IntTerm] -> ShowS
showList :: [IntTerm] -> ShowS
Show, IntTerm -> IntTerm -> Bool
(IntTerm -> IntTerm -> Bool)
-> (IntTerm -> IntTerm -> Bool) -> Eq IntTerm
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IntTerm -> IntTerm -> Bool
== :: IntTerm -> IntTerm -> Bool
$c/= :: IntTerm -> IntTerm -> Bool
/= :: IntTerm -> IntTerm -> Bool
Eq, Eq IntTerm
Eq IntTerm =>
(IntTerm -> IntTerm -> Ordering)
-> (IntTerm -> IntTerm -> Bool)
-> (IntTerm -> IntTerm -> Bool)
-> (IntTerm -> IntTerm -> Bool)
-> (IntTerm -> IntTerm -> Bool)
-> (IntTerm -> IntTerm -> IntTerm)
-> (IntTerm -> IntTerm -> IntTerm)
-> Ord IntTerm
IntTerm -> IntTerm -> Bool
IntTerm -> IntTerm -> Ordering
IntTerm -> IntTerm -> IntTerm
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: IntTerm -> IntTerm -> Ordering
compare :: IntTerm -> IntTerm -> Ordering
$c< :: IntTerm -> IntTerm -> Bool
< :: IntTerm -> IntTerm -> Bool
$c<= :: IntTerm -> IntTerm -> Bool
<= :: IntTerm -> IntTerm -> Bool
$c> :: IntTerm -> IntTerm -> Bool
> :: IntTerm -> IntTerm -> Bool
$c>= :: IntTerm -> IntTerm -> Bool
>= :: IntTerm -> IntTerm -> Bool
$cmax :: IntTerm -> IntTerm -> IntTerm
max :: IntTerm -> IntTerm -> IntTerm
$cmin :: IntTerm -> IntTerm -> IntTerm
min :: IntTerm -> IntTerm -> IntTerm
Ord)

-- k · i
-- k · (k' · x) = (k * k') · x
-- k · c = k * c
-- k · (i + j) = k · i + k · j
mul :: IntValue -> IntTerm -> IntTerm
mul :: IntValue -> IntTerm -> IntTerm
mul IntValue
k (IntVar IntValue
k' VariableIdentifier
x) = IntValue -> VariableIdentifier -> IntTerm
IntVar (IntValue
k IntValue -> IntValue -> IntValue
forall a. Num a => a -> a -> a
* IntValue
k') VariableIdentifier
x
mul IntValue
k (IntConst IntValue
k') = IntValue -> IntTerm
IntConst (IntValue
k IntValue -> IntValue -> IntValue
forall a. Num a => a -> a -> a
* IntValue
k')
mul IntValue
k (IntSum IntTerm
a IntTerm
b)  = IntTerm -> IntTerm -> IntTerm
IntSum (IntValue -> IntTerm -> IntTerm
mul IntValue
k IntTerm
a) (IntValue -> IntTerm -> IntTerm
mul IntValue
k IntTerm
b)