わかりやすくするために、次のようにするHeap
必要があります。
Inductive Heap A : Type :=
| Node : Heap A -> A -> Heap A -> Heap A
| Leaf : Heap A.
f
として定義されている
Fixpoint f A (h : Heap A) : list A :=
match h with
| Node h1 a h2 => f h1 ++ a :: f h2
| Leaf => []
end.
この場合、 はとの間の同型を定義
f
しません。代わりに、次のような関数を見つけることができます。
Heap A
list A
A
g : forall A, list A -> Heap A
forall A (l : list A), f (g l) = l
それにもかかわらず、同じ抽象化、つまり何らかのタイプの要素のセットを実装するために使用される場合、両者はある意味で同等であるHeap
と言いたいです。list
Coq などのパラメトリック ポリモーフィズムを持つ言語でこのアイデアを検証できる正確かつ正式な方法があります。パラメトリック性として知られるこの原則は、パラメトリックなポリモーフィック関数が、それらをインスタンス化する型に課す関係を尊重することを大まかに述べています。
これは少し抽象的なので、もっと具体的にしましょう。と のみをfoo
使用するリストに対する関数 (たとえば) があるとします。パラメトリック性を使用し
て同等のバージョンに置き換えることができるようにするには、 の定義をポリモーフィックにし、リスト上の関数を抽象化する必要があります。++
nth
foo
Heap
foo
Definition foo (T : Set -> Set)
(app : forall A, T A -> T A -> T A)
(nth : forall A, T A -> nat -> option A)
A (l : T A) : T A :=
(* ... *)
リスト上でインスタンス化することにより、最初に foo のプロパティを証明します。
Definition list_foo := foo list @app @nth.
Lemma list_foo_lemma : (* Some statement *).
さて、H_app
とH_nth
は対応するリストと互換性があり、foo
は多相的であるため、パラメトリック性の理論は証明できると言っています
Definition H_foo := foo Heap @H_app @H_nth.
Lemma foo_param : forall A (h : Heap A),
f (H_foo h) = list_foo (f h).
list_foo
この補題があれば、 のプロパティを の同様のプロパティに転送できるはずですH_foo
。たとえば、簡単な例として、H_app
リストへの変換まで、 が連想的であることを示すことができます。
forall A (h1 h2 h3 : Heap A),
list_foo (H_app h1 (H_app h2 h3)) =
list_foo (H_app (H_app h1 h2) h3).
パラメトリック性の良いところは、パラメトリックにポリモーフィックな関数に適用されることです
: 適切な互換性条件が型に保持されている限り、特定の関数の 2 つのインスタンス化を同様の方法で に関連付けることができるはず
foo_param
です。
ただし、2 つの問題があります。1 つ目は、ベース定義をポリモーフィックなものに変更する必要があることですが、これはおそらくそれほど悪くはありません。さらに悪いことに、パラメトリック性により、foo_param
特定の条件下などで常に補題を証明できることが保証されますが、Coq はそれを無料で提供するわけではなく、これらの補題を手動で示す必要があります。痛みを和らげるには、次の 2 つの方法があります。
定型的な証明を自動的に導出するのに役立つ Coq 用のパラメトリック性プラグイン(CoqParam) があります。とはいえ、使ったことがないので、使いやすさはなんとも言えません。
Coq 効果的な代数ライブラリ (略してCoqEAL ) は、パラメトリック性を使用して効率的なアルゴリズムについて証明し、より便利なアルゴリズムについて推論します。特に、あなたが提案したように、nat
とを切り替えることができる改良点を定義しています。BinNat
内部的には、型クラスの推論に基づくインフラストラクチャを使用しており、元の例に適応させることができますが、現在、代わりに CoqParam を使用するように実装を移行していると聞きました。