Slides etc.
Here are the slides for my talk on Types & Proof Assistants in the Tufts Logic Working Group.
find a working version of the Haskell code from the talk here
(This code is not quite identical to that in the talk – e.g. it uses the built-in Haskell operators
&&
and||
etc rather than the versions defined in the talk. And the evaluator returns aMaybe Bool
rather than aBool
)you can also see this code below
also find the Agda code from the talk here
Code
Haskell source for the “propositional logic” evaluator
module Main where
import Prelude
data Formula = Var String
| And Formula Formula
| Or Formula Formula
| Not Formula
| Implies Formula Formula
data Value = Value String Bool
lookup' :: [ Value ] -> String -> Maybe Bool
= Nothing
lookup' [] _ Value s b) : tail) t = if s==t then Just b else lookup' tail t
lookup' ((
eval :: [ Value ] -> Formula -> Maybe Bool
Var s) = lookup' vals s
eval vals (Not p) = do
eval vals (<- eval vals p
result pure $ not result
And p q) = do
eval vals (<- eval vals p
pp <- eval vals q
qq pure $ pp && qq
Or p q) = do
eval vals (<- eval vals p
pp <- eval vals q
qq pure $ pp || qq
Implies p q) = do
eval vals (<- eval vals p
pp <- eval vals q
qq pure $ not pp || qq
-- here is a formula
f :: Formula
= And (Var "p") (Or (Var "q") (And (Not (Var "r")) (Var "p")))
f
-- and here are values for the propositional variables
= [ Value "p" True
values Value "q" False
, Value "r" True
,
]
-- and this will evaluate the formula
result :: Maybe Bool
= eval values f
result
-- should evaluate to: Just False
-- λ> result
-- Just False
-- λ>
main :: IO ()
=
main putStrLn ""
Agda source
module talk where
-- define the natural numbers
data ℕ : Set where
: ℕ
zero succ : ℕ -> ℕ
{-# BUILTIN NATURAL ℕ #-}
-- additional of natural numbers
+_ : ℕ → ℕ → ℕ
_+ b = b
zero succ n + b = succ (n + b)
--------------------------------------------------------------------------------
-- Cartesian product
data _×_ ( A B : Set ) : Set where
<_,_> : A -> B -> A × B
-- example of an ordered pair
: ℕ × ℕ
pair = < 1 , 2 >
pair
--------------------------------------------------------------------------------
-- "vectors" of some type A of length n
data Vec ( A : Set) : ℕ -> Set where
: Vec A zero
[] _::_ : { n : ℕ } -> A -> Vec A n -> Vec A (succ n)
-- "zip" two vectors of length n
zip : { A B : Set } -> ( n : ℕ ) -> Vec A n -> Vec B n -> Vec (A × B) n
zip zero [] [] = []
zip (succ n) (x :: xs) (y :: ys) = < x , y > :: (zip n xs ys)
-- examples of vetors & zip
: Vec ℕ 2
a = 1 :: (2 :: [])
a
: Vec ℕ 2
b = 0 :: (3 :: [])
b
--------------------------------------------------------------------------------
-- conjuction
&_ : Set -> Set -> Set
_A & B = A × B
-- here is a "proof" that A & B -> A
: { A B : Set } -> A & B -> A
first < a , b > = a
first
-- the observation is that if a : A and b : B
-- then first < a , b > : A is a "non-canonical"
-- proof of A
--------------------------------------------------------------------------------
-- Martin-Löf defines equality in predicate logic [19] as the set
-- inductively generated by the reflexive rule
data _≡_ {A : Set} : A -> A -> Set where
: (a : A) -> a ≡ a
refl
-- the constructor refl a amounts a canonical proof of the reflexive law a ≡ a
--------------------------------------------------------------------------------
-- here is a proof that 0 + x = x
+-identity-left : ∀ (x : ℕ) -> (0 + x) ≡ x
+-identity-left x = refl x
-- notice: this "function" takes as input a natural number x, and returns
-- a term of a type whose definition *depends on x*.
-- this proof amounts to the reflexive law the point is that on the
-- left hand side, 0 + x is "definitionally equal" to x (see the
-- definition of the term _+_, above )
-- to prove x + 0 = x is slightly more difficult because this equality
-- doesn't result directly from the defn of _+_
-- we use the following natural recursion "combinator"
: {C : ℕ -> Set} -- view C as a family of propositions indexed by ℕ
natrec -> (C zero) -- base case
-> ( (m : ℕ) -- ind step {
-> C m -- { induction hyp
-> C (succ m) ) -- {
-> (n : ℕ)
-> C n -- conclusion
= p
natrec p h zero succ n) = h n (natrec p h n)
natrec p h (
-- and we'll use the following term in our induction step below. For
-- natural numbers n,m this transforms a proof of n ≡ m into a proof
-- of (n+1) ≡ (m+1)
-succ : { n m : ℕ } -> n ≡ m -> succ n ≡ succ m
eq-succ (refl m) = refl (succ m)
eq
-- finally here is our proof that x + 0 = x
+-identity-right : (x : ℕ) -> (x + 0) ≡ x
+-identity-right x = natrec
-> (k + 0) ≡ k }
{\k 0)
(refl -> eq-succ ih)
(\k ih x