module UHC.Light.Compiler.Gam.Base
( emptyGam, gamMap, gamLookup, gamLookupDup, gamPushNew, gamPop, gamTop, gamAddGam, gamAdd, gamPushGam, gamToAssocL, gamToAssocDupL, assocLToGam, assocDupLToGam, gamKeys
, gamSingleton, gamInsert, gamUnion, gamUnions, gamFromAssocL
, assocLToGamWithDups
, gamToOnlyDups
, gamPartition
, gamMapElts
, gamMapThr
, gamUnzip
, gamElts
, gamNoDups
, Gam
, gamLookupMetaLev
, gamTopUpdate
, gamMetaLevSingleton
, gamUnionWith )
where
import Data.List
import UHC.Util.Utils
import UHC.Light.Compiler.Base.HsName.Builtin
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.NameAspect
import qualified Data.Set as Set
import UHC.Light.Compiler.Opts.Base
import Data.Maybe
import qualified Data.Set as Set
import qualified Data.Map as Map
import UHC.Util.ScopeMapGam







{-# LINE 47 "src/ehc/Gam/Base.chs" #-}
type Gam k v        =   SGam k v

{-# LINE 51 "src/ehc/Gam/Base.chs" #-}
emptyGam            ::            Gam k v
gamSingleton        ::            k -> v        -> Gam k v
gamLookup           ::  Ord k =>  k -> Gam k v  -> Maybe v
gamToAssocL         ::  Ord k =>  Gam k v       -> AssocL k v
gamPushNew          ::            Gam k v       -> Gam k v
gamPushGam          ::  Ord k =>  Gam k v       -> Gam k v -> Gam k v
gamPop              ::  Ord k =>  Gam k v       -> (Gam k v,Gam k v)
gamAddGam           ::  Ord k =>  Gam k v       -> Gam k v -> Gam k v
gamAdd              ::  Ord k =>  k -> v        -> Gam k v -> Gam k v

{-# LINE 76 "src/ehc/Gam/Base.chs" #-}
gamLookupMetaLev :: Ord k => MetaLev -> k -> Gam k v -> Maybe v
gamLookupMetaLev mlev k g = fmap head $ gamLookupMetaLevDup mlev k g

{-# LINE 81 "src/ehc/Gam/Base.chs" #-}
gamToAssocL     g                   = [ (k,v) | (k,(v:_)) <- gamToAssocDupL g ]

gamLookup       k g                 = fmap head $ gamLookupDup k g
{-# INLINE gamLookup #-}

assocLToGam                         = gamUnions . map (uncurry gamSingleton)

{-# LINE 90 "src/ehc/Gam/Base.chs" #-}
emptyGam                            = emptySGam
{-# INLINE emptyGam #-}

gamSingleton                        = sgamSingleton
{-# INLINE gamSingleton #-}

gamPushNew                          = sgamPushNew
{-# INLINE gamPushNew #-}

gamPushGam                          = sgamPushGam
{-# INLINE gamPushGam #-}

gamPop                              = sgamPop
{-# INLINE gamPop #-}

gamAddGam                           = sgamUnion
{-# INLINE gamAddGam #-}

gamAdd          k v g               = sgamUnion (sgamSingleton k v) g
{-# INLINE gamAdd #-}

{-# LINE 113 "src/ehc/Gam/Base.chs" #-}
gamTop              ::  Ord k =>  Gam k v     -> Gam k v
assocLToGam         ::  Ord k =>  AssocL k v  -> Gam k v

{-# LINE 123 "src/ehc/Gam/Base.chs" #-}
gamTop                              = sgamTop
{-# INLINE gamTop #-}

{-# LINE 128 "src/ehc/Gam/Base.chs" #-}
-- | Update top entries, all duplicates
gamTopUpdate :: Ord k => (v -> v) -> k -> Gam k v -> Gam k v
gamTopUpdate upd = sgamAlterDupOnTop $ maybe Nothing (Just . upd)
{-# INLINE gamTopUpdate #-}

{-# LINE 135 "src/ehc/Gam/Base.chs" #-}
gamMetaLevSingleton                        = sgamMetaLevSingleton
{-# INLINE gamMetaLevSingleton #-}

{-# LINE 145 "src/ehc/Gam/Base.chs" #-}
assocDupLToGam :: Ord k => AssocL k [v] -> Gam k v
assocDupLToGam = sgamFromAssocDupL
{-# INLINE assocDupLToGam #-}

{-# LINE 151 "src/ehc/Gam/Base.chs" #-}
assocLToGamWithDups :: Ord k => AssocL k v -> Gam k v
assocLToGamWithDups = assocDupLToGam . assocLGroupSort
{-# INLINE assocLToGamWithDups #-}

{-# LINE 163 "src/ehc/Gam/Base.chs" #-}
gamToAssocDupL :: Ord k => Gam k v -> AssocL k [v]
gamToAssocDupL = sgamToAssocDupL
{-# INLINE gamToAssocDupL #-}

{-# LINE 169 "src/ehc/Gam/Base.chs" #-}
gamToOnlyDups :: Ord k => Gam k v -> AssocL k [v]
gamToOnlyDups g = [ x | x@(n,(_:_:_)) <- gamToAssocDupL g ]

{-# LINE 179 "src/ehc/Gam/Base.chs" #-}
gamNoDups :: Ord k => Gam k v -> Gam k v
gamNoDups = sgamNoDups
{-# INLINE gamNoDups #-}

{-# LINE 190 "src/ehc/Gam/Base.chs" #-}
gamMap :: (Ord k,Ord k') => ((k,v) -> (k',v')) -> Gam k v -> Gam k' v'
gamMap = sgamMap
{-# INLINE gamMap #-}

{-# LINE 196 "src/ehc/Gam/Base.chs" #-}
gamMapElts :: Ord k => (v -> v') -> Gam k v -> Gam k v'
gamMapElts f = gamMap (\(n,v) -> (n,f v))
{-# INLINE gamMapElts #-}

{-# LINE 210 "src/ehc/Gam/Base.chs" #-}
gamPartition :: Ord k => (k -> v -> Bool) -> Gam k v -> (Gam k v,Gam k v)
gamPartition = sgamPartitionWithKey
{-# INLINE gamPartition #-}

{-# LINE 231 "src/ehc/Gam/Base.chs" #-}
gamMapThr :: (Ord k,Ord k') => ((k,v) -> t -> ((k',v'),t)) -> t -> Gam k v -> (Gam k' v',t)
gamMapThr = sgamMapThr
{-# INLINE gamMapThr #-}

{-# LINE 237 "src/ehc/Gam/Base.chs" #-}
gamKeys :: Ord k => Gam k v -> [k]
gamKeys = assocLKeys . gamToAssocL
{-# INLINE gamKeys #-}

{-# LINE 243 "src/ehc/Gam/Base.chs" #-}
gamElts :: Ord k => Gam k v -> [v]
gamElts = assocLElts . gamToAssocL
{-# INLINE gamElts #-}

{-# LINE 254 "src/ehc/Gam/Base.chs" #-}
gamLookupMetaLevDup :: Ord k => MetaLev -> k -> Gam k v -> Maybe [v]
gamLookupMetaLevDup = sgamLookupMetaLevDup
{-# INLINE gamLookupMetaLevDup #-}

gamLookupDup :: Ord k => k -> Gam k v -> Maybe [v]
gamLookupDup = gamLookupMetaLevDup metaLevVal
{-# INLINE gamLookupDup #-}

{-# LINE 271 "src/ehc/Gam/Base.chs" #-}
gamUnzip :: Ord k => Gam k (v1,v2) -> (Gam k v1,Gam k v2)
gamUnzip g = sgamUnzip g
{-# INLINE gamUnzip #-}

{-# LINE 281 "src/ehc/Gam/Base.chs" #-}
gamInsert :: Ord k => k -> v -> Gam k v -> Gam k v
gamInsert = gamAdd
{-# INLINE gamInsert #-}

gamUnion :: Ord k => Gam k v -> Gam k v -> Gam k v
gamUnion = gamAddGam
{-# INLINE gamUnion #-}

gamFromAssocL ::  Ord k =>  AssocL k v  -> Gam k v
gamFromAssocL = assocLToGam
{-# INLINE gamFromAssocL #-}

{-# LINE 295 "src/ehc/Gam/Base.chs" #-}
gamUnionWith :: Ord k => (v -> [v] -> [v]) -> Gam k v -> Gam k v -> Gam k v
gamUnionWith cmb = sgamUnionWith (Just cmb)
{-# INLINE gamUnionWith #-}

{-# LINE 301 "src/ehc/Gam/Base.chs" #-}
gamUnions :: Ord k => [Gam k v] -> Gam k v
gamUnions [] = emptyGam
gamUnions gs = foldr1 gamUnion gs