module OBDD.IntIntMap 
       
( IntIntMap ()       
, empty, lookup, insert, singleton, (!)
)  
       
where

import Prelude hiding ( lookup )  
  
import Data.IntMap (IntMap)
import qualified Data.IntMap.Strict as M

newtype IntIntMap v = IntIntMap (IntMap (IntMap v))

empty :: IntIntMap v
empty = IntMap (IntMap v) -> IntIntMap v
forall v. IntMap (IntMap v) -> IntIntMap v
IntIntMap IntMap (IntMap v)
forall a. IntMap a
M.empty

singleton :: (Key, Key) -> v -> IntIntMap v
singleton (Key
i, Key
j) v
v = 
    IntMap (IntMap v) -> IntIntMap v
forall v. IntMap (IntMap v) -> IntIntMap v
IntIntMap (IntMap (IntMap v) -> IntIntMap v)
-> IntMap (IntMap v) -> IntIntMap v
forall a b. (a -> b) -> a -> b
$ Key -> IntMap v -> IntMap (IntMap v)
forall a. Key -> a -> IntMap a
M.singleton Key
i (Key -> v -> IntMap v
forall a. Key -> a -> IntMap a
M.singleton Key
j v
v) 

lookup :: (Key, Key) -> IntIntMap b -> Maybe b
lookup (Key
i, Key
j) (IntIntMap IntMap (IntMap b)
mm) = do
    IntMap b
m <- Key -> IntMap (IntMap b) -> Maybe (IntMap b)
forall a. Key -> IntMap a -> Maybe a
M.lookup Key
i IntMap (IntMap b)
mm
    Key -> IntMap b -> Maybe b
forall a. Key -> IntMap a -> Maybe a
M.lookup Key
j IntMap b
m

(!) :: IntIntMap v -> (Int,Int) -> v
IntIntMap IntMap (IntMap v)
m ! :: IntIntMap v -> (Key, Key) -> v
! (Key
i,Key
j) = IntMap (IntMap v)
m IntMap (IntMap v) -> Key -> IntMap v
forall a. IntMap a -> Key -> a
M.! Key
i IntMap v -> Key -> v
forall a. IntMap a -> Key -> a
M.! Key
j

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