addEPDeclToSig :: Sign -> Token -> EPDomain -> Sign
addEPDeclToSig sig tok dom = g $ sig {epdecls = ed'}
    where (mD, ed') = Map.insertLookupWithKey f tok epd $ epdecls sig
          epd = EPDecl tok dom Nothing
          f _ _ v@(EPDecl _ dom' _)
              | dom' == dom = v
              | otherwise = error $ "addEPDeclToSig: EP already"
                            ++ " assigned another domain: " ++ show tok ++ "in"
                            ++ show dom'
          g s =
              case (mD, dom) of
                (Nothing, ClosedInterval a b) ->
                    case mapMaybe getEPVarRef [a, b] of
                      [] -> s
                      l -> foldl addEmptyEPDomVarDeclToSig s l
                _ -> s
            


-- TODO: add support for epdecls and report errors if they do not match!

{- Two signatures s1 and s2 are compatible if the common part has the
   following properties:

   * if the default value of an extparam is defined in s1 and s2 it has to be the same
   * if the domains (of extparams or vars) are both given, they must not be disjoint
   * the arities must conincide for the same operator

-}

-- | Union of signatures
addEPDeclToSig :: Sign -> Token -> EPDomain -> Sign
addEPDeclToSig sig tok dom = g $ sig {epdecls = ed'}
    where (mD, ed') = Map.insertLookupWithKey f tok epd $ epdecls sig
          epd = EPDecl tok dom Nothing
          f _ _ v@(EPDecl _ dom' _)
              | dom' == dom = v
              | otherwise = error $ "addEPDeclToSig: EP already"
                            ++ " assigned another domain: " ++ show tok ++ "in"
                            ++ show dom'
          g s =
              case (mD, dom) of
                (Nothing, ClosedInterval a b) ->
                    case mapMaybe getEPVarRef [a, b] of
                      [] -> s
                      l -> foldl addEmptyEPDomVarDeclToSig s l
                _ -> s
            


-- TODO: add support for epdecls and report errors if they do not match!

{- Two signatures s1 and s2 are compatible if the common part has the
   following properties:

   * if the default value of an extparam is defined in s1 and s2 it has to be the same
   * if the domains (of extparams or vars) are both given, they must not be disjoint
   * the arities must conincide for the same operator

-}

-- | Union of signatures
addEPDeclToSig sig tok dom = g $ sig {epdecls = ed'}
    where (mD, ed') = Map.insertLookupWithKey f tok epd $ epdecls sig
          epd = EPDecl tok dom Nothing
          f _ _ v@(EPDecl _ dom' _)
              | dom' == dom = v
              | otherwise = error $ "addEPDeclToSig: EP already"
                            ++ " assigned another domain: " ++ show tok ++ "in"
                            ++ show dom'
          g s =
              case (mD, dom) of
                (Nothing, ClosedInterval a b) ->
                    case mapMaybe getEPVarRef [a, b] of
                      [] -> s
                      l -> foldl addEmptyEPDomVarDeclToSig s l
                _ -> s
            


-- TODO: add support for epdecls and report errors if they do not match!

{- Two signatures s1 and s2 are compatible if the common part has the
   following properties:

   * if the default value of an extparam is defined in s1 and s2 it has to be the same
   * if the domains (of extparams or vars) are both given, they must not be disjoint
   * the arities must conincide for the same operator

-}

-- | Union of signatures