Сейчас у меня есть код, который по существу работает следующим образом:
data Expression
= Literal Bool
| Variable String
| Not Expression
| Or Expression Expression
| And Expression Expression
deriving Eq
simplify :: Expression -> Expression
simplify (Literal b) = Literal b
simplify (Variable s) = Variable s
simplify (Not e) = case simplify e of
(Literal b) -> Literal (not b)
e' -> Not e'
simplify (And a b) = case (simplify a, simplify b) of
(Literal False, _) -> Literal False
(_, Literal False) -> Literal False
(a', b') -> And a' b'
simplify (Or a b) = case (simplify a, simplify b) of
(Literal True, _) -> Literal True
(_, Literal True) -> Literal True
(a', b') -> Or a' b'
И многие другие подобные шаблоны, касающиеся всех способов упрощения булевого выражения. Однако, поскольку я добавляю больше операторов и правил, это растет очень и чувствует... неуклюжий. Тем более, что некоторые правила должны быть добавлены дважды для учета коммутативности.
Как я могу красиво реорганизовать партии и множество шаблонов, некоторые из которых (большинство, я бы сказал), даже симметричны (например, возьмем шаблоны And и Or)?
В настоящее время добавление правила для упрощения And (Variable "x") (Not (Variable "x"))
to Literal False
требует от меня добавить два вложенных правила, которые практически не оптимальны.