型システムでのソート操作の証明


9

プログラミング言語の型システムがどれほど有益であるかを知りたい。たとえば、依存して型付けされたプログラミング言語でVectorは、ベクトルのサイズを型シグネチャに組み込んだクラスを作成できることを知っています。それは事実上の例のようなものです。appendこれらのシグネチャを使用して関数を記述し、コンパイラが結果のリストのサイズが入力リストの合計になることを証明することもできます。

たとえば、ソートアルゴリズムの型シグネチャをエンコードして、コンパイラが結果のリストが入力リストの順列であることを保証する方法はありますか?可能であれば、これをどのように行うことができますか?

回答:


13

はい、ソートルーチンの正確なタイプを表すことが可能です。そのタイプを持つ関数は、実際に入力リストをソートする必要があります。

より高度で洗練された解決策があるかもしれませんが、基本的なものだけをスケッチします。

f: nat -> nat0 ..1

Definition permutation (n: nat) (f: nat -> nat): Prop :=
  (* once restricted, its codomain is 0..n-1 *)
  (forall m, m < n -> f m < n) /\
  (* it is injective, hence surjective *)
  (forall m1 m2, m1 < n -> m2 < n -> f m1 = f m2 -> m1 = m2) .

単純な補題は簡単に証明できます。

Lemma lem1: forall n f, permutation n f -> m < n -> f m < n.
... (* from the def *)

メートルhメートル<

Definition nth {A} {n} (l: list A n) m (h : m < n): A :=
... (* recursion over n *)

の順序が与えられるAと、リストがソートされることを表現できます。

Definition ordering (A: Type) :=
   { leq: A->A->bool |
     (* axioms for ordering *)
     (forall a, leq a a = true) /\
     (forall a b c, leq a b = true -> leq b c = true -> leq a c = true) /\
     (forall a b, leq a b = true -> leq b a = true -> a = b)
    } .

Definition sorted {A} {n} (o: ordering A) (l: list A n): Prop :=
...

最後に、並べ替えアルゴリズムのタイプを次に示します。

Definition mysort (A: Type) (o: ordering A) (n: nat) (l: list A n):
   {s: list A n | sorted o s /\
                  exists f (p: permutation n f),
                  forall (m: nat) (h: m < n), 
                     nth l m h = nth s (f m) (lem1 n f p h) } :=
... (* the sorting algorithm, and a certificate for its output *)

s0 ..1lsfメートル<nth

ただし、並べ替えアルゴリズムが正しいことを証明する必要があるのはユーザー、つまりプログラマーであることに注意してください。コンパイラーは、ソートが正しいことを単に検証するだけではなく、提供された証明をチェックするだけです。実際、コンパイラはそれ以上のことはできません。「このプログラムはソートアルゴリズムです」などのセマンティックプロパティは(ライスの定理により)決定できないため、証明ステップを完全に自動化することは望めません。

遠い将来においても、自動定理証明器が非常に賢くなり、実際に使用されている「ほとんど」のアルゴリズムが自動的に正しいことが証明されることを期待できます。ライスの定理は、これがすべての場合に実行できるわけではないと述べているだけです。私たちが期待できるのは、正確で広く適用されますが、本質的に不完全なシステムです。

最後に、単純な型システムであっても不完全であることを忘れてしまうことがあります。たとえばJavaでも

int f(int x) {
   if (x+2 != 2+x)
      return "Houston, we have a problem!";
   return 42;
}

意味的にはタイプセーフです(常に整数を返します)が、型チェッカーは到達不能な戻りについて文句を言うでしょう。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.