Logic, machines

&

sequent calculus

Alexander Gryzlov

Adform

19/12/2018

Lists

data List : Type -> Type where
  Nil  :                List a   -- aka []
  (::) : a -> List a -> List a

List membership

These are natural numbers in disguise!

data Elem : a -> List a -> Type where
  Here  :              Elem x (x::xs)
  There : Elem x xs -> Elem x (y::xs)
data Nat : Type where
  Z : Nat
  S : Nat -> Nat

ListS as sets

Subset : List a -> List a -> Type 
Subset {a} xs ys = 
  {x : a} -> Elem x xs -> Elem x ys

Lambda calculus

A formal rewriting system at the heart of FP

 

Untyped :

 

x (variable)
λx.M (abstraction)
M N (application)

+ β-reduction

(λx.M) N → M[x:=N]

untyped Lambda calculus

DeBrujin indices

Term0 : Term
Term0 = App (Lam $ App (Var Z) (Var Z)) 
            (Lam $ Var Z)

Term1 : Term
Term1 = App (App (Lam $ Var Z) (Lam $ Var Z))
            (Lam $ Var Z)

Term2 : Term
Term2 = App (Lam $ Var Z) 
            (App (Lam $ Var Z) (Lam $ Var Z))
data Term = Var Nat 
          | Lam Term
          | App Term Term
(λ x. x x) (λ x. x)

 

((λ x. x) (λ x. x)) 
(λ x. x)

 

(λ x. x) 
((λ x. x) (λ x. x))

untyped Lambda calculus

1.

(λ x. x x) (λ x. x)

~

x. x) (λ x. x)

~

(λ x. x)
2.
((λ x. x) (λ x. x)) 
(λ x. x)

~

x. x) (λ x. x)

~

(λ x. x)
3.
x. x) 
((λ x. x) (λ x. x))

~

x. x) (λ x. x)

~

(λ x. x)

simply-typed Lambda calculus

data Ty = A | Imp Ty Ty
infix 5 ~>
(~>) : Ty -> Ty -> Ty
(~>) = Imp

data Term : List Ty -> Ty -> Type where
  Var : Elem a g                  -> Term g a 
  Lam : Term (a::g) b             -> Term g (a~>b)
  App : Term g (a~>b) -> Term g a -> Term g b
    
TestTy : Ty
TestTy = A ~> A

-- Term1 not typeable because of self-application!
  
Term2 : Term [] TestTy
Term2 = App (App (Lam $ Var Here) (Lam $ Var Here)) (Lam $ Var Here)
  
Term3 : Term [] TestTy
Term3 = App (Lam $ Var Here) (App (Lam $ Var Here) (Lam $ Var Here))
  
Result : Term [] TestTy
Result = Lam $ Var Here 

(structural) Proof theory

A branch of logic studying proofs as mathematical objects

 

Curry-Howard iso:

Theorem ~ Type

Proof ~ Term

Sequent:

For now, let's restrict the RHS to a single formula:

natural deduction

Minimal propositional logic:

Var : 
Elem a g ->
Term g a
Lam :
Term (a::g) b ->
Term g (a~>b)
App : 
Term g (a~>b) ->
Term g a -> 
Term g b

Sequent calculus

VarS : 
Elem a g -> 
TermS g a
Cut :
TermS g a ->
TermS (a::g) b ->
TermS g b
ImpL : 
TermS g a -> 
TermS (b::g) c -> 
TermS ((a~>b)::g) c
ImpR : 
TermS (a::g) b -> 
TermS g (a~>b)

structural properties

weakening contraction  permutation

 

 

Gentzen's LJ

data LJ : List Ty -> Ty -> Type where
  AxJ   : LJ [a] a
  CutJ  : LJ g a -> LJ (a::g) b -> LJ g b
  ImpLJ : LJ g a -> LJ (b::g) c -> LJ ((a~>b)::g) c
  ImpRJ : LJ (a::g) b -> LJ g (a~>b)
  WSJ   : LJ g b -> LJ (a::g) b
  CSJ   : LJ (a::a::g) b -> LJ (a::g) b
  PSJ   : LJ (g ++ a::b::d) c -> LJ (g ++ b::a::d) c

two-sided Sequent calculus

Splits sequents into kinds

and adds activation rules:

+ structural rules for both sides!

two-sided Sequent calculus

mutual 
  data Cmd : List Ty -> List Ty -> Type where 
    C : Term g a d -> CoTerm g a d -> Cmd g d
    CWL : ...
    CCL : ...
    CPL : ...
    CWR : ...

  data Term : List Ty -> Ty -> List Ty -> Type where
    Var : Term [a] a []
    Mu  : Cmd g (a::d) -> Term g a d
    ...

  data CoTerm : List Ty -> Ty -> List Ty -> Type where
    CoVar : CoTerm [] a [a]
    Mut   : Cmd (a::g) d -> CoTerm g a d
    ...

aka Gentzen's LK

two-sided Sequent calculus

mutual 
  data Cmd : List Ty -> List Ty -> Type where 
    C : Term g a d -> CoTerm g a d -> Cmd g d

  data Term : List Ty -> Ty -> List Ty -> Type where
    Var : Elem a g -> Term g a d
    Mu  : Cmd g (a::d) -> Term g a d

  data CoTerm : List Ty -> Ty -> List Ty -> Type where
    CoVar : Elem a d -> CoTerm g a d
    Mut   : Cmd (a::g) d -> CoTerm g a d

internalise structurals

Subset : List a -> List a -> Type
Subset {a} xs ys = {x : a} -> Elem x xs -> Elem x ys

data IsSubset : List a -> List a -> Type where 
  Id    :                 IsSubset     l      l    
  Cons2 : IsSubset l m -> IsSubset (a::l) (a::m) 

shift : IsSubset l m -> Subset l m  
shift  Id        el        = el
shift (Cons2 s)  Here      = Here
shift (Cons2 s) (There el) = There $ shift s el 

mutual    
  shiftCmd : IsSubset g g1 -> IsSubset d d1 
          -> Cmd g d -> Cmd g1 d1    

  shiftTerm : IsSubset g g1 -> IsSubset d d1 
           -> Term g a d -> Term g1 a d1    

  shiftCoTerm : IsSubset g g1 -> IsSubset d d1 
             -> CoTerm g a d -> CoTerm g1 a d1  

Connectives

E.g., we can add function, tuples & discriminated unions:

data Ty = A | Imp Ty Ty | Prod Ty Ty | Sum Ty Ty

mutual 
  data Cmd : List Ty -> List Ty -> Type where 
    C : Term g a d -> CoTerm g a d -> Cmd g d

  data Term : List Ty -> Ty -> List Ty -> Type where
    Var  : Elem a g -> Term g a d
    Mu   : Cmd g (a::d) -> Term g a d
    Lam  : Term (a::g) b d -> Term g (Imp a b) d
    Pair : Term g a d -> Term g b d -> Term g (Prod a b) d
    Inl  : Term g a d -> Term g (Sum a b) d
    Inr  : Term g b d -> Term g (Sum a b) d

  data CoTerm : List Ty -> Ty -> List Ty -> Type where
    CoVar : Elem a d -> CoTerm g a d
    Mut   : Cmd (a::g) d -> CoTerm g a d
    AppC  : Term g a d -> CoTerm g b d -> CoTerm g (Imp a b) d
    MatP  : Cmd (a::b::g) d -> CoTerm g (Prod a b) d
    MatS  : Cmd (a::g) d -> Cmd (b::g) d -> CoTerm g (Sum a b) d

Abstract machines

Like a virtual machine, but abstract :)

Usually includes closures, stacks & environments

KRivine Abstract machine

Lazy (call by name)

KRivine Abstract machine

mutual
  Env : Type 
  Env = List Clos

  data Clos = Cl Term Env

Stack : Type
Stack = List Clos

State : Type
State = (Term, Env, Stack)

step : State -> Maybe State
step (Var  Z   , Cl t e::_,    s) = Just (    t,    e,         s)
step (Var (S n),      _::e,    s) = Just (Var n,    e,         s)
step (Lam t    ,         e, c::s) = Just (    t, c::e,         s)
step (App t u  ,         e,    s) = Just (    t,    e, Cl u e::s)
step  _                           = Nothing

cek

Control + Environment + Kontinuation

Eager (call by value)

cek

mutual
  Env : Type 
  Env = List Clos

  data Clos = Cl Term Env

data Frame = Fun Term Env | Arg Clos

Stack : Type
Stack = List Frame

data State = L Term Env Stack | R Clos Stack

step : State -> Maybe State
step (L (Var  Z)    (v::_)            s ) = Just $ R  v                                  s
step (L (Var (S n)) (_::e)            s ) = Just $ L (Var n)     e                       s
step (L (Lam t)         e             s ) = Just $ R (Cl (Lam t) e)                      s
step (L (App t u)       e             s ) = Just $ L u           e             (Fun t e::s)
step (R (Cl (Lam t)    e) (Fun t1 e1::s)) = Just $ L t1          e1 (Arg (Cl (Lam t) e)::s)
step (R (Cl (Lam t)    e) (    Arg v::s)) = Just $ L t       (v::e)                      s
step  _                                   = Nothing

Deconstructing

application, lambdas & LET

(λx.t) u → t[x:=u]
<λx.t | u·e> → <t[x:=u] | e>
<μ(x·α).c | u·e> → c[x:=u,α:=e]
λx.t === μ(x·α).<t|α>
<t u | e> → <t | u·e>
<μα.c | e> → c[α:=e]

 

t u === μα.<t|u·α>
let x=t in u   ===   μα.<t|μ~x.<u|α>>

Deconstructing

application & lambdas

mutual 
  data Cmd : List Ty -> List Ty -> Type where 
    C : Term g a d -> CoTerm g a d -> Cmd g d

  data Term : List Ty -> Ty -> List Ty -> Type where
    Var  : Elem a g -> Term g a d
    Mu   : Cmd g (a::d) -> Term g a d
    MatC : Cmd (a::g) (b::d) -> Term g (Imp a b) d

  data CoTerm : List Ty -> Ty -> List Ty -> Type where
    CoVar : Elem a d -> CoTerm g a d
    Mut   : Cmd (a::g) d -> CoTerm g a d
    AppC  : Term g a d -> CoTerm g b d -> CoTerm g (Imp a b) d

lam : Term (a::g) b d -> Term g (Imp a b) d
lam t = 
  MatC $ C (shiftTerm t) (CoVar Here)

app : Term g (Imp a b) d -> Term g a d -> Term g b d
app t u = 
  Mu $ 
  C (shiftTerm t) (AppC (shiftTerm u) (CoVar Here))

let_ : Term g a d -> Term (a::g) b d -> Term g b d    
let_ t u = Mu $ C (shiftTerm t) 
                  (Mut $ C (shiftTerm u) (CoVar Here))

call/cc

callcc : Term g (Imp (Imp a b) a) (a::d) -> Term g a d
callcc f = 
  Mu $ C f
         (AppC 
           (MatC $ C (Var Here) (CoVar $ There Here))
           (CoVar Here))

reduction

reduce : Cmd g d -> Maybe (Cmd g d)
reduce (C (Mu c)    e        ) = Just $ cosubst c e
reduce (C  t       (Mut c)   ) = Just $ subst c t
reduce (C (MatC c) (AppC t e)) = Just $ subst 
                                        (cosubst c (shiftCoTerm e)) 
                                        (shiftTerm t)
reduce  _                      = Nothing

critical pair!

Dual reduction - LKT

Amounts to lazy evaluation

Dual reduction - LKT

mutual 
  data Cmd : List Ty -> List Ty -> Type where 
    C : Term g a d -> CoTerm g a d -> Cmd g d

  data Term : List Ty -> Ty -> List Ty -> Type where
    Var  : Elem a g -> Term g a d
    Mu   : Cmd g (a::d) -> Term g a d
    MatC : Cmd (a::g) (b::d) -> Term g (Imp a b) d

  data CoTerm : List Ty -> Ty -> List Ty -> Type where
    CoVal : CoValue g a d -> CoTerm g a d
    Mut   : Cmd (a::g) d -> CoTerm g a d

  data CoValue : List Ty -> Ty -> List Ty -> Type where
    Empty : CoValue g a d
    CoVar : Elem a d -> CoValue g a d
    AppC  : Term g a d -> CoValue g b d 
         -> CoValue g (Imp a b) d

Dual reduction - LKQ

Amounts to eager evaluation

Dual reduction - LKQ

mutual 
  data Cmd : List Ty -> List Ty -> Type where 
    C : Term g a d -> CoTerm g a d -> Cmd g d

  data Term : List Ty -> Ty -> List Ty -> Type where
    Val  : Value g a d -> Term g a d
    Mu   : Cmd g (a::d) -> Term g a d

  data Value : List Ty -> Ty -> List Ty -> Type where
    Var  : Elem a g -> Value g a d
    MatC : Cmd (a::g) (b::d) -> Value g (Imp a b) d

  data CoTerm : List Ty -> Ty -> List Ty -> Type where
    CoVar : Elem a d -> CoTerm g a d
    Empty : CoTerm g a d
    Mut   : Cmd (a::g) d -> CoTerm g a d
    AppC  : Value g a d -> CoTerm g b d 
         -> CoTerm g (Imp a b) d

Polarization

Types

Terms

more polarities

call by need! (true laziness)

effects

reduce : Monad m => Cmd g d -> m (Cmd g d)
...



Adjunction f g => Monad (Compose g f)
???

generalizing connectives

Move to

  • inductive sums of products and
  • coinductive records of functions/matches

 

Infinite structures become first class

polymorphism

Both universal and existential

dependent types

Literature

Thanks!

Copy of Logic, machines and sequent calculus

By Oleg Nizhnik

Copy of Logic, machines and sequent calculus

  • 842