타입 시스템에서 정렬 작업 증명


9

프로그래밍 언어의 유형 시스템이 얼마나 유용한 지 알고 싶습니다. 예를 들어, 의존적으로 유형이 지정된 프로그래밍 언어 Vector에서 벡터의 크기를 유형 서명에 통합 하는 클래스를 만들 수 있다는 것을 알고 있습니다 . 사실상의 예와 같습니다. append컴파일러는 결과 목록의 크기가 입력 목록의 합임을 증명할 수 있도록 해당 서명을 사용하여 함수 를 작성할 수도 있습니다.

예를 들어, 컴파일러가 결과 목록이 입력 목록의 순열임을 보증하도록 정렬 알고리즘의 유형 서명으로 인코딩하는 방법이 있습니까? 가능하다면 어떻게 할 수 있습니까?

답변:


13

예, 정렬 루틴에 대해 정확한 유형을 표현할 수 있으므로 해당 유형의 모든 함수가 실제로 입력 목록을 정렬해야합니다.

좀 더 고급스럽고 우아한 솔루션이있을 수 있지만 기본 솔루션 만 스케치하겠습니다.

Coq와 같은 표기법을 사용합니다. 우리 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 ..1입력 목록의 요소를 l출력 목록 의 요소로 매핑합니다 s. 위의 정리를 호출하여 증명해야합니다.에프(미디엄)<에 필요한 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.