module Helium.StaticAnalysis.Heuristics.ListOfHeuristics (listOfHeuristics) where
import Helium.Main.Args (Option(..))
import Helium.StaticAnalysis.Miscellaneous.ConstraintInfo
import Helium.StaticAnalysis.Heuristics.HeuristicsInfo ()
import Top.Implementation.TypeGraph.Heuristic
import Top.Implementation.TypeGraph.DefaultHeuristics
import Top.Implementation.TypeGraph.ClassMonadic
import Helium.StaticAnalysis.Heuristics.RepairHeuristics
import Helium.StaticAnalysis.Heuristics.UnifierHeuristics
import Helium.StaticAnalysis.Heuristics.OnlyResultHeuristics
import Helium.StaticAnalysis.Heuristics.TieBreakerHeuristics
import Top.Implementation.TypeGraph.Path
import Data.Maybe
import Top.Implementation.TypeGraph.Basics
listOfHeuristics :: [Option] -> Siblings -> Path (EdgeId, ConstraintInfo) -> [Heuristic ConstraintInfo]
listOfHeuristics options siblings path =
let is = [ makeEdgeNr i | SelectConstraintNumber i <- options ]
in [ selectConstraintNumbers is | not (null is) ]
++
[ avoidForbiddenConstraints
, highParticipation 0.95 path
, phaseFilter
] ++
[ Heuristic (Voting (
[ siblingFunctions siblings
, siblingLiterals
, applicationHeuristic
, variableFunction
, tupleHeuristic
, fbHasTooManyArguments
, constraintFromUser path
, unaryMinus (Overloading `elem` options)
] ++
[ similarNegation | Overloading `notElem` options ] ++
[ unifierVertex | UnifierHeuristics `elem` options ]))
| NoRepairHeuristics `notElem` options
] ++
[ inPredicatePath | Overloading `elem` options ] ++
[ avoidApplicationConstraints
, avoidNegationConstraints
, avoidTrustedConstraints
, avoidFolkloreConstraints
, firstComeFirstBlamed
]
avoidForbiddenConstraints :: Heuristic ConstraintInfo
avoidForbiddenConstraints = Heuristic (
let f (_, info) = return (not (isHighlyTrusted info))
in edgeFilter "Avoid forbidden constraints" f)
phaseFilter :: Heuristic ConstraintInfo
phaseFilter = Heuristic (
let f (_, info) = return (phaseOfConstraint info)
in maximalEdgeFilter "Highest phase number" f)
constraintFromUser :: HasTypeGraph m ConstraintInfo => Path (EdgeId, ConstraintInfo) -> Selector m ConstraintInfo
constraintFromUser path =
SelectorList ("Constraints from .type file", helper path)
where
helper path' edges =
let
bestEdge = rec_ path'
edgeNrs = [ i | (EdgeId _ _ i, _) <- edges ]
rec_ path'' =
case path'' of
x :|: y -> f min (rec_ x) (rec_ y)
x :+: y -> f max (rec_ x) (rec_ y)
Step (EdgeId _ _ cNR, info) | isJust (maybeUserConstraint info) && cNR `elem` edgeNrs
-> Just cNR
_ -> Nothing
f :: (a -> a -> a) -> Maybe a -> Maybe a -> Maybe a
f g ma mb =
case (ma, mb) of
(Just a, Just b) -> Just (g a b)
(Nothing, _ ) -> mb
_ -> ma
in
case [ tuple | tuple@(EdgeId _ _ cNR, _) <- edges, Just cNR == bestEdge ] of
[] -> return Nothing
(edgeID, info):_ ->
let (groupID, number) = fromMaybe (0, 0) (maybeUserConstraint info)
otherEdges = let p info' =
case maybeUserConstraint info' of
Just (a, b) -> a == groupID && b > number
Nothing -> False
in [ e | (e, i) <- edges, p i ]
in return . Just $
(8, "constraints from .type file", edgeID:otherEdges, info)