packages feed

ptera-core-0.1.0.0: src/Language/Parser/Ptera/Data/Symbolic/IntSet.hs

module Language.Parser.Ptera.Data.Symbolic.IntSet where

import           Language.Parser.Ptera.Prelude hiding (empty)

import qualified Data.IntSet                   as DataIntSet


type T = IntSet

type Key = Int

data IntSet
    = StraightSet DataIntSet.IntSet
    | NegativeSet DataIntSet.IntSet
    deriving (Eq, Show)

instance Semigroup IntSet where
    (<>) = union

instance Monoid IntSet where
    mempty = StraightSet DataIntSet.empty

full :: IntSet
full = NegativeSet DataIntSet.empty

singleton :: Key -> IntSet
singleton k = StraightSet do DataIntSet.singleton k

invert :: IntSet -> IntSet
invert = \case
    StraightSet s -> NegativeSet s
    NegativeSet s -> StraightSet s

fromList :: [Key] -> IntSet
fromList ks = StraightSet do DataIntSet.fromList ks

insert :: Key -> IntSet -> IntSet
insert k = \case
    StraightSet s -> StraightSet do DataIntSet.insert k s
    NegativeSet s -> NegativeSet do DataIntSet.delete k s

delete :: Key -> IntSet -> IntSet
delete k = \case
    StraightSet s -> StraightSet do DataIntSet.delete k s
    NegativeSet s -> NegativeSet do DataIntSet.insert k s

member :: Key -> IntSet -> Bool
member k = \case
    StraightSet s -> DataIntSet.member k s
    NegativeSet s -> not do DataIntSet.member k s

union :: IntSet -> IntSet -> IntSet
union (StraightSet s1) (StraightSet s2) = StraightSet do DataIntSet.union s1 s2
union (StraightSet s1) (NegativeSet s2) = NegativeSet do DataIntSet.difference s2 s1
union (NegativeSet s1) (StraightSet s2) = NegativeSet do DataIntSet.difference s1 s2
union (NegativeSet s1) (NegativeSet s2) = NegativeSet do DataIntSet.intersection s1 s2

intersection :: IntSet -> IntSet -> IntSet
intersection (StraightSet s1) (StraightSet s2) = StraightSet do DataIntSet.intersection s1 s2
intersection (StraightSet s1) (NegativeSet s2) = StraightSet do DataIntSet.difference s1 s2
intersection (NegativeSet s1) (StraightSet s2) = StraightSet do DataIntSet.difference s2 s1
intersection (NegativeSet s1) (NegativeSet s2) = NegativeSet do DataIntSet.union s1 s2

difference :: IntSet -> IntSet -> IntSet
difference (StraightSet s1) (StraightSet s2) = StraightSet do DataIntSet.difference s1 s2
difference (StraightSet s1) (NegativeSet s2) = StraightSet do DataIntSet.intersection s1 s2
difference (NegativeSet s1) (StraightSet s2) = NegativeSet do DataIntSet.union s1 s2
difference (NegativeSet s1) (NegativeSet s2) = StraightSet do DataIntSet.difference s2 s1