型理論 なんて自分には関係ないと思っているあなたへ
DESCRIPTION
型理論の啓蒙TRANSCRIPT
型理論
松下祐介(Kinokkory@shiatsumat)
なんて自分には関係ないと 思っているあなたへ
型 「C言語でいうとたとえば
整数型:int
実数型:double
文字型:char
型Tのポインタ型:T*
型Tの定数型:const T
みたいなものだよね。」
とは
型 「まあ大体分かってるよ。値の種類でしょ。それだけのこと。型なんて勉強している暇があったらプログラミング勉強してるほうがずっといいね。」
とは
型 「Haskellとかの実用的でない関数型言語の畑の人々が勝手に騒いでるだけでしょ。C++ / Java / Pythonのプログラマーには関係ないよ。」
とは
型 「いや、すべてのプログラマーにとって、型を知ることは意味があるものだよ。」
とは
型 「型はそんなに簡単なものではないよ。」
とは
型 とは、プログラムがある種の振る舞いを起こさないことを保証するための手法である。
型 システムはプログラミング言語によって様々である。 型システムがプログラミング言語の根幹を決めているといってもよい。
静的検査↔ 動的検査
全称型 存在型
直積型 直和型 矢印型
型推論 部分型付け
抽象的データ型
再帰的データ型
オブジェクト
型安全↔型安全でない
奥深い、世界。
面白い!
証明 定理証明支援系でも 型理論は大いに 役立っている
証明 とは
数学的に客観的な方法で、あることが成り立つことを説明すること
1+1=?
1+1=2
なぜ?
「だって、ほら、 リンゴを1個お皿に乗せて、 もう1個お皿に乗せたら、 2個になってるじゃないか。」
「 “1” と “リンゴ1個” は違うだろ? “+” と “さらにお皿に乗せる” は違うだろ?そんなのじゃ証明になってないよ」
「じゃあ、 “1” “2” “+” “=” って いったいどういう意味なんだよ。」
「じゃあ、Coqで数と足し算を定義して、証明してみよう」
Inductive Nat:Set :=
| O : Nat
| S : Nat -> Nat.
Natとは自然数 (0以上の整数) のこと。Oがゼロを表し、Sが次の数 (1+) を表す。 「0, 1, 2, 3, ...」は「O, S O, S (S O), S (S (S O)), ...」
Fixpoint Plus(m n:Nat):Nat :=
match m with
| O => n
| S m' => S (Plus m' n)
end.
Infix “+” := Plus.
要するに、
0+n=n, (1+m’)+n=1+(m’+n)
Theorem OnePlusOneEqualsTwo:
S O + S O = S (S O).
Proof.
simpl.
reflexivity.
Qed.
これで1+1=2が証明できた。
......
Lemma reduce_lemma :
forall ctx (ctx' : seq (term * typ)) t ty,
typing ([seq Some p.2 | p <- ctx'] ++ ctx) t ty ->
Forall (fun p => reducible ctx p.1 p.2) ctx' ->
reducible ctx (substitute_seq 0 [seq p.1 | p <- ctx'] t) ty.
Proof.
move => ctx ctx' t ty; elim: t ty ctx ctx'.
- move => /= n ty ctx ctx'.
rewrite /substitute_seqv typvar_seqindex subn0 size_map shiftzero.
elim: ctx' n => [| c' ctx' IH []] /=.
- move => n H _; rewrite nth_nil subn0.
apply CR3 => //.
- by constructor.
- move => t' H0; inversion H0.
- by case => H [H0 H1]; rewrite H.
- by move => n H [H0 H1]; apply IH.
- move => tl IHtl tr IHtr ty ctx ctx' H H0.
inversion H; subst => {H}.
case: (IHtl (tyfun ty1 ty) ctx ctx') => //= H1 H2; split; auto.
apply typapp with ty1 => //.
apply subject_substitute_seq => //.
by rewrite drop0; move: H0; apply Forall_impl => p [].
- move => t IHt ty ctx ctx' H H0.
inversion H; subst => {H} /=.
apply abstraction_lemma.
- constructor.
apply subject_substitute_seq => //.
by rewrite /= drop0; move: H0; apply Forall_impl => p [].
- move => t2 ctx2 H H1.
rewrite substitute_seq_cons_eq.
apply (IHt ty2 ctx2 ((t2, ty1) :: ctx')) => /=.
- move: H3; apply ctxleq_preserves_typing.
move: H; apply (ctxleq_appl (Some ty1 :: _)).
- split => //.
move: H0; apply Forall_impl => p.
by apply ctxleq_preserves_reducibility.
Qed.
Theorem typed_term_is_snorm : forall ctx t ty, typing ctx t ty -> SNorm t.
Proof.
move => ctx t ty H.
apply (@CR1 ctx t ty).
move: (@reduce_lemma ctx [::] t ty H) => /=.
by rewrite substitute_seq_nil_eq; apply.
Qed.
単純型付けラムダ計算の強正規化性の証明の一部
Theorem monad_bind_assoc
: forall{t1 t2 t3:TypeWithEquality}
(ma:TWE_Type (m t1))
(k:TWE_Type (t1 -> m t2)%TypeWithEquality)
(h:TWE_Type (t2 -> m t3)%TypeWithEquality),
TWE_Equality (m t3)
(AWE_Arrow (AWE_Arrow bindM ma)
(Build_ArrowWithEquality (fun x => AWE_Arrow (AWE_Arrow bindM (AWE_Arrow k x)) h)
(fun (x y : TWE_Type t1) (Hxy : TWE_Equality t1 x y) =>
AWE_Compat bindM
(AWE_Arrow k x)
(AWE_Arrow k y)
(AWE_Compat k x y Hxy)
h
h
(Equivalence_Reflexive(Equivalence:=TWE_Equivalence _) h)
)
)
)
(AWE_Arrow (AWE_Arrow bindM (AWE_Arrow (AWE_Arrow bindM ma) k)) h).
Proof.
intros.
intros x y H.
unfold bindM,returnM; simpl.
apply (AWE_Compat ma).
simpl.
intros x0 y0 H0.
assert (HEql: TWE_Equality _ (AWE_Arrow k x0) (AWE_Arrow k y0)).
apply (AWE_Compat k).
apply H0.
apply HEql.
simpl.
intros x1 y1 H1.
assert (HEql2: TWE_Equality _ (AWE_Arrow h x1) (AWE_Arrow h y1)).
apply (AWE_Compat h).
apply H1.
apply HEql2.
apply H.
Qed.
End ContinuationMonadBase.
Module FContinuationMonadBaseBase <:HasReturnType.
Definition ReturnType : TypeWithEquality := TypeWithEquality_eq False.
End FContinuationMonadBaseBase.
Module FContinuationMonadBase := FContinuationMonadBaseBase <+ ContinuationMonadBase.
Maybeモナドがモナド則を満たすことの証明の一部
「人間が証明したほうが早そうだけど、 パソコンに証明させると何が嬉しいの?」
「自動証明の機構を作れたり、
ソースコードを解析してプログラムが ある挙動をすることを証明できたり、
結構嬉しいことがいっぱいあるよ」
「フェルマーの最終定理も証明できるの?」
「証明は本当に信用できるの?」
「Coqはどういう仕組みで動いているの?」
「論理と型がどう関係しているの?」
面白い!
型理論