{-# LANGUAGE BangPatterns      #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs      #-}
{-# LANGUAGE TypeFamilies      #-}

module HaskellWorks.Data.BalancedParens.RangeMin2
  ( RangeMin2(..)
  , mkRangeMin2
  ) where

import Control.DeepSeq
import Data.Int
import GHC.Generics
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.BalancedParens.BalancedParens
import HaskellWorks.Data.BalancedParens.CloseAt
import HaskellWorks.Data.BalancedParens.Enclose
import HaskellWorks.Data.BalancedParens.FindClose
import HaskellWorks.Data.BalancedParens.FindCloseN
import HaskellWorks.Data.BalancedParens.FindOpen
import HaskellWorks.Data.BalancedParens.FindOpenN
import HaskellWorks.Data.BalancedParens.NewCloseAt
import HaskellWorks.Data.BalancedParens.OpenAt
import HaskellWorks.Data.Bits.AllExcess.AllExcess1
import HaskellWorks.Data.Bits.BitLength
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Excess.MinExcess
import HaskellWorks.Data.Excess.MinExcess1
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.RankSelect.Base.Rank0
import HaskellWorks.Data.RankSelect.Base.Rank1
import HaskellWorks.Data.Vector.AsVector64
import Prelude                                         hiding (length)

import qualified Data.Vector                                               as DV
import qualified Data.Vector.Storable                                      as DVS
import qualified HaskellWorks.Data.BalancedParens.Internal.Vector.Storable as DVS

data RangeMin2 a = RangeMin2
  { forall a. RangeMin2 a -> a
rangeMin2BP       :: !a
  , forall a. RangeMin2 a -> Vector Int8
rangeMin2L0Min    :: !(DVS.Vector Int8)
  , forall a. RangeMin2 a -> Vector Int8
rangeMin2L0Excess :: !(DVS.Vector Int8)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L1Min    :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L1Excess :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L2Min    :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L2Excess :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L3Min    :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L3Excess :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L4Min    :: !(DVS.Vector Int16)
  , forall a. RangeMin2 a -> Vector Int16
rangeMin2L4Excess :: !(DVS.Vector Int16)
  } deriving (forall a. NFData a => RangeMin2 a -> ()
forall a. (a -> ()) -> NFData a
rnf :: RangeMin2 a -> ()
$crnf :: forall a. NFData a => RangeMin2 a -> ()
NFData, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (RangeMin2 a) x -> RangeMin2 a
forall a x. RangeMin2 a -> Rep (RangeMin2 a) x
$cto :: forall a x. Rep (RangeMin2 a) x -> RangeMin2 a
$cfrom :: forall a x. RangeMin2 a -> Rep (RangeMin2 a) x
Generic)

factorL0 :: Integral a => a
factorL0 :: forall a. Integral a => a
factorL0 = a
1
{-# INLINE factorL0 #-}

factorL1 :: Integral a => a
factorL1 :: forall a. Integral a => a
factorL1 = a
32
{-# INLINE factorL1 #-}

factorL2 :: Integral a => a
factorL2 :: forall a. Integral a => a
factorL2 = a
32
{-# INLINE factorL2 #-}

factorL3 :: Integral a => a
factorL3 :: forall a. Integral a => a
factorL3 = a
32
{-# INLINE factorL3 #-}

factorL4 :: Integral a => a
factorL4 :: forall a. Integral a => a
factorL4 = a
32
{-# INLINE factorL4 #-}

pageSizeL0 :: Integral a => a
pageSizeL0 :: forall a. Integral a => a
pageSizeL0 = forall a. Integral a => a
factorL0
{-# INLINE pageSizeL0 #-}

pageSizeL1 :: Integral a => a
pageSizeL1 :: forall a. Integral a => a
pageSizeL1 = forall a. Integral a => a
pageSizeL0 forall a. Num a => a -> a -> a
* forall a. Integral a => a
factorL1
{-# INLINE pageSizeL1 #-}

pageSizeL2 :: Integral a => a
pageSizeL2 :: forall a. Integral a => a
pageSizeL2 = forall a. Integral a => a
pageSizeL1 forall a. Num a => a -> a -> a
* forall a. Integral a => a
factorL2
{-# INLINE pageSizeL2 #-}

pageSizeL3 :: Integral a => a
pageSizeL3 :: forall a. Integral a => a
pageSizeL3 = forall a. Integral a => a
pageSizeL2 forall a. Num a => a -> a -> a
* forall a. Integral a => a
factorL3
{-# INLINE pageSizeL3 #-}

pageSizeL4 :: Integral a => a
pageSizeL4 :: forall a. Integral a => a
pageSizeL4 = forall a. Integral a => a
pageSizeL3 forall a. Num a => a -> a -> a
* forall a. Integral a => a
factorL4
{-# INLINE pageSizeL4 #-}

mkRangeMin2 :: AsVector64 a => a -> RangeMin2 a
mkRangeMin2 :: forall a. AsVector64 a => a -> RangeMin2 a
mkRangeMin2 a
bp = RangeMin2
  { rangeMin2BP :: a
rangeMin2BP       = a
bp
  , rangeMin2L0Min :: Vector Int8
rangeMin2L0Min    = forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
DVS.reword Vector Int16
rmL0Min
  , rangeMin2L0Excess :: Vector Int8
rangeMin2L0Excess = forall a b.
(Storable a, Integral a, Storable b, Num b) =>
Vector a -> Vector b
DVS.reword Vector Int16
rmL0Excess
  , rangeMin2L1Min :: Vector Int16
rangeMin2L1Min    = Vector Int16
rmL1Min
  , rangeMin2L1Excess :: Vector Int16
rangeMin2L1Excess = Vector Int16
rmL1Excess
  , rangeMin2L2Min :: Vector Int16
rangeMin2L2Min    = Vector Int16
rmL2Min
  , rangeMin2L2Excess :: Vector Int16
rangeMin2L2Excess = Vector Int16
rmL2Excess
  , rangeMin2L3Min :: Vector Int16
rangeMin2L3Min    = Vector Int16
rmL3Min
  , rangeMin2L3Excess :: Vector Int16
rangeMin2L3Excess = Vector Int16
rmL3Excess
  , rangeMin2L4Min :: Vector Int16
rangeMin2L4Min    = Vector Int16
rmL4Min
  , rangeMin2L4Excess :: Vector Int16
rangeMin2L4Excess = Vector Int16
rmL4Excess
  }
  where bpv :: Vector Count
bpv           = forall a. AsVector64 a => a -> Vector Count
asVector64 a
bp
        lenBP :: Int
lenBP         = forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall v. Length v => v -> Count
length Vector Count
bpv) :: Int
        lenL0 :: Int
lenL0         = Int
lenBP
        lenL1 :: Int
lenL1         = (forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a
pageSizeL1) forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL2 :: Int
lenL2         = (forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a
pageSizeL2) forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL3 :: Int
lenL3         = (forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a
pageSizeL3) forall a. Num a => a -> a -> a
+ Int
1 :: Int
        lenL4 :: Int
lenL4         = (forall a. Storable a => Vector a -> Int
DVS.length Vector Int16
rmL0Min forall a. Integral a => a -> a -> a
`div` forall a. Integral a => a
pageSizeL4) forall a. Num a => a -> a -> a
+ Int
1 :: Int
        allMinL0 :: Vector MinExcess
allMinL0      = forall a. Int -> (Int -> a) -> Vector a
DV.generate  Int
lenL0 (\Int
i -> if Int
i forall a. Eq a => a -> a -> Bool
== Int
lenBP then Int -> Int -> MinExcess
MinExcess (-Int
64) (-Int
64) else forall a. MinExcess1 a => a -> MinExcess
minExcess1 (Vector Count
bpv forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i))
        -- Note: (0xffffffffffffffc0 :: Int64) = -64
        rmL0Excess :: Vector Int16
rmL0Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL0 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL1Excess :: Vector Int16
rmL1Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL1 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL2Excess :: Vector Int16
rmL2Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL2 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL3Excess :: Vector Int16
rmL3Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL3 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL3 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL4Excess :: Vector Int16
rmL4Excess    = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL4 (\Int
i -> forall a b. (Integral a, Num b) => a -> b
fromIntegral (forall a. AllExcess1 a => a -> Int
allExcess1 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
pageSizeL4 Count
0xffffffffffffffc0 Vector Count
bpv))) :: DVS.Vector Int16
        rmL0Min :: Vector Int16
rmL0Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL0 (\Int
i -> let MinExcess Int
minE Int
_ = Vector MinExcess
allMinL0 forall a. Vector a -> Int -> a
DV.! Int
i in forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minE) :: DVS.Vector Int16
        rmL1Min :: Vector Int16
rmL1Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL1 (\Int
i -> forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL1 Int16
0 Vector Int16
rmL0Min) (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL1 Int16
0 Vector Int16
rmL0Excess))
        rmL2Min :: Vector Int16
rmL2Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL2 (\Int
i -> forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL2 Int16
0 Vector Int16
rmL1Min) (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL2 Int16
0 Vector Int16
rmL1Excess))
        rmL3Min :: Vector Int16
rmL3Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL3 (\Int
i -> forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL3 Int16
0 Vector Int16
rmL2Min) (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL3 Int16
0 Vector Int16
rmL2Excess))
        rmL4Min :: Vector Int16
rmL4Min       = forall a. Storable a => Int -> (Int -> a) -> Vector a
DVS.generate Int
lenL4 (\Int
i -> forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin Int16
0 (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL4 Int16
0 Vector Int16
rmL3Min) (forall a. Storable a => Int -> Int -> a -> Vector a -> Vector a
DVS.pageFill Int
i forall a. Integral a => a
factorL4 Int16
0 Vector Int16
rmL3Excess))

genMin :: (Integral a, DVS.Storable a) => a -> DVS.Vector a -> DVS.Vector a -> a
genMin :: forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin a
mL Vector a
mins Vector a
excesses = if Bool -> Bool
not (forall a. Storable a => Vector a -> Bool
DVS.null Vector a
mins) Bool -> Bool -> Bool
|| Bool -> Bool
not (forall a. Storable a => Vector a -> Bool
DVS.null Vector a
excesses)
  then forall a.
(Integral a, Storable a) =>
a -> Vector a -> Vector a -> a
genMin (forall a. (Storable a, Integral a) => Vector a -> a
DVS.lastOrZero Vector a
mins forall a. Ord a => a -> a -> a
`min` (a
mL forall a. Num a => a -> a -> a
+ forall a. (Storable a, Integral a) => Vector a -> a
DVS.lastOrZero Vector a
excesses)) (forall a. Storable a => Vector a -> Vector a
DVS.init Vector a
mins) (forall a. Storable a => Vector a -> Vector a
DVS.init Vector a
excesses)
  else a
mL

data FindState = FindBP
  | FindL0 | FindFromL0
  | FindL1 | FindFromL1
  | FindL2 | FindFromL2
  | FindL3 | FindFromL3
  | FindL4 | FindFromL4

rm2FindClose  :: (BitLength a, NewCloseAt a) => RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose :: forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindBP = if RangeMin2 a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p
  then if Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
    then forall a. a -> Maybe a
Just Count
p
    else forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (Int
s forall a. Num a => a -> a -> a
- Int
1) (Count
p forall a. Num a => a -> a -> a
+ Count
1) FindState
FindFromL0
  else forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (Int
s forall a. Num a => a -> a -> a
+ Int
1) (Count
p forall a. Num a => a -> a -> a
+ Count
1) FindState
FindFromL0
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL0 =
  let i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` Count
64 in
  let mins :: Vector Int8
mins = forall a. RangeMin2 a -> Vector Int8
rangeMin2L0Min RangeMin2 a
v in
  let minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int8
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindBP
    else if RangeMin2 a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
      then forall a. a -> Maybe a
Just Count
p
      else  let excesses :: Vector Int8
excesses  = forall a. RangeMin2 a -> Vector Int8
rangeMin2L0Excess RangeMin2 a
v in
            let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int8
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
            forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ Count
64) FindState
FindFromL0
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL1 =
  let !i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1) in
  let !mins :: Vector Int16
mins = forall a. RangeMin2 a -> Vector Int16
rangeMin2L1Min RangeMin2 a
v in
  let !minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL0
    else if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v
      then if RangeMin2 a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
        then forall a. a -> Maybe a
Just Count
p
        else  let excesses :: Vector Int16
excesses  = forall a. RangeMin2 a -> Vector Int16
rangeMin2L1Excess RangeMin2 a
v in
              let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
              forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1)) FindState
FindFromL1
      else forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL2 =
  let !i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2) in
  let !mins :: Vector Int16
mins = forall a. RangeMin2 a -> Vector Int16
rangeMin2L2Min RangeMin2 a
v in
  let !minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL1
    else if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v
      then if RangeMin2 a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
        then forall a. a -> Maybe a
Just Count
p
        else  let excesses :: Vector Int16
excesses  = forall a. RangeMin2 a -> Vector Int16
rangeMin2L2Excess RangeMin2 a
v in
              let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
              forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2)) FindState
FindFromL2
      else forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL3 =
  let !i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL3) in
  let !mins :: Vector Int16
mins = forall a. RangeMin2 a -> Vector Int16
rangeMin2L3Min RangeMin2 a
v in
  let !minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL2
    else if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v
      then if RangeMin2 a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
        then forall a. a -> Maybe a
Just Count
p
        else  let excesses :: Vector Int16
excesses  = forall a. RangeMin2 a -> Vector Int16
rangeMin2L3Excess RangeMin2 a
v in
              let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
              forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL3)) FindState
FindFromL3
        else forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL4 =
  let !i :: Count
i = Count
p forall a. Integral a => a -> a -> a
`div` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL4) in
  let !mins :: Vector Int16
mins = forall a. RangeMin2 a -> Vector Int16
rangeMin2L4Min RangeMin2 a
v in
  let !minE :: Int
minE = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
mins forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i) :: Int in
  if forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s forall a. Num a => a -> a -> a
+ Int
minE forall a. Ord a => a -> a -> Bool
<= Int
0
    then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL3
    else if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v
      then if RangeMin2 a
v forall v. NewCloseAt v => v -> Count -> Bool
`newCloseAt` Count
p Bool -> Bool -> Bool
&& Int
s forall a. Ord a => a -> a -> Bool
<= Int
1
        then forall a. a -> Maybe a
Just Count
p
        else  let excesses :: Vector Int16
excesses  = forall a. RangeMin2 a -> Vector Int16
rangeMin2L4Excess RangeMin2 a
v in
              let excess :: Int
excess    = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Vector Int16
excesses forall v. AtIndex v => v -> Position -> Elem v
!!! forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
i)  :: Int in
              forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
excess forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
s)) (Count
p forall a. Num a => a -> a -> a
+ (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL4)) FindState
FindFromL4
        else forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL0
  | Count
p forall a. Integral a => a -> a -> a
`mod` Count
64 forall a. Eq a => a -> a -> Bool
== Count
0             = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL1
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v   = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindBP
  | Bool
otherwise                   = forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL1
  | Count
p forall a. Integral a => a -> a -> a
`mod` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL1) forall a. Eq a => a -> a -> Bool
== Count
0  = if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL2 else forall a. Maybe a
Nothing
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v       = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL0
  | Bool
otherwise                       = forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL2
  | Count
p forall a. Integral a => a -> a -> a
`mod` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL2) forall a. Eq a => a -> a -> Bool
== Count
0  = if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL3 else forall a. Maybe a
Nothing
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v       = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL1
  | Bool
otherwise                       = forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL3
  | Count
p forall a. Integral a => a -> a -> a
`mod` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL3) forall a. Eq a => a -> a -> Bool
== Count
0  = if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL4 else forall a. Maybe a
Nothing
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v       = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL2
  | Bool
otherwise                       = forall a. Maybe a
Nothing
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindFromL4
  | Count
p forall a. Integral a => a -> a -> a
`mod` (Count
64 forall a. Num a => a -> a -> a
* forall a. Integral a => a
pageSizeL4) forall a. Eq a => a -> a -> Bool
== Count
0  = if Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v then forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL4 else forall a. Maybe a
Nothing
  | Count
0 forall a. Ord a => a -> a -> Bool
<= Count
p Bool -> Bool -> Bool
&& Count
p forall a. Ord a => a -> a -> Bool
< forall v. BitLength v => v -> Count
bitLength RangeMin2 a
v       = forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v Int
s Count
p FindState
FindL3
  | Bool
otherwise                       = forall a. Maybe a
Nothing
{-# INLINE rm2FindClose #-}

instance TestBit a => TestBit (RangeMin2 a) where
  .?. :: RangeMin2 a -> Position -> Bool
(.?.) = forall a. TestBit a => a -> Position -> Bool
(.?.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE (.?.) #-}

instance Rank1 a => Rank1 (RangeMin2 a) where
  rank1 :: RangeMin2 a -> Count -> Count
rank1 = forall v. Rank1 v => v -> Count -> Count
rank1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE rank1 #-}

instance Rank0 a => Rank0 (RangeMin2 a) where
  rank0 :: RangeMin2 a -> Count -> Count
rank0 = forall v. Rank0 v => v -> Count -> Count
rank0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE rank0 #-}

instance BitLength a => BitLength (RangeMin2 a) where
  bitLength :: RangeMin2 a -> Count
bitLength = forall v. BitLength v => v -> Count
bitLength forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE bitLength #-}

instance OpenAt a => OpenAt (RangeMin2 a) where
  openAt :: RangeMin2 a -> Count -> Bool
openAt = forall v. OpenAt v => v -> Count -> Bool
openAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE openAt #-}

instance CloseAt a => CloseAt (RangeMin2 a) where
  closeAt :: RangeMin2 a -> Count -> Bool
closeAt = forall v. CloseAt v => v -> Count -> Bool
closeAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE closeAt #-}

instance NewCloseAt a => NewCloseAt (RangeMin2 a) where
  newCloseAt :: RangeMin2 a -> Count -> Bool
newCloseAt = forall v. NewCloseAt v => v -> Count -> Bool
newCloseAt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE newCloseAt #-}

instance FindOpenN a => FindOpenN (RangeMin2 a) where
  findOpenN :: RangeMin2 a -> Count -> Count -> Maybe Count
findOpenN = forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RangeMin2 a -> a
rangeMin2BP
  {-# INLINE findOpenN #-}

instance (BitLength a, FindCloseN a, NewCloseAt a) => FindCloseN (RangeMin2 a) where
  findCloseN :: RangeMin2 a -> Count -> Count -> Maybe Count
findCloseN RangeMin2 a
v Count
s Count
p  = (forall a. Num a => a -> a -> a
+ Count
1) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` forall a.
(BitLength a, NewCloseAt a) =>
RangeMin2 a -> Int -> Count -> FindState -> Maybe Count
rm2FindClose RangeMin2 a
v (forall a b. (Integral a, Num b) => a -> b
fromIntegral Count
s) (Count
p forall a. Num a => a -> a -> a
- Count
1) FindState
FindFromL0
  {-# INLINE findCloseN  #-}

instance (BitLength a, NewCloseAt a, CloseAt a, FindCloseN a) => FindClose (RangeMin2 a) where
  findClose :: RangeMin2 a -> Count -> Maybe Count
findClose RangeMin2 a
v Count
p = if RangeMin2 a
v forall v. CloseAt v => v -> Count -> Bool
`closeAt` Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindCloseN v => v -> Count -> Count -> Maybe Count
findCloseN RangeMin2 a
v Count
1 (Count
p forall a. Num a => a -> a -> a
+ Count
1)
  {-# INLINE findClose #-}

instance (OpenAt a, FindOpenN a) => FindOpen (RangeMin2 a) where
  findOpen :: RangeMin2 a -> Count -> Maybe Count
findOpen RangeMin2 a
v Count
p = if RangeMin2 a
v forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then forall a. a -> Maybe a
Just Count
p else forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  RangeMin2 a
v Count
0 (Count
p forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpenN a => Enclose (RangeMin2 a) where
  enclose :: RangeMin2 a -> Count -> Maybe Count
enclose RangeMin2 a
v = forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN RangeMin2 a
v Count
1
  {-# INLINE enclose #-}

instance (BitLength a, NewCloseAt a, CloseAt a, OpenAt a, FindOpenN a, FindCloseN a) => BalancedParens (RangeMin2 a)