Safe Haskell | None |
---|---|
Language | Haskell2010 |
Simple Constraint solver
- data PredState
- type PredOracle p = Map p PredState
- makeOracle :: Ord p => [(p, PredState)] -> PredOracle p
- oraclePredicates :: Ord p => PredOracle p -> [(p, PredState)]
- emptyOracle :: PredOracle p
- predIsSet :: Ord p => PredOracle p -> p -> Bool
- predIsUnset :: Ord p => PredOracle p -> p -> Bool
- predIsUndef :: Ord p => PredOracle p -> p -> Bool
- predIs :: Ord p => PredOracle p -> p -> PredState -> Bool
- predState :: Ord p => PredOracle p -> p -> PredState
- data Constraint e p
- = Predicate p
- | Not (Constraint e p)
- | And [Constraint e p]
- | Or [Constraint e p]
- | Xor [Constraint e p]
- | CBool Bool
- simplifyConstraint :: Constraint e p -> Constraint e p
- constraintReduce :: (Ord p, Eq p, Eq e) => PredOracle p -> Constraint e p -> Constraint e p
- data Rule e p a
- = Terminal a
- | NonTerminal [(Constraint e p, Rule e p a)]
- | Fail e
- orderedNonTerminal :: [(Constraint e p, Rule e p a)] -> Rule e p a
- mergeRules :: Rule e p a -> Rule e p b -> Rule e p (a, b)
- evalsTo :: (Ord (Pred a), Eq a, Eq (PredTerm a), Eq (Pred a), Predicated a) => a -> PredTerm a -> Constraint e (Pred a)
- data MatchResult e nt t
- = NoMatch
- | Match t
- | DontMatch nt
- | MatchFail [e]
- | MatchDiverge [nt]
- class Predicated a where
- createPredicateTable :: (Ord (Pred a), Eq (Pred a), Eq a, Predicated a, Predicated a, Pred a ~ Pred a) => a -> (PredOracle (Pred a) -> Bool) -> Bool -> Either (PredTerm a) [(PredOracle (Pred a), PredTerm a)]
- initP :: nt -> t -> MatchResult e nt (nt, t)
- applyP :: Predicated ntb => MatchResult e (ntb -> nt) (ntb -> nt, PredTerm ntb -> t) -> MatchResult e ntb (PredTerm ntb) -> MatchResult e nt (nt, t)
- resultP :: MatchResult e nt (nt, t) -> MatchResult e nt t
Oracle
Predicate state
type PredOracle p = Map p PredState Source #
Predicate oracle
makeOracle :: Ord p => [(p, PredState)] -> PredOracle p Source #
Create an oracle from a list
oraclePredicates :: Ord p => PredOracle p -> [(p, PredState)] Source #
Get a list of predicates from an oracle
emptyOracle :: PredOracle p Source #
Oracle that always answer Undef
predIsUnset :: Ord p => PredOracle p -> p -> Bool Source #
Ask an oracle if a predicate is unset
predIsUndef :: Ord p => PredOracle p -> p -> Bool Source #
Ask an oracle if a predicate is undefined
Constraint
data Constraint e p Source #
Predicate p | |
Not (Constraint e p) | |
And [Constraint e p] | |
Or [Constraint e p] | |
Xor [Constraint e p] | |
CBool Bool |
Functor (Constraint e) Source # | |
Eq p => Eq (Constraint e p) Source # | |
Ord p => Ord (Constraint e p) Source # | |
Show p => Show (Constraint e p) Source # | |
(Ord p, Eq e, Eq p) => Predicated (Constraint e p) Source # | |
type PredErr (Constraint e p) Source # | |
type Pred (Constraint e p) Source # | |
type PredTerm (Constraint e p) Source # | |
simplifyConstraint :: Constraint e p -> Constraint e p Source #
Simplify a constraint
constraintReduce :: (Ord p, Eq p, Eq e) => PredOracle p -> Constraint e p -> Constraint e p Source #
Reduce a constraint
Rule
Terminal a | |
NonTerminal [(Constraint e p, Rule e p a)] | |
Fail e |
Functor (Rule e p) Source # | |
(Eq e, Eq p, Eq a) => Eq (Rule e p a) Source # | |
(Ord e, Ord p, Ord a) => Ord (Rule e p a) Source # | |
(Show e, Show p, Show a) => Show (Rule e p a) Source # | |
(Ord p, Eq e, Eq a, Eq p) => Predicated (Rule e p a) Source # | |
type PredErr (Rule e p a) Source # | |
type Pred (Rule e p a) Source # | |
type PredTerm (Rule e p a) Source # | |
orderedNonTerminal :: [(Constraint e p, Rule e p a)] -> Rule e p a Source #
NonTerminal whose constraints are evaluated in order
Earlier constraints must be proven false for the next ones to be considered
evalsTo :: (Ord (Pred a), Eq a, Eq (PredTerm a), Eq (Pred a), Predicated a) => a -> PredTerm a -> Constraint e (Pred a) Source #
Constraint checking that a predicated value evaluates to some terminal
data MatchResult e nt t Source #
Reduction result
NoMatch | |
Match t | |
DontMatch nt | |
MatchFail [e] | |
MatchDiverge [nt] |
Predicated data
class Predicated a where Source #
Predicated data
data T data NT type family RuleT e p a s :: * where RuleT e p a T = a RuleT e p a NT = Rule e p a data PD t = PD { p1 :: RuleT () Bool Int t , p2 :: RuleT () Bool String t } deriving instance Eq (PD T) deriving instance Show (PD T) deriving instance Ord (PD T) deriving instance Eq (PD NT) deriving instance Show (PD NT) deriving instance Ord (PD NT) instance Predicated (PD NT) where type PredErr (PD NT) = () type Pred (PD NT) = Bool type PredTerm (PD NT) = PD T liftTerminal (PD a b) = PD (liftTerminal a) (liftTerminal b) reducePredicates oracle (PD a b) = initP PD PD |> (applyP
reducePredicates oracle a) |> (applyP
reducePredicates oracle b) |> resultP getTerminals (PD as bs) = [ PD a b | a <- getTerminals as , b <- getTerminals bs ] getPredicates (PD a b) = concat [ getPredicates a , getPredicates b ]
Error type
Predicate type
Terminal type
liftTerminal :: PredTerm a -> a Source #
Build a non terminal from a terminal
reducePredicates :: PredOracle (Pred a) -> a -> MatchResult (PredErr a) a (PredTerm a) Source #
Reduce predicates
getTerminals :: a -> [PredTerm a] Source #
Get possible resulting terminals
getPredicates :: a -> [Pred a] Source #
Get used predicates
(Ord p, Eq e, Eq p) => Predicated (Constraint e p) Source # | |
(Ord p, Eq e, Eq a, Eq p) => Predicated (Rule e p a) Source # | |
createPredicateTable :: (Ord (Pred a), Eq (Pred a), Eq a, Predicated a, Predicated a, Pred a ~ Pred a) => a -> (PredOracle (Pred a) -> Bool) -> Bool -> Either (PredTerm a) [(PredOracle (Pred a), PredTerm a)] Source #
Create a table of predicates that return a terminal
initP :: nt -> t -> MatchResult e nt (nt, t) Source #
Initialise a reduction result (typically with two functions/constructors)
applyP :: Predicated ntb => MatchResult e (ntb -> nt) (ntb -> nt, PredTerm ntb -> t) -> MatchResult e ntb (PredTerm ntb) -> MatchResult e nt (nt, t) Source #
Compose reduction results
We reuse the MatchResult data type: * a "terminal" on the left can be used to build either a terminal or a non terminal * a "non terminal" on the left can only be used to build a non terminal
resultP :: MatchResult e nt (nt, t) -> MatchResult e nt t Source #
Fixup result (see initP and applyP)