There is a function simplify , where simplify :: Proposition -> Proposition
, where
data Proposition = Const Bool
| Var String
| And Proposition Proposition
| Or Proposition Proposition
| Not Proposition
deriving Show
It is used to reduce the size of a given proposition.
For example,
simplify (Const False `And` a) == Const False
simplify (Const True `And` a) == a
My attempt is to use pattern matching in that case:
simplify (Const False `And` a) = Const False
simplify (Const False `Or` a) = Const False
simplify (Const False `Not` a) = Const False
simplify (Const True `And` a) = a
simplify (Const True `Or` a) = a
simplify (Const True `Not` a) = a
simplify prop = prop
But I am receiving two types of errors:
The constructor 'Not' should have 1 argument, but has been given 2
Variable not in scope: a :: Proposition
What am I doing wrong?
There are several things that can be improved in your approach.
First, there are a few errors in your function, as already pointed out in the commments, the 'Not' constructor only takes one argument so
simplify (Const False `Not` a) = Const False
and
simplify (Const True `Not` a) = a
will not work. In addition there are some logic errors,
simplify (Const False `Or` a) = Const False
and
simplify (Const True `Or` a) = a
are incorrect.
Once these are fixed, your function should properly simplify, but only on the top level of the proposition. In order to simplify the whole proposition you need to add recursive calls to each right side that includes a variable and add the missing cases that are currently covered by
simplify prop = prop
eg you should change your cases like
simplify (Const True `And` a) = a
to
simplify (Const True `And` a) = simplify a
and add cases like
simplify (a `And` b) = ((simplify a) `And` (Simplify b))
This way the function will go through the entire proposition and stop at the first level. One way to make sure you have all cases covered is to remove
simplify prop = prop
and make a case for each constructor. For the variables, you can just write
simplify (Var a) = (Var a)
and that will leave them as they are.
In addition, top level functions are expected to have type annotations, so consider adding
simplify :: Proposition -> Proposition
above your function declaration.
A minor nitpick: In cases like
simplify (Const False `And` a) = Const False
you don't need to bind a and can instead use a wildcard, like so:
simplify (Const False `And` _) = Const False
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.