module ZkFold.Base.Algebra.Polynomials.Multivariate.Substitution where

import           Data.Map                                              (Map, lookup)
import           Prelude                                               hiding (Num (..), length, lookup, product,
                                                                        replicate, sum, (!!), (^))

import           ZkFold.Base.Algebra.Basic.Field                       (Zp, fromZp)
import           ZkFold.Base.Algebra.Polynomials.Multivariate.Monomial
import           ZkFold.Base.Data.Vector                               (Vector, fromVector)
import           ZkFold.Prelude                                        ((!!))

-- | Data structure `s` can be viewed as a substitution from `i` to `b`
class Substitution s i b where
    subs :: s -> (i -> b)

instance Variable i => Substitution (Map i b) i (Maybe b) where
    subs :: Map i b -> i -> Maybe b
subs = (i -> Map i b -> Maybe b) -> Map i b -> i -> Maybe b
forall a b c. (a -> b -> c) -> b -> a -> c
flip i -> Map i b -> Maybe b
forall k a. Ord k => k -> Map k a -> Maybe a
lookup

instance Substitution (Vector n b) (Zp n) b where
    subs :: Vector n b -> Zp n -> b
subs Vector n b
v Zp n
i = Vector n b -> [b]
forall (size :: Natural) a. Vector size a -> [a]
fromVector Vector n b
v [b] -> Natural -> b
forall a. [a] -> Natural -> a
!! Zp n -> Natural
forall (p :: Natural). Zp p -> Natural
fromZp Zp n
i