定理証明によるプログラミング - Programming with Theorem-Proving (PwTP) は豊かで広いプログラミングパラダイムで、プログラムと証明が構文的に絡み合って密着させることができます。 PwTP をサポートすることは ATS の主要な機能で、ATS の新規性は主にここにあります。 カリー=ハワード同型対応に馴染んだ人々にとって、少しでも証明とプログラムの間でこの同型を本質的に使ったことがあれば、ATS でサポートされている PwTP は簡単であることを強調したいです: 書かれた ATS プログラムの動的な部分はもちろん純粋ではありませんし、 ATS/LF にエンコードされた証明は積極的に必要なわけでもありません。 けれども、ATS での関数型プログラミングのスタイルで記述できる証明の構築は ATS のデザインの観点で根本的に重要です。 プログラムを証明と結合することが必要なのです。
この章では、単純だけれど説得力のある例を使って ATS でサポートされる PwTP のパワーと柔軟性を説明します。 けれでも、PwTP を使った実用例は ATS の線形型を導入した後まで紹介できません。 線形型の証明はプログラムと結合して、メモリやオブジェクト (例: ファイルハンドル) のようなリソースを追跡したり安全に操作したりすることができます。 特に、PwTP は ATS における命令型プログラミングをサポートする土台となります。
この章で解説するコードと追加のテストコードは オンライン から入手できます。
ATS の制約ソルバはやや非力な力しか持っていません。 特に、非線形の整数項を含む制約 (例: 値の乗法の使用を意味するような制約) はただちに破棄されます。 この非力さは当然対策されるべきです。さもなくば ATS の型システムの実用性における深刻な制限になってしまいます。 ここでは単純な例を使って、非線形の制約を直接扱う必要性を回避して定理証明を使うことができるのか説明します。
関数テンプレート list_concat は次のような実装です:
// // [list_concat] does typecheck in ATS2 // [list_concat] does not typecheck in ATS1 // fun{ a:t@ype } list_concat{m,n:nat} ( xss: list (list (a, n), m) ) : list (a, m * n) = case+ xss of | list_nil () => list_nil () | list_cons (xs, xss) => list_append<a> (xs, list_concat xss) // end of [list_concat]
fun{ a:t@ype } list_concat{m,n:nat} ( xss: list(list(a, n), m) ) : [p:nat] (MUL(m, n, p) | list(a, p)) = ( // case+ xss of | list_nil () => (MULbas() | list_nil()) | list_cons (xs, xss) => let val (pf | res) = list_concat (xss) in (MULind pf | list_append<a> (xs, res)) end // end of [list_cons] // ) (* end of [list_concat] *)