uhc-light-1.1.7.0: src/UHC/Light/Compiler/Pred/Heuristics.hs
module UHC.Light.Compiler.Pred.Heuristics
( Heuristic, SHeuristic
, HeurAlts (..), HeurRed (..)
, toHeuristic
, heurTry
, localChoice
, binChoice
, solvable
, heurScopedEHC )
where
import UHC.Light.Compiler.Ty
import UHC.Light.Compiler.Ty.FitsInCommon2
import UHC.Light.Compiler.CHR
import UHC.Light.Compiler.VarMp
import UHC.Light.Compiler.Pred.CHR
import UHC.Light.Compiler.Pred.Evidence
import UHC.Light.Compiler.CHR.Constraint
import Data.List (nub,partition)
import Data.Maybe
import UHC.Util.Pretty
import UHC.Util.AGraph
import UHC.Util.Utils
{-# LINE 17 "src/ehc/Pred/Heuristics.chs" #-}
type Heuristic p info = [info] -> HeurAlts p info -> [(info, Evidence p info)]
type SHeuristic p info = HeurAlts p info -> Evidence p info
{-# LINE 45 "src/ehc/Pred/Heuristics.chs" #-}
data HeurAlts p info
= HeurAlts
{ redaltsPredicate :: p
, redaltsAlts :: [HeurRed p info]
}
data HeurRed p info
= HeurRed
{ redInfo :: info
, redContext :: [HeurAlts p info]
}
| HeurRed_Rec
{ redRecPred :: p
}
{-# LINE 62 "src/ehc/Pred/Heuristics.chs" #-}
instance Show (HeurAlts p info) where
show _ = "HeurAlts"
instance Show (HeurRed p info) where
show _ = "HeurRed"
{-# LINE 70 "src/ehc/Pred/Heuristics.chs" #-}
instance (PP p, PP info) => PP (HeurAlts p info) where
pp x = "HeurAlts" >#< redaltsPredicate x >#< ppBracketsCommasBlock (redaltsAlts x)
instance (PP p, PP info) => PP (HeurRed p info) where
pp (HeurRed i subs) = "HeurRed" >#< i >#< ppBracketsCommasBlock subs
pp (HeurRed_Rec p ) = "HeurRec" >#< p
{-# LINE 83 "src/ehc/Pred/Heuristics.chs" #-}
toHeuristic :: SHeuristic p info -> Heuristic p info
toHeuristic h infos alts
= zip infos (repeat ev)
where ev = h alts
{-# LINE 94 "src/ehc/Pred/Heuristics.chs" #-}
heurTry :: Eq p => SHeuristic p info -> SHeuristic p info -> SHeuristic p info
heurTry f g a | null (evidUnresolved ev) = ev
| otherwise = g a
where ev = f a
{-# LINE 105 "src/ehc/Pred/Heuristics.chs" #-}
localChoice :: (Eq p, Eq info) => (p -> [info] -> [info]) -> SHeuristic p info
localChoice choose (HeurAlts p reds) =
case filter ((`elem` redinfos) . redInfo) reds of
[] -> Evid_Unresolved p (concatMap evidUnresolved [ Evid_Proof p i evs | (i,evs) <- chs reds])
[r@(HeurRed_Rec p)] -> Evid_Recurse p
[r@(HeurRed i _)] -> Evid_Proof p i (snd $ ch r)
rs -> reallyOverlapEvid p (chs rs)
where redinfos = choose p (map redInfo reds)
ch (HeurRed i rs) = (i,map (localChoice choose) rs)
chs rs = map ch rs
{-# LINE 118 "src/ehc/Pred/Heuristics.chs" #-}
binChoice :: (Eq p, Eq info) => (info -> info -> PartialOrdering) -> SHeuristic p info
binChoice order = localChoice (const local)
where local [] = []
local is = [mx]
where (mx,eqPairs) = heurMaximumBy order is
{-# LINE 126 "src/ehc/Pred/Heuristics.chs" #-}
-- | Choose maximum, also giving list of equals of there are more maximum x-es
heurChoose :: (x -> x -> PartialOrdering) -> (x,[x]) -> x -> (x,[x])
heurChoose cmp (x,eqPairs) y
= case cmp x y of
P_LT -> (y,[])
P_GT -> (x,eqPairs)
P_EQ -> (x,if null eqPairs then [x,y] else y:eqPairs)
heurMaximumBy :: (x -> x -> PartialOrdering) -> [x] -> (x,[x])
heurMaximumBy cmp (x:xs)
= foldl (heurChoose cmp) (x,[]) xs
{-# LINE 144 "src/ehc/Pred/Heuristics.chs" #-}
contextChoice :: Eq p => (p -> [HeurRed p info] -> [HeurRed p info]) -> SHeuristic p info
contextChoice choose (HeurAlts p reds) =
case choose p reds of
[] -> Evid_Unresolved p [UnresolvedTrace_Fail p []]
[r@(HeurRed_Rec p)] -> Evid_Recurse p
[r@(HeurRed i _)] -> Evid_Proof p i (snd $ ch r)
rs -> reallyOverlapEvid p (chs rs)
where ch (HeurRed i rs) = (i,map (contextChoice choose) rs)
chs rs = map ch rs
contextBinChoice :: Eq p => (HeurRed p info -> HeurRed p info -> PartialOrdering) -> SHeuristic p info
contextBinChoice order = contextChoice (const local)
where local [] = []
local is | null eqPairs = [mx]
| otherwise = eqPairs
where (mx,eqPairs) = heurMaximumBy order is -- do something with equal pairs, construct Evid_Ambig perhaps?
{-# LINE 169 "src/ehc/Pred/Heuristics.chs" #-}
reallyOverlapEvid :: p -> [(info,[Evidence p info])] -> Evidence p info
reallyOverlapEvid p evs
= case filter (not . null . snd) evs of
[] -> Evid_Ambig p evs
[(i,ev)] -> Evid_Proof p i ev
_ -> Evid_Ambig p evs
{-# LINE 188 "src/ehc/Pred/Heuristics.chs" #-}
solvable :: HeurAlts p info -> HeurAlts p info
solvable (HeurAlts p rs) = HeurAlts p (catMaybes (map heu rs))
where heu h@(HeurRed info reds) | all hasAlts reds' = Just (HeurRed info reds')
| otherwise = Nothing
where reds' = map solvable reds
heu h@(HeurRed_Rec p ) = Just h
hasAlts :: HeurAlts p info -> Bool
hasAlts (HeurAlts _ []) = False
hasAlts _ = True
{-# LINE 207 "src/ehc/Pred/Heuristics.chs" #-}
cmpSpecificness :: CHRMatchable (FIIn' gm) Pred VarMp => FIIn' gm -> Pred -> Pred -> PartialOrdering
cmpSpecificness env p q =
case chrMatchTo env (emptyVarMp :: VarMp) p q of
Nothing -> P_GT
Just _ -> case chrMatchTo env (emptyVarMp :: VarMp) q p of
Nothing -> P_LT
Just _ -> P_EQ
{-# LINE 284 "src/ehc/Pred/Heuristics.chs" #-}
cmpEqReds :: RedHowAnnotation -> RedHowAnnotation -> PartialOrdering
cmpEqReds r1 r2 = panic ("cmpEqReds: don't know how to deal with: " ++ show (pp r1) ++ " and " ++ show (pp r2))
{-# LINE 307 "src/ehc/Pred/Heuristics.chs" #-}
anncmpEHCScoped :: CHRMatchable (FIIn' gm) Pred VarMp => Bool -> FIIn' gm -> HeurRed CHRPredOcc RedHowAnnotation -> HeurRed CHRPredOcc RedHowAnnotation -> PartialOrdering
anncmpEHCScoped preferInst env ann1 ann2
= case (ann1,ann2) of
(HeurRed (RedHow_Assumption _ _) _ , _ ) -> P_GT
(_ , HeurRed (RedHow_Assumption _ _) _ ) -> P_LT
(HeurRed (RedHow_ByScope ByScopeRedHow_Assume) _
, _ ) -> P_GT
(_ , HeurRed (RedHow_ByScope ByScopeRedHow_Assume) _) -> P_LT
(HeurRed_Rec _ , _ ) -> P_GT
(_ , HeurRed_Rec _ ) -> P_LT
(HeurRed (RedHow_ByInstance _ p s) _ , HeurRed (RedHow_ByInstance _ q t) _ ) -> case pscpCmpByLen s t of
EQ -> cmpSpecificness env p q
ord -> toPartialOrdering ord
(HeurRed (RedHow_ByInstance _ _ s) _ , HeurRed (RedHow_ByScope _) [HeurAlts q _]) -> toPartialOrdering $ pscpCmpByLen s (cpoScope q)
(HeurRed (RedHow_ByScope _) [HeurAlts p _], HeurRed (RedHow_ByInstance _ _ t) _ ) -> toPartialOrdering $ pscpCmpByLen (cpoScope p) t
(HeurRed (RedHow_ByInstance _ _ _) _ , _ ) | preferInst -> P_GT
(_ , HeurRed (RedHow_ByInstance _ _ _) _ ) | preferInst -> P_LT
(HeurRed (RedHow_ByLabel _ _ s) _ , HeurRed (RedHow_ByLabel _ _ t) _ ) -> toPartialOrdering $ pscpCmpByLen s t
(HeurRed (RedHow_ByLabel _ _ _) _ , _ ) -> P_GT
(_ , HeurRed (RedHow_ByLabel _ _ _) _ ) -> P_LT
(HeurRed (RedHow_BySuperClass _ _ _) _ , _ ) -> P_GT
(_ , HeurRed (RedHow_BySuperClass _ _ _) _ ) -> P_LT
(HeurRed (RedHow_ByScope _) [HeurAlts p _], HeurRed (RedHow_ByScope _) [HeurAlts q _]) -> toPartialOrdering $ pscpCmpByLen (cpoScope p) (cpoScope q)
(HeurRed (RedHow_ByScope _) _ , _ ) -> P_GT
(_ , HeurRed (RedHow_ByScope _) _ ) -> P_LT
(HeurRed (RedHow_ByInstance _ _ _) _ , _ ) -> P_GT
(_ , HeurRed (RedHow_ByInstance _ _ _) _ ) -> P_LT
_ -> panic ("anncmpEHCScoped: don't know how to deal with:\n " ++ show (pp ann1) ++ "\n " ++ show (pp ann2))
{-# LINE 353 "src/ehc/Pred/Heuristics.chs" #-}
heurScopedEHC :: CHRMatchable (FIIn' gm) Pred VarMp => FIIn' gm -> Heuristic CHRPredOcc RedHowAnnotation
heurScopedEHC env
= toHeuristic
$ ifthenelseSHeuristic isEqHeuristic
eqHeuristic
{-
defaultHeuristic
-}
{-
$ heurTry (contextBinChoice (anncmpEHCScoped True env))
-- (contextBinChoice (anncmpEHCScoped False env))
(contextChoice ehcOnlySuperReduce)
-}
$ contextBinChoice (anncmpEHCScoped True env)
where
isEqHeuristic _ = False
eqHeuristic = binChoice cmpEqReds . solvable
{-
defaultHeuristic
= contextBinChoice (anncmpEHCScoped env)
-}
ifthenelseSHeuristic :: (p -> Bool) -> SHeuristic p info -> SHeuristic p info -> SHeuristic p info
ifthenelseSHeuristic g t e alts
| g (redaltsPredicate alts) = t alts
| otherwise = e alts