Coqでsprintf

upcamp 2012 にて
Coqでsprintf
• printf(“%s : %dn”, “Coq”, strlen(“Coq”));
• 第二引数以降の型が、第一引数に依存!
• 依存型のわかりやすい例
Coqでsprintf
•   printf(“%s : %dn”, “Coq”, strlen(“Coq”));
•   第二引数以降の型が、第一引数に依存!
•   依存型のわかりやすい例
•   sprintf “Hello”
    – (string)型を返して欲しい
• sprintf “There are %d pens.”
    – (Z -> string)型を返して欲しい
• 引数によって戻り値の型が異なる
Coqでsprintf
• Coqにおける文字・文字列
 – 文字(ascii) : 8ビットのタプル
 – 文字列(string) : asciiからなるリスト構造
• Coqにおける整数
 – 自然数(nat) : ペアノの公理による非負整数
 – 整数(Z) : 2進数表現による整数
toStringの実装
• Zからstringへ変換
• 一般的な再帰で書く
• 停止性証明が必要なので、Fixpointではな
  くFunctionで書く
• 一部を証明モードで補完したいので、
  FunctionではなくProgram Fixpointを使う
関数定義の命令
                         証明モードを併用しな 証明モードを併用する
                         い
単なる定義                    Definition             Program Definition
構造帰納法による定義               Fixpoint{struct x}     Program Fixpoint{struct x}
停止性証明による定義               Function{wf lt x}      Program Fixpoint{wf lt x}
(1)
停止性証明による定義              Function{measure f x} Program Fixpoint{measure f x}
(2)
※1 Functionでは、定義直後に停止性証明の証明モードに入る。証明終了後に
余帰納法
実際に関数が定義される。            CoFixpoint            Program CoFixpoint
※2 Programでは、定義後にObligation命令(Obligation 1 や Next Obligation) を使っ
てプレースホルダーの証明をするモードに入る。証明終了後に実際に関数が定
義される。場合によっては全て自動で証明されてしまう。
※3 Fixpoint{struct x}では、引数xの構造について単調減少な再帰呼び出しのみ許
可される。CoFixpointでは、戻り値の構造について単調減少な再帰呼び出しの
み許可される。
toStringの実装
• 非負整数Nから文字列への変換関数
• 再帰呼び出しでNの値が単調減少
toStringの実装
• 整数から文字列への変換関数
toStringの実装
• 実行例
sprintfの実装の準備
• 型と値のペアを定義する
sprintfの実装の準備
• {| TV_T := nat ; TV_V := 10 |}
• {| TV_T := string ; TV_V := “Hello” |}
sprintfの実装
• sprintf_impl
  – 書式文字列に対する再帰で書く
  – 構造帰納法なので停止性証明は不要
     • “%04d”などの複雑な書式文字列に対応したい場
       合、停止性証明を導入する必要性が生じそう
sprintfの実装
• 帰納法&マッチング
sprintfの実装
• 実行例
• sprintf “Hello, world!”
  – → “Hello, world!”
• sprintf “%d + %d = %d” (1) (2) (1+2)
  – → “1 + 2 = 3”
• sprintf “Hello, %s!” “Masaki”
  – → “Hello, Masaki”
ソースコード
• https://gist.github.com/3329025
おまけ
emacsで:wしたら強制終了するマクロを作るっていうネタあるんですけど
使う人居ますか
[2012/08/11 22:28:45] qnighy (原 将己): vimでC-x C-sしたら強制終了ってい
う逆のネタもあります
おまけ
• 「VimでEmacsの保存コマンド→死亡」
  を実装してみました
おまけ
• といっても以下の2つを実行するだけ
• :map <C-x><C-s> :qall!<Enter>
• :map! <C-x><C-s> :qall!<Enter>

• SLでは物足らないあなたに…

Coqでsprintf