Tip sisteminde bir sıralama işlemini kanıtlama


9

Bir programlama dilinde bir yazı sisteminin ne kadar faydalı olabileceğini bilmek istiyorum. Örneğin, bağımlı Vectortipte bir programlama dilinde, vektör boyutunu tip imzasında birleştiren bir sınıf oluşturabileceğimizi biliyorum . Fiili bir örnek gibidir. appendBu imzaları kullanarak bir işlev de yazabiliriz, böylece derleyici sonuç listesinin boyutunun giriş listelerinin toplamı olacağını kanıtlar.

Örneğin, bir sıralama algoritmasının tür imzasında kodlamanın bir yolu var mı? Mümkünse bu nasıl yapılabilir?

Yanıtlar:


13

Evet, bir sıralama rutini için kesin bir tip ifade etmek mümkündür, öyle ki bu tipe sahip herhangi bir fonksiyon gerçekten de giriş listesini sıralamalıdır.

Daha gelişmiş ve zarif bir çözüm olsa da, sadece temel bir çözüm çizeceğim.

Coq benzeri bir gösterim kullanacağız. f: nat -> nat üzerinde bir permütasyon görevi gören bir yüklem belirleyerek başlayalım :0..n1

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) .

Basit bir lemma kolayca kanıtlanabilir.

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

Biz ne olduğunu tanımlamak uzunluğunda olan bir listenin inci elemanı . Bu işlev , gerçekten de bulunduğunu belirten bir kanıt gerektirir .mnhm<n

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

Sipariş Averildiğinde bir listenin sıralandığını ifade edebiliriz:

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 :=
...

Son olarak, bir sıralama algoritması türü:

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 *)

Sonuç listesi bu çıktı türü devletler solduğu uzun elemanları, bu sıralanır ve bir permütasyon var olduğunu giriş listesindeki unsurları eşleyen çıkış listesindeki düğmelerin . Yukarıdaki lemmayı , gerekli olan olduğunu kanıtlamak için çağırmamız gerektiğini unutmayın .n0..n1lsf(m)<nnth

Bununla birlikte, sıralama algoritmalarının doğru olduğunu kanıtlaması gereken kullanıcının, yani programcı olduğuna dikkat edin. Derleyici, sıralamanın doğru olduğunu doğrulamaz: tek yaptığı, sağlanan bir kanıtı kontrol etmektir. Aslında, derleyici bundan daha fazlasını yapamaz: "Bu program bir sıralama algoritmasıdır" gibi anlamsal özellikler kararsızdır (Rice teoremi ile), bu yüzden kanıtlama adımını tam otomatik hale getirmeyi umamayız.

Uzak, uzak gelecekte, otomatik teorem kanıtlayıcıların o kadar akıllı hale gelmelerini umuyoruz ki pratik olarak kullanılan algoritmaların çoğu otomatik olarak doğrulanabilir. Pirinç teoremi sadece bunun her durumda yapılamayacağını belirtir. Tek ümit edebileceğimiz doğru, yaygın olarak uygulanabilir, ancak doğal olarak eksik bir sistemdir.

Son bir not olarak, bazen basit tip sistemlerin bile eksik olduğu unutulmaktadır ! Örneğin Java'da bile

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

anlamsal olarak güvenlidir (her zaman bir tamsayı döndürür), ancak tür denetleyicisi erişilemez dönüşten şikayet eder.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.