-- | Motivic classes in homology


{-# LANGUAGE 
      DataKinds, KindSignatures, TypeOperators, ScopedTypeVariables, MultiParamTypeClasses,
      TypeFamilies, FlexibleContexts, TypeSynonymInstances, FlexibleInstances
  #-}
module Math.RootLoci.Motivic.Homology where

--------------------------------------------------------------------------------


import Data.Array

import Data.Proxy
import GHC.TypeLits

import Unsafe.Coerce as Unsafe

import Math.Combinat.Classes
import Math.Combinat.Numbers
import Math.Combinat.Partitions

import qualified Math.Algebra.Polynomial.FreeModule as ZMod

import qualified Math.Algebra.Polynomial.Monomial.Infinite as XInf
import qualified Math.Algebra.Polynomial.Monomial.Indexed  as XS

import Math.Algebra.Polynomial.Multivariate.Infinite as XInf
import Math.Algebra.Polynomial.Multivariate.Indexed  as XS

import Math.Algebra.Polynomial.Class
import Math.Algebra.Polynomial.Univariate
import Math.Algebra.Polynomial.Pretty

import Math.RootLoci.Geometry.Cohomology ( G(..) )

import Math.RootLoci.Misc.Common
import Math.RootLoci.Motivic.Abstract as Abstract
import Math.RootLoci.Motivic.Classes

import Math.RootLoci.CSM.Aluffi

--------------------------------------------------------------------------------


interpretSingleLam :: (Dim -> KRing Integer) -> SingleLam -> KRing Integer
interpretSingleLam :: (Dim -> KRing Integer) -> SingleLam -> KRing Integer
interpretSingleLam Dim -> KRing Integer
symFun (SingleLam (Bindings [Dim]
bindings) (Single [(Var, Int)]
body)) = KRing Integer
result where
  syms :: [KRing Integer]
syms   = (Dim -> KRing Integer) -> [Dim] -> [KRing Integer]
forall a b. (a -> b) -> [a] -> [b]
map Dim -> KRing Integer
symFun [Dim]
bindings
  result :: KRing Integer
result = GRing Integer -> KRing Integer
forall c. Ring c => GRing c -> KRing c
psiAny (GRing Integer -> KRing Integer) -> GRing Integer -> KRing Integer
forall a b. (a -> b) -> a -> b
$ [KRing Integer] -> GRing Integer
forall c. Ring c => [KRing c] -> GRing c
crossKs ([KRing Integer] -> GRing Integer)
-> [KRing Integer] -> GRing Integer
forall a b. (a -> b) -> a -> b
$ ((Var, Int) -> KRing Integer) -> [(Var, Int)] -> [KRing Integer]
forall a b. (a -> b) -> [a] -> [b]
map (Var, Int) -> KRing Integer
f [(Var, Int)]
body 
  f :: (Var, Int) -> KRing Integer
f (DeBruijn Int
i, Int
e) = Int -> KRing Integer -> KRing Integer
forall c. Ring c => Int -> KRing c -> KRing c
omegaH Int
e ([KRing Integer]
syms[KRing Integer] -> Int -> KRing Integer
forall a. [a] -> Int -> a
!!Int
i)  

csmPn :: Dim -> KRing Integer
csmPn :: Dim -> KRing Integer
csmPn (Dim Int
d) = FreeMod Integer (U "u") -> KRing Integer
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod Integer (U "u") -> KRing Integer)
-> FreeMod Integer (U "u") -> KRing Integer
forall a b. (a -> b) -> a -> b
$ [(U "u", Integer)] -> FreeMod Integer (U "u")
forall c b. (Eq c, Num c, Ord b) => [(b, c)] -> FreeMod c b
ZMod.fromList [ (Int -> U "u"
forall (var :: Symbol). Int -> U var
U Int
k , Int -> Int -> Integer
forall a. Integral a => a -> a -> Integer
binomial (Int
dInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)) | Int
k<-[Int
0..Int
d] ]

-- | CSM class in homology

csm_xlam_P1 :: Partition -> KRing Integer
csm_xlam_P1 :: Partition -> KRing Integer
csm_xlam_P1 Partition
part = FreeMod Integer (U "u") -> KRing Integer
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod Integer (U "u") -> KRing Integer)
-> FreeMod Integer (U "u") -> KRing Integer
forall a b. (a -> b) -> a -> b
$ (SingleLam -> FreeMod Integer (U "u"))
-> FreeMod Integer SingleLam -> FreeMod Integer (U "u")
forall b1 b2 c.
(Ord b1, Ord b2, Eq c, Num c) =>
(b1 -> FreeMod c b2) -> FreeMod c b1 -> FreeMod c b2
ZMod.flatMap SingleLam -> FreeMod Integer (U "u")
f (Partition -> FreeMod Integer SingleLam
Abstract.xlam Partition
part) where
  f :: SingleLam -> FreeMod Integer (U "u")
f SingleLam
x = KRing Integer -> FreeMod Integer (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni ((Dim -> KRing Integer) -> SingleLam -> KRing Integer
interpretSingleLam Dim -> KRing Integer
csmPn SingleLam
x)

-- | CSM class in cohomology (via Poincare duality)

csm_xlam_P1_cohom :: Partition -> ZMod.ZMod G 
csm_xlam_P1_cohom :: Partition -> ZMod G
csm_xlam_P1_cohom Partition
part = (U "u" -> G) -> FreeMod Integer (U "u") -> ZMod G
forall a b c.
(Ord a, Ord b, Eq c, Num c) =>
(a -> b) -> FreeMod c a -> FreeMod c b
ZMod.mapBase U "u" -> G
f (FreeMod Integer (U "u") -> ZMod G)
-> FreeMod Integer (U "u") -> ZMod G
forall a b. (a -> b) -> a -> b
$ KRing Integer -> FreeMod Integer (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni (KRing Integer -> FreeMod Integer (U "u"))
-> KRing Integer -> FreeMod Integer (U "u")
forall a b. (a -> b) -> a -> b
$ Partition -> KRing Integer
csm_xlam_P1 Partition
part  where
  n :: Int
n   = Partition -> Int
forall a. HasWeight a => a -> Int
weight Partition
part
  f :: U "u" -> G
f (U Int
k) = Int -> G
G (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k)

-- | Compares Aluffi's CSM formula to the motivic algorithm (up to partitions of size @n@)

test_motivic_csm_vs_aluffi :: Int -> Bool
test_motivic_csm_vs_aluffi :: Int -> Bool
test_motivic_csm_vs_aluffi Int
n = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and
  [ Partition -> ZMod G
csm_xlam_P1_cohom Partition
part ZMod G -> ZMod G -> Bool
forall a. Eq a => a -> a -> Bool
== Partition -> ZMod G
aluffiOpenCSM Partition
part
  | Int
k<-[Int
1..Int
n] , Partition
part <- Int -> [Partition]
partitions Int
k 
  ]

--------------------------------------------------------------------------------


instance SingleToMulti (KRing c) (GRing c) where
  singleToMulti :: KRing c -> GRing c
singleToMulti = KRing c -> GRing c
forall c. KRing c -> GRing c
embedInf

instance Ring c => Psi (GRing c) (KRing c) where
  psi :: GRing c -> KRing c
psi = GRing c -> KRing c
forall c. Ring c => GRing c -> KRing c
psiAny

instance Ring c => Omega (KRing c) where
  omega :: Int -> KRing c -> KRing c
omega = Int -> KRing c -> KRing c
forall c. Ring c => Int -> KRing c -> KRing c
omegaH

--------------------------------------------------------------------------------


type KRing c   = Univariate c "u"     -- ^ @lim_n H_*(Sym^n(P1))@

type GRing c   = XInf.Poly  c "u"     -- ^ @lim_{n1,n2,...} H_*(Sym^n1(P1) x Sym^n2(P1) x ... )@


-- fuck Haskell's type level naturals, they are completely unusable

-- type NRing c k = XS.Poly    c "u" k   -- ^ @lim_{n1,...,nk} H_*(Sym^n1(P1) x ... x Sym^nk(P1) )@


embedInf :: KRing c -> GRing c
embedInf :: KRing c -> GRing c
embedInf = FreeMod c (XInf "u") -> GRing c
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod c (XInf "u") -> GRing c)
-> (KRing c -> FreeMod c (XInf "u")) -> KRing c -> GRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (U "u" -> XInf "u") -> FreeMod c (U "u") -> FreeMod c (XInf "u")
forall a b c.
(Ord a, Ord b) =>
(a -> b) -> FreeMod c a -> FreeMod c b
ZMod.unsafeMapBase U "u" -> XInf "u"
forall (var :: Symbol) (var :: Symbol). U var -> XInf var
f (FreeMod c (U "u") -> FreeMod c (XInf "u"))
-> (KRing c -> FreeMod c (U "u"))
-> KRing c
-> FreeMod c (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KRing c -> FreeMod c (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni where
  f :: U var -> XInf var
f (U Int
k) = if Int
k Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then [Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf [Int
k] else [Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf []

project1 :: GRing c -> KRing c
project1 :: GRing c -> KRing c
project1 = FreeMod c (U "u") -> KRing c
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod c (U "u") -> KRing c)
-> (GRing c -> FreeMod c (U "u")) -> GRing c -> KRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XInf "u" -> U "u") -> FreeMod c (XInf "u") -> FreeMod c (U "u")
forall a b c.
(Ord a, Ord b) =>
(a -> b) -> FreeMod c a -> FreeMod c b
ZMod.unsafeMapBase XInf "u" -> U "u"
forall (var :: Symbol) (var :: Symbol). XInf var -> U var
f (FreeMod c (XInf "u") -> FreeMod c (U "u"))
-> (GRing c -> FreeMod c (XInf "u"))
-> GRing c
-> FreeMod c (U "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GRing c -> FreeMod c (XInf "u")
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly where
  f :: XInf var -> U var
f (XInf [Int]
ns) = Int -> U var
forall (var :: Symbol). Int -> U var
U (Int -> U var) -> Int -> U var
forall a b. (a -> b) -> a -> b
$ [Int] -> Int
forall a. [a] -> a
head [Int]
ns

delta2 :: Ring c => KRing c -> GRing c
delta2 :: KRing c -> GRing c
delta2 = FreeMod c (XInf "u") -> GRing c
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod c (XInf "u") -> GRing c)
-> (KRing c -> FreeMod c (XInf "u")) -> KRing c -> GRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (U "u" -> FreeMod c (XInf "u"))
-> FreeMod c (U "u") -> FreeMod c (XInf "u")
forall b1 b2 c.
(Ord b1, Ord b2, Eq c, Num c) =>
(b1 -> FreeMod c b2) -> FreeMod c b1 -> FreeMod c b2
ZMod.flatMap U "u" -> FreeMod c (XInf "u")
forall c (var :: Symbol) (var :: Symbol).
(Eq c, Num c) =>
U var -> FreeMod c (XInf var)
f (FreeMod c (U "u") -> FreeMod c (XInf "u"))
-> (KRing c -> FreeMod c (U "u"))
-> KRing c
-> FreeMod c (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KRing c -> FreeMod c (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni where
  f :: U var -> FreeMod c (XInf var)
f (U Int
k) = [FreeMod c (XInf var)] -> FreeMod c (XInf var)
forall b c. (Ord b, Eq c, Num c) => [FreeMod c b] -> FreeMod c b
ZMod.sum [ XInf var -> FreeMod c (XInf var)
forall c b. Num c => b -> FreeMod c b
ZMod.generator ([Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf [Int
i,Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i]) | Int
i<-[Int
0..Int
k] ] 

deltaN :: Ring c => Int -> KRing c -> GRing c
deltaN :: Int -> KRing c -> GRing c
deltaN Int
n KRing c
input 
  | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0    = [Char] -> GRing c
forall a. HasCallStack => [Char] -> a
error [Char]
"deltaN: n <= 0"
  | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1    = KRing c -> GRing c
forall c. KRing c -> GRing c
embedInf KRing c
input
  | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2    = KRing c -> GRing c
forall c. Ring c => KRing c -> GRing c
delta2   KRing c
input
  | Bool
otherwise = GRing (GRing c) -> GRing c
forall c n. Ring c => GRing (GRing c) -> GRing c
unify1st2nd
              (GRing (GRing c) -> GRing c) -> GRing (GRing c) -> GRing c
forall a b. (a -> b) -> a -> b
$ (KRing c -> GRing c) -> Poly (KRing c) "u" -> GRing (GRing c)
forall coeff c1 (var :: Symbol).
(Eq coeff, Num coeff) =>
(c1 -> coeff) -> Poly c1 var -> Poly coeff var
mapCoeffP KRing c -> GRing c
forall c. Ring c => KRing c -> GRing c
delta2 
              (Poly (KRing c) "u" -> GRing (GRing c))
-> Poly (KRing c) "u" -> GRing (GRing c)
forall a b. (a -> b) -> a -> b
$ GRing c -> Poly (KRing c) "u"
forall c n. Ring c => GRing c -> GRing (KRing c)
separate1st (Int -> KRing c -> GRing c
forall c. Ring c => Int -> KRing c -> GRing c
deltaN (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) KRing c
input)
  where
    mapCoeffP :: (c1 -> coeff) -> Poly c1 var -> Poly coeff var
mapCoeffP c1 -> coeff
f = FreeMod coeff (XInf var) -> Poly coeff var
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod coeff (XInf var) -> Poly coeff var)
-> (Poly c1 var -> FreeMod coeff (XInf var))
-> Poly c1 var
-> Poly coeff var
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c1 -> coeff) -> FreeMod c1 (XInf var) -> FreeMod coeff (XInf var)
forall b c2 c1.
(Ord b, Eq c2, Num c2) =>
(c1 -> c2) -> FreeMod c1 b -> FreeMod c2 b
ZMod.mapCoeff c1 -> coeff
f (FreeMod c1 (XInf var) -> FreeMod coeff (XInf var))
-> (Poly c1 var -> FreeMod c1 (XInf var))
-> Poly c1 var
-> FreeMod coeff (XInf var)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Poly c1 var -> FreeMod c1 (XInf var)
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly

psi2 :: Ring c => GRing c -> KRing c
psi2 :: GRing c -> KRing c
psi2 = FreeMod c (U "u") -> KRing c
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod c (U "u") -> KRing c)
-> (GRing c -> FreeMod c (U "u")) -> GRing c -> KRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XInf "u" -> Maybe (U "u", c))
-> FreeMod c (XInf "u") -> FreeMod c (U "u")
forall a b c.
(Ord a, Ord b, Eq c, Num c) =>
(a -> Maybe (b, c)) -> FreeMod c a -> FreeMod c b
ZMod.mapMaybeBaseCoeff XInf "u" -> Maybe (U "u", c)
forall b (var :: Symbol) (var :: Symbol).
Num b =>
XInf var -> Maybe (U var, b)
f (FreeMod c (XInf "u") -> FreeMod c (U "u"))
-> (GRing c -> FreeMod c (XInf "u"))
-> GRing c
-> FreeMod c (U "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GRing c -> FreeMod c (XInf "u")
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly where
  f :: XInf var -> Maybe (U var, b)
f (XInf [Int]
xs) = let [Int
i,Int
j] = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
2 ([Int]
xs [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
0,Int
0])
                in  (U var, b) -> Maybe (U var, b)
forall a. a -> Maybe a
Just ( Int -> U var
forall (var :: Symbol). Int -> U var
U (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
j) , Integer -> b
forall a. Num a => Integer -> a
fromInteger (Int -> Int -> Integer
forall a. Integral a => a -> a -> Integer
binomial (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
j) Int
i) )

psiNaive :: (Ring c) => Int -> GRing c -> KRing c
psiNaive :: Int -> GRing c -> KRing c
psiNaive Int
n GRing c
input 
  | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0    = [Char] -> KRing c
forall a. HasCallStack => [Char] -> a
error [Char]
"psiN: n <= 0"
  | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1    = GRing c -> KRing c
forall c. GRing c -> KRing c
project1 GRing c
input
  | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2    = GRing c -> KRing c
forall c. Ring c => GRing c -> KRing c
psi2     GRing c
input
  | Bool
otherwise = GRing c -> KRing c
forall c. Ring c => GRing c -> KRing c
psi2 (GRing c -> KRing c) -> GRing c -> KRing c
forall a b. (a -> b) -> a -> b
$ KRing (KRing c) -> GRing c
forall c. Ring c => KRing (KRing c) -> GRing c
kkToG2 (KRing (KRing c) -> GRing c) -> KRing (KRing c) -> GRing c
forall a b. (a -> b) -> a -> b
$ Int -> GRing (KRing c) -> KRing (KRing c)
forall c. Ring c => Int -> GRing c -> KRing c
psiNaive (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (GRing (KRing c) -> KRing (KRing c))
-> GRing (KRing c) -> KRing (KRing c)
forall a b. (a -> b) -> a -> b
$ GRing c -> GRing (KRing c)
forall c n. Ring c => GRing c -> GRing (KRing c)
separate1st GRing c
input

psiAny :: Ring c => GRing c -> KRing c
psiAny :: GRing c -> KRing c
psiAny = FreeMod c (U "u") -> KRing c
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod c (U "u") -> KRing c)
-> (GRing c -> FreeMod c (U "u")) -> GRing c -> KRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XInf "u" -> Maybe (U "u", c))
-> FreeMod c (XInf "u") -> FreeMod c (U "u")
forall a b c.
(Ord a, Ord b, Eq c, Num c) =>
(a -> Maybe (b, c)) -> FreeMod c a -> FreeMod c b
ZMod.mapMaybeBaseCoeff XInf "u" -> Maybe (U "u", c)
forall b (var :: Symbol) (var :: Symbol).
Num b =>
XInf var -> Maybe (U var, b)
f (FreeMod c (XInf "u") -> FreeMod c (U "u"))
-> (GRing c -> FreeMod c (XInf "u"))
-> GRing c
-> FreeMod c (U "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GRing c -> FreeMod c (XInf "u")
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly where
  f :: XInf var -> Maybe (U var, b)
f (XInf [Int]
is) = (U var, b) -> Maybe (U var, b)
forall a. a -> Maybe a
Just (Int -> U var
forall (var :: Symbol). Int -> U var
U ([Int] -> Int
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum [Int]
is) , Integer -> b
forall a. Num a => Integer -> a
fromInteger ([Int] -> Integer
forall a. Integral a => [a] -> Integer
multinomial [Int]
is))

omegaNaive :: Ring c => Int -> KRing c -> KRing c
omegaNaive :: Int -> KRing c -> KRing c
omegaNaive Int
n = GRing c -> KRing c
forall c. Ring c => GRing c -> KRing c
psiAny (GRing c -> KRing c) -> (KRing c -> GRing c) -> KRing c -> KRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> KRing c -> GRing c
forall c. Ring c => Int -> KRing c -> GRing c
deltaN Int
n

omegaH :: Ring c => Int -> KRing c -> KRing c
omegaH :: Int -> KRing c -> KRing c
omegaH Int
d = FreeMod c (U "u") -> KRing c
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod c (U "u") -> KRing c)
-> (KRing c -> FreeMod c (U "u")) -> KRing c -> KRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (U "u" -> Maybe (U "u", c))
-> FreeMod c (U "u") -> FreeMod c (U "u")
forall a b c.
(Ord a, Ord b, Eq c, Num c) =>
(a -> Maybe (b, c)) -> FreeMod c a -> FreeMod c b
ZMod.mapMaybeBaseCoeff U "u" -> Maybe (U "u", c)
f (FreeMod c (U "u") -> FreeMod c (U "u"))
-> (KRing c -> FreeMod c (U "u")) -> KRing c -> FreeMod c (U "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KRing c -> FreeMod c (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni where
  f :: U "u" -> Maybe (U "u", c)
f (U Int
k) = (U "u", c) -> Maybe (U "u", c)
forall a. a -> Maybe a
Just (Int -> U "u"
forall (var :: Symbol). Int -> U var
U Int
k, Int -> c
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
d c -> Int -> c
forall a b. (Num a, Integral b) => a -> b -> a
^ Int
k)

separate1st :: forall c n. (Ring c) => GRing c -> GRing (KRing c) 
separate1st :: GRing c -> GRing (KRing c)
separate1st = FreeMod (KRing c) (XInf "u") -> GRing (KRing c)
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod (KRing c) (XInf "u") -> GRing (KRing c))
-> (GRing c -> FreeMod (KRing c) (XInf "u"))
-> GRing c
-> GRing (KRing c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (XInf "u" -> Maybe (XInf "u", KRing c))
-> FreeMod (KRing c) (XInf "u") -> FreeMod (KRing c) (XInf "u")
forall a b c.
(Ord a, Ord b, Eq c, Num c) =>
(a -> Maybe (b, c)) -> FreeMod c a -> FreeMod c b
ZMod.mapMaybeBaseCoeff XInf "u" -> Maybe (XInf "u", KRing c)
forall b (var :: Symbol) (var :: Symbol) (var :: Symbol).
(AlmostPolynomial b, MonomP b ~ U var) =>
XInf var -> Maybe (XInf var, b)
g (FreeMod (KRing c) (XInf "u") -> FreeMod (KRing c) (XInf "u"))
-> (GRing c -> FreeMod (KRing c) (XInf "u"))
-> GRing c
-> FreeMod (KRing c) (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (c -> KRing c)
-> FreeMod c (XInf "u") -> FreeMod (KRing c) (XInf "u")
forall b c2 c1.
(Ord b, Eq c2, Num c2) =>
(c1 -> c2) -> FreeMod c1 b -> FreeMod c2 b
ZMod.mapCoeff c -> KRing c
f (FreeMod c (XInf "u") -> FreeMod (KRing c) (XInf "u"))
-> (GRing c -> FreeMod c (XInf "u"))
-> GRing c
-> FreeMod (KRing c) (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GRing c -> FreeMod c (XInf "u")
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly where
  f :: c -> KRing c
f c
c  = CoeffP (KRing c) -> KRing c
forall p. AlmostPolynomial p => CoeffP p -> p
scalarP c
CoeffP (KRing c)
c :: KRing c
  g :: XInf var -> Maybe (XInf var, b)
g (XInf (Int
k:[Int]
ns)) = (XInf var, b) -> Maybe (XInf var, b)
forall a. a -> Maybe a
Just ([Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf [Int]
ns, b
c) where
    c :: b
c = MonomP b -> b
forall p. AlmostPolynomial p => MonomP p -> p
monomP (Int -> U var
forall (var :: Symbol). Int -> U var
U Int
k)

unify1st :: forall c n. (Ring c) => GRing (KRing c) -> GRing c 
unify1st :: GRing (KRing c) -> GRing c
unify1st = FreeMod c (XInf "u") -> GRing c
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod c (XInf "u") -> GRing c)
-> (GRing (KRing c) -> FreeMod c (XInf "u"))
-> GRing (KRing c)
-> GRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(XInf "u", c)] -> FreeMod c (XInf "u")
forall c b. (Eq c, Num c, Ord b) => [(b, c)] -> FreeMod c b
ZMod.fromList ([(XInf "u", c)] -> FreeMod c (XInf "u"))
-> (GRing (KRing c) -> [(XInf "u", c)])
-> GRing (KRing c)
-> FreeMod c (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((XInf "u", KRing c) -> [(XInf "u", c)])
-> [(XInf "u", KRing c)] -> [(XInf "u", c)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (XInf "u", KRing c) -> [(XInf "u", c)]
forall (var :: Symbol) b (var :: Symbol) (var :: Symbol).
(XInf var, Univariate b var) -> [(XInf var, b)]
f ([(XInf "u", KRing c)] -> [(XInf "u", c)])
-> (GRing (KRing c) -> [(XInf "u", KRing c)])
-> GRing (KRing c)
-> [(XInf "u", c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FreeMod (KRing c) (XInf "u") -> [(XInf "u", KRing c)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList (FreeMod (KRing c) (XInf "u") -> [(XInf "u", KRing c)])
-> (GRing (KRing c) -> FreeMod (KRing c) (XInf "u"))
-> GRing (KRing c)
-> [(XInf "u", KRing c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GRing (KRing c) -> FreeMod (KRing c) (XInf "u")
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly where
  f :: (XInf var, Univariate b var) -> [(XInf var, b)]
f (XInf [Int]
xs , Uni FreeMod b (U var)
poly) = [ ([Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf (Int
kInt -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:[Int]
xs) , b
c)  | (U Int
k, b
c) <- FreeMod b (U var) -> [(U var, b)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList FreeMod b (U var)
poly ]

unify1st2nd :: forall c n. (Ring c) => GRing (GRing c) -> GRing c 
unify1st2nd :: GRing (GRing c) -> GRing c
unify1st2nd = FreeMod c (XInf "u") -> GRing c
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod c (XInf "u") -> GRing c)
-> (GRing (GRing c) -> FreeMod c (XInf "u"))
-> GRing (GRing c)
-> GRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(XInf "u", c)] -> FreeMod c (XInf "u")
forall c b. (Eq c, Num c, Ord b) => [(b, c)] -> FreeMod c b
ZMod.fromList ([(XInf "u", c)] -> FreeMod c (XInf "u"))
-> (GRing (GRing c) -> [(XInf "u", c)])
-> GRing (GRing c)
-> FreeMod c (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((XInf "u", GRing c) -> [(XInf "u", c)])
-> [(XInf "u", GRing c)] -> [(XInf "u", c)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (XInf "u", GRing c) -> [(XInf "u", c)]
forall (var :: Symbol) b (var :: Symbol) (var :: Symbol).
(XInf var, Poly b var) -> [(XInf var, b)]
f ([(XInf "u", GRing c)] -> [(XInf "u", c)])
-> (GRing (GRing c) -> [(XInf "u", GRing c)])
-> GRing (GRing c)
-> [(XInf "u", c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FreeMod (GRing c) (XInf "u") -> [(XInf "u", GRing c)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList (FreeMod (GRing c) (XInf "u") -> [(XInf "u", GRing c)])
-> (GRing (GRing c) -> FreeMod (GRing c) (XInf "u"))
-> GRing (GRing c)
-> [(XInf "u", GRing c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GRing (GRing c) -> FreeMod (GRing c) (XInf "u")
forall c (v :: Symbol). Poly c v -> FreeMod c (XInf v)
XInf.unPoly where
  f :: (XInf var, Poly b var) -> [(XInf var, b)]
f (XInf [Int]
xs , XInf.Poly FreeMod b (XInf var)
poly) = [ ([Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf ([Int]
kl[Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++[Int]
xs) , b
c)  | (XInf [Int]
kl0, b
c) <- FreeMod b (XInf var) -> [(XInf var, b)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList FreeMod b (XInf var)
poly , let kl :: [Int]
kl = Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
2 ([Int]
kl0[Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++[Int
0,Int
0]) ]

crossKs :: Ring c => [KRing c] -> GRing c
crossKs :: [KRing c] -> GRing c
crossKs = FreeMod c (XInf "u") -> GRing c
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod c (XInf "u") -> GRing c)
-> ([KRing c] -> FreeMod c (XInf "u")) -> [KRing c] -> GRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XInf "u"
-> (XInf "u" -> XInf "u" -> XInf "u")
-> [FreeMod c (XInf "u")]
-> FreeMod c (XInf "u")
forall b c.
(Ord b, Eq c, Num c) =>
b -> (b -> b -> b) -> [FreeMod c b] -> FreeMod c b
ZMod.productWith XInf "u"
forall (var :: Symbol). XInf var
empty XInf "u" -> XInf "u" -> XInf "u"
forall (var :: Symbol) (var :: Symbol) (var :: Symbol).
XInf var -> XInf var -> XInf var
cross ([FreeMod c (XInf "u")] -> FreeMod c (XInf "u"))
-> ([KRing c] -> [FreeMod c (XInf "u")])
-> [KRing c]
-> FreeMod c (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FreeMod c (U "u") -> FreeMod c (XInf "u"))
-> [FreeMod c (U "u")] -> [FreeMod c (XInf "u")]
forall a b. (a -> b) -> [a] -> [b]
map ((U "u" -> XInf "u") -> FreeMod c (U "u") -> FreeMod c (XInf "u")
forall a b c.
(Ord a, Ord b, Eq c, Num c) =>
(a -> b) -> FreeMod c a -> FreeMod c b
ZMod.mapBase U "u" -> XInf "u"
forall (var :: Symbol) (var :: Symbol). U var -> XInf var
sing) ([FreeMod c (U "u")] -> [FreeMod c (XInf "u")])
-> ([KRing c] -> [FreeMod c (U "u")])
-> [KRing c]
-> [FreeMod c (XInf "u")]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (KRing c -> FreeMod c (U "u")) -> [KRing c] -> [FreeMod c (U "u")]
forall a b. (a -> b) -> [a] -> [b]
map KRing c -> FreeMod c (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni where
  sing :: U var -> XInf var
sing (U Int
k) = [Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf [Int
k]
  cross :: XInf var -> XInf var -> XInf var
cross (XInf [Int]
as) (XInf [Int]
bs) = [Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf ([Int]
as[Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++[Int]
bs)
  empty :: XInf var
empty = [Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf []

kkToG2 :: Ring c => KRing (KRing c) -> GRing c 
kkToG2 :: KRing (KRing c) -> GRing c
kkToG2 = FreeMod c (XInf "u") -> GRing c
forall coeff (var :: Symbol).
FreeMod coeff (XInf var) -> Poly coeff var
XInf.Poly (FreeMod c (XInf "u") -> GRing c)
-> (KRing (KRing c) -> FreeMod c (XInf "u"))
-> KRing (KRing c)
-> GRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(XInf "u", c)] -> FreeMod c (XInf "u")
forall c b. (Eq c, Num c, Ord b) => [(b, c)] -> FreeMod c b
ZMod.fromList ([(XInf "u", c)] -> FreeMod c (XInf "u"))
-> (KRing (KRing c) -> [(XInf "u", c)])
-> KRing (KRing c)
-> FreeMod c (XInf "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((U "u", KRing c) -> [(XInf "u", c)])
-> [(U "u", KRing c)] -> [(XInf "u", c)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (U "u", KRing c) -> [(XInf "u", c)]
forall (var :: Symbol) b (var :: Symbol) (var :: Symbol).
(U var, Univariate b var) -> [(XInf var, b)]
f ([(U "u", KRing c)] -> [(XInf "u", c)])
-> (KRing (KRing c) -> [(U "u", KRing c)])
-> KRing (KRing c)
-> [(XInf "u", c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FreeMod (KRing c) (U "u") -> [(U "u", KRing c)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList (FreeMod (KRing c) (U "u") -> [(U "u", KRing c)])
-> (KRing (KRing c) -> FreeMod (KRing c) (U "u"))
-> KRing (KRing c)
-> [(U "u", KRing c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KRing (KRing c) -> FreeMod (KRing c) (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni where
  f :: (U var, Univariate b var) -> [(XInf var, b)]
f (U Int
k , Uni FreeMod b (U var)
poly) = [ ([Int] -> XInf var
forall (var :: Symbol). [Int] -> XInf var
XInf [Int
k,Int
l] , b
c)  | (U Int
l, b
c) <- FreeMod b (U var) -> [(U var, b)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList FreeMod b (U var)
poly ]

unifyKK :: Ring c => KRing (KRing c) -> KRing c 
unifyKK :: KRing (KRing c) -> KRing c
unifyKK = FreeMod c (U "u") -> KRing c
forall coeff (var :: Symbol).
FreeMod coeff (U var) -> Univariate coeff var
Uni (FreeMod c (U "u") -> KRing c)
-> (KRing (KRing c) -> FreeMod c (U "u"))
-> KRing (KRing c)
-> KRing c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(U "u", c)] -> FreeMod c (U "u")
forall c b. (Eq c, Num c, Ord b) => [(b, c)] -> FreeMod c b
ZMod.fromList ([(U "u", c)] -> FreeMod c (U "u"))
-> (KRing (KRing c) -> [(U "u", c)])
-> KRing (KRing c)
-> FreeMod c (U "u")
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((U "u", KRing c) -> [(U "u", c)])
-> [(U "u", KRing c)] -> [(U "u", c)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (U "u", KRing c) -> [(U "u", c)]
forall (var :: Symbol) b (var :: Symbol) (var :: Symbol).
(U var, Univariate b var) -> [(U var, b)]
f ([(U "u", KRing c)] -> [(U "u", c)])
-> (KRing (KRing c) -> [(U "u", KRing c)])
-> KRing (KRing c)
-> [(U "u", c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FreeMod (KRing c) (U "u") -> [(U "u", KRing c)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList (FreeMod (KRing c) (U "u") -> [(U "u", KRing c)])
-> (KRing (KRing c) -> FreeMod (KRing c) (U "u"))
-> KRing (KRing c)
-> [(U "u", KRing c)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KRing (KRing c) -> FreeMod (KRing c) (U "u")
forall c (v :: Symbol). Univariate c v -> FreeMod c (U v)
unUni where
  f :: (U var, Univariate b var) -> [(U var, b)]
f (U Int
k , Uni FreeMod b (U var)
poly) = [ (Int -> U var
forall (var :: Symbol). Int -> U var
U (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
l) , b
c)  | (U Int
l, b
c) <- FreeMod b (U var) -> [(U var, b)]
forall c b. FreeMod c b -> [(b, c)]
ZMod.toList FreeMod b (U var)
poly ]

--------------------------------------------------------------------------------


{-
deltaN :: Num c => Int -> KRing c -> GRing c
deltaN 0 = error "deltaN: 0"
deltaN 1 = embed
deltaN 2 = delta2
deltaN 
-}