module Bool where
-- | Syntax of the simple Boolean expression language.
data Exp
= Tru
| Fls
| Not Exp
| If Exp Exp Exp
deriving (Eq,Show)
-- | Big-step semantics.
eval :: Exp -> Exp
eval Tru = Tru
eval Fls = Fls
eval (Not e) = case eval e of
Tru -> Fls
Fls -> Tru
_ -> error "eval: whoops"
eval (If c t e) = case eval c of
Tru -> eval t
Fls -> eval e
_ -> error "eval: whoops"
-- | One-step reduction relation for the small-step semantics.
step :: Exp -> Exp
-- reflexive rules (not actually part of the relation)
step Tru = Tru
step Fls = Fls
-- reduction rules
step (Not Tru) = Fls
step (Not Fls) = Tru
step (If Tru t e) = t
step (If Fls t e) = e
-- congruence rules
step (Not e) = Not (step e)
step (If c t e) = If (step c) t e
-- | Reflexive, transitive closure of the one-step reduction.
steps :: Exp -> Exp
-- reflexive rules for values
steps Tru = Tru
steps Fls = Fls
-- transitivity rule for non-values
steps e = steps (step e)
-- | Produce the reduction sequence for an expression.
reduce :: Exp -> [Exp]
reduce Tru = [Tru]
reduce Fls = [Fls]
reduce e = e : reduce (step e)