第11回名古屋Scala

9/17 に、第11回名古屋Scala勉強会に参加してきました。

今回は23章と24章の予定だったけど、盛り上がったので24章は次回に。

  • 23章 for 式の再説
    • モナド (1)
      • bind : M[A] => (A => M[B]) => M[B]
        • 最初の M[A] がレシーバ (Scala)
      • return : A => M[A]
      • この 2 つがあるとき、M は モナド (Haskell, do式が使える)
      • 不思議な抽象だけど、いろいろ便利
        • 例:リスト、Option (Maybe), IO処理、メモリ状態、パーサ、etc.
      • Scala だと、bind は flatMap、return は 単一コンストラクタ (ユニットコンストラクタ) に対応
      • for 式を使うには、map が必要 (map : M[A] => (A => B) => M[B] (Scala, 最初の M[A] がレシーバ))
        • flatMap と 単一コンストラクタ から作成できる
          • map (f) = flatMap (x => new M(f(x)))
        • do 式の return は、Scala だと for 式の yield に対応
          • ただし return と違って途中で使えない
    • F# のコンピューテーション式
      • Bind と Return メソッドを持つ型を作ると、do式っぽいものが使える
        • モナドの bind, return とは違う (↑はモナドにならない)
        • 何かよく分からないもの
    • モナド (2)
      • モナドは、bind と return について、右/左単位元を持ち、結合則を満たさないといけない
      • filter はモナドと関係ない
        • filter は ゴミw
        • モナドプラス に guard ってのがある (filter よりもっときれい)
    • パターンマッチ
      • 忍者パターンマッチ
        • パターンマッチで変数を定義する
scala> val h = ("hoge", 99)
h: (java.lang.String, Int) = (hoge,99)

scala> val (name, age) = h
name: java.lang.String = hoge
age: Int = 99
      • ドラゴンパターンマッチ
        • パターンマッチで無名関数を定義する
        • p.430 inCheck ドラゴンパターンマッチによる実装 ↓
scala> def inCheck:((Int,Int),(Int,Int))=>Boolean = {
     |   case ((x1,x2),(y1,y2)) => x1 == y1 || x2 == y2 || (x1 - y1).abs == (x2 - y2).abs
     | }
inCheck: ((Int, Int), (Int, Int)) => Boolean
  • こんなの書きました
    • bleis とん
      • テスティングフレームワーク作ってみた
        • パラメタライズドテスト書きたい
        • テスト仕様書とかテストケースから自動生成したい
          • Excel とか大変
    • leque さん
      • lift で ファイルビューワ的な
        • lift でクロージャ → いい感じに js に!
      • dump
        • List("") とかをいい感じに表示してくれる
        • REPL のなかとか、こう...
        • 2.8 から catching が使える
  • bleis宅

次の日に Gitの勉強会 があったので、泊めてもらうことに。
wk6 と mrxptn も一緒。


bleis と F# の話してたりして、気付いたら 3時。
そこから (みんな寝てから)、化物語の最終巻と AB を見る。
・・・・・・
天使ちゃんマジ天使。
・・・・・・
お、2人起きた。(6時くらい)
・・・・・・
天使ちゃんマジ天使。
・・・・・・
昼か。(11時くらい)


wk6 は別の勉強会らしく、少し早く出てた。
3人で名古屋駅でラーメン食べて、Git勉強会へ。

続・Coqりさん Q.E.D.

Coqりさん 証明のかけら の続き (再挑戦)。

Require Import Arith.

Fixpoint fib1 n:nat :=
 match n with
  | 0 => 0
  | 1 => 1
  | S (S m as p) => fib1 p + fib1 m
 end.

Fixpoint fib2 n a b:nat :=
 match n with
  | 0 => a
  | S n => fib2 n b (a + b)
 end.

Lemma plus_1_Sn :
 forall n:nat, n + 1 = S n.
Proof.
 intro n.
 rewrite plus_n_O.
 rewrite plus_Snm_nSm.
 reflexivity.
Qed.

Lemma plus_2_SSn :
 forall n:nat, n + 2 = S (S n).
Proof.
 intro n.
 rewrite plus_n_O.
 rewrite plus_Snm_nSm.
 rewrite plus_Snm_nSm.
 reflexivity.
Qed.

Theorem fib1_fib :
 forall n:nat, fib1 n + fib1 (n + 1) = fib1 (n + 2).
Proof.
 intro n.
 rewrite plus_1_Sn.
 rewrite plus_2_SSn.
 simpl fib1.
 destruct n.
  reflexivity.
  
  ring.
Qed.

Theorem fib2_fib :
 forall n a b:nat, fib2 n a b + fib2 (n + 1) a b = fib2 (n + 2) a b.
Proof.
 induction n.
  intros a b.
  reflexivity.
  
  intros a b.
  rewrite plus_Sn_m.
  rewrite plus_Sn_m.
  simpl.
  rewrite (IHn b (a + b)).
  reflexivity.
Qed.

Lemma fib1_eq_fib2_aux :
 forall n:nat, fib1 n = fib2 n 0 1 /\ fib1 (S n) = fib2 (S n) 0 1.
Proof.
 induction n.
  split.
   reflexivity.
   
   reflexivity.
  destruct IHn.
  split.
   exact H0.
   
   rewrite <- plus_2_SSn.
   rewrite <- fib1_fib.
   rewrite <- fib2_fib.
   rewrite plus_1_Sn.
   rewrite <- H.
   rewrite <- H0.
   reflexivity.
Qed.

Theorem fib1_eq_fib2 :
 forall n:nat, fib1 n = fib2 n 0 1.
Proof.
 intro n.
 destruct (fib1_eq_fib2_aux n).
 exact H.
Qed.

で、できたー!


これまでは流れが追えるように . で書いてきたけど、そろそろ ; 使っていってもいいかもしれない。

SKK とか

K I = F と、S K K = I を証明してみる。

Definition I {A:Type} x:A := x.
Definition K {A B:Type} (x:A) (y:B) := x.
Definition F {A B:Type} (x:A) (y:B) := y.
Definition S {A B C:Type} (x:A->B->C) (y:A->B) (z:A) := x z (y z).

Theorem ki_f : forall (A B:Type)(x:A)(y:B), K I x y = F x y.
Proof.
  intros A B x y.
  unfold K.
  unfold I.
  unfold F.
  reflexivity.
Qed.

Theorem skk_i : forall (A B:Type)(x:A), S K (K:A->B->A) x = I x.
Proof.
  intros A B x.
  unfold S.
  unfold K.
  unfold I.
  reflexivity.
Qed.

まぁ、展開するだけなんですけどね。

第1回 Scala座

9/4 に、第1回 Scala座に行ってきました。

資料などはこちらUstreamこちら

  • 開会の挨拶
    • Scala
      • 全国レベルのScalaの勉強会!
      • 大きなイベントは関東が多い
        • 悔しい! → 名古屋で開催!
  • これまでのScala、これからのScala
    • これまで編
      • Scalaって
      • Less typing を目指した言語仕様
        • 型推論とか
        • メソッド名短め
      • 型推論
        • ネストした型パラメータもちゃんと推論してくれる
        • 無名関数の型も引数含めて推論してくれる
      • ファーストクラス関数とクロージャ
      • パターンマッチ
        • switch 文を超強力で柔軟にしたもの
        • オプション型便利
          • List の headOption, reduceLeftOption とか
            • List が空だと None を返す
      • trait による Mix-in
        • 実装を持てるインタフェース的な
      • Read-Eval-Print Loop (REPL)
        • 対話型評価環境
        • テスト書く → REPLで確認 → コードに書く → テストする → (黄金の回転!)
        • Scala は公式 LL!
      • Scala Way
        • 関数型的にも、手続き型的にも書ける
          • val と var
          • immutable と mutable (コレクションライブラリ)
          • 高階関数と for/while
          • パターンマッチと if/else
          • Option と null
        • 手続き型風から関数型風へ
          • 「すごく・・・ださいです・・・。」→「すごく・・・短いです・・・。」
          • 高階関数を使う
          • ケースクラスの導入
          • Option の導入
            • パターンマッチ, getOrElse
          • 高階関数作る → 制御構文的に使える
        • #librahack も簡単
          • タイーホされるので(ry
      • 事例
        • みんな大好きついったーのバックエンドも一部 Scala で動いてます
        • 他にも沢山
    • これから編
      • 2.8 について
        • 7/15 正式リリース
        • 名前付き/デフォルトパラメータ
          • caseクラスの copy (2.8から) とかで便利に使える
        • コレクションライブラリ再設計
          • 殆どのAPIがtraitに
          • Mapなどが元の型を保持するようになった
            • Map を map すると Map になるようになった
              • 2.7 までは ArrayBuffer が返ってた
          • 便利なAPIが追加
            • collect
              • 部分関数を受け取って、filter と map をまとめてやる
            • scanLeft
              • foldLeftの途中も返す版
                • (これでフィボナッチも簡単)
scala> val fib:Stream[Int] = Stream.cons(0, fib.scanLeft(1)(_+_))
fib: Stream[Int] = Stream(0, ?)

scala> fib take 20 foreach (x => printf("%d ", x))
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181
        • package object
          • package にメソッドや変数を定義できる
          • package 毎に Predef を定義できる
            • implicit conversion との組み合わせが便利
        • @specialize
          • プリミティブ型に対する boxing/unboxing を回避
            • プリミティブ用にメソッドをオーバーロード
            • 高階関数使うときとか
        • 限定継続サポート
        • etc...
      • 2.8 以降の話
        • 2.8.1
          • 9 〜 10月
          • Bugfix
        • 2.9
          • 12 〜 1月
          • parallel collection
            • 並列化コレクション
  • Scalaでプレゼンテーションの試み
    • Scala で自作プレゼンテーションソフト
      • ドキュメントも Scala で書く
        • DSL を提供
        • Ant でビルド
        • ドキュメントにプログラム(GUI付き)を貼り付けれる
  • ScalaDaysに行ってみて
    • Scala Days 2010
    • 発表
      • PEGEX について
        • kmizu さん
        • パターンマッチライブラリPEGEXについて
        • School Days ネタ通じず
        • 英語の聞き取り能力大事
          • 話す方は身振り手振りでなんとかなる
      • A Case Study in DSL Development
        • Scala の機能を活かしてDSLを作った
        • Python によるDSLと比較
        • かなりトリッキーなDSL
      • Automated Refactoring for Scala
      • Lightweight Language Processing in Kiama and Scala
        • 言語処理ライブラリの話
      • Lightweight language support for type-based, concurrent event processing
        • 型情報を使ってScalaのActorライブラリを最適化
          • コードサイズは殆ど同じ
          • 劇的に性能改善
      • Named and Default Arguments in Scala
        • 名前付き引数とデフォルト引数についての話
        • 継承やジェネリクスが絡むと複雑
        • 型チェックは呼び出し側で行われる
      • Automatic refactoring for Scala programs
      • An Experiment with Automatic Resource Management
      • Type-safe SQL embedded in Scala
      • Scala at LinkedIn
      • Migration a Struts/Java vE-Mail Application to Lift/Scala
        • Struts のコードを Scala Lift でどうするか
        • 例外処理をどうするか
      • The Scala IDE for Eclipse
      • sbt
        • Scala用のビルドツールsbtの設計・実装の話
        • 設定ファイルをScalaで書ける
        • immutable か基本
        • DSL
      • Processing with Spde
        • Processing の Scala 版である、Spde の話
        • 無名関数などを活用して、Processing よりも簡潔にコードを書ける
      • Sneaking Scala Into Your Organization
        • 自分の会社でScalaを使うには
        • Scalaの学習曲線の急さをどう緩和するか
        • どの部分でScalaをまず採用するか
        • Web Testing の DSL
      • The Future of Scala
        • グループ毎に Scala の未来について議論する
        • 都合により参加できず。
    • Scala Days 延長戦
  • ScalaでAndroidアプリ開発
    • Androidアプリが動くまで
      • ソース → .class ファイル → .dex ファイル → .apk ファイル → インストール、実行
        • 数十秒かかる
    • メソッド名を間違えた場合
      • 動的型付け言語の場合
        • インストールまでして、実行時に初めてエラー
      • Scala の場合
        • ソースからのコンパイル時にエラー
    • Java と比べて、無名関数とか暗黙の型変換とか便利
      • Java っぽく書くことも出来る
    • デメリット
      • アプリサイズが大きくなる
        • 同機能のJava実装と比較して 4 〜 5 倍程度
      • protected static メンバにアクセス不可
        • 現状は Java 側でラッパーを用意しておくしかない
      • Google Maps API (maps.jar) 使うとコンパイルエラー
        • 次期バージョン (2.8.1) で修正される予定
    • 環境
      • sbt + sbt-android-plugin
        • apk 作成に加え、インストールまで面倒見てくれる
      • ensime
      • 自分にあったツールを使いましょう
  • Web Flavor
    • コンセプト
      • Better CGI
        • Java Servletのラッパ
        • 低レベルの機構を隠蔽
        • 必要以上に複雑にしない
      • 何でもScala
        • 設定ファイルもScala
      • 直感的
        • 既にある概念は他から持ってくる
    • 仕様
    • 開発
      • Model作成 → Controller作成 → View作成
  • GAEでLiftやってみた
    • → GAE で関数的 Web フレームワーク Lift を使う
    • 事例
      • 事例 1 Lift + GAE
        • もともと Grooby で依頼
          • → いや、Scala
            • 業務的には不具合があるとまずい
              • 型がある方が安全 (実行時エラーを減らせる)
        • クライアント側は flash とか OCaml とか
        • テスト + 証明
      • 事例 2 ScalaCUI システム
        • ネットワーク機器管理
        • Web インタフェースも作ってる
    • Lift について
      • 関数的Webフレームワーク
        • 他のWebフレームワークと比べて最も特徴的な部分
      • Ajax、セッション管理、テンプレート、ORマッピングなど、Webアプリで必要なものは大体ある
    • プロジェクトの作成
      • maven があれば非常に簡単
        • コマンドで一発
    • ビルド、テスト、デバッグ
      • ビルド、テストはmavenで一発
      • ローカルで確認できる
      • GAEサーバへのデプロイもコマンドで
    • 関数的な部分
      • ボタンを高階関数で抽象化
        • ボタン生成メソッドの引数に、ボタンを押されたときの処理をする関数(/クロージャ)を書ける
      • Box モナド
        • Option 型の代わりの様なもの
          • Box 型は失敗時に情報を持てる
            • 後ろに ?~ でエラーメッセージが指定できる
          • Option 型と同様に、for 式で Haskell の do の様に使う
            • ただしクラスファイルの名前がものすごく長くなる
        • guard は自分での拡張
          • MonadPlus 的な
            • 2.8 じゃないとちょっと難しい
    • やっててよかった関数型言語
      • OCamlHaskell を知っていると、Scala や Lift の関数的な部分が習得しやすい
      • いろんな言語を勉強するのは非常にいいこと
    • その他の便利な関数型言語
      • F# (.NET)
        • Scala より型推論がかなり強力
      • haXe (flash, php, js, C++)
        • AcitonScript に似た言語
        • 型推論とかもある
    • まとめ
  • 関数型言語Scalaで実装する型推論
    • Scala による型推論の実装 〜僕と一緒に型推論しませんか〜
    • 型は便利だが、書きたくない
      • 型推論素敵
    • Scala では、引数の型、型パラメータは書かないといけない
      • 型推論はもっとがんばれる
    • Hindley-Milner型システム
      • ちょっとだけ本気を出した型推論
        • 型推論四天王では最弱の存在らしい
      • 型注釈がなくても型が推論できる
      • OCamlHaskell の型推論のベース
      • 実装はそれほど難しくない
      • 作ってみた
        • Scalet
    • Scalet
    • 実装
      • 評価機
        • パターンマッチって素敵ですよね
      • 型の定義
        • case クラスって素敵ですよね
      • 型推論
        • 前提を列挙 → 制約を生成 → 単一化 (方程式を解く)
    • Hindley-Milner型システム
      • 証明もされてる
        • これで推論した型がただ一つに定まる
        • 停止する
        • 完全性と健全性
      • なぜ Scala にないか (想像)
        • 構造的部分型にしないといけない
          • Java との互換性を保つのが難しい
    • 証明
  • ToDo 的な
    • Scala 2.8 から入ったらしい継続について調べる
      • 継続は力 (違

|> in Scala

F# の |> を Scala でやってみた。

scala> class Holder[A](a:A) {
     |   def |>[B](f:A => B) = f(a)
     | }
defined class Holder

scala> implicit def any2holder[A](a:A) = new Holder(a)
any2holder: [A](a: A)Holder[A]

scala> val succ = (x:Int) => x + 1
succ: (Int) => Int = <function1>

scala> 3 |> succ |> succ
res0: Int = 5

scala> 3 |> { (x:Int) => x * 2 } |> succ
res1: Int = 7


お、これは・・・

scala> 3 |> {
     |   case x => x * 2
     | }
res2: Int = 6

scala> 3 match {
     |   case x => x * 2
     | }
res3: Int = 6

おお!match と同じように使える!

  • 追記
scala> class Holder[A](a:A) {
     |   def |>[B](f:A=>B) = f(a)
     |   def <|:[B](f:A=>B) = f(a)
     | }
defined class Holder

scala> implicit def any2holder[A](a:A) = new Holder(a)
any2holder: [A](a: A)Holder[A]

scala> val succ = (x:Int) => x + 1
succ: (Int) => Int = <function1>

scala> succ <|: succ <|: 10
res0: Int = 12


scala> val tw = (x:Int) => x * 2
tw: (Int) => Int = <function1>

scala> succ <|: succ <|: 10 |> tw |> tw
res1: Int = 48

scala> tw <|: tw <|: 10 |> succ |> succ
res2: Int = 42

おー!

メモ晒し

自分の Coq メモを晒してみる。

■ ; について
T1 ; T2
	T1 適用後、T1 によって出来た全てのサブゴールに対して T2 を適用
T1 ; [T2 | T3] 
	T1 適用後、T1 によって出来たサブゴール a, b に対して、a に T2、b に T3 を適用
	(不要なら T2, T3 を省略可(何もしない)) 
 
■tacticについて
intro / intros
	前提の導入
	ゴールの forall や -> で括られた部分を前提へ
	intros で名前を付けるときは左から
	前提に持って行かない場合は、名前を _ にする (intros のみ)
apply
	前提 A -> B、ゴール B があるとき、ゴールを A にする
	ゴールに適用できる関数があるとき、apply 関数 でゴールに関数を適用する
assert
	assert (前提の名前 := 式) で、式によって証明させる命題を前提に追加する
exact
	前提 H がゴールと同じ場合、exact H でゴールの証明を終了する
	証明と等価な関数があるとき、exact 関数 でゴールの証明を終了する
assumption
	前提にゴールがある場合、ゴールの証明を終了する
elim
	前提によって、以下の規則を適用
	・前提が A /\ B の場合
		ゴール G を、A -> B -> G にする
	・前提が A \/ B の場合
		ゴール G を、A -> G と B -> G に分割する
	・前提が not A の場合
		ゴールを A にする
	・前提が exists x : A, P x の場合
		ゴール G を、forall x:A, P x -> G にする
split
	and のゴールを分解する
	apply conj の省略形
left / right
	or のゴールの片方を選ぶ
	left は apply or_introl、right は apply or_intror の省略形
exists
	前提に H : x:A があるとき、exists H で、ゴールの exists a:A, P a を P x にする
clear
	指定した前提を除去
auto
	intro, apply, assumption 等を、ユーザの指示無しで組み合わせてゴールに辿り着ける場合、適用
trivial
	intro, apply, assumption 等を、1回だけ適用
tauto
	トートロジーである場合、適用
try tauto
	tautoが可能であれば、適用 (出来ないならば何もしない)
cut
	cut P で、ゴール G を、P -> G と P に分割する
generalize
	前提 A、ゴール G のとき、ゴールを A -> G にする
rewrite
	前提 H : A = B のとき、
		・rewrite (->) H でゴールの A を B にする
		・rewrite <- H でゴールの B を A にする
replace A with B
	ゴール G を、G 中の A を B に置き換えたものと、B = A に分割
unfold A
	ゴールの A を展開する
transitivity C
	ゴールの A = B を A = C と C = B に分割
symmetry
	ゴールの A = B を B = A にする
reflexivity
	ゴールが A = A のとき、ゴールの証明を終了する (反射律)

(* このあたりてきとう *)
simpl
	簡約 (?)
compute / cbv
	簡約 (?)
congruence
	ゴールが、同値変形で導ける場合、適用 (?)
omega
	nat, Z 上の、~, /\, \/, -> で組み立てられた等式や不等式を自動で頑張ってくれる?
	使うときは、Require Import Omega.
ring
	ゴールが、環の性質を使った変形で導ける場合、適用 (?)
field
	ゴールが、体の性質を使った変形で導ける場合、適用 (?)

induction n
	n に関する帰納法の開始
inversion H
	H が成立するための前提を前提に追加する
injection H
	コンストラクタ C に対し前提 H : C a = C b のとき、ゴール G を a = b -> G にする

■coqtopのコマンド
*通常モード
Check ...
	...の型等を表示
Eval compute in ...
	...を計算
Locate "(演算子)"
	(演算子) の定義を表示
Section ...
	...という名前でセクションを切る
Goal ...(Prop)
	...の証明を開始
Print ...(定理とか)
	...の中身を関数形式で表示 

*証明モード
Restart
	証明を始めから
Abort
	証明をやめる
Undo
	証明を1つ戻す

■その他
-> は右結合

チュートリアル続き読まないと。
(1.4 くらいまでしか行ってない)

  • 追記

最新版はここに

Coq庵

8/29 に、Coq庵 に行ってきました。

資料等はこちら


行き道で祭りやってた。
一部道が通れなかったりして、少し迷うなど。

  • 初めてのCoq
    • 仕様記述言語
      • Prolog
      • ACL2, HOL/Light
        • 完全自動証明
        • 自動で証明してくれるが、表現力がやや低い
      • Isabelle/HOL, Coq, Agda
        • 手動証明
        • 表現力が非常に高い
    • Coq の特徴
      • 高階論理
        • 表現力最強
      • 自動証明機能 (tactic)
        • 対話的に人間が証明を与えるが、部分的に自動証明を使うこともできる
      • プログラムと連携
        • 証明したものをそのまま実行できる
        • OCaml, Haskell, Sheme に出力できる
    • Coq の中身
      • 関数型プログラム的
        • Vernacularコマンド (プログラムの文)
        • Gallina式 (プログラムの式)
          • 内部はラムダ式
      • 論理学的
        • tactic
          • 証明、証明を含む式
          • 小文字で始まって . で終わる
    • Coq のプログラム
      • Vernacular
        • 大文字で始まって . で終わる
        • Fixpoint
        • Theorem
          • 定理の宣言
          • : の後ろに Gallina 式
        • Proof
          • 特に意味はない
            • ここから証明 ってマークに使う
        • Qed
          • ここまでが定理証明
      • tactic
        • 小文字で始まって . で終わる
        • tactic 同士を ; で繋げられる
      • Gallina 式
        • match ... with ... | ...
        • x :: xs
    • Coq で書かれたプログラム
      • 大きいの
        • CAMP
        • coqtail
          • OCaml の任意精度演算モジュール
      • 小さいの
    • Coq 習得の道
      • MLやHaskellを知る
      • 書いてみる、マニュアル、Twitter、Blog
        • 分からなければマニュアル
          • Web上の Reference Manualにコマンドなどの一覧がある
          • コマンドのエイリアスがたくさんある
        • Twitter、Blogで聞いてみる
          • 第一人者的な人が答えてくれるかも
        • Blogで報告
    • 更に熟練するには
      • CPDT (Certified Program with Dependent Types)
      • Coq'Art
      • その他 Curry-Howard 対応や型理論など
      • 勉強会会に参加しよう
        • ProofCafe(栄)
        • Formal Method 勉強会
  • Coq による暗号アルゴリズムの実装の暗号学的安全性検証
    • 暗号プログラムの安全性検証の必要
      • 暗号学的安全性の検証は行われていない
      • 不具合が発見された場合の社会的・経済的影響が大きい
    • → 暗号アルゴリズムの安全性検証とプログラム(実装)の検証
    • 疑似乱数生成期 BBS (Blum Blum Shub) の実装の安全性検証
      • ゲーム列による安全性証明
      • システムと攻撃者の挑戦としてモデル化
    • 実装の正しさの検証
      • ホーア論理、操作的意味論、etc.
    • Coqを用いた形式化
      • Inductive 内の :> は展開になる
  • にわとりかんさつにっき in お茶大
    • 浅井先生の研究室のお話
      • Coq 使い多い (8人中 6人)
      • Coq ゼミ
        • 2008年にあった
        • http://pllab.is.ocha.ac.jp/lab.html
        • 「型 = 命題、プログラム = 証明」
        • Coq 楽しそう
          • プログラム書いてテストケース通っても、それがちゃんと正しいかは分からない
            • Coq で 証明したら一応安心できるかな
        • 証明に良さそう
          • 手で書く証明よりも間違いがなくて良さそう
    • ICFP 2009 B.C.Pierce の招待講演
    • CPS変換
      • 「継続渡し形式」ってのに変換する
        • 状態を取って処理の続きをやる関数 を引数に渡す
    • 非関数化
      • CPSで渡してた関数を、データ構造にする
    • CPS変換・非関数化の正当性
      • 正当性の証明は Coq で
        • 売ら出された喧嘩定理は買い証明しましょう
      • CPS変換の正当性の証明 (factorial)
        • ∀n∈N, fact_ds n = fact_cps n id
          • n で induction すると証明できない
            • 継続が変わっているから
          • id を一般的な形にして証明
          • ∀n∈N, k∈N → N, k (fact_ds n) = fact_cps n k
            • これは n に関する帰納法でいける
      • 非関数化の正当性の証明 (factorial)
        • 先と同様に渡すやつを一般化して帰納法で証明
          • 一部ちょっと制約付ける
    • CPS変換 + 非関数化の正当性 (fibonacci)
      • 結構複雑になる
    • shift/reset
      • 継続のオペレータ
  • 一般たらいまわし関数の停止性を証明する
    • たらい回し関数の定義
      • t(x,y,z) := if x <= y then y else t(t(x-1,y,z), t(y-1, z, x), t(z-1, x, y))
      • 複雑な再帰
        • 停止性が問題
    • 深さ制限付きたらい回し関数
      • カウントを付ける
      • t_n(x,y,z) := if x <= y then y else t_{n-1}(t_{n-1}(x-1,y,z), t_{n-1}(y-1, z, x), t_{n-1}(z-1, x, y))
        • t_0(x,y,z) = ⊥ (bottom)
    • 停止性
      • 整数 x, y, z に対して停止する : ∃n, t_n(x, y, z) ≠ ⊥
    • 一般たらいまわし関数
      • 引数が増える
    • Coq で表現
      • ⊥を加えた整数型
        • option Z で表現
        • Some x が計算完了 (以下 Vx)
        • None が 未完了 (以下 B)
    • 深さ制限付き再帰
      • 皆さんよく知ってる Y コンビネータ
        • Yn O init recur = init
        • Yn (S n) init recur = recur (Yn n init recur)
        • 普通の Y は、Y f = f (Y f)
    • 再帰制限付きたらい回し関数 (ntarai)
      • ntarai n v = Yn n ntarai_init ntarai_recur
      • ntarai_init x = B
      • ntarai_recur f (Vx Vy v) = ...
      • ntarai_recur f _ = B
    • 最初に証明したいこと
      • 深さ n で停止したら、n 以上の m でも n で停止する
      • forall n m v x, ntarai n v = V x -> n <= m -> ntarai m v = V x
        • bottom が出てきた場合、計算経過が異なることが
        • bottom を値に書き換えても結果は変わらないことを証明
          • f ⊥ = V a -> ∀x, f x = V a
            • 美しくない
          • x = y ∨ x = ⊥ -> f x = f y ∨ f x = f ⊥
            • 対称になった!
        • R x y := x = y ∨ x = ⊥ とすると、R は半順序 (x ≪ y)
        • 証明したいこと:x ≪ y -> f x ≪ f y
          • f は単調増加
        • 多変数関数の場合
          • [xi] ≪ [yi] <-> forall i, xi ≪ yi
          • リストで与える
        • 連続な関数の合成は連続
        • Coq で順序を定義する
          • le を定義
            • dZ, list dZ, list (list dZ) の le はそれぞれ違う関数
              • 型クラスを使おう!
    • 型クラス
      • Coq 8.2 から
      • Haskell の型クラスとだいたい同じ
      • Coq の型クラスでは、関数に関する要請を指定できる
        • たとえば、Monad クラスに Monad 則を強制したり
        • 実装側でその要請を証明する必要がある
      • Coq の型クラスでは、型に対する実装に名前を付けられる
        • インスタンス定義の外で証明する場合、Defined. で証明を終了する (Qed. だとダメ)
      • 型クラスを要求するときは、型とインスタンス定義を引数に取るようにする
        • 型は省略する記法がある (インスタンス定義の型部分の型にバッククオートを使う)
      • インスタンス定義も、型のように自動推論してくれる
  • Coq でガベージコレクションの証明
    • コードはgithubに
    • マーク & スイープ GC
      • GC アルゴリズム3人衆の中で最弱
      • マークフェーズ
        • ルートから辿れるオブジェクトにマークを付ける
      • スイープフェーズ
        • マークのついてないオブジェクトを回収し、マークを外す
    • GCは完全でなければならない
      • トレース漏れ = 不良GC
        • 生存中のオブジェクトを削除してしまう (バグ)
      • アルゴリズムはホントに正しいか
      • アルゴリズムが正しくても、ちゃんと実装できているか
      • そこで Coq です!
    • Coq でプログラムを書く → 証明する → OCaml 等に変換して実行する
    • メモリのモデル化
      • Record で表現
    • Coq には3種類の集合モジュールがある
      • Ensembles, ListSet, FSet
    • ルートから辿れるオブジェクトの探索
      • 普通に書くと停止性が保証できない
      • 未探索のオブジェクトの集合を引数にもらって、停止性を保証する
        • 呼び出し毎に必ず減少するので、停止性が保証できる
    • 安全なGC
      • フリーリストと使用中のメモリに重複がない
      • 初期状態はSafety
      • SafetyなメモリをGCしてもSafety
    • Coq → OCaml
      • CoqBase を使うと、OCaml のライブラリを使ってくれる
  • ペアプルービング

最初はこんな感じで書いて、

Theorem Modus_ponens: forall (P Q: Prop), (P -> Q) -> P -> Q.
Proof.
  intros P Q. (* forall のところの P Q が Prop だよってのを前提へ *)
  intro H. (* (P -> Q) -> P -> Q の (P -> Q) を H として前提へ *)
  intro p. (* P -> Q の P を p をして前提へ *)
  apply H. (* ゴール Q、前提 H (P -> Q) から、ゴールを P に *)
  exact p. (* ゴール P 、それは前提 p にある *)
Admitted.

2人にまったりと解説のようなものをしてみる。
で、auto ってのがあるよって、

Theorem Modus_ponens: forall (P Q: Prop), (P -> Q) -> P -> Q.
Proof.
  auto. (*`・ω・´*)
Admitted.
Require Import Classical.

Theorem Peirce: forall (P Q: Prop), ((P -> Q) -> P) -> P.
Proof.
  intros P Q.
  intro H0.
  elim (classic P).
    intros p.
    exact p.
    
    intro p1.
    apply H0.
    intro p2.
    elim p1.
    exact p2.
Admitted.

classic ってのが、Coq.Logic.Classical_Prop にあって、

Axiom classic : forall P:Prop, P \/ ~ P.

こんな感じになってる。
古典論理の排中律。

Theorem sqrt_2: forall (n m:nat), n*n = 2*m*m -> m = 0.
Proof.
  intros n m H0.
  destruct m.
    reflexivity.
    (*´・ω・`*)
Admitted.

こういうのって Coq だと難しめ?
まだ自分には分からなかった (´・ω・`)

Axiom Falso: False.

Fixpoint pow a n :=
match n with
| O => 1
| S m => a * pow a m
end.

Theorem Fermat's_Last_Theorem:
  forall (a b c n: nat), n > 2 -> pow a n + pow b n = pow c n ->
  a = 0 /\ b = 0 /\ c = 0.
Proof.
  elimtype False.
  exact Falso.
Admitted.

elimtype False. でゴールを False にできるらしい。
(他の人の見ると apply False_ind. が普通?)

てか、この場合前提に False があるので、case Falso. でいいらしい。

Theorem Fermat's_Last_Theorem:
  forall (a b c n: nat), n > 2 -> pow a n + pow b n = pow c n ->
  a = 0 /\ b = 0 /\ c = 0.
Proof.
  case Falso.
Admitted.

(Coq 証明事例集: 前提が……のとき 参考にさせてもらいました)

Axiom Peirce: forall (P Q: Prop), ((P -> Q) -> P) -> P.

Theorem Excluded_Middle: forall (P: Prop), P \/ ~P.
Proof.
  intro P.
  (*Д*)
Admitted.

時間切れ。

OCaml Meeting 2010 in Nagoya

8/28 に、OCaml Meeting 2010 in Nagoya に行ってきました。

朝早く起きて名古屋大学へ。
暑い・・・

  • やってみようOCaml / Walk with OCaml
    • OCamlの基礎についてのお話
    • 会場の人の殆どはOCamlでプログラムを書いたことがあるみたい
    • haXeって言語がある
    • 高速で動作して欲しいときは ocamlopt を使うとみんなハッピーになれる
    • OCamlラムダ計算 (λ+ :ラムダプラス)
λterm ::=
 | x
 | λterm λterm
 | fun x -> λterm
追加で
 | 定数・リスト
 | バリアント・ペア
 | let, match, if
さらに
 | 代入可能な変数・ループ・モジュール
 | 多相バリアント・オブジェクト
さらに最新版(3.12)からモジュールが第一級に
    OCamlどこいってしまうんや
    • OCamlのいいとこ
      • 強力な型チェック
      • nullがないっていうのは非常に良いこと
        • nullがあっていいことなんて一つもないのに、なんであるのかわからない
      • 実行効率いい
      • Coqとの連携が用意
    • OCamlTwitterクライアント ocamltter
      • OCaml対話環境内で動く
      • 激しくRTするもの簡単w
    • まとめ
      • 型安全で高信頼
      • 仕事で使うと健康になる
      • より高信頼にしたいときはCoqで証明
  • F# の流技 / Fluent Feature in F#
    • OCaml △!
      • → F# △! → F# |>
    • パイプライン演算子 |>
      • let (|>) x f = f x
    • F# は inline 関数が書ける (コンパイル時に展開)
      • |> は inline
    • オブジェクト指向
      • x.F().G().H()
      • x |> f |> g |> h
    • F#「OCamlと違うんです」
      • + 演算子とか
        • 関数オーバーロード
          • 型推論と相性悪い
    • F# の対話環境は fsi
    • 画面出力 System.Console.WriteLine
      • オーバーロードされている
    • F#「.NETですから」
      • OCaml と比べると 型推論 (´・ω・`)ショボーン
      • F# ではよく型を明示する
        • |> 使うと型も流してくれるので型明記を少なくできる
    • 単位付きの計算ができる
    • コンピューテーション式
  • OCaml 3.12における第一級モジュールと合成可能なシグネチャについて / First-class modules and composable signatures in OCaml 3.12
    • モジュールの役割
      • プログラム・名前空間の構造化
      • インタフェースによる仕様記述・部品化
      • 抽象型・プライベート型による隠蔽
      • ファンクタによる抽象化
    • モジュールがコア言語より優れている点
      • 型構成子に対する多相性がある
      • 正確な多相型要求
      • 存在型(抽象型)の定義
    • 3.12の新機能
    • 第一級モジュール
      • モジュールを通常の値のように受け渡しできる
        • モジュールを受け取る関数とか作れる
        • パラメータによって、使うモジュールを選択したりできる
        • クラスをモジュールに入れて、中のクラスを動的継承によって変更したりできる
        • 型の等式を表現できる (GADTs)
      • 完全に型付けされている
        • 安全!
      • 理論的には新しくない (10年前に出てる)
        • ファンクターとの干渉で安全でなかった
    • 第一級モジュールの制限
      • ファンクターの中では第一級モジュールを開くことは出来ない
      • 型の pack, unpack を全て書かなければならない
        • 多相メソッドと同じ機構を使って、多くの型注記が省ける
    • シグネチャ言語
    • 破壊的代入の制限
      • 代入をかけれるのは一番上レベルの型とモジュールのみ
      • パス (定義されているもの) しか代入できない
      • 型のパラメータ数。順番は変えられない
      • 削除によって、構文的にスコープが有効でないシグネチャになったりする
  • デザインレシピ、モジュール、抽象データ型 / Design Recipe, module, and abstract data type
    • デザインレシピ
      • データ定義を行う
      • 目的を考え、ヘッダを作る
      • 例を作り、それをテストプログラムにする
      • テンプレートを作る
      • 本体を書く
      • テストする
    • → 例 (テスト) が先!TDD!

プログラミングの基礎 (Computer Science Library)

プログラミングの基礎 (Computer Science Library)

  • Spot Your White Caml -- How to Make Yourself Happy in OCaml Projects
    • コードの成長が早くて、初めからいて少しずつ進化していくなら対応できるが、十分成長したコードをいきなり見ると辛い
    • どうやって OCaml のコードを読むか
      • まず、mli ファイル (インタフェース) を読む
      • ml ファイル (実装) は飛ばす
    • よい mli ファイルを書く
      • 実装の詳細は隠蔽する
      • どう使うか示す
      • 良い・短いコメントを付ける
      • 型で表す
      • ocamlc -i から始めると良い
    • 良くない mli ファイルは読まない
    • 良い質問
      • 何が書かれているか・どこにあるか は無駄
      • 何故 を聞くと良い
    • 時間の80%は検索に使うので、検索に使う時間を減らす
      • シンタックスハイライト
      • 手動検索
      • Grep
        • cmigrep
        • ocamlbrowser
        • ocamlspot
      • Tag
    • → 検索時間が半分になれば、3倍生産的になれる
    • 以下のような先輩の助言は無視
      • Grepで何とかなるよ
      • 手動検索も学習だ
      • すぐ慣れるよ
    • コンパイラに関連した解析ツールを使う
      • 型推論は便利だけど、コード中でこの変数の型なんだっけ?ってなりやすい
        • 変数の型を調べてくれるエディタ拡張がある
    • ocamlspotter
  • Lightning Sessions
    • FFTW/genfft誰得ハッキングガイド / The Hitchhacker's Guide to the FFTW/genfft
      • FFTW
        • The Fastest Fourier Transform in the West : 西洋最速のフーリエ変換
        • 支えているのは OCaml
          • コード自体は C だが、OCaml から生成されている
      • ループがないので、ループは OCaml 側で描く
      • C コード生成時に最適化する
    • OCaml版Hoogle、OCamlAPISearchの紹介
    • どーOCaml
      • http://ocaml.jp/cgi/docaml/docaml.cgi
      • fizzbuzz
        • when で分岐出来るが、タプルでmatchするといい感じ
      • メールアドレスフィルタ
        • メールアドレスをファイル名と見て、Filename.check_suffix で判定
        • String.is_suffix で判定 (Core ライブラリが必要)
      • ファイルコピー
        • Maybeモナドを作って、失敗しうる処理を連結
        • モジュール内にモジュールを作る
      • SQL文生成
        • エスケープを Str.global_replace で行う
        • プリペアドステートメントは PGOCaml ってのがある
      • どーOCamlOCamlで作られている
    • ゴルフ用楽打モジュール
      • goruby
        • Ruby の Golf 用公式インタラプタ
      • rakuda
        • gorubyOCaml
        • id とか % とか関数合成とかもある
        • h() で "Hello World!"
        • 標準入力から読み込む系もある
        • format 系の演算子もある
        • ビット演算用の演算子もある
        • 文字列操作・正規表現用の演算子もある
        • リスト操作・生成用の演算子もある
        • eval もある (型 (´・ω・`)ショボーン )
        • 関数適用もある (例外無視)
  • もの
    • 念願のグリーンバンドを手に入れた
    • OCaml Tシャツ 買った!

矛盾

楚人に盾と矛とを鬻(ひさ)ぐ者有り。之(これ)を誉めて(ほめて)曰く「吾が盾の堅きこと、能く(よく)陥す(とほす)もの莫し(なし)」と。また、その矛をほめていはく、「わが矛の利なること、物において陥(とほ)さざることなきなり。」と。あるひといはく、「子の矛を以て、子の盾を陥(とほ)さばいかん。」と。その人応ふること能はざりき。

矛盾 - Wikipedia
Theorem 矛盾 : forall (矛 盾:Type)(突き通す:矛 -> 盾 -> Prop),
 (exists 最強の矛:矛, forall あらゆる盾:盾, 突き通す 最強の矛 あらゆる盾) ->
 (exists 最強の盾:盾, forall あらゆる矛:矛, ~ 突き通す あらゆる矛 最強の盾) ->
 False.
Proof.
 intros 矛 盾 突き通す.
 intros どんな盾でも貫く矛がある どんな矛でも防ぐ盾がある.
 elim どんな盾でも貫く矛がある.
 intros 最強の矛 最強の矛はあらゆる盾を貫く.
 elim どんな矛でも防ぐ盾がある.
 intros 最強の盾 最強の盾はあらゆる矛を防ぐ.
 apply (最強の盾はあらゆる矛を防ぐ 最強の矛).
 apply (最強の矛はあらゆる盾を貫く 最強の盾).
Qed.

買った本

学校の売店に注文してた本が届いたそうなのでもらってきた。

Emacsテクニックバイブル ?作業効率をカイゼンする200の技?

Emacsテクニックバイブル ?作業効率をカイゼンする200の技?


今年の 8月・9月は Emacs 強化月間。(去年は vim だった)

  • 数学の本

層・圏・トポス―現代的集合像を求めて

層・圏・トポス―現代的集合像を求めて


圏論の基礎 が難しかったので。