module Top.Implementation.TypeGraph.DefaultHeuristics where
import Top.Implementation.TypeGraph.ApplyHeuristics (predicatePath, expandPath)
import Top.Implementation.TypeGraph.Basics
import Top.Implementation.TypeGraph.Heuristic
import Top.Implementation.TypeGraph.Path
import Data.List
import qualified Data.Map as M
import Top.Solver
defaultHeuristics :: Show info => Path (EdgeId, info) -> [Heuristic info]
defaultHeuristics path =
[ highParticipation 1.00 path, firstComeFirstBlamed ]
inMininalSet :: Path (EdgeId, info) -> Heuristic info
inMininalSet path =
Heuristic (
let sets = minimalSets eqInfo2 path
candidates = nubBy eqInfo2 (concat sets)
f e = return (any (eqInfo2 e) candidates)
in edgeFilter "In a smallest minimal set" f)
highParticipation :: Show info => Double -> Path (EdgeId, info) -> Heuristic info
highParticipation ratio path =
Heuristic (Filter ("Participation ratio [ratio="++show ratio++"]") selectTheBest)
where
selectTheBest es =
let (nrOfPaths, fm) = participationMap (mapPath (\(EdgeId _ _ cnr,_) -> cnr) path)
participationList = M.filterWithKey p fm
p cnr _ = cnr `elem` activeCNrs
activeCNrs = [ cnr | (EdgeId _ _ cnr, _) <- es ]
maxInList = maximum (M.elems participationList)
limit
| maxInList == nrOfPaths = maxInList
| otherwise = round (fromIntegral maxInList * ratio) `max` 1
goodCNrs = M.keys (M.filter (>= limit) participationList)
bestEdges = filter (\(EdgeId _ _ cnr,_) -> cnr `elem` goodCNrs) es
mymsg = unlines ("" : title : replicate 50 '-' : map f es)
title = "cnr edge ratio info"
f (edgeID@(EdgeId _ _ cnr),info) =
take 5 (show cnr++(if cnr `elem` goodCNrs then "*" else "")++repeat ' ') ++
take 14 (show edgeID++repeat ' ') ++
take 8 (show (M.findWithDefault 0 cnr fm * 100 `div` nrOfPaths)++"%"++repeat ' ') ++
"{"++show info++"}"
in do logMsg mymsg
return bestEdges
firstComeFirstBlamed :: Heuristic info
firstComeFirstBlamed =
Heuristic (
let f (EdgeId _ _ cnr, _) = return cnr
in maximalEdgeFilter "First come, first blamed" f)
selectConstraintNumbers :: [EdgeNr] -> Heuristic info
selectConstraintNumbers is =
Heuristic (
let f (EdgeId _ _ cnr, _) = return (cnr `elem` is)
in edgeFilter ("select constraint numbers " ++ show is) f)
inPredicatePath :: Heuristic info
inPredicatePath =
Heuristic (Filter "in a predicate path" f) where
f xs =
do pp <- predicatePath
path <- expandPath (simplifyPath pp)
let cnrs = nub [ c | (EdgeId _ _ c, _) <- steps path ]
p (EdgeId _ _ cnr, _) = cnr `elem` cnrs
ys = filter p xs
return (if null ys then xs else ys)