module Agda.Utils.IndexMap
(IndexMap, invariant, nil, snoc, append, fromList, update, index)
where
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IntMap
import qualified Data.List as L
import Agda.Utils.Impossible
newtype IndexMap a = IndexMap { forall a. IndexMap a -> IntMap a
indexMap :: IntMap a }
deriving IndexMap a -> IndexMap a -> Bool
(IndexMap a -> IndexMap a -> Bool)
-> (IndexMap a -> IndexMap a -> Bool) -> Eq (IndexMap a)
forall a. Eq a => IndexMap a -> IndexMap a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => IndexMap a -> IndexMap a -> Bool
== :: IndexMap a -> IndexMap a -> Bool
$c/= :: forall a. Eq a => IndexMap a -> IndexMap a -> Bool
/= :: IndexMap a -> IndexMap a -> Bool
Eq
instance Show a => Show (IndexMap a) where
show :: IndexMap a -> String
show !(IndexMap IntMap a
m) =
String
"Agda.Utils.IndexMap.fromList " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [a] -> String
forall a. Show a => a -> String
show (IntMap a -> [a]
forall a. IntMap a -> [a]
IntMap.elems IntMap a
m)
invariant :: IndexMap a -> Bool
invariant :: forall a. IndexMap a -> Bool
invariant !(IndexMap IntMap a
m) = IntMap a -> [Int]
forall a. IntMap a -> [Int]
IntMap.keys IntMap a
m [Int] -> [Int] -> Bool
forall a. Eq a => a -> a -> Bool
== [Int
0 .. IntMap a -> Int
forall a. IntMap a -> Int
IntMap.size IntMap a
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1]
mapIndex :: IndexMap a -> Int -> Int
mapIndex :: forall a. IndexMap a -> Int -> Int
mapIndex !IndexMap a
m !Int
i = IntMap a -> Int
forall a. IntMap a -> Int
IntMap.size (IndexMap a -> IntMap a
forall a. IndexMap a -> IntMap a
indexMap IndexMap a
m) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
inRange :: Int -> IndexMap a -> Bool
inRange :: forall a. Int -> IndexMap a -> Bool
inRange !Int
i !IndexMap a
m = Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< IntMap a -> Int
forall a. IntMap a -> Int
IntMap.size (IndexMap a -> IntMap a
forall a. IndexMap a -> IntMap a
indexMap IndexMap a
m)
nil :: IndexMap a
nil :: forall a. IndexMap a
nil = IntMap a -> IndexMap a
forall a. IntMap a -> IndexMap a
IndexMap IntMap a
forall a. IntMap a
IntMap.empty
snoc :: IndexMap a -> a -> IndexMap a
snoc :: forall a. IndexMap a -> a -> IndexMap a
snoc !(IndexMap IntMap a
m) !a
x = IntMap a -> IndexMap a
forall a. IntMap a -> IndexMap a
IndexMap (Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert (IntMap a -> Int
forall a. IntMap a -> Int
IntMap.size IntMap a
m) a
x IntMap a
m)
append :: IndexMap a -> [a] -> IndexMap a
append :: forall a. IndexMap a -> [a] -> IndexMap a
append !IndexMap a
m ![a]
xs = (IndexMap a -> a -> IndexMap a) -> IndexMap a -> [a] -> IndexMap a
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' IndexMap a -> a -> IndexMap a
forall a. IndexMap a -> a -> IndexMap a
snoc IndexMap a
m [a]
xs
fromList :: [a] -> IndexMap a
fromList :: forall a. [a] -> IndexMap a
fromList = IndexMap a -> [a] -> IndexMap a
forall a. IndexMap a -> [a] -> IndexMap a
append IndexMap a
forall a. IndexMap a
nil
update :: Int -> a -> IndexMap a -> IndexMap a
update :: forall a. Int -> a -> IndexMap a -> IndexMap a
update !Int
i !a
x !IndexMap a
m
| Int -> IndexMap a -> Bool
forall a. Int -> IndexMap a -> Bool
inRange Int
i IndexMap a
m = IntMap a -> IndexMap a
forall a. IntMap a -> IndexMap a
IndexMap (Int -> a -> IntMap a -> IntMap a
forall a. Int -> a -> IntMap a -> IntMap a
IntMap.insert (IndexMap a -> Int -> Int
forall a. IndexMap a -> Int -> Int
mapIndex IndexMap a
m Int
i) a
x (IndexMap a -> IntMap a
forall a. IndexMap a -> IntMap a
indexMap IndexMap a
m))
| Bool
otherwise = IndexMap a
forall a. HasCallStack => a
__IMPOSSIBLE__
index :: Int -> IndexMap a -> a
index :: forall a. Int -> IndexMap a -> a
index !Int
i !IndexMap a
m = case Int -> IntMap a -> Maybe a
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup (IndexMap a -> Int -> Int
forall a. IndexMap a -> Int -> Int
mapIndex IndexMap a
m Int
i) (IndexMap a -> IntMap a
forall a. IndexMap a -> IntMap a
indexMap IndexMap a
m) of
Just a
x -> a
x
Maybe a
Nothing -> a
forall a. HasCallStack => a
__IMPOSSIBLE__