Lecture 3 (2018-01-23)
Our first interpreter; type classes
> module Lec03 where
We saw some examples from the homework and did some refactoring as a
class.
Then I introduced us to our first interpreter. We started on the
board, defining a grammar like so:
```
p, q in Prop ::= ⊤ | ⊥ | p ∧ q | p ∨ q | ¬ p | p ⇒ q
p1 = ⊤ ∧ ⊥
p2 = ⊥ ∨ ⊥
```
We talked about what the propositions p1 and p2 mean... nothing, yet!
We had to define an interpretation function, where we interpret
elements of Prop as booleans:
```
2 = { true, false} with standard operations &&, ||, and !
interp : Prop -> 2
interp(⊤) = true
interp(⊥) = false
interp(p ∧ q) = interp(p) && interp(q)
interp(p ∨ q) = interp(p) || interp(q)
interp(¬ p) = !interp(p)
interp(p ⇒ q) = !interp(p) || interp(q)
```
Then we did the same in Haskell:
> data Prop =
> T
> | F
> | And Prop Prop
> | Or Prop Prop
> | Not Prop
> | Implies Prop Prop
>
> p1 :: Prop
> p1 = T `And` F
>
> interp :: Prop -> Bool
> interp T = True
> interp F = False
> interp (And p q) = interp p && interp q
> interp (Or p q) = interp p || interp q
> interp (Not p) = not $ interp p
> interp (Implies p q) = not (interp p) || interp q
We wrote a "pretty printer" for `Prop` which prints out appropriately
parenthesized concrete syntax. It was a little aggressive, though,
printing *way* too many parentheses:
> instance Show Prop where
> show T = "T"
> show F = "F"
> show (And a b) =
> "And (" ++ show a ++ ") (" ++ show b ++ ")"
> show (Or a b) =
> "Or (" ++ show a ++ ") (" ++ show b ++ ")"
> show (Implies a b) =
> "Implies (" ++ show a ++ ") (" ++ show b ++ ")"
> show (Not a) = "Not (" ++ show a ++ ")"
Finally, we talked about how we can manipulate the abstract syntax of
`Prop` in its own right; for example, we can translate away any use of
`Implies`.
> -- | Compile away implication in propositions.
> --
> -- Examples:
> --
> -- >>> interp (compile (Implies (Or T F) F))
> -- False
> --
> -- >>> compile (Or T F)
> -- Or T F
> --
> -- >>> compile (Or (Implies F T) F)
> -- (Or (Or (Not F) T) F)
> compile :: Prop -> Prop
> compile (Implies p q) = Not (compile p) `Or` compile q
> compile (And p q) = And (compile p) (compile q)
> compile (Or p q) = Or (compile p) (compile q)
> compile (Not p) = Not $ compile p
> compile T = T
> compile F = F