module UHC.Light.Compiler.CHR
( module UHC.Light.Compiler.CHR.Key
, CHR (..)
, CHREmptySubstitution (..)
, CHRMatchable (..)
, CHRCheckable (..)
, (<==>), (==>), (|>) )
where
import qualified UHC.Light.Compiler.Base.TreeTrie as TreeTrie
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.Substitutable
import UHC.Light.Compiler.VarMp
import Data.Monoid
import qualified Data.Set as Set
import UHC.Util.Pretty
import UHC.Light.Compiler.CHR.Key
import Control.Monad
import UHC.Util.Binary
import UHC.Util.Serialize
data CHR cnstr guard subst
= CHR
{ chrHead :: ![cnstr]
, chrSimpSz :: !Int
, chrGuard :: ![guard]
, chrBody :: ![cnstr]
}
deriving (Typeable, Data)
emptyCHRGuard :: [a]
emptyCHRGuard = []
instance Show (CHR c g s) where
show _ = "CHR"
instance (PP c,PP g) => PP (CHR c g s) where
pp chr
= case chr of
(CHR h@(_:_) sz g b) | sz == 0 -> ppChr ([ppL h, pp "==>"] ++ ppGB g b)
(CHR h@(_:_) sz g b) | sz == length h -> ppChr ([ppL h, pp "<==>"] ++ ppGB g b)
(CHR h@(_:_) sz g b) -> ppChr ([ppL (take sz h), pp "|", ppL (drop sz h), pp "<==>"] ++ ppGB g b)
(CHR [] _ g b) -> ppChr (ppGB g b)
where ppGB g@(_:_) b@(_:_) = [ppL g, "|" >#< ppL b]
ppGB g@(_:_) [] = [ppL g >#< "|"]
ppGB [] b@(_:_) = [ppL b]
ppGB [] [] = []
ppL [x] = pp x
ppL xs = ppBracketsCommasBlock xs
ppChr l = vlist l
instance TTKeyable cnstr => TTKeyable (CHR cnstr guard subst) where
toTTKey' o chr = toTTKey' o $ head $ chrHead chr
instance (VarExtractable c v,VarExtractable g v) => VarExtractable (CHR c g s) v where
varFreeSet (CHR {chrHead=h, chrGuard=g, chrBody=b})
= Set.unions $ concat [map varFreeSet h, map varFreeSet g, map varFreeSet b]
instance (VarUpdatable c s,VarUpdatable g s) => VarUpdatable (CHR c g s) s where
varUpd s r@(CHR {chrHead=h, chrGuard=g, chrBody=b})
= r {chrHead = map (varUpd s) h, chrGuard = map (varUpd s) g, chrBody = map (varUpd s) b}
class CHREmptySubstitution subst where
chrEmptySubst :: subst
class (TTKeyable x) => CHRMatchable env x subst where
chrMatchTo :: env -> subst -> x -> x -> Maybe subst
class CHRCheckable env x subst where
chrCheck :: env -> subst -> x -> Maybe subst
infix 1 <==>, ==>
infixr 0 |>
(<==>), (==>) :: [c] -> [c] -> CHR c g s
hs <==> bs = CHR hs (length hs) emptyCHRGuard bs
hs ==> bs = CHR hs 0 emptyCHRGuard bs
(|>) :: CHR c g s -> [g] -> CHR c g s
chr |> g = chr {chrGuard = chrGuard chr ++ g}
instance (Serialize c,Serialize g,Serialize s) => Serialize (CHR c g s) where
sput (CHR a b c d) = sput a >> sput b >> sput c >> sput d
sget = liftM4 CHR sget sget sget sget