{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

-- | Very strong types for working with indices, counts, etc within sequences.
module Test.Ouroboros.Consensus.ChainGenerator.Counting (
    -- * general counts
    Count (Count)
  , forgetBase
  , forgetElem
  , getCount
  , (+)
  , (-)
    -- * indices and sizes
  , Index
  , Preds
  , Size
  , Total
  , forRange_
  , lastIndex
  , range
  , uniformIndex
    -- * windows
  , Contains (Contains, UnsafeContains)
  , Lbl (Lbl)
  , SomeWindow (SomeWindow)
  , Win
  , forgetWindow
  , fromWindow
  , fromWindowVar
  , joinWin
  , toWindow
  , toWindowVar
  , truncateWin
  , windowLast
  , windowSize
  , windowStart
  , withSuffixWindow
  , withTopWindow
  , withWindow
  , withWindowBetween
    -- * vectors
  , MVector (MVector)
  , Vector (Vector)
  , createV
  , getMVector
  , getVector
  , lengthMV
  , lengthV
  , modifyMV
  , readMV
  , readV
  , replicateMV
  , sliceMV
  , sliceV
  , unsafeThawV
  , writeMV
    -- * variables
  , Other
  , Var
  , joinVar
  , toIndex
  , toSize
  , toVar
  ) where

import           Control.Monad.ST (ST)
import           Data.Coerce (coerce)
import           Data.Foldable (for_)
import           Data.Kind (Type)
import           Data.Proxy (Proxy (Proxy))
import qualified Data.Type.Equality as TypeEq
import qualified Data.Vector.Unboxed as V
import qualified Data.Vector.Unboxed.Mutable as MV
import           GHC.OverloadedLabels (IsLabel (fromLabel))
import           Prelude hiding ((+), (-))
import qualified Prelude
import qualified System.Random.Stateful as R
import qualified Test.Ouroboros.Consensus.ChainGenerator.Some as Some
import qualified Test.QuickCheck as QC

-----

infixl 6 .+, .-

(.+) :: Int -> Int -> Int
.+ :: Int -> Int -> Int
(.+) = Int -> Int -> Int
forall a. Num a => a -> a -> a
(Prelude.+)

(.-) :: Int -> Int -> Int
.- :: Int -> Int -> Int
(.-) = Int -> Int -> Int
forall a. Num a => a -> a -> a
(Prelude.-)

-----

-- | A type-indexed Int to represent counts of elements in containers
--
-- * @base@ is the type-level name of the container in which we are counting (e.g. @Win (Lbl HonestLbl) skolem1@)
-- * @elem@ is the type-level name of the elements in the container (e.g. 'Test.Ouroboros.Consensus.ChainGenerator.Slot.SlotE')
-- * @which@ is the type-level name of some property that identifies the
--   particular elements that we are counting (e.g. 'Pred', 'Total', or 'Other')
--
-- TODO: rename @base@ to @container@
newtype Count (base :: Type) (elem :: kelem) (which :: kwhich) = Count Int
  deriving (Gen (Count base elem which)
Gen (Count base elem which)
-> (Count base elem which -> [Count base elem which])
-> Arbitrary (Count base elem which)
Count base elem which -> [Count base elem which]
forall a. Gen a -> (a -> [a]) -> Arbitrary a
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Gen (Count base elem which)
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> [Count base elem which]
$carbitrary :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Gen (Count base elem which)
arbitrary :: Gen (Count base elem which)
$cshrink :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> [Count base elem which]
shrink :: Count base elem which -> [Count base elem which]
QC.Arbitrary, Count base elem which -> Count base elem which -> Bool
(Count base elem which -> Count base elem which -> Bool)
-> (Count base elem which -> Count base elem which -> Bool)
-> Eq (Count base elem which)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
$c== :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
== :: Count base elem which -> Count base elem which -> Bool
$c/= :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
/= :: Count base elem which -> Count base elem which -> Bool
Eq, Eq (Count base elem which)
Eq (Count base elem which) =>
(Count base elem which -> Count base elem which -> Ordering)
-> (Count base elem which -> Count base elem which -> Bool)
-> (Count base elem which -> Count base elem which -> Bool)
-> (Count base elem which -> Count base elem which -> Bool)
-> (Count base elem which -> Count base elem which -> Bool)
-> (Count base elem which
    -> Count base elem which -> Count base elem which)
-> (Count base elem which
    -> Count base elem which -> Count base elem which)
-> Ord (Count base elem which)
Count base elem which -> Count base elem which -> Bool
Count base elem which -> Count base elem which -> Ordering
Count base elem which
-> Count base elem which -> Count base elem which
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
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Eq (Count base elem which)
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Ordering
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which
-> Count base elem which -> Count base elem which
$ccompare :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Ordering
compare :: Count base elem which -> Count base elem which -> Ordering
$c< :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
< :: Count base elem which -> Count base elem which -> Bool
$c<= :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
<= :: Count base elem which -> Count base elem which -> Bool
$c> :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
> :: Count base elem which -> Count base elem which -> Bool
$c>= :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> Count base elem which -> Bool
>= :: Count base elem which -> Count base elem which -> Bool
$cmax :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which
-> Count base elem which -> Count base elem which
max :: Count base elem which
-> Count base elem which -> Count base elem which
$cmin :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which
-> Count base elem which -> Count base elem which
min :: Count base elem which
-> Count base elem which -> Count base elem which
Ord, ReadPrec [Count base elem which]
ReadPrec (Count base elem which)
Int -> ReadS (Count base elem which)
ReadS [Count base elem which]
(Int -> ReadS (Count base elem which))
-> ReadS [Count base elem which]
-> ReadPrec (Count base elem which)
-> ReadPrec [Count base elem which]
-> Read (Count base elem which)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
ReadPrec [Count base elem which]
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
ReadPrec (Count base elem which)
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Int -> ReadS (Count base elem which)
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
ReadS [Count base elem which]
$creadsPrec :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Int -> ReadS (Count base elem which)
readsPrec :: Int -> ReadS (Count base elem which)
$creadList :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
ReadS [Count base elem which]
readList :: ReadS [Count base elem which]
$creadPrec :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
ReadPrec (Count base elem which)
readPrec :: ReadPrec (Count base elem which)
$creadListPrec :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
ReadPrec [Count base elem which]
readListPrec :: ReadPrec [Count base elem which]
Read, Int -> Count base elem which -> ShowS
[Count base elem which] -> ShowS
Count base elem which -> String
(Int -> Count base elem which -> ShowS)
-> (Count base elem which -> String)
-> ([Count base elem which] -> ShowS)
-> Show (Count base elem which)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Int -> Count base elem which -> ShowS
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
[Count base elem which] -> ShowS
forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> String
$cshowsPrec :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Int -> Count base elem which -> ShowS
showsPrec :: Int -> Count base elem which -> ShowS
$cshow :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
Count base elem which -> String
show :: Count base elem which -> String
$cshowList :: forall base kelem (elem :: kelem) kwhich (which :: kwhich).
[Count base elem which] -> ShowS
showList :: [Count base elem which] -> ShowS
Show)

getCount :: Count base elem which -> Int
getCount :: forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Int
getCount (Count Int
n) = Int
n

infixl 6 +, -

(+) :: Count base elem which -> Int -> Count base elem which
+ :: forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Int -> Count base elem which
(+) (Count Int
i) Int
j = Int -> Count base elem which
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int
i Int -> Int -> Int
.+ Int
j)

(-) :: Count base elem which -> Int -> Count base elem which
(-) (Count Int
i) Int
j = Int -> Count base elem which
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int
i Int -> Int -> Int
.- Int
j)

forgetBase :: Count base elem which -> Some.Forgotten (Count () elem which)
forgetBase :: forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Forgotten (Count () elem which)
forgetBase (Count Int
x) = Count () elem which -> Forgotten (Count () elem which)
forall a. a -> Forgotten a
Some.forgotten (Count () elem which -> Forgotten (Count () elem which))
-> Count () elem which -> Forgotten (Count () elem which)
forall a b. (a -> b) -> a -> b
$ Int -> Count () elem which
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
x

forgetElem :: Count base elem which -> Some.Forgotten (Count base () which)
forgetElem :: forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Forgotten (Count base () which)
forgetElem (Count Int
x) = Count base () which -> Forgotten (Count base () which)
forall a. a -> Forgotten a
Some.forgotten (Count base () which -> Forgotten (Count base () which))
-> Count base () which -> Forgotten (Count base () which)
forall a b. (a -> b) -> a -> b
$ Int -> Count base () which
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
x

-----

-- | Type-level name for counting elements with an index smaller
-- than a given value
data Preds

-- | Type-level name for counting all elements in a container
data Total

type Index base elem = Count base elem Preds
type Size  base elem = Count base elem Total

-- | The 'Index' of the rightmost element in the sequence of the given 'Size'
lastIndex :: Size base elem -> Index base elem
lastIndex :: forall {kelem} base (elem :: kelem).
Size base elem -> Index base elem
lastIndex (Count Int
n) = Int -> Count base elem Preds
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int
n Int -> Int -> Int
.- Int
1)

range :: Size base elem -> [Index base elem]
range :: forall {kelem} base (elem :: kelem).
Size base elem -> [Index base elem]
range (Count Int
n) = [Int] -> [Index base elem]
forall a b. Coercible a b => a -> b
coerce [Int
0 .. Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
n Int -> Int -> Int
.- Int
1]

forRange_ :: Applicative f => Size base elem -> (Index base elem -> f a) -> f ()
forRange_ :: forall {kelem} (f :: * -> *) base (elem :: kelem) a.
Applicative f =>
Size base elem -> (Index base elem -> f a) -> f ()
forRange_ Size base elem
c = [Index base elem] -> (Index base elem -> f a) -> f ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Size base elem -> [Index base elem]
forall {kelem} base (elem :: kelem).
Size base elem -> [Index base elem]
range Size base elem
c)

uniformIndex :: R.StatefulGen g m => Size base elem -> g -> m (Index base elem)
uniformIndex :: forall {kelem} g (m :: * -> *) base (elem :: kelem).
StatefulGen g m =>
Size base elem -> g -> m (Index base elem)
uniformIndex Size base elem
n g
g = Int -> Count base elem Preds
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int -> Count base elem Preds)
-> m Int -> m (Count base elem Preds)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int, Int) -> g -> m Int
forall a g (m :: * -> *).
(UniformRange a, StatefulGen g m) =>
(a, a) -> g -> m a
forall g (m :: * -> *). StatefulGen g m => (Int, Int) -> g -> m Int
R.uniformRM (Int
0, Count base elem Preds -> Int
forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Int
getCount (Count base elem Preds -> Int) -> Count base elem Preds -> Int
forall a b. (a -> b) -> a -> b
$ Size base elem -> Count base elem Preds
forall {kelem} base (elem :: kelem).
Size base elem -> Index base elem
lastIndex Size base elem
n) g
g

-----

-- | A human-readable label for a 'Win'
data Lbl lbl = Lbl   -- no explicit kind var so that type applications don't
                     -- need to provide the kind
                     --
                     -- TODO as of GHC 9.0, use a standalone kind signature to
                     -- declare k as /inferred/ instead of /specified/
instance (lbl TypeEq.~~ s) => IsLabel s (Lbl lbl) where fromLabel :: Lbl lbl
fromLabel = Lbl lbl
forall {k} (lbl :: k). Lbl lbl
Lbl

-- | A type-level name for a window within some containing sequence
--
-- * @lbl@ is a name component that can be used in multiple names
-- * @skolem@ is a component to differentiate between names which use the
--   same @lbl@
--
-- TODO: rename Win to WinLabel
data Win (lbl :: klbl) (skolem :: Type)

-- | Values of this type describe a window in a sequence of elements.
--
-- A window is an infix of the sequence, and it is described with an
-- offset and a length or size (the number of elements in the window).
--
-- * @elem@ is a type-level name of the elements in the containing sequence (e.g. 'Test.Ouroboros.Consensus.ChainGenerator.Slot.SlotE')
-- * @outer@ is a type-level name identifying the containing sequence (e.g. @Win (Lbl HonestLbl) skolem1@)
-- * @inner@ is a type-level name for the window that the value describes (e.g. @Win (Lbl ScgLbl) skolem2@)
--
-- Note that nothing is said about the containing sequence other
-- than its type name.
--
-- TODO: rename Contains to Window
data Contains (elem :: kelem) (outer :: Type) (inner :: Type) =
    UnsafeContains
        !(Index outer elem)   -- ^ index of the start of the window as
                              -- an offset in the containing sequence.
        !(Size  inner elem)   -- ^ size of the window
                              -- INVARIANT: does not reach past the end of the containing
                              -- sequence (whatever that end is)
  deriving (Contains elem outer inner -> Contains elem outer inner -> Bool
(Contains elem outer inner -> Contains elem outer inner -> Bool)
-> (Contains elem outer inner -> Contains elem outer inner -> Bool)
-> Eq (Contains elem outer inner)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall kelem (elem :: kelem) outer inner.
Contains elem outer inner -> Contains elem outer inner -> Bool
$c== :: forall kelem (elem :: kelem) outer inner.
Contains elem outer inner -> Contains elem outer inner -> Bool
== :: Contains elem outer inner -> Contains elem outer inner -> Bool
$c/= :: forall kelem (elem :: kelem) outer inner.
Contains elem outer inner -> Contains elem outer inner -> Bool
/= :: Contains elem outer inner -> Contains elem outer inner -> Bool
Eq, ReadPrec [Contains elem outer inner]
ReadPrec (Contains elem outer inner)
Int -> ReadS (Contains elem outer inner)
ReadS [Contains elem outer inner]
(Int -> ReadS (Contains elem outer inner))
-> ReadS [Contains elem outer inner]
-> ReadPrec (Contains elem outer inner)
-> ReadPrec [Contains elem outer inner]
-> Read (Contains elem outer inner)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall kelem (elem :: kelem) outer inner.
ReadPrec [Contains elem outer inner]
forall kelem (elem :: kelem) outer inner.
ReadPrec (Contains elem outer inner)
forall kelem (elem :: kelem) outer inner.
Int -> ReadS (Contains elem outer inner)
forall kelem (elem :: kelem) outer inner.
ReadS [Contains elem outer inner]
$creadsPrec :: forall kelem (elem :: kelem) outer inner.
Int -> ReadS (Contains elem outer inner)
readsPrec :: Int -> ReadS (Contains elem outer inner)
$creadList :: forall kelem (elem :: kelem) outer inner.
ReadS [Contains elem outer inner]
readList :: ReadS [Contains elem outer inner]
$creadPrec :: forall kelem (elem :: kelem) outer inner.
ReadPrec (Contains elem outer inner)
readPrec :: ReadPrec (Contains elem outer inner)
$creadListPrec :: forall kelem (elem :: kelem) outer inner.
ReadPrec [Contains elem outer inner]
readListPrec :: ReadPrec [Contains elem outer inner]
Read, Int -> Contains elem outer inner -> ShowS
[Contains elem outer inner] -> ShowS
Contains elem outer inner -> String
(Int -> Contains elem outer inner -> ShowS)
-> (Contains elem outer inner -> String)
-> ([Contains elem outer inner] -> ShowS)
-> Show (Contains elem outer inner)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall kelem (elem :: kelem) outer inner.
Int -> Contains elem outer inner -> ShowS
forall kelem (elem :: kelem) outer inner.
[Contains elem outer inner] -> ShowS
forall kelem (elem :: kelem) outer inner.
Contains elem outer inner -> String
$cshowsPrec :: forall kelem (elem :: kelem) outer inner.
Int -> Contains elem outer inner -> ShowS
showsPrec :: Int -> Contains elem outer inner -> ShowS
$cshow :: forall kelem (elem :: kelem) outer inner.
Contains elem outer inner -> String
show :: Contains elem outer inner -> String
$cshowList :: forall kelem (elem :: kelem) outer inner.
[Contains elem outer inner] -> ShowS
showList :: [Contains elem outer inner] -> ShowS
Show)

pattern Contains :: Index outer elem -> Size inner elem -> Contains elem outer inner
pattern $mContains :: forall {r} {kelem} {outer} {elem :: kelem} {inner}.
Contains elem outer inner
-> (Index outer elem -> Size inner elem -> r) -> ((# #) -> r) -> r
Contains x y <- UnsafeContains x y

{-# COMPLETE Contains #-}

forgetWindow :: Contains elem outer inner -> Some.Forgotten (Index outer elem, Index outer elem)
forgetWindow :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner
-> Forgotten (Index outer elem, Index outer elem)
forgetWindow Contains elem outer inner
win = (Index outer elem, Index outer elem)
-> Forgotten (Index outer elem, Index outer elem)
forall a. a -> Forgotten a
Some.forgotten (Contains elem outer inner -> Index outer elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index outer elem
windowStart Contains elem outer inner
win, Contains elem outer inner -> Index outer elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index outer elem
windowLast Contains elem outer inner
win)

-- | Converts an index of a window into an index in the containing sequence.
fromWindow :: Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow (Contains (Count Int
i) Size inner elem
_n) (Count Int
j) = Int -> Count outer elem Preds
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int
i Int -> Int -> Int
.+ Int
j)

-- | Converts a count of elements in a window to a count of elements in the
-- containing sequence.
fromWindowVar :: Contains elem outer inner -> Var inner x -> Var outer x
fromWindowVar :: forall {kelem} {kelem} (elem :: kelem) outer inner (x :: kelem).
Contains elem outer inner -> Var inner x -> Var outer x
fromWindowVar Contains elem outer inner
_ (Count Int
x) = Int -> Count outer x Other
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
x

toWindow :: Contains elem outer inner -> Index outer elem -> Maybe (Index inner elem)
{-# INLINE toWindow #-}
toWindow :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner
-> Index outer elem -> Maybe (Index inner elem)
toWindow (Contains (Count Int
i) (Count Int
n)) (Count Int
j) = if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
j Bool -> Bool -> Bool
&& Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
i Int -> Int -> Int
.+ Int
n then Index inner elem -> Maybe (Index inner elem)
forall a. a -> Maybe a
Just (Int -> Index inner elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int
j Int -> Int -> Int
.- Int
i)) else Maybe (Index inner elem)
forall a. Maybe a
Nothing

toWindowVar :: Contains elem outer inner -> Var outer x -> Var inner x
toWindowVar :: forall {kelem} {kelem} (elem :: kelem) outer inner (x :: kelem).
Contains elem outer inner -> Var outer x -> Var inner x
toWindowVar Contains elem outer inner
_ (Count Int
x) = Int -> Count inner x Other
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
x

windowSize :: Contains elem outer inner -> Size inner elem
windowSize :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Size inner elem
windowSize (Contains Index outer elem
_i (Count Int
n)) = Int -> Count inner elem Total
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
n

windowStart :: Contains elem outer inner -> Index outer elem
windowStart :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index outer elem
windowStart Contains elem outer inner
win = Contains elem outer inner -> Index inner elem -> Index outer elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow Contains elem outer inner
win (Int -> Index inner elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
0)

windowLast :: Contains elem outer inner -> Index outer elem
windowLast :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index outer elem
windowLast Contains elem outer inner
win = Contains elem outer inner -> Index inner elem -> Index outer elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow Contains elem outer inner
win (Index inner elem -> Index outer elem)
-> Index inner elem -> Index outer elem
forall a b. (a -> b) -> a -> b
$ Size inner elem -> Index inner elem
forall {kelem} base (elem :: kelem).
Size base elem -> Index base elem
lastIndex (Size inner elem -> Index inner elem)
-> Size inner elem -> Index inner elem
forall a b. (a -> b) -> a -> b
$ Contains elem outer inner -> Size inner elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Size inner elem
windowSize Contains elem outer inner
win

truncateWin :: Contains elem outer inner -> Size inner elem -> Contains elem outer inner
truncateWin :: forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner
-> Size inner elem -> Contains elem outer inner
truncateWin (UnsafeContains Index outer elem
start Size inner elem
len) Size inner elem
x = Index outer elem -> Size inner elem -> Contains elem outer inner
forall kelem (elem :: kelem) outer inner.
Index outer elem -> Size inner elem -> Contains elem outer inner
UnsafeContains Index outer elem
start (Size inner elem -> Size inner elem -> Size inner elem
forall a. Ord a => a -> a -> a
min Size inner elem
len Size inner elem
x)

-- | 'Contains' is a 'Data.Semigroupoid.Semigroupoid'
joinWin :: Contains elem outer mid -> Contains elem mid inner -> Contains elem outer inner
{-# INLINE joinWin #-}
joinWin :: forall {kelem} (elem :: kelem) outer mid inner.
Contains elem outer mid
-> Contains elem mid inner -> Contains elem outer inner
joinWin Contains elem outer mid
win Contains elem mid inner
win2 = Index outer elem -> Size inner elem -> Contains elem outer inner
forall kelem (elem :: kelem) outer inner.
Index outer elem -> Size inner elem -> Contains elem outer inner
UnsafeContains (Contains elem outer mid -> Index mid elem -> Index outer elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow Contains elem outer mid
win (Index mid elem -> Index outer elem)
-> Index mid elem -> Index outer elem
forall a b. (a -> b) -> a -> b
$ Contains elem mid inner -> Index mid elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index outer elem
windowStart Contains elem mid inner
win2) (Contains elem mid inner -> Size inner elem
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Size inner elem
windowSize Contains elem mid inner
win2)

data SomeWindow (lbl :: klbl) (outer :: Type) (elem :: kelem) =
    forall (skolem :: Type).
    SomeWindow
        !(Proxy skolem)
        !(Contains elem outer (Win lbl skolem))

instance Eq (SomeWindow lbl outer elem) where
    SomeWindow Proxy skolem
_l1 Contains elem outer (Win lbl skolem)
l2 == :: SomeWindow lbl outer elem -> SomeWindow lbl outer elem -> Bool
== SomeWindow Proxy skolem
_r1 Contains elem outer (Win lbl skolem)
r2 =
      Contains elem outer (Win lbl skolem)
-> Forgotten (Index outer elem, Index outer elem)
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner
-> Forgotten (Index outer elem, Index outer elem)
forgetWindow Contains elem outer (Win lbl skolem)
l2 Forgotten (Index outer elem, Index outer elem)
-> Forgotten (Index outer elem, Index outer elem) -> Bool
forall a. Eq a => a -> a -> Bool
== Contains elem outer (Win lbl skolem)
-> Forgotten (Index outer elem, Index outer elem)
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner
-> Forgotten (Index outer elem, Index outer elem)
forgetWindow Contains elem outer (Win lbl skolem)
r2

instance Show (SomeWindow lbl outer elem) where
    showsPrec :: Int -> SomeWindow lbl outer elem -> ShowS
showsPrec Int
p (SomeWindow Proxy skolem
prx Contains elem outer (Win lbl skolem)
win) =
        Int -> ShowBuilder (SomeWindow lbl outer elem) -> ShowS
forall a.
NoFun "runShowsPrec" a (AbsError "runShowsPrec" a) =>
Int -> ShowBuilder a -> ShowS
Some.runShowsPrec Int
p
      (ShowBuilder (SomeWindow lbl outer elem) -> ShowS)
-> ShowBuilder (SomeWindow lbl outer elem) -> ShowS
forall a b. (a -> b) -> a -> b
$ (Proxy skolem
 -> Contains elem outer (Win lbl skolem)
 -> SomeWindow lbl outer elem)
-> String
-> ShowBuilder
     (Proxy skolem
      -> Contains elem outer (Win lbl skolem)
      -> SomeWindow lbl outer elem)
forall a. a -> String -> ShowBuilder a
Some.showCtor Proxy skolem
-> Contains elem outer (Win lbl skolem)
-> SomeWindow lbl outer elem
forall klbl kelem (lbl :: klbl) outer (elem :: kelem) skolem.
Proxy skolem
-> Contains elem outer (Win lbl skolem)
-> SomeWindow lbl outer elem
SomeWindow String
"SomeWindow"
          ShowBuilder
  (Proxy skolem
   -> Contains elem outer (Win lbl skolem)
   -> SomeWindow lbl outer elem)
-> Proxy skolem
-> ShowBuilder
     (Contains elem outer (Win lbl skolem) -> SomeWindow lbl outer elem)
forall a b. Show a => ShowBuilder (a -> b) -> a -> ShowBuilder b
`Some.showArg` Proxy skolem
prx
          ShowBuilder
  (Contains elem outer (Win lbl skolem) -> SomeWindow lbl outer elem)
-> Contains elem outer (Win lbl skolem)
-> ShowBuilder (SomeWindow lbl outer elem)
forall a b. Show a => ShowBuilder (a -> b) -> a -> ShowBuilder b
`Some.showArg` Contains elem outer (Win lbl skolem)
win

instance Read (SomeWindow lbl outer elem) where
    readPrec :: ReadPrec (SomeWindow lbl outer elem)
readPrec =
        ReadBuilder (SomeWindow lbl outer elem)
-> ReadPrec (SomeWindow lbl outer elem)
forall a.
NoFun "runReadPrec" a (AbsError "runReadPrec" a) =>
ReadBuilder a -> ReadPrec a
Some.runReadPrec
      (ReadBuilder (SomeWindow lbl outer elem)
 -> ReadPrec (SomeWindow lbl outer elem))
-> ReadBuilder (SomeWindow lbl outer elem)
-> ReadPrec (SomeWindow lbl outer elem)
forall a b. (a -> b) -> a -> b
$ (Proxy Any
 -> Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem)
-> String
-> ReadBuilder
     (Proxy Any
      -> Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem)
forall a. a -> String -> ReadBuilder a
Some.readCtor Proxy Any
-> Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem
forall klbl kelem (lbl :: klbl) outer (elem :: kelem) skolem.
Proxy skolem
-> Contains elem outer (Win lbl skolem)
-> SomeWindow lbl outer elem
SomeWindow String
"SomeWindow"
          ReadBuilder
  (Proxy Any
   -> Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem)
-> ReadBuilder (Proxy Any)
-> ReadBuilder
     (Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem)
forall a b. ReadBuilder (a -> b) -> ReadBuilder a -> ReadBuilder b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadBuilder (Proxy Any)
forall a. Read a => ReadBuilder a
Some.readArg
          ReadBuilder
  (Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem)
-> ReadBuilder (Contains elem outer (Win lbl Any))
-> ReadBuilder (SomeWindow lbl outer elem)
forall a b. ReadBuilder (a -> b) -> ReadBuilder a -> ReadBuilder b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ReadBuilder (Contains elem outer (Win lbl Any))
forall a. Read a => ReadBuilder a
Some.readArg

-- | @withWindow outerSz lbl offset innerSz@ is a window of length @innerSz@
-- with name @lbl@ starting at @offset@ in a sequence with length @outerSz@.
--
-- If the window doesn't fit in the containing sequence, it is clipped so the
-- resulting (possibly empty) window is contained.
--
-- Note that the window can spill either on the right if @i + innerSz > outerSz@,
-- or it can spill on the left if @i < 0@, or it can spill on both sides
-- simultaneously.
--
withWindow :: Size outer elem -> Lbl lbl -> Index outer elem -> Size x elem -> SomeWindow lbl outer elem
withWindow :: forall {kelem} {klbl} outer (elem :: kelem) (lbl :: klbl) x.
Size outer elem
-> Lbl lbl
-> Index outer elem
-> Size x elem
-> SomeWindow lbl outer elem
withWindow (Count Int
n) Lbl lbl
_lbl (Count Int
i) (Count Int
m) =
    Proxy Any
-> Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem
forall klbl kelem (lbl :: klbl) outer (elem :: kelem) skolem.
Proxy skolem
-> Contains elem outer (Win lbl skolem)
-> SomeWindow lbl outer elem
SomeWindow Proxy Any
forall {k} (t :: k). Proxy t
Proxy (Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem)
-> Contains elem outer (Win lbl Any) -> SomeWindow lbl outer elem
forall a b. (a -> b) -> a -> b
$ Count outer elem Preds
-> Size (Win lbl Any) elem -> Contains elem outer (Win lbl Any)
forall kelem (elem :: kelem) outer inner.
Index outer elem -> Size inner elem -> Contains elem outer inner
UnsafeContains (Int -> Count outer elem Preds
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
i') (Int -> Size (Win lbl Any) elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
m')
  where
    i' :: Int
i' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
n (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
i)

    -- we compute the elements that fall outside the containing sequence
    precedingElements :: Int
precedingElements = Int
i' Int -> Int -> Int
.- Int
i
    trailingElements :: Int
trailingElements = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Int
.+ Int
m Int -> Int -> Int
.- Int
n

    m' :: Int
m' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
m Int -> Int -> Int
.- Int
precedingElements Int -> Int -> Int
.- Int
trailingElements

-- | @withWindowBetween outerSz lbl i j@ is the window between indices @i@
-- and @j@ with name @lbl@ in a containing sequence of length @outerSz@.
withWindowBetween :: Size outer elem -> Lbl lbl -> Index outer elem -> Index outer elem -> SomeWindow lbl outer elem
withWindowBetween :: forall {kelem} {klbl} outer (elem :: kelem) (lbl :: klbl).
Size outer elem
-> Lbl lbl
-> Index outer elem
-> Index outer elem
-> SomeWindow lbl outer elem
withWindowBetween Size outer elem
n Lbl lbl
lbl (Count Int
i) (Count Int
j) = Size outer elem
-> Lbl lbl
-> Count outer elem Preds
-> Size Any elem
-> SomeWindow lbl outer elem
forall {kelem} {klbl} outer (elem :: kelem) (lbl :: klbl) x.
Size outer elem
-> Lbl lbl
-> Index outer elem
-> Size x elem
-> SomeWindow lbl outer elem
withWindow Size outer elem
n Lbl lbl
lbl (Int -> Count outer elem Preds
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
i) (Int -> Size Any elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int -> Size Any elem) -> Int -> Size Any elem
forall a b. (a -> b) -> a -> b
$ Int
j Int -> Int -> Int
.- Int
i Int -> Int -> Int
.+ Int
1)

-- | @withSuffixWindow outerSz lbl i@ is the window between indices @i@ and the
-- end of the containing sequence of length @outerSz@ with name @lbl@.
withSuffixWindow :: Size outer elem -> Lbl lbl -> Index outer elem -> SomeWindow lbl outer elem
withSuffixWindow :: forall {kelem} {klbl} outer (elem :: kelem) (lbl :: klbl).
Size outer elem
-> Lbl lbl -> Index outer elem -> SomeWindow lbl outer elem
withSuffixWindow Size outer elem
n Lbl lbl
lbl Index outer elem
i = Size outer elem
-> Lbl lbl
-> Index outer elem
-> Size Any elem
-> SomeWindow lbl outer elem
forall {kelem} {klbl} outer (elem :: kelem) (lbl :: klbl) x.
Size outer elem
-> Lbl lbl
-> Index outer elem
-> Size x elem
-> SomeWindow lbl outer elem
withWindow Size outer elem
n Lbl lbl
lbl Index outer elem
i (Int -> Size Any elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int -> Size Any elem) -> Int -> Size Any elem
forall a b. (a -> b) -> a -> b
$ Size outer elem -> Int
forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Int
getCount Size outer elem
n Int -> Int -> Int
.- Index outer elem -> Int
forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Int
getCount Index outer elem
i)

-- | @withTopWindow lbl sz k@ passes to @k@ a window of size @sz@ with name
-- @lbl@ at offset @0@ of some containing sequence with a unique name @base@.
withTopWindow ::
     Lbl lbl
  -> Int
  -> (forall base. Proxy base -> SomeWindow lbl base elem -> ans)
  -> ans
withTopWindow :: forall {k} {k} (lbl :: k) (elem :: k) ans.
Lbl lbl
-> Int
-> (forall base. Proxy base -> SomeWindow lbl base elem -> ans)
-> ans
withTopWindow Lbl lbl
_lbl Int
n forall base. Proxy base -> SomeWindow lbl base elem -> ans
k =
      Proxy Any -> SomeWindow lbl Any elem -> ans
forall base. Proxy base -> SomeWindow lbl base elem -> ans
k Proxy Any
forall {k} (t :: k). Proxy t
Proxy (SomeWindow lbl Any elem -> ans) -> SomeWindow lbl Any elem -> ans
forall a b. (a -> b) -> a -> b
$ Proxy Any
-> Contains elem Any (Win lbl Any) -> SomeWindow lbl Any elem
forall klbl kelem (lbl :: klbl) outer (elem :: kelem) skolem.
Proxy skolem
-> Contains elem outer (Win lbl skolem)
-> SomeWindow lbl outer elem
SomeWindow Proxy Any
forall {k} (t :: k). Proxy t
Proxy (Contains elem Any (Win lbl Any) -> SomeWindow lbl Any elem)
-> Contains elem Any (Win lbl Any) -> SomeWindow lbl Any elem
forall a b. (a -> b) -> a -> b
$ Index Any elem
-> Size (Win lbl Any) elem -> Contains elem Any (Win lbl Any)
forall kelem (elem :: kelem) outer inner.
Index outer elem -> Size inner elem -> Contains elem outer inner
UnsafeContains (Int -> Index Any elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
0) (Int -> Size (Win lbl Any) elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
n)

-----

-- | Same indices as 'Index' and 'Size'
newtype Vector base elem a = Vector (V.Vector a)
  deriving (Vector base elem a -> Vector base elem a -> Bool
(Vector base elem a -> Vector base elem a -> Bool)
-> (Vector base elem a -> Vector base elem a -> Bool)
-> Eq (Vector base elem a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k (base :: k) k (elem :: k) a.
(Unbox a, Eq a) =>
Vector base elem a -> Vector base elem a -> Bool
$c== :: forall k (base :: k) k (elem :: k) a.
(Unbox a, Eq a) =>
Vector base elem a -> Vector base elem a -> Bool
== :: Vector base elem a -> Vector base elem a -> Bool
$c/= :: forall k (base :: k) k (elem :: k) a.
(Unbox a, Eq a) =>
Vector base elem a -> Vector base elem a -> Bool
/= :: Vector base elem a -> Vector base elem a -> Bool
Eq, ReadPrec [Vector base elem a]
ReadPrec (Vector base elem a)
Int -> ReadS (Vector base elem a)
ReadS [Vector base elem a]
(Int -> ReadS (Vector base elem a))
-> ReadS [Vector base elem a]
-> ReadPrec (Vector base elem a)
-> ReadPrec [Vector base elem a]
-> Read (Vector base elem a)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
ReadPrec [Vector base elem a]
forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
ReadPrec (Vector base elem a)
forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
Int -> ReadS (Vector base elem a)
forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
ReadS [Vector base elem a]
$creadsPrec :: forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
Int -> ReadS (Vector base elem a)
readsPrec :: Int -> ReadS (Vector base elem a)
$creadList :: forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
ReadS [Vector base elem a]
readList :: ReadS [Vector base elem a]
$creadPrec :: forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
ReadPrec (Vector base elem a)
readPrec :: ReadPrec (Vector base elem a)
$creadListPrec :: forall k (base :: k) k (elem :: k) a.
(Read a, Unbox a) =>
ReadPrec [Vector base elem a]
readListPrec :: ReadPrec [Vector base elem a]
Read, Int -> Vector base elem a -> ShowS
[Vector base elem a] -> ShowS
Vector base elem a -> String
(Int -> Vector base elem a -> ShowS)
-> (Vector base elem a -> String)
-> ([Vector base elem a] -> ShowS)
-> Show (Vector base elem a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k (base :: k) k (elem :: k) a.
(Show a, Unbox a) =>
Int -> Vector base elem a -> ShowS
forall k (base :: k) k (elem :: k) a.
(Show a, Unbox a) =>
[Vector base elem a] -> ShowS
forall k (base :: k) k (elem :: k) a.
(Show a, Unbox a) =>
Vector base elem a -> String
$cshowsPrec :: forall k (base :: k) k (elem :: k) a.
(Show a, Unbox a) =>
Int -> Vector base elem a -> ShowS
showsPrec :: Int -> Vector base elem a -> ShowS
$cshow :: forall k (base :: k) k (elem :: k) a.
(Show a, Unbox a) =>
Vector base elem a -> String
show :: Vector base elem a -> String
$cshowList :: forall k (base :: k) k (elem :: k) a.
(Show a, Unbox a) =>
[Vector base elem a] -> ShowS
showList :: [Vector base elem a] -> ShowS
Show)

instance (QC.Arbitrary a, V.Unbox a) => QC.Arbitrary (Vector base elem a) where
    arbitrary :: Gen (Vector base elem a)
arbitrary = (Vector a -> Vector base elem a
forall {k} {k} (base :: k) (elem :: k) a.
Vector a -> Vector base elem a
Vector (Vector a -> Vector base elem a)
-> ([a] -> Vector a) -> [a] -> Vector base elem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. Unbox a => [a] -> Vector a
V.fromList) ([a] -> Vector base elem a) -> Gen [a] -> Gen (Vector base elem a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen [a]
forall a. Arbitrary a => Gen a
QC.arbitrary
    shrink :: Vector base elem a -> [Vector base elem a]
shrink    = ([a] -> Vector base elem a) -> [[a]] -> [Vector base elem a]
forall a b. (a -> b) -> [a] -> [b]
map (Vector a -> Vector base elem a
forall {k} {k} (base :: k) (elem :: k) a.
Vector a -> Vector base elem a
Vector (Vector a -> Vector base elem a)
-> ([a] -> Vector a) -> [a] -> Vector base elem a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Vector a
forall a. Unbox a => [a] -> Vector a
V.fromList) ([[a]] -> [Vector base elem a])
-> (Vector base elem a -> [[a]])
-> Vector base elem a
-> [Vector base elem a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [[a]]
forall a. Arbitrary a => a -> [a]
QC.shrink ([a] -> [[a]])
-> (Vector base elem a -> [a]) -> Vector base elem a -> [[a]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> [a]
forall a. Unbox a => Vector a -> [a]
V.toList (Vector a -> [a])
-> (Vector base elem a -> Vector a) -> Vector base elem a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector base elem a -> Vector a
forall {k} {k} (base :: k) (elem :: k) a.
Vector base elem a -> Vector a
getVector

getVector :: Vector base elem a -> V.Vector a
getVector :: forall {k} {k} (base :: k) (elem :: k) a.
Vector base elem a -> Vector a
getVector (Vector Vector a
v) = Vector a
v

lengthV :: V.Unbox a => Vector base elem a -> Size base elem
lengthV :: forall {kelem} a base (elem :: kelem).
Unbox a =>
Vector base elem a -> Size base elem
lengthV = Int -> Count base elem Total
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int -> Count base elem Total)
-> (Vector base elem a -> Int)
-> Vector base elem a
-> Count base elem Total
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> Int
forall a. Unbox a => Vector a -> Int
V.length (Vector a -> Int)
-> (Vector base elem a -> Vector a) -> Vector base elem a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector base elem a -> Vector a
forall {k} {k} (base :: k) (elem :: k) a.
Vector base elem a -> Vector a
getVector

sliceV :: MV.Unbox a => Contains elem outer inner -> Vector outer elem a -> Vector inner elem a
{-# INLINE sliceV #-}
sliceV :: forall {k} a (elem :: k) outer inner.
Unbox a =>
Contains elem outer inner
-> Vector outer elem a -> Vector inner elem a
sliceV Contains elem outer inner
win (Vector Vector a
v) =
    Vector a -> Vector inner elem a
forall {k} {k} (base :: k) (elem :: k) a.
Vector a -> Vector base elem a
Vector (Vector a -> Vector inner elem a)
-> Vector a -> Vector inner elem a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Vector a -> Vector a
forall a. Unbox a => Int -> Int -> Vector a -> Vector a
V.slice Int
i Int
n Vector a
v
  where
    Count Int
i = Contains elem outer inner
-> Index inner elem -> Count outer elem Preds
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow Contains elem outer inner
win (Int -> Index inner elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
0)
    Count Int
n = Contains elem outer inner -> Count inner elem Total
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Size inner elem
windowSize Contains elem outer inner
win

unsafeThawV :: MV.Unbox a => Vector base elem a -> ST s (MVector base elem s a)
unsafeThawV :: forall {k} {k} a (base :: k) (elem :: k) s.
Unbox a =>
Vector base elem a -> ST s (MVector base elem s a)
unsafeThawV (Vector Vector a
v) = MVector s a -> MVector base elem s a
forall {k} {k} (base :: k) (elem :: k) s a.
MVector s a -> MVector base elem s a
MVector (MVector s a -> MVector base elem s a)
-> ST s (MVector s a) -> ST s (MVector base elem s a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vector a -> ST s (MVector (PrimState (ST s)) a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Vector a -> m (MVector (PrimState m) a)
V.unsafeThaw Vector a
v

createV :: MV.Unbox a => (forall s. ST s (MVector base elem s a)) -> Vector base elem a
createV :: forall {k} {k} a (base :: k) (elem :: k).
Unbox a =>
(forall s. ST s (MVector base elem s a)) -> Vector base elem a
createV forall s. ST s (MVector base elem s a)
m = Vector a -> Vector base elem a
forall {k} {k} (base :: k) (elem :: k) a.
Vector a -> Vector base elem a
Vector (Vector a -> Vector base elem a) -> Vector a -> Vector base elem a
forall a b. (a -> b) -> a -> b
$ (forall s. ST s (MVector s a)) -> Vector a
forall a. Unbox a => (forall s. ST s (MVector s a)) -> Vector a
V.create (MVector base elem s a -> MVector s a
forall {k} {k} (base :: k) (elem :: k) s a.
MVector base elem s a -> MVector s a
getMVector (MVector base elem s a -> MVector s a)
-> ST s (MVector base elem s a) -> ST s (MVector s a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ST s (MVector base elem s a)
forall s. ST s (MVector base elem s a)
m)

-- | A type-indexed vector carrying values of a container
--
-- * @base@ is a type-level name identifying the container (e.g. @Win (Lbl HonestLbl) skolem1@)
-- * @elem@ is a type-level name of the elements in the container (e.g. 'Test.Ouroboros.Consensus.ChainGenerator.Slot.SlotE')
--
newtype MVector base elem s a = MVector (MV.MVector s a)

getMVector :: MVector base elem s a -> MV.MVector s a
getMVector :: forall {k} {k} (base :: k) (elem :: k) s a.
MVector base elem s a -> MVector s a
getMVector (MVector MVector s a
mv) = MVector s a
mv

lengthMV :: MV.Unbox a => MVector base elem s a -> Size base elem
lengthMV :: forall {kelem} a base (elem :: kelem) s.
Unbox a =>
MVector base elem s a -> Size base elem
lengthMV = Int -> Count base elem Total
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count (Int -> Count base elem Total)
-> (MVector base elem s a -> Int)
-> MVector base elem s a
-> Count base elem Total
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVector s a -> Int
forall a s. Unbox a => MVector s a -> Int
MV.length (MVector s a -> Int)
-> (MVector base elem s a -> MVector s a)
-> MVector base elem s a
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVector base elem s a -> MVector s a
forall {k} {k} (base :: k) (elem :: k) s a.
MVector base elem s a -> MVector s a
getMVector

sliceMV :: MV.Unbox a => Contains elem outer inner -> MVector outer elem s a -> MVector inner elem s a
{-# INLINE sliceMV #-}
sliceMV :: forall {k} a (elem :: k) outer inner s.
Unbox a =>
Contains elem outer inner
-> MVector outer elem s a -> MVector inner elem s a
sliceMV Contains elem outer inner
win (MVector MVector s a
mv) =
    MVector s a -> MVector inner elem s a
forall {k} {k} (base :: k) (elem :: k) s a.
MVector s a -> MVector base elem s a
MVector (MVector s a -> MVector inner elem s a)
-> MVector s a -> MVector inner elem s a
forall a b. (a -> b) -> a -> b
$ Int -> Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
MV.slice Int
i Int
n MVector s a
mv
  where
    Count Int
i = Contains elem outer inner
-> Index inner elem -> Count outer elem Preds
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Index inner elem -> Index outer elem
fromWindow Contains elem outer inner
win (Int -> Index inner elem
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
0)
    Count Int
n = Contains elem outer inner -> Count inner elem Total
forall {kelem} (elem :: kelem) outer inner.
Contains elem outer inner -> Size inner elem
windowSize Contains elem outer inner
win

replicateMV :: MV.Unbox a => Size base elem -> ST s a -> ST s (MVector base elem s a)
replicateMV :: forall {k} a base (elem :: k) s.
Unbox a =>
Size base elem -> ST s a -> ST s (MVector base elem s a)
replicateMV (Count Int
n) ST s a
m = (MVector s a -> MVector base elem s a)
-> ST s (MVector s a) -> ST s (MVector base elem s a)
forall a b. (a -> b) -> ST s a -> ST s b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MVector s a -> MVector base elem s a
forall {k} {k} (base :: k) (elem :: k) s a.
MVector s a -> MVector base elem s a
MVector (ST s (MVector s a) -> ST s (MVector base elem s a))
-> ST s (MVector s a) -> ST s (MVector base elem s a)
forall a b. (a -> b) -> a -> b
$ Int -> ST s a -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m a -> m (MVector (PrimState m) a)
MV.replicateM Int
n ST s a
m

readMV   :: MV.Unbox a => MVector base elem s a ->             Index base elem ->      ST s a
writeMV  :: MV.Unbox a => MVector base elem s a ->             Index base elem -> a -> ST s ()
modifyMV :: MV.Unbox a => MVector base elem s a -> (a -> a) -> Index base elem ->      ST s ()

readMV :: forall {kelem} a base (elem :: kelem) s.
Unbox a =>
MVector base elem s a -> Index base elem -> ST s a
readMV   (MVector MVector s a
mv)   (Count Int
i)   = MVector (PrimState (ST s)) a -> Int -> ST s a
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
MV.read   MVector s a
MVector (PrimState (ST s)) a
mv Int
i
writeMV :: forall {kelem} a base (elem :: kelem) s.
Unbox a =>
MVector base elem s a -> Index base elem -> a -> ST s ()
writeMV  (MVector MVector s a
mv)   (Count Int
i) a
x = MVector (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
MV.write  MVector s a
MVector (PrimState (ST s)) a
mv Int
i a
x
modifyMV :: forall {kelem} a base (elem :: kelem) s.
Unbox a =>
MVector base elem s a -> (a -> a) -> Index base elem -> ST s ()
modifyMV (MVector MVector s a
mv) a -> a
f (Count Int
i)   = MVector (PrimState (ST s)) a -> (a -> a) -> Int -> ST s ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> (a -> a) -> Int -> m ()
MV.modify MVector s a
MVector (PrimState (ST s)) a
mv a -> a
f Int
i

readV :: MV.Unbox a => Vector base elem a -> Index base elem -> a
readV :: forall {kelem} a base (elem :: kelem).
Unbox a =>
Vector base elem a -> Index base elem -> a
readV (Vector Vector a
v) (Count Int
i) = Vector a
v Vector a -> Int -> a
forall a. Unbox a => Vector a -> Int -> a
V.! Int
i

-----

-- | A type-level name for counting elements without a specific property
data Other

deriving instance (which TypeEq.~~ Other) => Enum (Count base elem which)
deriving instance (which TypeEq.~~ Other) => Num  (Count base elem which)

type Var base elem = Count base elem Other

-- | For initializing a 'Var'
toVar :: Count base elem which -> Var base elem
toVar :: forall {kelem} {kwhich} base (elem :: kelem) (which :: kwhich).
Count base elem which -> Var base elem
toVar (Count Int
n) = Int -> Count base elem Other
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
n

-- | When the 'Var' has become a 'Size'
toSize :: Var base elem -> Size base elem
toSize :: forall {kelem} base (elem :: kelem).
Var base elem -> Size base elem
toSize (Count Int
n) = Int -> Count base elem Total
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
n

-- | When the 'Var' has become a 'Index'
toIndex :: Var base elem -> Index base elem
toIndex :: forall {kelem} base (elem :: kelem).
Var base elem -> Index base elem
toIndex (Count Int
i) = Int -> Count base elem Preds
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
i

-- | A count of things in an element can be lifted to a count of things in a vector
joinVar :: MVector base elem s a -> Var a x -> Var base x
joinVar :: forall {k} {kelem} base (elem :: k) s a (x :: kelem).
MVector base elem s a -> Var a x -> Var base x
joinVar MVector base elem s a
_ = \(Count Int
n) -> Int -> Var base x
forall kelem kwhich base (elem :: kelem) (which :: kwhich).
Int -> Count base elem which
Count Int
n