module OBDD.VarIntIntMap where

import qualified OBDD.IntIntMap as I
import qualified Data.Map.Strict as M
import Prelude hiding ( lookup )  
  

newtype VarIntIntMap k v = 
    VarIntIntMap ( M.Map k ( I.IntIntMap v ))
    
empty :: VarIntIntMap k v
empty = Map k (IntIntMap v) -> VarIntIntMap k v
forall k v. Map k (IntIntMap v) -> VarIntIntMap k v
VarIntIntMap Map k (IntIntMap v)
forall k a. Map k a
M.empty

lookup :: (k, Key, Key) -> VarIntIntMap k b -> Maybe b
lookup (k
k, Key
i, Key
j) (VarIntIntMap Map k (IntIntMap b)
mm) = do
    IntIntMap b
m <- k -> Map k (IntIntMap b) -> Maybe (IntIntMap b)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
k Map k (IntIntMap b)
mm
    (Key, Key) -> IntIntMap b -> Maybe b
forall b. (Key, Key) -> IntIntMap b -> Maybe b
I.lookup (Key
i, Key
j) IntIntMap b
m

insert :: (k, Key, Key) -> v -> VarIntIntMap k v -> VarIntIntMap k v
insert (k
k, Key
i, Key
j) v
v (VarIntIntMap Map k (IntIntMap v)
mm) = 
    case k -> Map k (IntIntMap v) -> Maybe (IntIntMap v)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup k
k Map k (IntIntMap v)
mm of
        Maybe (IntIntMap v)
Nothing -> Map k (IntIntMap v) -> VarIntIntMap k v
forall k v. Map k (IntIntMap v) -> VarIntIntMap k v
VarIntIntMap 
                   (Map k (IntIntMap v) -> VarIntIntMap k v)
-> Map k (IntIntMap v) -> VarIntIntMap k v
forall a b. (a -> b) -> a -> b
$ k -> IntIntMap v -> Map k (IntIntMap v) -> Map k (IntIntMap v)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert k
k ((Key, Key) -> v -> IntIntMap v
forall v. (Key, Key) -> v -> IntIntMap v
I.singleton (Key
i, Key
j) v
v) Map k (IntIntMap v)
mm
        Just IntIntMap v
m -> Map k (IntIntMap v) -> VarIntIntMap k v
forall k v. Map k (IntIntMap v) -> VarIntIntMap k v
VarIntIntMap           
                   (Map k (IntIntMap v) -> VarIntIntMap k v)
-> Map k (IntIntMap v) -> VarIntIntMap k v
forall a b. (a -> b) -> a -> b
$ k -> IntIntMap v -> Map k (IntIntMap v) -> Map k (IntIntMap v)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert k
k ((Key, Key) -> v -> IntIntMap v -> IntIntMap v
forall v. (Key, Key) -> v -> IntIntMap v -> IntIntMap v
I.insert (Key
i, Key
j) v
v IntIntMap v
m) Map k (IntIntMap v)
mm