packages feed

uhc-light-1.1.9.2: src/UHC/Light/Compiler/Pred/Heuristics.hs

module UHC.Light.Compiler.Pred.Heuristics
( Heuristic, SHeuristic
, HeurAlts, HeurAlts' (..), HeurRed, HeurRed' (..)
, toHeuristic
, heurTry
, localChoice
, binChoice
, solvable
, heurScopedEHC )
where
import UHC.Light.Compiler.Ty
import UHC.Light.Compiler.Ty.FitsInCommon2
import UHC.Util.CHR
import UHC.Light.Compiler.VarMp
import UHC.Light.Compiler.Pred.Evidence
import UHC.Light.Compiler.CHR.Key
import UHC.Light.Compiler.CHR.Constraint
import UHC.Light.Compiler.CHR.Guard
import UHC.Light.Compiler.CHR.Solve
import UHC.Light.Compiler.Base.Common
import Data.List (nub,partition)
import Data.Maybe
import UHC.Util.Pretty
import UHC.Util.AGraph
import UHC.Util.Utils

{-# LINE 23 "src/ehc/Pred/Heuristics.chs" #-}
type Heuristic' p info = [info] -> HeurAlts' p info -> [(info, Evidence' p info)]

type Heuristic = Heuristic' CHRPredOcc RedHowAnnotation

type SHeuristic' p info = HeurAlts' p info -> Evidence' p info

type SHeuristic = SHeuristic' CHRPredOcc RedHowAnnotation

{-# LINE 39 "src/ehc/Pred/Heuristics.chs" #-}
data HeurAlts' p info
  = HeurAlts
     { redaltsPredicate  	:: p
     , redaltsAlts  		:: [HeurRed' p info]
     }

type HeurAlts = HeurAlts' CHRPredOcc RedHowAnnotation

data HeurRed' p info
  = HeurRed
     { redInfo           	:: info
     , redContext   		:: [HeurAlts' p info]
     }
  | HeurRed_Rec
     { redRecPred           :: p
     }

type HeurRed = HeurRed' CHRPredOcc RedHowAnnotation

{-# LINE 60 "src/ehc/Pred/Heuristics.chs" #-}
instance Show (HeurAlts' p info) where
  show _ = "HeurAlts"

instance Show (HeurRed' p info) where
  show _ = "HeurRed"

{-# LINE 68 "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 81 "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 92 "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 103 "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 116 "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 124 "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 142 "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 167 "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 186 "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 205 "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 282 "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 305 "src/ehc/Pred/Heuristics.chs" #-}
anncmpEHCScoped :: CHRMatchable (FIIn' gm) Pred VarMp => Bool -> FIIn' gm -> HeurRed -> HeurRed -> 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 351 "src/ehc/Pred/Heuristics.chs" #-}
heurScopedEHC :: CHRMatchable (FIIn' gm) Pred VarMp => FIIn' gm -> Heuristic
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