190 likes | 340 Views
Jednoduchý typovaný λ -calcul. Typy: základné: A, B, … f unkcionálne: t 1 → t 2 ak M:t 1 →t 2 , N:t 1 , potom (M N):t 2 ak x:t 1 , M:t 2 , potom (λx.M):t 1 →t 2 Konvencia: → je asociat ívna doprava t 1 → t 2 → t 3 = t 1 → (t 2 → t 3 ). Jednoduchý λ -calcul, F 1. Termy
E N D
Jednoduchý typovaný λ-calcul • Typy: • základné: A, B, … • funkcionálne: t1 → t2 • ak M:t1→t2, N:t1, potom (M N):t2 • ak x:t1, M:t2, potom (λx.M):t1→t2 • Konvencia: → je asociatívna doprava • t1→ t2 → t3 = t1→ (t2 → t3)
Jednoduchý λ-calcul, F1 Termy t ::= x | λx.t | (t t) | n | + Typy α, β ::= Int | α→ β {x:α}:Γ├ x:α [VAR] {x:α}:Γ├ N:β [ABS] Γ├ (λx.N):α→β Γ├ M:α→β, Γ├ N:α [APPL] Γ├ (M N):β Γ├n:Int[INT] Γ├ +:Int→Int→Int [PLUS]
Tipujme typy • λx.x • (λxα.xα)β, potom β = α→α • λxy.x • (λxα yβ.xα)δ, potom δ = α→β→α • (λx.x)y • (λxα.xα)β yδ, potom β = α→α, δ = a • [(λxα.xα)α→α yα]α • λxyz.(xz)(yz) • λxαyβzδ.[(xαzδ)η(yβzδ)ε ]θ, α = δ→η, β = δ→ε, η = ε→θ • x:α=δ→(ε→θ), y:β = δ→ε, z:δ • (δ→(ε→θ))→(δ→ε)→δ→θ, výsledok je typu θ • λx.xx • (λxα.(xα xα)β)δ, potom α =?α→β, nemá riešenie... Sústava rovníc
Normálne formy Niektoré λ-termy nie sú otypovateľné,Y= Y = λf.(λx. f(x x)) (λx. f(x x)) :-) Church-Rosserova vlastnosť platí aj pre typovaný λkalkul Typovaný λ-term má normálnu formu (silne normalizovateľný, noetherovský) Neexistuje nekonečné odvodenie...
data LExp = LAMBDA String LExp | ID String | APL LExp LExp | CON String | CN Integer deriving(Show, Read, Eq) data Type = TInteger | Tvar Integer | Type :→ Type deriving(Show, Read, Eq) Type checkingvs. inference checkType :: LExp → Type → Bool Problém: • checkType (A B) T2 = checkType A (T1→T2) && checkType B T1 • ako uhádnuť T1 ??? typeInference:: LExp → Maybe Type = (Just Type | Nothing) Problém: • inferType (λx.M) = T1 → (inferType M) • Ako zistiť typ premennej x, T1 ???
data LExp = LAMBDA StringType LExp | ID String | APL LExp LExp | CON String | CN Integer deriving(Show, Read, Eq) data Type = TInteger | Type :→ Type deriving(Show, Read, Eq) Anotáciepremenných Termy t ::= x | λx:α.t | (t t) | n | + • ak x:T1, M:T2, potom (λx:T1.M): T1→T2 type Context = [(String, Type)] -- premenná a jej typ inferType :: Context → LExp → Maybe Type inferType ctx(ID var) = lookup var ctx -- [VAR] inferType ctx (APL m n) = t2 where -- [APPL] t1 :→ t2 = inferType ctx m -- môže výjsť Nothing, potom propaguj t3 = inferType ctx n-- Nothing aj do výsledku t1 == t3 inferType ctx (LAMBDA x t1 m) = t1 :→ inferType ((x,t1):ctx) m -- [ABS]
data LExp = LAMBDA StringLExp | ID String | APL LExp LExp | CON String | CN Integer deriving(Show, Read, Eq) data Type = TInteger | Tvar Integer | Type :→ Type deriving(Show, Read, Eq) Typové premenné • ak nepoznáme konkrétny typ, zavedieme typovú premennú, • algoritmus zozbiera podmienky (rovnosti) pre typové premenné, • ak máme šťastie, podarí sa nám ich vyriešiť • typové premenné: α, β,δ, η, δ, ε, θ budeme radšej indexovať type Constraints = [(Type,Type)] infer :: Context->LExp->Constraints->Constraints inferType ctx (APL m n)eqs = t2, {t1 = t2}, eqs’’ where -- [APL] t3→t2, eqs’ = inferType ctx meqs t1, eqs’’ = inferType ctx b eqs’ inferType ctx (LAMBDA x m) eqs= t1→t2, eqs’ -- [ABS] -- t1 je nová typová premenná where t2,eqs’ = inferType (x,t1):ctx m inferType ctx (ID var) eqs= lookup var ctx, eqs -- [VAR] Dostaneme sústavu rovníc, ktorú riešime
Inferencia typu λf.λa.λb.λc.c (f a) (f b):T, Ø, Ø ((c (f a)) (f b)):T4, f:T0,a:T1, b:T2, c:T3, {T=T0→T1→T2→T3→T4} (c (f a)):T5, (f b):T6, f:T0, a:T1, b:T2, c:T3, {T=T0→T1→T2→T3→T4, T5=T6→T4} c:T3, (f a):T8, (f b):T6, f:T0, a:T1, b:T2, c:T3,{T=T0→T1→T2→T3→T4, T5=T6→T4, T3=T8→T5} c:T3, (f a):T8, (f b):T6, f:T0, a:T1, b:T2, c:T3, {T=T0→T1→T2→T3→T4, T5=T6→T4, T3=T8→T5, T0=T1→T8, T0=T2→T6} Sústava rovníc: {T=T0→T1→T2→T3→T4, T5=T6→T4, T3=T8→T5, T0=T1→T8, T0=T2→T6} {T=T0→T1→T2→T3→T4, T5=T6→T4, T3=T8→T5, T0=T1→T8, T2=T1, T8=T6} Riešenie: T=T0→T1→T2→T3→T4 =(T1→T8)→T1→T1→(T8→T5)→T4= (T1→T8)→T1→T1→(T8→T8→T4) →T4
Inferencia typu λxyz.(xz)(yz):T, Ø, Ø λyz.(xz)(yz):T2, x:T1,{T=T1→T2} λz.(xz)(yz):T4, y:T3, x:T1,{T=T1→T2, T2=T3→T4} (xz)(yz):T6, z:T5, y:T3, x:T1,{T=T1→T2, T2=T3→T4, T4=T5→T6} (xz):T7, (yz):T8, z:T5, y:T3, x:T1, {T=T1→T2, T2=T3→T4, T4=T5→T6, T7=T8→T6} x:T9, z:T10, (yz):T8, z:T5, y:T3, x:T1, {T=T1→T2, T2=T3→T4, T4=T5→T6, T7=T8→T6,T9=T10→T7, T9=T1, T10=T5} y:T11, z:T12, z:T5, y:T3, x:T1, {T=T1→T2, T2=T3→T4, T4=T5→T6, T7=T8→T6,T9=T10→T7, T9=T1, T10=T5, T11=T12→T8, T11=T3, T12=T5} Sústava rovníc: {T=T1→T2, T2=T3→T4, T4=T5→T6, T7=T8→T6,T9=T10→T7, T9=T1, T10=T5, T11=T12→T8,T11=T3, T12=T5} {T=T1→T2, T2=T3→T4, T4=T5→T6, T7=T8→T6, T1=T5→T7, T3=T5→T8} Riešenie: T=T1→T2=T1→(T3→T4)=T1→(T3→(T5→T6)= (T5→T8→T6)→(T5→T8)→T5→T6
Unifikácia f(t1, …, tn) = f(s1, …, sn), C → t1 = s1, …, tn = sn,, C f(t1, …, tn) = g(s1, …, sm) → FAIL x=t, C → x=t, C[x:t] if not(xt) [OCCUR CHECK] x=t, C → FAIL if xt x=x, C → C !!! najivný algoritmus je exponenciálny t1=g(t2, t2), t2=g(t3, t3),t3=g(t, t) t1=g(t2, t2), t2=g(g(t, t), g(t, t)),t3=g(t, t) t1=g(g(g(t, t), g(t, t)), g(g(t, t), g(t, t))), t2=g(g(t, t), g(t, t)),t3=g(t, t)
Unifikácia unify [] = [] -- Just [] unify (S=T:C’) | S == T = unify C’ | S == ti && not(ti T) = unify(C’[ti:T]) ++ [ti/T] | T == ti && not(ti S) = unify(C’[ti:S]) ++ [ti/S] | S == S1→S2 and T == T1→T2 = unify(S1=T1:S2=T2:C’) | otherwise = fail -- Nothing • type Subst = [(Type,Type)] • type Constraints = [(Type,Type)] • unify::Constraints→Maybe Subst | S == ti && not(ti Free(T)) = [ti/T] : u where Just u = unify(C’[ti:T])
Unifikácia Type Subst = [(Type,Type)] unify::Type→Type→Maybe Subst unify _ _ Nothing = Nothing unify (a1→b1) (a2→b2) subst = subst2 where subst1 = unify a1 b1 subst subst2 = unify a2 b2 subst1 --dereferencia premennej miesto aplikacie substitúcie unify ti b subst = unify a b subst where a = deref ti subst unify a ti subst = unify a b subst where b = deref ti subst --predpokladáme, že tije dereferencovaná unify ti b subst = (ti,b):subst unify a ti subst = (ti,a):subst – zabránenie vzniku cyklu unify ti tj subst | i < j = (ti , tj):subst | j < i = (tj , ti):subst | otherwise subst
Polymorfický λ-kalkul, druhorádový λ-kalkul,System F2 V jednoducho-typovanom λ-kalkule doménou premenných sú funkcie, v druho-rádovom λ-kalkule doménou premenných sú typy: Typ α, β ::= Int | α → β | α.β • λx.x : α.α→α • TRUE(λx.λy.x), FALSE (λx.λy.y) : α.α→α→α • NOT : α.α→α • K (λx.λy.x) : α.β.α→β→α • 0,1,2 (λf.λx.f(f x)),… : α.(α→α)→α→α Dôsledky: • v takomto λ-kalkule vieme otypovať aj to, čo v F1 nevieme (ω) • inferencia v takomto kalkule je nerozhodnuteľný problém • F1, F2,F3, … →Fω • dependent type (t:Type, t)
System F2 Typy α, β ::= Int | α → β | α.β {x:α}:Γ├ x:α [VAR] {x:α}:Γ├ N:β [ABS] Γ├ (λx.N):α→β Γ├ M:α→β, Γ├ N:α [APPL] Γ├ (M N):β Γ├M:β[GEN] α not free in Γ Γ├M:α.β Γ├ M:α.β [INST] Γ├ M:β[α:θ]
λx.x : α.α→α AND : α.α→α→α 0,1,2,… : t.(t→t)→(t→t) Príklady v F2 {x:Int}├ x:Int [VAR] ├(λx.x):Int→Int[ABS] {x:α}├ x:α [VAR] ├(λx.x):α→α[ABS] ├(λx.x): α.α→α[GEN] ├(λx.x): Int→Int[INST] {x:α.α→α}├ x:α.α→α [VAR] {x:α.α→α}├ x:(β.β→β)→(β.β→β) [INST] {x:α.α→α}├ x:α.α→α [VAR] {x:α.α→α}├ (x x):α.α→α [APP] ├ λx.(x x):(α.α→α)→(α.α→α) [ABS] • podarilo sa nám otypovať výraz, ktorý v jednoducho-typovanom kalkule sa nedal • dostali sme však typ (α.α→α)→(α.α→α), ktorý vnútri obsahuje kvantifikátory (deep type) na rozdieľ od tých, čo ich majú len na najvyššej úrovni, napr. t.(t→t)→(t→t) – shallow type
Let polymorfizmus chceme zakázať kvantifikáciu typov vnútri typového výrazu (zakázať deep type) Typy α, β ::= Int | α → β | α θ ::= α | α.θ premenná viazaná λ výrazom nemôže byť polymofrického typu, napr. f (λx.x) where f = λg.[… (g 1) …. (g True) … ] • idd = (\x->x) • foo = f idd where f = \g->(if (g True) then (g 2) else (g 1)) Nahradíme pravidlo [GEN] pravidlom [LET] Γ├ M:β, Γ, x:α.β├ N:δ[LET] α in β, α not free in Γ Γ├let x=M in N : δ
Typy a formule • K = (λxy.x)α→β→α • S = λxyz.xz(yz)(δ→ε→θ)→(δ→ε)→δ→θ Hilbertov axiomatický systém: A → (B → A) ((A → (B→C)) → ((A→B) → A→(A→C)) Modus ponens: A A→B B
K = (λxy.x)α→β→α S = λxyz.xz(yz)(δ→ε→θ)→(δ→ε)→δ→θ Curry-Howardov izomorfizmus • S K K = I S:(δ→ε→θ)→(δ→ε)→(δ→θ) K:α→β→α K:φ→ψ→φ -------------- (δ→ε→θ)= α→β→α (δ→ε)=φ→ψ→φ δ=θ (δ→ε→δ)= α→β→α, δ= α, ε=β (δ→ε)=φ→ψ→φ, δ=φ, ε=ψ→φ S:(δ→(ψ→δ)→δ) → (δ→(ψ→δ)) → (δ→δ) K:(δ→(ψ→δ)→δ) K:(δ→(ψ→δ))
K = (λxy.x)α→β→α S = λxyz.xz(yz)(δ→ε→θ)→(δ→ε)→δ→θ Curry-Howardov izomorfizmus S:(A→(B→A)→A) → (A→(B→A)) → (A→A) K:(A→(B→A)→A) SK:(A→(B→A)) → (A→A) K:(A→(B→A)) SKK:(A→A)