1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE DeriveGeneric #-}
4 module Distribution
.Types
.Condition
12 import Distribution
.Compat
.Prelude
15 -- | A boolean expression parameterized over the variable type used.
20 | COr
(Condition c
) (Condition c
)
21 | CAnd
(Condition c
) (Condition c
)
22 deriving (Show, Eq
, Typeable
, Data
, Generic
)
24 -- | Boolean negation of a 'Condition' value.
25 cNot
:: Condition a
-> Condition a
26 cNot
(Lit b
) = Lit
(not b
)
30 -- | Boolean AND of two 'Condition' values.
31 cAnd
:: Condition a
-> Condition a
-> Condition a
32 cAnd
(Lit
False) _
= Lit
False
33 cAnd _
(Lit
False) = Lit
False
38 -- | Boolean OR of two 'Condition' values.
39 cOr
:: Eq v
=> Condition v
-> Condition v
-> Condition v
40 cOr
(Lit
True) _
= Lit
True
41 cOr _
(Lit
True) = Lit
True
50 instance Functor Condition
where
51 f `
fmap` Var c
= Var
(f c
)
52 _ `
fmap` Lit c
= Lit c
53 f `
fmap` CNot c
= CNot
(fmap f c
)
54 f `
fmap` COr c d
= COr
(fmap f c
) (fmap f d
)
55 f `
fmap` CAnd c d
= CAnd
(fmap f c
) (fmap f d
)
57 instance Foldable Condition
where
58 f `foldMap` Var c
= f c
59 _ `foldMap` Lit _
= mempty
60 f `foldMap` CNot c
= foldMap f c
61 f `foldMap` COr c d
= foldMap f c `mappend` foldMap f d
62 f `foldMap` CAnd c d
= foldMap f c `mappend` foldMap f d
64 instance Traversable Condition
where
65 f `traverse` Var c
= Var `
fmap` f c
66 _ `traverse` Lit c
= pure
$ Lit c
67 f `traverse` CNot c
= CNot `
fmap` traverse f c
68 f `traverse` COr c d
= COr `
fmap` traverse f c
<*> traverse f d
69 f `traverse` CAnd c d
= CAnd `
fmap` traverse f c
<*> traverse f d
71 instance Applicative Condition
where
75 instance Monad Condition
where
79 (>>=) (Lit x
) _
= Lit x
82 (>>=) (CNot x
) f
= CNot
(x
>>= f
)
83 (>>=) (COr x y
) f
= COr
(x
>>= f
) (y
>>= f
)
84 (>>=) (CAnd x y
) f
= CAnd
(x
>>= f
) (y
>>= f
)
86 instance Monoid
(Condition a
) where
90 instance Semigroup
(Condition a
) where
93 instance Alternative Condition
where
97 instance MonadPlus Condition
where
101 instance Binary c
=> Binary
(Condition c
)
102 instance Structured c
=> Structured
(Condition c
)
103 instance NFData c
=> NFData
(Condition c
) where rnf
= genericRnf
105 -- | Simplify the condition and return its free variables.
108 -> (c
-> Either d
Bool)
109 -- ^ (partial) variable assignment
110 -> (Condition d
, [d
])
111 simplifyCondition cond i
= fv
. walk
$ cond
113 walk cnd
= case cnd
of
114 Var v
-> either Var Lit
(i v
)
116 CNot c
-> case walk c
of
117 Lit
True -> Lit
False
118 Lit
False -> Lit
True
120 COr c d
-> case (walk c
, walk d
) of
121 (Lit
False, d
') -> d
'
122 (Lit
True, _
) -> Lit
True
123 (c
', Lit
False) -> c
'
124 (_
, Lit
True) -> Lit
True
125 (c
', d
') -> COr c
' d
'
126 CAnd c d
-> case (walk c
, walk d
) of
127 (Lit
False, _
) -> Lit
False
129 (_
, Lit
False) -> Lit
False
131 (c
', d
') -> CAnd c
' d
'
138 COr c1 c2
-> fv
' c1
++ fv
' c2
139 CAnd c1 c2
-> fv
' c1
++ fv
' c2