Александр Грызлов
Statebox
Scaλa Russia 2019
Москва, 28/09/2019
1
инженерия доказательств
модальная логика
3
системы модальных типов
эффекты и линейные типы
продвинутые системы:
Granule и Blott
2
теория доказательств
лямбда-исчисление
финал
использование корректных/логических инструментов для моделирования и формализации чего-то кроме программ:
две модальности:
◻ (необходимо) и ◊ (возможно)
предпорядок систем (от аппликатива до комонады):
набор модальностей в зависимости от формулировки:
3 ветви инженерии доказательств:
модальная логика:
3 вида систем:
(2 и 3 были изобретены Герхардом Генценом в 1930х)
доказательства строятся из применений правил
строительный блок правила называется секвенцией:
аксиома интродукция элиминация
практически Scala:
но:
data List : Type -> Type where
Nil : List a -- aka `[]`
(::) : a -> List a -> List a -- aka `Cons`data Nat : Type where
Z : Nat
S : Nat -> Natстерев индексы, получим снова унарные числа
data Elem : a -> List a -> Type where
Here : Elem x (x::xs)
There : Elem x xs -> Elem x (y::xs)--elem2Nat : {a : t} -> {g : List t} -> Elem a g -> Nat
elem2Nat : Elem a g -> Nat
elem2Nat Here = Z
elem2Nat (There el) = S (elem2Nat el)
конструктивное доказательство вхождения это номер элемента
открыто Вильямом Говардом в 1969
Var :
Elem a g ->
Term g aLam :
Term (a::g) b ->
Term g (a~>b)App :
Term g (a~>b) ->
Term g a ->
Term g b
aka "глобально безымянное" представление
λx.x ~ λ 0
λx.λy.y ~ λ λ 0
λx.λy.x ~ λ λ 1
λx.λy.(x y) ~ λ λ (1 0)
λx.λy.λz.x ~ λ λ λ 2
infixr 5 ~>
data Ty = A | (~>) Ty Ty
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
IdTy : Ty
IdTy = A ~> A
-- ((λx.x) (λx.x)) (λx.x)
Term1 : Term [] IdTy
Term1 = App (App (Lam $ Var Here) (Lam $ Var Here)) (Lam $ Var Here)
-- (λx.x) ((λx.x) (λx.x))
Term2 : Term [] IdTy
Term2 = App (Lam $ Var Here) (App (Lam $ Var Here) (Lam $ Var Here))
-- λx.x
Result : Term [] IdTy
Result = Lam $ Var Here начнем с фрагмента алетической логики, т.е., единственной модальности ◻
infixr 5 ~>
data Ty = A | (~>) Ty Ty | Box Ty
data Term : List Ty -> List Ty -> Ty -> Type where
Var : Elem a g -> Term d g a
Lam : Term d (a::g) b -> Term d g (a~>b)
App : Term d g (a~>b) -> Term d g a -> Term d g b
Shut : Term [] d a -> Term d g (Box a)
Letbox : Term d g (Box a) -> Term (a::d) g b -> Term d g b
axiomK : Term d g (Box (a ~> b) ~> Box a ~> Box b)
axiomK = Lam $ Lam $ Letbox (Var $ There Here)
(Letbox (Var Here)
(Shut $ App (Var $ There Here) (Var Here)))data Term : List Ty -> List Ty -> Ty -> Type where
Var : Elem a g -> Term d g a
MVar : Elem a d -> Term d g a
Lam : Term d (a::g) b -> Term d g (a~>b)
App : Term d g (a~>b) -> Term d g a -> Term d g b
Shut : Term d [] a -> Term d g (Box a)
Letbox : Term d g (Box a) -> Term (a::d) g b -> Term d g b
axiomK : Term d g (Box (a ~> b) ~> Box a ~> Box b)
axiomK = Lam $ Lam $ Letbox (Var $ There Here)
(Letbox (Var Here)
(Shut $ App (MVar $ There Here) (MVar Here)))
-- aka `eval`
axiomT : Term d g (Box a ~> a)
axiomT = Lam $ Letbox (Var Here) (MVar Here)
axiom4 : Term d g (Box a ~> Box (Box a))
axiom4 = Lam $ Letbox (Var Here) (Shut $ Shut $ MVar Here)в интерпретации Фитча вместо стека контекстов используется контекст с замка́ми:
data Term : List (List Ty) -> List Ty -> Ty -> Type where
Var : Elem a g -> Term ph g a
Lam : Term ph (a::g) b -> Term ph g (a~>b)
App : Term ph g (a~>b) -> Term ph g a -> Term ph g b
Shut : Term (g::ph) [] a -> Term ph g (Box a) -- ~quasiquote
Open : Term ph g (Box a) -> Term (g::ph) d a -- ~unquote0
axiomK : Term ph g (Box (a ~> b) ~> Box a ~> Box b)
axiomK = Lam $ Lam $ Shut $ App (Open $ Var $ There Here)
(Open $ Var Here)data Pref : a -> List a -> a -> List a -> Type where
HereP : Pref x xs x xs
ThereP : Pref x xs y ys -> Pref x xs z (y::ys)
data Term : List (List Ty) -> List Ty -> Ty -> Type where
Var : Elem a g -> Term ph g a
Lam : Term ph (a::g) b -> Term ph g (a~>b)
App : Term ph g (a~>b) -> Term ph g a -> Term ph g b
Shut : Term (g::ph) [] a -> Term ph g (Box a) -- ~quasiquote
Open : Pref g ph d ps -> Term ph g (Box a) -> Term ps d a -- ~unquoteN
axiomK : Term ph g (Box (a ~> b) ~> Box a ~> Box b)
axiomK = Lam $ Lam $ Shut $ App (Open (ThereP HereP) (Var $ There Here))
(Open (ThereP HereP) (Var Here))
axiomT : Term ph g (Box a ~> a)
axiomT = Lam $ Open HereP (Var Here)
axiom4 : Term ph g (Box a ~> Box (Box a))
axiom4 = Lam $ Shut $ Shut $ Open (ThereP $ ThereP HereP) (Var Here)
-- элиминация паттерн-матчингом
let (a, b) = a⊕b in foo a b
-- элиминация проекциями
let a = fst a&b in foo a
let b = snd a&b in bar b...
Letbox : Term d g (Box a) -> Term (a::d) g b -> Term d g b
axiomK : Term d g (Box (a ~> b) ~> Box a ~> Box b)
axiomK = Lam $ Lam $ Letbox (Var $ There Here)
(Letbox (Var Here)
(Shut $ App (MVar $ There Here) (MVar Here)))в диадической интерпретации мы "паттерн-матчим" содержимое коробки:
...
Open : Pref g ph d ps -> Term ph g (Box a) -> Term ps d a
axiomK : Term ph g (Box (a ~> b) ~> Box a ~> Box b)
axiomK = Lam $ Lam $ Shut $ App (Open (ThereP HereP) (Var $ There Here))
(Open (ThereP HereP) (Var Here))в Крипке-Фитча мы "проецируем" нужный контекст:
infixr 5 ~*
data Ty = A
| (~*) Ty Ty
| Bang Ty -- !
data Split : List a -> List a -> List a -> Type where
Nil : Split [] [] []
ConsR : Split xs ls rs -> Split (x::xs) ls (x::rs)
ConsL : Split xs ls rs -> Split (x::xs) (x::ls) rs
data Term : List Ty -> List Ty -> Ty -> Type where
Var : Term [a] g a
IVar : Elem a g -> Term [] g a
Lam : Term (a::l) g b -> Term l g (a~*b)
App : Split l l1 l2 -> Term l1 g (a~*b) -> Term l2 g a -> Term l g b
Lift : Term [] g a -> Term [] g (Bang a)
Letbang : Split l l1 l2 -> Term l1 g (Bang a) -> Term l2 (a::g) b -> Term l g b
ok : Term [] g (a ~* a)
ok = Lam Var
ok2 : Term [] g (a ~* Bang b ~* a)
ok2 = Lam $ Lam $ Letbang (ConsL $ ConsR Nil) Var Var
-- bad : Term [] [] (a ~* b ~* a)
infixr 5 ~>
data Ty = A
| (~>) Ty Ty
| M Ty -- effect
mutual
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
Val : PTerm g a -> Term g (M a)
data PTerm : List Ty -> Ty -> Type where
Wrap : Term g a -> PTerm g a
Letval : Term g (M a) -> PTerm (a::g) b -> PTerm g bmap : Term g ((a ~> b) ~> M a ~> M b)
map = Lam $ Lam $ Val $ Letval (Var Here)
(Wrap $ App (Var $ There $ There Here)
(Var Here))
pure : Term g (a ~> M a)
pure = Lam $ Val $ Wrap $ Var Here
flatten : Term g (M (M a) ~> M a)
flatten = Lam $ Val $ Letval (Var Here)
(Letval (Var Here)
(Wrap $ Var Here))
flatMap : Term g ((a ~> M b) ~> M a ~> M b)
flatMap = Lam $ Lam $ Val $ Letval (Var Here)
(Letval (App (Var $ There $ There Here)
(Var Here))
(Wrap $ Var Here))-- You cannot have your cake and eat it...
-- impossible : Cake → (Happy, Cake)
-- impossible cake = (eat cake, have cake)
-- ...unless you have infinite cake
possible : Cake [∞] → (Happy, Cake [∞])
possible lotsOfCake =
let [cake] = lotsOfCake in (eat cake, [have cake])
-- ...or to there is a more precise way
accurate : ∀ {n : Nat} . Cake [n+1] → (Happy, Cake [n])
accurate lotsOfCake =
let [cake] = lotsOfCake in (eat cake, [have cake])