Доведення операції сортування в системі типів


9

Хочу знати, наскільки може бути корисною система типу в мові програмування. Наприклад, я знаю, що в залежності від набраної мови програмування ми можемо створити Vectorклас, що включає розмір вектора в підпис типу. Це як приклад де-факто. Ми також можемо записати функцію, appendвикористовуючи ці підписи, щоб компілятор довів, що розмір списку в результаті буде сумою вхідних списків.

Чи існує спосіб кодування, наприклад, підпису типу алгоритму сортування, щоб компілятор гарантував отриманому списку перестановку вхідного списку? Як це можна зробити, якщо це можливо?

Відповіді:


13

Так, можна висловити точний тип для процедури сортування, так що будь-яка функція, що має цей тип, дійсно повинна сортувати список введення.

Хоча може бути більш просунуте і елегантне рішення, я начеркну лише елементарне.

Ми будемо використовувати позначення, подібні кок. Почнемо з визначення присудка, який вимагає, що f: nat -> natдіє як перестановка на :0 ..н-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 *)

Стану виводу типу , що список результатів sє елементів довжиною, упорядковано, і що існує перестановка , який відображає елементи в списку введення на них в списку виведення . Зауважимо, що нам доведеться звернутися до леми вище, щоб довести , чого вимагає .н0 ..н-1lsf(м)<нnth

Однак зауважте, що саме користувач, тобто програміст, повинен довести їх алгоритм сортування правильним. Компілятор не просто перевірить правильність сортування: все, що він робить, це перевірка наданого доказу. Дійсно, компілятор не може зробити більше того: семантичні властивості, такі як "ця програма є алгоритмом сортування", не можна визначити (за теоремою Райса), тому ми не можемо сподіватися зробити крок доведення повністю автоматичним.

У далекому, далекому майбутньому ми все ще можемо сподіватися, що докази автоматичної теореми стануть такими розумними, що "більшість" практично використаних алгоритмів можуть бути автоматично доведені правильними. Теорема Райса стверджує лише, що цього робити не можна у всіх випадках. Все, на що ми можемо сподіватися, - це правильна, широко застосовувана, але по суті неповна система.

На завершення іноді забувається, що навіть прості системи типу є неповними ! Наприклад, навіть на Java

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

це семантично безпечний тип (він завжди повертає ціле число), але перевіряючи тип буде скаржитися на недоступний повернення.


7

Тван ван Лаарховен має приємний повністю відпрацьований приклад в Агді "Правильність і час виконання об'єднання, сортування та вибір вибору".

Зауваження також цікаві: у них, наприклад, згадується рішення Боба Аткі, що включає глибоке вбудовування лінійної логіки .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.