{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}

{-# LANGUAGE ViewPatterns #-}
module Algebra.Ring.Polynomial.Labeled
  ( IsUniqueList,
    LabPolynomial (LabelPolynomial, unLabelPolynomial),
    LabPolynomial',
    LabUnipol,
    Wraps,
    canonicalMap,
    canonicalMap',
    renameVars,
    renameVars',
    IsSubsetOf,
  )
where

import Algebra.Internal
import Algebra.Ring.Polynomial
import Algebra.Ring.Polynomial.Univariate
import Algebra.Scalar
import AlgebraicPrelude
import Control.DeepSeq (NFData)
import Control.Lens (each, (%~), (&))
import qualified Data.Coerce as DC
import qualified Data.List as L
#if MIN_VERSION_singletons(3,0,0)
import Data.Singletons (type (@@))
import Data.Eq.Singletons
import Data.Function.Singletons (FlipSym0)
import Data.List.Singletons hiding (Group)
import Data.Maybe.Singletons
#else
import Data.Singletons.Prelude hiding (SNum(..))
import Data.Singletons.Prelude.List hiding (Group)
#endif
import qualified Data.Sized as S
import GHC.Exts (Constraint)
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 802
import qualified Data.Text as T
#endif
import GHC.TypeLits (symbolVal, TypeError, ErrorMessage(..), Symbol, KnownSymbol)
import qualified Numeric.Algebra as NA
import qualified Prelude as P

type family UniqueList' (x :: Symbol) (xs :: [Symbol]) :: Constraint where
  UniqueList' x '[] = ()
  UniqueList' x (x ': xs) = TypeError ( 'Text "The variable " ':<>: 'ShowType x ':<>: 'Text " occurs more than once!")
  UniqueList' x (y ': xs) = UniqueList' x xs

type family UniqueList (xs :: [Symbol]) :: Constraint where
  UniqueList '[] = ()
  UniqueList (x ': xs) = (UniqueList' x xs, UniqueList xs)

class (UniqueList xs) => IsUniqueList (xs :: [Symbol])

instance (UniqueList xs) => IsUniqueList (xs :: [Symbol])

-- | This instance allows something like @#x :: LabPolynomial (OrderedPolynomial Integer Grevlex 3) '["x", "y", "z"]@.
instance
  ( KnownSymbol symb
  , SingI vars
  , UniqueList vars
  , IsPolynomial poly
  , Wraps vars poly
  , Elem symb vars ~ 'True
  ) =>
  IsLabel symb (LabPolynomial poly vars) where

  fromLabel :: LabPolynomial poly vars
fromLabel 
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 802
    = 
    let vs :: [String]
vs = (Text -> String) -> [Text] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Text -> String
T.unpack ([Text] -> [String]) -> [Text] -> [String]
forall a b. (a -> b) -> a -> b
$ Sing vars -> Demote [Symbol]
forall k (a :: k). SingKind k => Sing a -> Demote k
fromSing (Sing vars
forall k (a :: k). SingI a => Sing a
sing :: Sing vars)
        v :: String
v  = Proxy symb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy symb
forall k (t :: k). Proxy t
Proxy :: Proxy symb)
    in LabPolynomial poly vars
-> (Int -> LabPolynomial poly vars)
-> Maybe Int
-> LabPolynomial poly vars
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> LabPolynomial poly vars
forall a. HasCallStack => String -> a
error String
"impossible!") (Ordinal (Length vars) -> LabPolynomial poly vars
forall poly. IsPolynomial poly => Ordinal (Arity poly) -> poly
var (Ordinal (Length vars) -> LabPolynomial poly vars)
-> (Int -> Ordinal (Length vars)) -> Int -> LabPolynomial poly vars
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Ordinal (Length vars)
forall a. Enum a => Int -> a
toEnum) (Maybe Int -> LabPolynomial poly vars)
-> Maybe Int -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ String -> [String] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
L.elemIndex String
v [String]
vs
#else
    k =
    let vs = fromSing (sing :: Sing vars)
        v    = symbolVal' k
    in maybe (error "impossible!") (var . toEnum) $ L.elemIndex v vs
#endif

newtype LabPolynomial poly (vars :: [Symbol]) = LabelPolynomial_ {LabPolynomial poly vars -> poly
_unLabelPolynomial :: poly}
  deriving (LabPolynomial poly vars -> ()
(LabPolynomial poly vars -> ()) -> NFData (LabPolynomial poly vars)
forall a. (a -> ()) -> NFData a
forall poly (vars :: [Symbol]).
NFData poly =>
LabPolynomial poly vars -> ()
rnf :: LabPolynomial poly vars -> ()
$crnf :: forall poly (vars :: [Symbol]).
NFData poly =>
LabPolynomial poly vars -> ()
NFData)

type role LabPolynomial representational nominal

{-# COMPLETE LabelPolynomial #-}

pattern LabelPolynomial ::
  Wraps vars poly =>
  Wraps vars poly =>
  poly ->
  LabPolynomial poly vars
pattern $bLabelPolynomial :: poly -> LabPolynomial poly vars
$mLabelPolynomial :: forall r (vars :: [Symbol]) poly.
Wraps vars poly =>
LabPolynomial poly vars
-> (Wraps vars poly => poly -> r) -> (Void# -> r) -> r
LabelPolynomial {LabPolynomial poly vars -> Wraps vars poly => poly
unLabelPolynomial} =
  LabelPolynomial_ unLabelPolynomial

{- | Convenient type-synonym for @'LabPlynomial'@ wrapping @'OrderedPolynomial'@
   and @'Unipol'@.
-}
type family LabPolynomial' r ord vars where
  LabPolynomial' r ord '[x] = LabPolynomial (Unipol r) '[x]
  LabPolynomial' r ord vars = LabPolynomial (OrderedPolynomial r ord (Length vars)) vars

-- | Convenient type-synonym for @'LabPlynomial'@ wrapping univariate polynomial @'Unipol'@.
type LabUnipol r sym = LabPolynomial (Unipol r) '[sym]

type Wraps vars poly = (IsUniqueList vars, Arity poly ~ Length vars)

instance
  (PrettyCoeff (Coefficient poly), IsOrderedPolynomial poly, Wraps vars poly, SingI vars) =>
  Show (LabPolynomial poly vars)
  where
  showsPrec :: Int -> LabPolynomial poly vars -> ShowS
showsPrec Int
d (LabelPolynomial_ poly
f) =
    let svs :: Sing vars
svs = Sing vars
forall k (a :: k). SingI a => Sing a
sing :: Sing vars
        vs :: [String]
vs =
#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 802
          (Text -> String) -> [Text] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map Text -> String
T.unpack ([Text] -> [String]) -> [Text] -> [String]
forall a b. (a -> b) -> a -> b
$
#endif

          Sing vars -> Demote [Symbol]
forall k (a :: k). SingKind k => Sing a -> Demote k
fromSing Sing vars
svs
        vsVec :: Sized Vector (Length vars) String
vsVec = SNat (Length vars)
-> (Ordinal (Length vars) -> String)
-> Sized Vector (Length vars) String
forall (f :: * -> *) (n :: Nat) a.
(CFreeMonoid f, Dom f a) =>
SNat n -> (Ordinal n -> a) -> Sized f n a
generate SNat (Length vars)
forall (n :: Nat). KnownNat n => SNat n
sNat ((Ordinal (Length vars) -> String)
 -> Sized Vector (Length vars) String)
-> (Ordinal (Length vars) -> String)
-> Sized Vector (Length vars) String
forall a b. (a -> b) -> a -> b
$ \Ordinal (Length vars)
i -> [String]
vs [String] -> Int -> String
forall a. [a] -> Int -> a
!! Ordinal (Length vars) -> Int
forall a. Enum a => a -> Int
fromEnum Ordinal (Length vars)
i
     in Sized (Arity poly) String -> Int -> poly -> ShowS
forall poly.
(IsOrderedPolynomial poly, PrettyCoeff (Coefficient poly)) =>
Sized (Arity poly) String -> Int -> poly -> ShowS
showsPolynomialWith Sized (Arity poly) String
Sized Vector (Length vars) String
vsVec Int
d poly
f

instance
  (Wraps vars poly, P.Num poly) =>
  P.Num (LabPolynomial poly vars)
  where
  fromInteger :: Integer -> LabPolynomial poly vars
fromInteger = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> (Integer -> poly) -> Integer -> LabPolynomial poly vars
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> poly
forall a. Num a => Integer -> a
P.fromInteger
  LabelPolynomial_ poly
f + :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
+ LabelPolynomial_ poly
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> poly -> poly
forall a. Num a => a -> a -> a
P.+ poly
g
  LabelPolynomial_ poly
f * :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
* LabelPolynomial_ poly
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> poly -> poly
forall a. Num a => a -> a -> a
P.* poly
g
  abs :: LabPolynomial poly vars -> LabPolynomial poly vars
abs = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
forall b c a. (b -> c) -> (a -> b) -> a -> c
. poly -> poly
forall a. Num a => a -> a
P.abs (poly -> poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  LabelPolynomial_ poly
f - :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
- LabelPolynomial_ poly
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> poly -> poly
forall a. Num a => a -> a -> a
P.- poly
g
  negate :: LabPolynomial poly vars -> LabPolynomial poly vars
negate = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
forall b c a. (b -> c) -> (a -> b) -> a -> c
. poly -> poly
forall a. Num a => a -> a
P.negate (poly -> poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  signum :: LabPolynomial poly vars -> LabPolynomial poly vars
signum = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
forall b c a. (b -> c) -> (a -> b) -> a -> c
. poly -> poly
forall a. Num a => a -> a
P.signum (poly -> poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial

instance (Wraps vars poly, Additive poly) => Additive (LabPolynomial poly vars) where
  LabelPolynomial_ poly
f + :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
+ LabelPolynomial_ poly
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> poly -> poly
forall r. Additive r => r -> r -> r
+ poly
g
  {-# INLINE (+) #-}

instance (Wraps vars poly, Multiplicative poly) => Multiplicative (LabPolynomial poly vars) where
  LabelPolynomial_ poly
f * :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
* LabelPolynomial_ poly
g =
    poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> poly -> poly
forall r. Multiplicative r => r -> r -> r
* poly
g
  {-# INLINE (*) #-}

instance (Wraps vars poly, Abelian poly) => Abelian (LabPolynomial poly vars)

instance (Wraps vars poly, Commutative poly) => Commutative (LabPolynomial poly vars)

instance (Wraps vars poly, Unital poly) => Unital (LabPolynomial poly vars) where
  one :: LabPolynomial poly vars
one = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ poly
forall r. Unital r => r
one
  {-# INLINE one #-}

instance (Wraps vars poly, Group poly) => Group (LabPolynomial poly vars) where
  negate :: LabPolynomial poly vars -> LabPolynomial poly vars
negate = (poly -> poly)
-> LabPolynomial poly vars -> LabPolynomial poly vars
DC.coerce @(poly -> poly) poly -> poly
forall r. Group r => r -> r
negate
  {-# INLINE negate #-}

instance (Wraps vars poly, RightModule Natural poly) => RightModule Natural (LabPolynomial poly vars) where
  LabelPolynomial_ poly
f *. :: LabPolynomial poly vars -> Natural -> LabPolynomial poly vars
*. Natural
a = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> Natural -> poly
forall r m. RightModule r m => m -> r -> m
*. Natural
a
  {-# INLINE (*.) #-}

instance (Wraps vars poly, LeftModule Natural poly) => LeftModule Natural (LabPolynomial poly vars) where
  Natural
a .* :: Natural -> LabPolynomial poly vars -> LabPolynomial poly vars
.* LabelPolynomial_ poly
f = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ Natural
a Natural -> poly -> poly
forall r m. LeftModule r m => r -> m -> m
.* poly
f
  {-# INLINE (.*) #-}

instance (Wraps vars poly, RightModule Integer poly) => RightModule Integer (LabPolynomial poly vars) where
  LabelPolynomial_ poly
f *. :: LabPolynomial poly vars -> Integer -> LabPolynomial poly vars
*. Integer
a = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> Integer -> poly
forall r m. RightModule r m => m -> r -> m
*. Integer
a
  {-# INLINE (*.) #-}

instance (Wraps vars poly, LeftModule Integer poly) => LeftModule Integer (LabPolynomial poly vars) where
  Integer
a .* :: Integer -> LabPolynomial poly vars -> LabPolynomial poly vars
.* LabelPolynomial_ poly
f = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ Integer
a Integer -> poly -> poly
forall r m. LeftModule r m => r -> m -> m
.* poly
f
  {-# INLINE (.*) #-}

instance (Wraps vars poly, Monoidal poly) => Monoidal (LabPolynomial poly vars) where
  zero :: LabPolynomial poly vars
zero = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ poly
forall m. Monoidal m => m
zero
  {-# INLINE zero #-}

instance (Wraps vars poly, Semiring poly) => Semiring (LabPolynomial poly vars)

instance (Wraps vars poly, Rig poly) => Rig (LabPolynomial poly vars)

instance (Wraps vars poly, Ring poly) => Ring (LabPolynomial poly vars) where
  fromInteger :: Integer -> LabPolynomial poly vars
fromInteger Integer
n = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Integer -> poly
forall r. Ring r => Integer -> r
NA.fromInteger Integer
n :: poly)
  {-# INLINE fromInteger #-}

instance (Wraps vars poly, LeftModule (Scalar r) poly) => LeftModule (Scalar r) (LabPolynomial poly vars) where
  Scalar r
a .* :: Scalar r -> LabPolynomial poly vars -> LabPolynomial poly vars
.* LabelPolynomial_ poly
f = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ Scalar r
a Scalar r -> poly -> poly
forall r m. LeftModule r m => r -> m -> m
.* poly
f
  {-# INLINE (.*) #-}

instance (Wraps vars poly, RightModule (Scalar r) poly) => RightModule (Scalar r) (LabPolynomial poly vars) where
  LabelPolynomial_ poly
f *. :: LabPolynomial poly vars -> Scalar r -> LabPolynomial poly vars
*. Scalar r
a = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly
f poly -> Scalar r -> poly
forall r m. RightModule r m => m -> r -> m
*. Scalar r
a
  {-# INLINE (*.) #-}

instance (Wraps vars poly, DecidableZero poly) => DecidableZero (LabPolynomial poly vars) where
  isZero :: LabPolynomial poly vars -> Bool
isZero = poly -> Bool
forall r. DecidableZero r => r -> Bool
isZero (poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial

instance (Wraps vars poly, Eq poly) => Eq (LabPolynomial poly vars) where
  == :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
(==) = poly -> poly -> Bool
forall a. Eq a => a -> a -> Bool
(==) (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  /= :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
(/=) = poly -> poly -> Bool
forall a. Eq a => a -> a -> Bool
(/=) (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial

instance (Wraps vars poly, Ord poly) => Ord (LabPolynomial poly vars) where
  compare :: LabPolynomial poly vars -> LabPolynomial poly vars -> Ordering
compare = poly -> poly -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (poly -> poly -> Ordering)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  <= :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
(<=) = poly -> poly -> Bool
forall a. Ord a => a -> a -> Bool
(<=) (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  >= :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
(>=) = poly -> poly -> Bool
forall a. Ord a => a -> a -> Bool
(>=) (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  < :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
(<) = poly -> poly -> Bool
forall a. Ord a => a -> a -> Bool
(<) (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  > :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
(>) = poly -> poly -> Bool
forall a. Ord a => a -> a -> Bool
(>) (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial

instance (IsPolynomial poly, Wraps vars poly) => IsPolynomial (LabPolynomial poly vars) where
  type Coefficient (LabPolynomial poly vars) = Coefficient poly
  type Arity (LabPolynomial poly vars) = Arity poly

  liftMap :: (Ordinal (Arity (LabPolynomial poly vars)) -> alg)
-> LabPolynomial poly vars -> alg
liftMap Ordinal (Arity (LabPolynomial poly vars)) -> alg
mor = (Ordinal (Arity poly) -> alg) -> poly -> alg
forall poly alg.
(IsPolynomial poly, Module (Scalar (Coefficient poly)) alg,
 Ring alg, Commutative alg) =>
(Ordinal (Arity poly) -> alg) -> poly -> alg
liftMap Ordinal (Arity poly) -> alg
Ordinal (Arity (LabPolynomial poly vars)) -> alg
mor (poly -> alg)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> alg
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE liftMap #-}

  terms' :: LabPolynomial poly vars
-> Map
     (Monomial (Arity (LabPolynomial poly vars)))
     (Coefficient (LabPolynomial poly vars))
terms' = poly -> Map (Sized Vector (Length vars) Int) (Coefficient poly)
forall poly.
IsPolynomial poly =>
poly -> Map (Monomial (Arity poly)) (Coefficient poly)
terms' (poly -> Map (Sized Vector (Length vars) Int) (Coefficient poly))
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Map (Sized Vector (Length vars) Int) (Coefficient poly)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE terms' #-}

  monomials :: LabPolynomial poly vars
-> HashSet (Monomial (Arity (LabPolynomial poly vars)))
monomials = poly -> HashSet (Sized Vector (Length vars) Int)
forall poly.
IsPolynomial poly =>
poly -> HashSet (Monomial (Arity poly))
monomials (poly -> HashSet (Sized Vector (Length vars) Int))
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> HashSet (Sized Vector (Length vars) Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE monomials #-}

  coeff' :: Monomial (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars -> Coefficient (LabPolynomial poly vars)
coeff' Monomial (Arity (LabPolynomial poly vars))
m = Monomial (Arity poly) -> poly -> Coefficient poly
forall poly.
IsPolynomial poly =>
Monomial (Arity poly) -> poly -> Coefficient poly
coeff' Monomial (Arity poly)
Monomial (Arity (LabPolynomial poly vars))
m (poly -> Coefficient poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Coefficient poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE coeff' #-}

  constantTerm :: LabPolynomial poly vars -> Coefficient (LabPolynomial poly vars)
constantTerm = poly -> Coefficient poly
forall poly. IsPolynomial poly => poly -> Coefficient poly
constantTerm (poly -> Coefficient poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Coefficient poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE constantTerm #-}

  sArity :: proxy (LabPolynomial poly vars)
-> SNat (Arity (LabPolynomial poly vars))
sArity proxy (LabPolynomial poly vars)
_ = Proxy poly -> SNat (Arity poly)
forall poly (proxy :: * -> *).
IsPolynomial poly =>
proxy poly -> SNat (Arity poly)
sArity (Proxy poly
forall k (t :: k). Proxy t
Proxy :: Proxy poly)
  {-# INLINE sArity #-}

  arity :: proxy (LabPolynomial poly vars) -> Integer
arity proxy (LabPolynomial poly vars)
_ = Proxy poly -> Integer
forall poly (proxy :: * -> *).
IsPolynomial poly =>
proxy poly -> Integer
arity (Proxy poly
forall k (t :: k). Proxy t
Proxy :: Proxy poly)
  {-# INLINE arity #-}

  fromMonomial :: Monomial (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars
fromMonomial Monomial (Arity (LabPolynomial poly vars))
m = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Monomial (Arity poly) -> poly
forall poly. IsPolynomial poly => Monomial (Arity poly) -> poly
fromMonomial Monomial (Arity poly)
Monomial (Arity (LabPolynomial poly vars))
m :: poly)
  {-# INLINE fromMonomial #-}

  toPolynomial' :: (Coefficient (LabPolynomial poly vars),
 Monomial (Arity (LabPolynomial poly vars)))
-> LabPolynomial poly vars
toPolynomial' (Coefficient (LabPolynomial poly vars)
r, Monomial (Arity (LabPolynomial poly vars))
deg) = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ ((Coefficient poly, Monomial (Arity poly)) -> poly
forall poly.
IsPolynomial poly =>
(Coefficient poly, Monomial (Arity poly)) -> poly
toPolynomial' (Coefficient poly
Coefficient (LabPolynomial poly vars)
r, Monomial (Arity poly)
Monomial (Arity (LabPolynomial poly vars))
deg) :: poly)
  {-# INLINE toPolynomial' #-}

  polynomial' :: Map
  (Monomial (Arity (LabPolynomial poly vars)))
  (Coefficient (LabPolynomial poly vars))
-> LabPolynomial poly vars
polynomial' Map
  (Monomial (Arity (LabPolynomial poly vars)))
  (Coefficient (LabPolynomial poly vars))
dic = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Map (Monomial (Arity poly)) (Coefficient poly) -> poly
forall poly.
IsPolynomial poly =>
Map (Monomial (Arity poly)) (Coefficient poly) -> poly
polynomial' Map (Monomial (Arity poly)) (Coefficient poly)
Map
  (Monomial (Arity (LabPolynomial poly vars)))
  (Coefficient (LabPolynomial poly vars))
dic :: poly)
  {-# INLINE polynomial' #-}

  totalDegree' :: LabPolynomial poly vars -> Int
totalDegree' = poly -> Int
forall poly. IsPolynomial poly => poly -> Int
totalDegree' (poly -> Int)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE totalDegree' #-}

instance (IsOrderedPolynomial poly, Wraps vars poly) => IsOrderedPolynomial (LabPolynomial poly vars) where
  type MOrder (LabPolynomial poly vars) = MOrder poly

  leadingTerm :: LabPolynomial poly vars
-> (Coefficient (LabPolynomial poly vars),
    OrderedMonomial
      (MOrder (LabPolynomial poly vars))
      (Arity (LabPolynomial poly vars)))
leadingTerm = poly
-> (Coefficient poly, OrderedMonomial (MOrder poly) (Length vars))
forall poly.
IsOrderedPolynomial poly =>
poly
-> (Coefficient poly, OrderedMonomial (MOrder poly) (Arity poly))
leadingTerm (poly
 -> (Coefficient poly, OrderedMonomial (MOrder poly) (Length vars)))
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> (Coefficient poly, OrderedMonomial (MOrder poly) (Length vars))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE leadingTerm #-}

  leadingCoeff :: LabPolynomial poly vars -> Coefficient (LabPolynomial poly vars)
leadingCoeff = poly -> Coefficient poly
forall poly. IsOrderedPolynomial poly => poly -> Coefficient poly
leadingCoeff (poly -> Coefficient poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Coefficient poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE leadingCoeff #-}

  splitLeadingTerm :: LabPolynomial poly vars
-> ((Coefficient (LabPolynomial poly vars),
     OrderedMonomial
       (MOrder (LabPolynomial poly vars))
       (Arity (LabPolynomial poly vars))),
    LabPolynomial poly vars)
splitLeadingTerm = (poly -> (Term poly, poly))
-> LabPolynomial poly vars
-> ((Coefficient poly,
     OrderedMonomial (MOrder poly) (Length vars)),
    LabPolynomial poly vars)
DC.coerce @(poly -> (Term poly, poly)) poly -> (Term poly, poly)
forall poly.
IsOrderedPolynomial poly =>
poly
-> ((Coefficient poly, OrderedMonomial (MOrder poly) (Arity poly)),
    poly)
splitLeadingTerm
  {-# INLINE splitLeadingTerm #-}

  fromOrderedMonomial :: OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars
fromOrderedMonomial OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (OrderedMonomial (MOrder poly) (Arity poly) -> poly
forall poly.
IsOrderedPolynomial poly =>
OrderedMonomial (MOrder poly) (Arity poly) -> poly
fromOrderedMonomial OrderedMonomial (MOrder poly) (Arity poly)
OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m :: poly)
  {-# INLINE fromOrderedMonomial #-}

  orderedMonomials :: LabPolynomial poly vars
-> Set
     (OrderedMonomial
        (MOrder (LabPolynomial poly vars))
        (Arity (LabPolynomial poly vars)))
orderedMonomials = poly -> Set (OrderedMonomial (MOrder poly) (Length vars))
forall poly.
IsOrderedPolynomial poly =>
poly -> Set (OrderedMonomial (MOrder poly) (Arity poly))
orderedMonomials (poly -> Set (OrderedMonomial (MOrder poly) (Length vars)))
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Set (OrderedMonomial (MOrder poly) (Length vars))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE orderedMonomials #-}

  toPolynomial :: (Coefficient (LabPolynomial poly vars),
 OrderedMonomial
   (MOrder (LabPolynomial poly vars))
   (Arity (LabPolynomial poly vars)))
-> LabPolynomial poly vars
toPolynomial (Coefficient (LabPolynomial poly vars)
r, OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
deg) = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Term poly -> poly
forall poly.
IsOrderedPolynomial poly =>
(Coefficient poly, OrderedMonomial (MOrder poly) (Arity poly))
-> poly
toPolynomial (Coefficient poly
Coefficient (LabPolynomial poly vars)
r, OrderedMonomial (MOrder poly) (Arity poly)
OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
deg) :: poly)
  {-# INLINE toPolynomial #-}

  polynomial :: Map
  (OrderedMonomial
     (MOrder (LabPolynomial poly vars))
     (Arity (LabPolynomial poly vars)))
  (Coefficient (LabPolynomial poly vars))
-> LabPolynomial poly vars
polynomial Map
  (OrderedMonomial
     (MOrder (LabPolynomial poly vars))
     (Arity (LabPolynomial poly vars)))
  (Coefficient (LabPolynomial poly vars))
dic = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Map (OrderedMonomial (MOrder poly) (Arity poly)) (Coefficient poly)
-> poly
forall poly.
IsOrderedPolynomial poly =>
Map (OrderedMonomial (MOrder poly) (Arity poly)) (Coefficient poly)
-> poly
polynomial Map (OrderedMonomial (MOrder poly) (Arity poly)) (Coefficient poly)
Map
  (OrderedMonomial
     (MOrder (LabPolynomial poly vars))
     (Arity (LabPolynomial poly vars)))
  (Coefficient (LabPolynomial poly vars))
dic :: poly)
  {-# INLINE polynomial #-}

  terms :: LabPolynomial poly vars
-> Map
     (OrderedMonomial
        (MOrder (LabPolynomial poly vars))
        (Arity (LabPolynomial poly vars)))
     (Coefficient (LabPolynomial poly vars))
terms = poly
-> Map
     (OrderedMonomial (MOrder poly) (Length vars)) (Coefficient poly)
forall poly.
IsOrderedPolynomial poly =>
poly
-> Map
     (OrderedMonomial (MOrder poly) (Arity poly)) (Coefficient poly)
terms (poly
 -> Map
      (OrderedMonomial (MOrder poly) (Length vars)) (Coefficient poly))
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Map
     (OrderedMonomial (MOrder poly) (Length vars)) (Coefficient poly)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE terms #-}

  coeff :: OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars -> Coefficient (LabPolynomial poly vars)
coeff OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m = OrderedMonomial (MOrder poly) (Arity poly)
-> poly -> Coefficient poly
forall poly.
IsOrderedPolynomial poly =>
OrderedMonomial (MOrder poly) (Arity poly)
-> poly -> Coefficient poly
coeff OrderedMonomial (MOrder poly) (Arity poly)
OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m (poly -> Coefficient poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Coefficient poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  {-# INLINE coeff #-}

  OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m >* :: OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars -> LabPolynomial poly vars
>* LabelPolynomial_ poly
f = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (OrderedMonomial (MOrder poly) (Arity poly)
OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m OrderedMonomial (MOrder poly) (Arity poly) -> poly -> poly
forall poly.
IsOrderedPolynomial poly =>
OrderedMonomial (MOrder poly) (Arity poly) -> poly -> poly
>* poly
f)
  {-# INLINE (>*) #-}

  LabelPolynomial_ poly
f *< :: LabPolynomial poly vars
-> OrderedMonomial
     (MOrder (LabPolynomial poly vars))
     (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars
*< OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly
f poly -> OrderedMonomial (MOrder poly) (Arity poly) -> poly
forall poly.
IsOrderedPolynomial poly =>
poly -> OrderedMonomial (MOrder poly) (Arity poly) -> poly
*< OrderedMonomial (MOrder poly) (Arity poly)
OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
m)
  {-# INLINE (*<) #-}

  diff :: Ordinal (Arity (LabPolynomial poly vars))
-> LabPolynomial poly vars -> LabPolynomial poly vars
diff Ordinal (Arity (LabPolynomial poly vars))
n (LabelPolynomial_ poly
f) = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Ordinal (Arity poly) -> poly -> poly
forall poly.
IsOrderedPolynomial poly =>
Ordinal (Arity poly) -> poly -> poly
diff Ordinal (Arity poly)
Ordinal (Arity (LabPolynomial poly vars))
n poly
f)
  {-# INLINE diff #-}

  mapMonomialMonotonic :: (OrderedMonomial
   (MOrder (LabPolynomial poly vars))
   (Arity (LabPolynomial poly vars))
 -> OrderedMonomial
      (MOrder (LabPolynomial poly vars))
      (Arity (LabPolynomial poly vars)))
-> LabPolynomial poly vars -> LabPolynomial poly vars
mapMonomialMonotonic OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
-> OrderedMonomial
     (MOrder (LabPolynomial poly vars))
     (Arity (LabPolynomial poly vars))
f (LabelPolynomial_ poly
g) = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ (OrderedMonomial (MOrder poly) (Arity poly)
 -> OrderedMonomial (MOrder poly) (Arity poly))
-> poly -> poly
forall poly.
IsOrderedPolynomial poly =>
(OrderedMonomial (MOrder poly) (Arity poly)
 -> OrderedMonomial (MOrder poly) (Arity poly))
-> poly -> poly
mapMonomialMonotonic OrderedMonomial (MOrder poly) (Arity poly)
-> OrderedMonomial (MOrder poly) (Arity poly)
OrderedMonomial
  (MOrder (LabPolynomial poly vars))
  (Arity (LabPolynomial poly vars))
-> OrderedMonomial
     (MOrder (LabPolynomial poly vars))
     (Arity (LabPolynomial poly vars))
f poly
g
  {-# INLINE mapMonomialMonotonic #-}

class (All (FlipSym0 @@ ElemSym0 @@ ys) xs ~ 'True) => IsSubsetOf (xs :: [a]) (ys :: [a]) where
  _suppress :: proxy xs -> proxy ys -> x -> x
  _suppress proxy xs
_ proxy ys
_ = x -> x
forall a. a -> a
id

instance (All (FlipSym0 @@ ElemSym0 @@ ys) xs ~ 'True) => IsSubsetOf (xs :: [a]) (ys :: [a])

instance (ZeroProductSemiring poly, Wraps vars poly) => ZeroProductSemiring (LabPolynomial poly vars)

instance (IntegralDomain poly, Wraps vars poly) => IntegralDomain (LabPolynomial poly vars) where
  divides :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
divides = poly -> poly -> Bool
forall d. IntegralDomain d => d -> d -> Bool
divides (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  maybeQuot :: LabPolynomial poly vars
-> LabPolynomial poly vars -> Maybe (LabPolynomial poly vars)
maybeQuot LabPolynomial poly vars
f LabPolynomial poly vars
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> Maybe poly -> Maybe (LabPolynomial poly vars)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> poly -> poly -> Maybe poly
forall d. IntegralDomain d => d -> d -> Maybe d
maybeQuot (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
f) (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
g)

instance (UFD poly, Wraps vars poly) => UFD (LabPolynomial poly vars)

instance (PID poly, Wraps vars poly) => PID (LabPolynomial poly vars) where
  egcd :: LabPolynomial poly vars
-> LabPolynomial poly vars
-> (LabPolynomial poly vars, LabPolynomial poly vars,
    LabPolynomial poly vars)
egcd (LabelPolynomial_ poly
f) (LabelPolynomial_ poly
g) =
    poly -> poly -> (poly, poly, poly)
forall d. PID d => d -> d -> (d, d, d)
egcd poly
f poly
g (poly, poly, poly)
-> ((poly, poly, poly)
    -> (LabPolynomial poly vars, LabPolynomial poly vars,
        LabPolynomial poly vars))
-> (LabPolynomial poly vars, LabPolynomial poly vars,
    LabPolynomial poly vars)
forall a b. a -> (a -> b) -> b
& (poly -> Identity (LabPolynomial poly vars))
-> (poly, poly, poly)
-> Identity
     (LabPolynomial poly vars, LabPolynomial poly vars,
      LabPolynomial poly vars)
forall s t a b. Each s t a b => Traversal s t a b
each ((poly -> Identity (LabPolynomial poly vars))
 -> (poly, poly, poly)
 -> Identity
      (LabPolynomial poly vars, LabPolynomial poly vars,
       LabPolynomial poly vars))
-> (poly -> LabPolynomial poly vars)
-> (poly, poly, poly)
-> (LabPolynomial poly vars, LabPolynomial poly vars,
    LabPolynomial poly vars)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_

instance (GCDDomain poly, Wraps vars poly) => GCDDomain (LabPolynomial poly vars) where
  gcd :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
gcd LabPolynomial poly vars
f LabPolynomial poly vars
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly -> poly -> poly
forall d. GCDDomain d => d -> d -> d
gcd (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
f) (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
g)
  reduceFraction :: LabPolynomial poly vars
-> LabPolynomial poly vars
-> (LabPolynomial poly vars, LabPolynomial poly vars)
reduceFraction LabPolynomial poly vars
f LabPolynomial poly vars
g =
    poly -> poly -> (poly, poly)
forall d. GCDDomain d => d -> d -> (d, d)
reduceFraction (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
f) (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
g)
      (poly, poly)
-> ((poly, poly)
    -> (LabPolynomial poly vars, LabPolynomial poly vars))
-> (LabPolynomial poly vars, LabPolynomial poly vars)
forall a b. a -> (a -> b) -> b
& (poly -> Identity (LabPolynomial poly vars))
-> (poly, poly)
-> Identity (LabPolynomial poly vars, LabPolynomial poly vars)
forall s t a b. Each s t a b => Traversal s t a b
each ((poly -> Identity (LabPolynomial poly vars))
 -> (poly, poly)
 -> Identity (LabPolynomial poly vars, LabPolynomial poly vars))
-> (poly -> LabPolynomial poly vars)
-> (poly, poly)
-> (LabPolynomial poly vars, LabPolynomial poly vars)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_
  lcm :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
lcm LabPolynomial poly vars
f LabPolynomial poly vars
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly -> poly -> poly
forall d. GCDDomain d => d -> d -> d
lcm (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
f) (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
g)

instance (UnitNormalForm poly, Wraps vars poly) => UnitNormalForm (LabPolynomial poly vars) where
  splitUnit :: LabPolynomial poly vars
-> (LabPolynomial poly vars, LabPolynomial poly vars)
splitUnit = ((poly -> Identity (LabPolynomial poly vars))
-> (poly, poly)
-> Identity (LabPolynomial poly vars, LabPolynomial poly vars)
forall s t a b. Each s t a b => Traversal s t a b
each ((poly -> Identity (LabPolynomial poly vars))
 -> (poly, poly)
 -> Identity (LabPolynomial poly vars, LabPolynomial poly vars))
-> (poly -> LabPolynomial poly vars)
-> (poly, poly)
-> (LabPolynomial poly vars, LabPolynomial poly vars)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_) ((poly, poly)
 -> (LabPolynomial poly vars, LabPolynomial poly vars))
-> (LabPolynomial poly vars -> (poly, poly))
-> LabPolynomial poly vars
-> (LabPolynomial poly vars, LabPolynomial poly vars)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. poly -> (poly, poly)
forall r. UnitNormalForm r => r -> (r, r)
splitUnit (poly -> (poly, poly))
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> (poly, poly)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial

instance (DecidableUnits poly, Wraps vars poly) => DecidableUnits (LabPolynomial poly vars) where
  isUnit :: LabPolynomial poly vars -> Bool
isUnit = poly -> Bool
forall r. DecidableUnits r => r -> Bool
isUnit (poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  recipUnit :: LabPolynomial poly vars -> Maybe (LabPolynomial poly vars)
recipUnit = (poly -> LabPolynomial poly vars)
-> Maybe poly -> Maybe (LabPolynomial poly vars)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (Maybe poly -> Maybe (LabPolynomial poly vars))
-> (LabPolynomial poly vars -> Maybe poly)
-> LabPolynomial poly vars
-> Maybe (LabPolynomial poly vars)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. poly -> Maybe poly
forall r. DecidableUnits r => r -> Maybe r
recipUnit (poly -> Maybe poly)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Maybe poly
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  LabelPolynomial_ poly
f ^? :: LabPolynomial poly vars -> n -> Maybe (LabPolynomial poly vars)
^? n
n = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> Maybe poly -> Maybe (LabPolynomial poly vars)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (poly
f poly -> n -> Maybe poly
forall r n. (DecidableUnits r, Integral n) => r -> n -> Maybe r
^? n
n)

instance
  (DecidableAssociates poly, Wraps vars poly) =>
  DecidableAssociates (LabPolynomial poly vars)
  where
  isAssociate :: LabPolynomial poly vars -> LabPolynomial poly vars -> Bool
isAssociate = poly -> poly -> Bool
forall r. DecidableAssociates r => r -> r -> Bool
isAssociate (poly -> poly -> Bool)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> LabPolynomial poly vars
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial

instance
  (Euclidean poly, Wraps vars poly) =>
  Euclidean (LabPolynomial poly vars)
  where
  degree :: LabPolynomial poly vars -> Maybe Natural
degree = poly -> Maybe Natural
forall d. Euclidean d => d -> Maybe Natural
degree (poly -> Maybe Natural)
-> (LabPolynomial poly vars -> poly)
-> LabPolynomial poly vars
-> Maybe Natural
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial
  divide :: LabPolynomial poly vars
-> LabPolynomial poly vars
-> (LabPolynomial poly vars, LabPolynomial poly vars)
divide (LabelPolynomial_ poly
f) (LabelPolynomial_ poly
g) =
    poly -> poly -> (poly, poly)
forall d. Euclidean d => d -> d -> (d, d)
divide poly
f poly
g (poly, poly)
-> ((poly, poly)
    -> (LabPolynomial poly vars, LabPolynomial poly vars))
-> (LabPolynomial poly vars, LabPolynomial poly vars)
forall a b. a -> (a -> b) -> b
& (poly -> Identity (LabPolynomial poly vars))
-> (poly, poly)
-> Identity (LabPolynomial poly vars, LabPolynomial poly vars)
forall s t a b. Each s t a b => Traversal s t a b
each ((poly -> Identity (LabPolynomial poly vars))
 -> (poly, poly)
 -> Identity (LabPolynomial poly vars, LabPolynomial poly vars))
-> (poly -> LabPolynomial poly vars)
-> (poly, poly)
-> (LabPolynomial poly vars, LabPolynomial poly vars)
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_
  quot :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
quot LabPolynomial poly vars
f LabPolynomial poly vars
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly -> poly -> poly
forall d. Euclidean d => d -> d -> d
quot (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
f) (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
g)
  rem :: LabPolynomial poly vars
-> LabPolynomial poly vars -> LabPolynomial poly vars
rem LabPolynomial poly vars
f LabPolynomial poly vars
g = poly -> LabPolynomial poly vars
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ (poly -> LabPolynomial poly vars)
-> poly -> LabPolynomial poly vars
forall a b. (a -> b) -> a -> b
$ poly -> poly -> poly
forall d. Euclidean d => d -> d -> d
rem (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
f) (LabPolynomial poly vars -> poly
forall poly (vars :: [Symbol]). LabPolynomial poly vars -> poly
_unLabelPolynomial LabPolynomial poly vars
g)

-- | So unsafe! Don't expose it!
permute0 :: (SEq k) => SList (xs :: [k]) -> SList (ys :: [k]) -> Sized (Length xs) Integer
permute0 :: SList xs -> SList ys -> Sized (Length xs) Integer
permute0 SList xs
SNil SList ys
_ = Sized (Length xs) Integer
forall (f :: * -> *) (n :: Nat) a.
(KnownNat n, CFreeMonoid f, Dom f a, n ~ 0) =>
Sized f n a
S.Nil
permute0 (SCons Sing n1
x Sing n2
xs) SList ys
ys =
  case Sing n1 -> Sing ys -> Sing (Apply (Apply ElemIndexSym0 n1) ys)
forall a (t1 :: a) (t2 :: [a]).
SEq a =>
Sing t1 -> Sing t2 -> Sing (Apply (Apply ElemIndexSym0 t1) t2)
sElemIndex Sing n1
x Sing ys
SList ys
ys of
    SJust (singToSNat -> n) -> SNat n
-> (KnownNat n => Sized (1 + Length n2) Integer)
-> Sized (1 + Length n2) Integer
forall (n :: Nat) r. SNat n -> (KnownNat n => r) -> r
withKnownNat SNat n
n ((KnownNat n => Sized (1 + Length n2) Integer)
 -> Sized (1 + Length n2) Integer)
-> (KnownNat n => Sized (1 + Length n2) Integer)
-> Sized (1 + Length n2) Integer
forall a b. (a -> b) -> a -> b
$
      let k :: SNat (Length n2)
k = Sing (Length n2) -> SNat (Length n2)
forall (n :: Nat). Sing n -> SNat n
singToSNat (Sing (Length n2) -> SNat (Length n2))
-> Sing (Length n2) -> SNat (Length n2)
forall a b. (a -> b) -> a -> b
$ Sing n2 -> Sing (Apply LengthSym0 n2)
forall (t :: * -> *) a (t1 :: t a).
SFoldable t =>
Sing t1 -> Sing (Apply LengthSym0 t1)
sLength Sing n2
xs
       in SNat (1 + Length n2)
-> (KnownNat (1 + Length n2) => Sized (1 + Length n2) Integer)
-> Sized (1 + Length n2) Integer
forall (n :: Nat) r. SNat n -> (KnownNat n => r) -> r
withKnownNat (KnownNat 1 => SNat 1
forall (n :: Nat). KnownNat n => SNat n
sNat @1 SNat 1 -> SNat (Length n2) -> SNat (1 + Length n2)
forall (n :: Nat) (m :: Nat). SNat n -> SNat m -> SNat (n + m)
%+ SNat (Length n2)
k) ((KnownNat (1 + Length n2) => Sized (1 + Length n2) Integer)
 -> Sized (1 + Length n2) Integer)
-> (KnownNat (1 + Length n2) => Sized (1 + Length n2) Integer)
-> Sized (1 + Length n2) Integer
forall a b. (a -> b) -> a -> b
$
            SNat (Length n2)
-> (KnownNat (Length n2) => Sized (1 + Length n2) Integer)
-> Sized (1 + Length n2) Integer
forall (n :: Nat) r. SNat n -> (KnownNat n => r) -> r
withKnownNat SNat (Length n2)
k (Natural -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral (SNat n -> Natural
forall (n :: Nat) (proxy :: Nat -> *).
KnownNat n =>
proxy n -> Natural
natVal SNat n
n) Integer
-> Sized Vector (Length n2) Integer
-> Sized (1 + Length n2) Integer
forall (f :: * -> *) a (n :: Nat) (n1 :: Nat).
(Dom f a, KnownNat n, CFreeMonoid f, n ~ (1 + n1), KnownNat n1) =>
a -> Sized f n1 a -> Sized f n a
S.:< SList n2 -> SList ys -> Sized (Length n2) Integer
forall k (xs :: [k]) (ys :: [k]).
SEq k =>
SList xs -> SList ys -> Sized (Length xs) Integer
permute0 Sing n2
SList n2
xs SList ys
ys)
    Sing (Apply (Apply ElemIndexSym0 n1) ys)
SNothing -> String -> Sized (1 + Length n2) Integer
forall a. HasCallStack => String -> a
error String
"oops, you called permute0 for non-subset..."

permute ::
  forall k (xs :: [k]) ys.
  (IsSubsetOf xs ys, SEq k) =>
  SList xs ->
  SList ys ->
  Sized (Length xs) Integer
permute :: SList xs -> SList ys -> Sized (Length xs) Integer
permute = Proxy xs
-> Proxy ys
-> (SList xs -> SList ys -> Sized (Length xs) Integer)
-> SList xs
-> SList ys
-> Sized (Length xs) Integer
forall a (xs :: [a]) (ys :: [a]) (proxy :: [a] -> *) x.
IsSubsetOf xs ys =>
proxy xs -> proxy ys -> x -> x
_suppress (Proxy xs
forall k (t :: k). Proxy t
Proxy :: Proxy xs) (Proxy ys
forall k (t :: k). Proxy t
Proxy :: Proxy ys) SList xs -> SList ys -> Sized (Length xs) Integer
forall k (xs :: [k]) (ys :: [k]).
SEq k =>
SList xs -> SList ys -> Sized (Length xs) Integer
permute0

canonicalMap ::
  forall xs ys poly poly'.
  ( SingI xs
  , SingI ys
  , IsSubsetOf xs ys
  , Wraps xs poly
  , Wraps ys poly'
  , IsPolynomial poly
  , IsPolynomial poly'
  , Coefficient poly ~ Coefficient poly'
  ) =>
  LabPolynomial poly xs ->
  LabPolynomial poly' ys
canonicalMap :: LabPolynomial poly xs -> LabPolynomial poly' ys
canonicalMap (LabelPolynomial_ poly
f) =
  let sxs :: Sing xs
sxs = Sing xs
forall k (a :: k). SingI a => Sing a
sing :: Sing xs
      sys :: Sing ys
sys = Sing ys
forall k (a :: k). SingI a => Sing a
sing :: Sing ys
      dics :: Sized (Length xs) Integer
dics = SList xs -> SList ys -> Sized (Length xs) Integer
forall k (xs :: [k]) (ys :: [k]).
(IsSubsetOf xs ys, SEq k) =>
SList xs -> SList ys -> Sized (Length xs) Integer
permute Sing xs
SList xs
sxs Sing ys
SList ys
sys
      ords :: [Ordinal (Length ys)]
ords = SNat (Length ys) -> [Ordinal (Length ys)]
forall (n :: Nat). SNat n -> [Ordinal n]
enumOrdinal (Maybe poly' -> SNat (Arity poly')
forall poly (proxy :: * -> *).
IsPolynomial poly =>
proxy poly -> SNat (Arity poly)
sArity (Maybe poly' -> SNat (Arity poly'))
-> Maybe poly' -> SNat (Arity poly')
forall a b. (a -> b) -> a -> b
$ poly' -> Maybe poly'
forall a. a -> Maybe a
Just poly'
ans)
      mor :: Ordinal (Length xs) -> poly'
mor Ordinal (Length xs)
o = Ordinal (Arity poly') -> poly'
forall poly. IsPolynomial poly => Ordinal (Arity poly) -> poly
var ([Ordinal (Length ys)]
ords [Ordinal (Length ys)] -> Int -> Ordinal (Length ys)
forall a. [a] -> Int -> a
!! Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Sized (Length xs) Integer
Sized Vector (Length xs) Integer
dics Sized Vector (Length xs) Integer -> Ordinal (Length xs) -> Integer
forall (f :: * -> *) (n :: Nat) c.
(CFoldable f, Dom f c) =>
Sized f n c -> Ordinal n -> c
S.%!! Ordinal (Length xs)
o)) :: poly'
      ans :: poly'
ans = (Ordinal (Arity poly) -> poly') -> poly -> poly'
forall poly alg.
(IsPolynomial poly, Module (Scalar (Coefficient poly)) alg,
 Ring alg, Commutative alg) =>
(Ordinal (Arity poly) -> alg) -> poly -> alg
liftMap Ordinal (Arity poly) -> poly'
Ordinal (Length xs) -> poly'
mor poly
f
   in poly' -> LabPolynomial poly' ys
forall poly (vars :: [Symbol]). poly -> LabPolynomial poly vars
LabelPolynomial_ poly'
ans
{-# INLINE canonicalMap #-}

canonicalMap' ::
  ( SingI xs
  , SingI ys
  , IsSubsetOf xs ys
  , Wraps xs poly
  , Wraps ys poly'
  , IsPolynomial poly
  , IsPolynomial poly'
  , Coefficient poly ~ Coefficient poly'
  ) =>
  proxy poly' ->
  proxy' ys ->
  LabPolynomial poly xs ->
  LabPolynomial poly' ys
canonicalMap' :: proxy poly'
-> proxy' ys -> LabPolynomial poly xs -> LabPolynomial poly' ys
canonicalMap' proxy poly'
_ proxy' ys
_ = LabPolynomial poly xs -> LabPolynomial poly' ys
forall (xs :: [Symbol]) (ys :: [Symbol]) poly poly'.
(SingI xs, SingI ys, IsSubsetOf xs ys, Wraps xs poly,
 Wraps ys poly', IsPolynomial poly, IsPolynomial poly',
 Coefficient poly ~ Coefficient poly') =>
LabPolynomial poly xs -> LabPolynomial poly' ys
canonicalMap
{-# INLINE canonicalMap' #-}

renameVars ::
  (SingI ys, SingI xs, Length xs ~ Length ys, IsPolynomial poly) =>
  LabPolynomial poly xs ->
  LabPolynomial poly ys
renameVars :: LabPolynomial poly xs -> LabPolynomial poly ys
renameVars = LabPolynomial poly xs -> LabPolynomial poly ys
DC.coerce
{-# INLINE renameVars #-}

renameVars' ::
  (SingI ys, SingI xs, Length xs ~ Length ys, IsPolynomial poly) =>
  proxy ys ->
  LabPolynomial poly xs ->
  LabPolynomial poly ys
renameVars' :: proxy ys -> LabPolynomial poly xs -> LabPolynomial poly ys
renameVars' proxy ys
_ = LabPolynomial poly xs -> LabPolynomial poly ys
DC.coerce
{-# INLINE renameVars' #-}