아마도 올바른 프로그램에 대해 무엇을 알고 있습니까?


37

점점 더 복잡 해지는 컴퓨터 프로그램과 점점 더 사회에서 컴퓨터의 중요성이 높아짐에 따라 코드가 올바르게 작동한다는 공식적인 증거를 제공해야하는 프로그래밍 언어를 집단적으로 사용하지 않는 이유가 궁금합니다.

이 용어는 '인증 ​​컴파일러'라고 생각합니다 ( 여기서 찾았습니다 ). 코드를 작성해야 할뿐만 아니라 코드의 사양을 명시하고 코드가 코드를 준수한다는 것을 입증하는 프로그래밍 언어를 컴파일하는 컴파일러 사양 (또는 자동화 된 프로 버를 사용).

인터넷을 검색하는 동안 매우 간단한 프로그래밍 언어를 사용하거나 최신 프로그래밍 언어를 적용하려는 프로젝트가 실패했습니다. 이것은 내 질문으로 이어집니다.

완전한 프로그래밍 언어를 구현하는 인증 컴파일러가 있습니까? 아니면 매우 어렵거나 이론적으로 불가능합니까?

또한, 나는 복잡 클래스는 다음과 같은 증명 프로그램과 관련된보고 아직했습니다 '증거가 존재하는 튜링 기계에 의해 모든 언어의 클래스를 decidable가이 튜링 기계가 정지'나는 부를 것이다, ProvableR 에 아날로그로, R , 재귀 적 언어의 집합.

I 이러한 복잡도 종류 공부의 이점을 볼 수있다 : 예를 들어,에 대한 ProvableR 중단 문제가 decidable이다 (I에도 추측 ProvableRE 명백한 방식으로 정의 된 것 결정 가능한 언어의 가장 큰 클래스). 또한, 실제로 유용한 프로그램을 배제 할 수 있을지 의심됩니다.

두 번째 질문은 다음과 같습니다.

포함 언어가 특정 속성을 가질 수 있어야하는 복잡성 클래스에 대해 무엇을 알고 있습니까?


1
컴파일러는 가능한 모든 길이 i 증명을 열거하여 프로그램이 정지한다는 증거를 찾을 때까지 1에서 무한대로 이동할 수 있습니다. 컴파일러에 대한 입력이 중단되어야하는 경우 컴파일러는 항상 그 증거를 찾습니다. 중지 문제는 결정할 수 없으므로 중지 된 프로그램이 있다고 결론을 내릴 수 있지만 이에 대한 증거는 없습니다. 중요한 점은 프로그램이 증거가 있는지 확인할 수없고 증거가 있으면 찾을 수 없다는 것입니다.
Alex ten Brink

3
나는 당신이 그들을 분리해야한다고 생각합니다. 그들은 다른 답변을 가진 다른 질문입니다.
Mark Reitblatt

4
첫 번째 질문에서 영향력있는 논문은 "사회적 프로세스와 이론과 프로그램의 증거", portal.acm.org/citation.cfm?id=359106
Colin McQuillan

1
프로그램 검증은 결정할 수 없습니다. 따라서 한 가지 문제는 무엇이 좋은 솔루션을 구성하는지 말하는 것입니다. cstheory.stackexchange.com/questions/4016/…
Radu GRIGore

2
@Colin : 그 논문은 증거 분석을 위해 읽을 가치가 있지만, 그 예측은 위조되었습니다. 오늘날 우리는 컴파일러, 운영 체제 커널, 가비지 수집기 및 데이터베이스를 모두 수정했습니다. 그들의 비판을 피하기위한 비법은 공식적인 증거에 대한 하위 수준의 세부 사항에 대한 인간의 검증을 피하는 것이 아니라 기계의 증명에 대한 검증을 사용하고 인간을 사용하여 증명 검사기를 검증하는 것이 었습니다. 형식 이론에 대한 Noam의 언급은 최신 기술이있는 곳이며, 형식 이론이 기능적이므로 명령형 프로그램을 구속력있는 것으로 남겨둔다.
Neel Krishnaswami

답변:


28

"컴파일러 인증"은 일반적으로 약간 다른 것을 의미합니다. 즉, 생성하는 기계어 코드가 상위 레벨 시맨틱을 올바르게 구현 함을 증명할 수있는 컴파일러가 있음을 의미합니다. 즉, 이것은 컴파일러 버그가 없다는 증거입니다. 사람들이 컴파일러에 제공하는 프로그램은 여전히 ​​틀릴 수 있지만 컴파일러는 잘못된 프로그램의 올바른 기계 코드 버전을 생성합니다. 이 라인에서 가장 큰 성공 사례는 CompCert에서 검증 한 컴파일러 인데, 이는 C의 큰 부분 집합을위한 컴파일러입니다.

Compcert 컴파일러 자체는 정확성 증명 (Coq에서 수행)이있는 프로그램으로, 프로그램 코드를 생성 할 경우 (CompCert 설계자가 사용한 어셈블리 및 C의 작동 의미와 관련하여) 정확함을 보장합니다. 이러한 것들을 기계 점검하는 노력은 상당히 크다. 일반적으로 정확성 증명은 확인중인 프로그램 크기의 1x에서 100x 사이입니다. 기계 검사 프로그램과 증명을 작성하는 것은 배우는 새로운 기술입니다. 수학이나 프로그래밍은 아니지만 둘 다 잘 수행하는 데 달려 있습니다. 초보자 프로그래머처럼 다시 시작하는 것처럼 느껴집니다.

그러나 이에 대한 특별한 이론적 장벽은 없습니다. 이 행을 따르는 유일한 것은 모든 프로그램이 전체 언어 인 모든 언어에 대해 전체 언어로 프로그래밍 할 때 기하 급수적으로 더 큰 일반적인 재귀 언어로 프로그램을 찾을 수 있다는 Blum Size 정리 입니다. 이 결과를 이해하는 방법은 전체 언어가 프로그램뿐만 아니라 종료 증명을 인코딩한다는 것입니다. 따라서 긴 종료 증명 기능을 갖춘 짧은 프로그램을 가질 수 있습니다. 그러나 관리 가능한 종료 증명 기능이있는 프로그램 만 작성하므로 실제로는 실제로 중요하지 않습니다.

편집 : Dai Le는 마지막 요점에 대해 자세히 설명했습니다.

이것은 프로그램이 왜 작동하는지 이해할 수 있다면 그 이유가 수백만 페이지에 달하는 막대한 가능성이 거의 없다는 사실에 근거한 실질적인 주장입니다. (내가 사용한 가장 긴 불변은 몇 페이지 길이이며 소년은 리뷰어를 불평하게 만듭니다! 변하지 않는 것도 사람들이 그것을 이해하는 데 도움이되는 모든 이야기를 제거하는 이유이기 때문에 이해할 수 있습니다.)

그러나 이론적 인 이유도 있습니다. 기본적으로 정확성 증명이 매우 긴 프로그램을 체계적으로 발명하는 방법은 많이 모릅니다. 주요 방법은 (1) 정확성을 입증하는 논리를 취하고 (2) 해당 논리에 직접 표현할 수없는 속성을 찾고 (일관성 증명은 일반적인 출처 임) (3) 다음과 같은 프로그램을 찾는 것입니다. 정확성 증명은 표현할 수없는 재산의 표현 가능한 결과에 의존합니다. (2)는 표현할 수 없기 때문에 각 표현 가능한 결과의 증거는 독립적으로 수행되어야하므로 정확성 증명의 크기를 높일 수 있습니다. 간단한 예로 부모 관계가있는 1 차 논리에서는 조상 관계를 표현할 수 없습니다.kkk

이 주제에 대한 정교한 이해를 "역 수학"이라고하며, 주어진 이론을 증명하기 위해 어떤 공리가 필요한지에 대한 연구입니다. 나는 그것에 대해 많이 알지 못하지만 CS에 응용 프로그램에 대한 질문을 게시하면 적어도 Timothy Chow와 다른 여러 사람들이 흥미로운 것을 말할 수 있다고 확신합니다.


1
이 시점을 좀 더 자세히 설명해 주시겠습니까? "관리 가능한 종료 증명 기능이있는 프로그램 만 작성하겠습니다"?
Dai Le

업데이트 된 답변에 감사드립니다! 당신의 대답은 정말로 내 관점을 열어줍니다. 사실 나는 나 자신도 "역 수학"에 대해 약간의 연구를하지만, 당신이 언급 한 연결을 깨닫지 못했습니다. 다시 감사합니다!
Dai Le

1
편집의 요점은 자연 증거 시스템 (예 : Frege)에서 긴 증거를 요구하는 타톨 로지 후보자가 거의 없다는 사실과 관련이 있습니다. 그 이유 중 하나는 우리가 타우 톨로지를 아는 유일한 방법은 처음에는 타블로 지이기 때문입니다. 왜냐하면 우리가 반드시 그렇게 오래 걸리지 않았다는 증거를 염두에 두었 기 때문입니다!
Joshua Grochow

22

첫 번째 질문에 대한 대답은 일반적으로 현재 도구로 는 너무 많은 작업이라는 것 입니다. 느낌을 얻으려면 Coq에서 Bubble Sort의 정확성을 증명하는 것이 좋습니다 (또는 조금 더 도전을 원한다면 Quick Sort를 사용하십시오). 그런 기본 알고리즘의 정확성을 입증하는 것이 너무 어렵고 시간이 많이 걸리는 한 프로그래머가 검증 된 프로그램을 작성할 것으로 기대하는 것이 합리적이라고 생각하지 않습니다.

이 질문은 왜 수학자들이 증거 확인자가 검증 할 수있는 공식적인 증거를 쓰지 않는지 묻는 것과 비슷합니다. 공식적인 정확성 증명을 가진 프로그램을 작성한다는 것은 쓰여진 코드에 대한 수학적 정리를 증명하는 것을 의미하며, 그 질문에 대한 답변도 귀하의 질문에 적용됩니다.

이것은 확인 된 프로그램의 성공 사례가 없다는 것을 의미하지는 않습니다. Microsoft 하이퍼 바이저 와 같은 시스템의 정확성을 입증하는 그룹 이 있다는 것을 알고 있습니다. 관련 사례는 Microsoft의 Verified C Compiler 입니다. 그러나 일반적으로 현재 도구는 일반 프로그래머 (및 수학자)에게 유용하기 전에 많은 개발 (SE 및 HCI 측면 포함)이 필요합니다.

전체 기능 만있는 언어의 프로그램 크기 증가에 대한 Neel의 답변 의 마지막 단락과 관련하여 실제로는 더 많은 것을 쉽게 증명할 수 있습니다 (정확히 이해하면). 모든 프로그래밍 언어의 구문이 ce이고 총 계산 가능한 함수 집합이 ce가 아닌 것으로 기대하는 것이 합리적이므로 모든 프로그램이 총체 인 프로그래밍 언어의 경우 모든 프로그램에서 계산할 수없는 총 계산 가능한 함수가 있습니다 ( 해당 언어로 제공됩니다.


AC0AC0-복잡성 클래스에 대해 완전하므로 복잡성 클래스의 모든 문제를 포함하며 해당 프로그램의 전체 성을 증명할 수 있습니다. 증명 이론과 복잡성 이론의 관계는 증명 복잡성에 대해 연구됩니다 . 관심이 있으시면 SA Cook과 P. Nguyen의 최근 저서 인 " Proof Complexity of Proof Complexity "를 참조하십시오. ( 2008 년 초안 을 사용할 수 있습니다.) 따라서 기본적인 대답은 많은 클래스 "아마도 C = C"입니다.

PAϵ0TPA2FIΣ1

그러나 같은 기능을 확장 적으로 계산하는 프로그램도 있지만 두 프로그램이 동일한 기능을 계산하고 있음을 증명할 수는 없습니다. 즉, 프로그램이 확장 적으로 동일하지만 그렇지 않다는 것을 증명할 수는 없습니다. 의도적으로. (이것은 모닝 스타 및 이브닝 스타와 유사합니다.) 또한 이론적으로 전체를 증명할 수없는 프로그램을 얻기 위해 주어진 전체 프로그램을 쉽게 수정할 수 있습니다.


PnnP증명으로부터 인수 분해를위한 알고리즘. (가능한 첫 번째 방법을 최대한 자동화하려고하는 연구원도 있지만 프로그램의 흥미로운 비 사소한 속성을 확인하는 것은 계산이 어렵고 오 탐지 없이는 완전히 확인할 수 없습니다.)


3
좋은 대답입니다! 한 가지 방법은 증명에서 프로그램을 추출하는 것입니다. 예를 들어 Coq에서 자동으로 수행 할 수 있습니다. 관련 영역은 증거 마이닝으로 , 사람들 (보통 수학 논리에서 일하는 사람들)은 주어진 증거에서 정보를 추출하려고 시도합니다. 예를 들어, 어떤 경우에는 고전적으로 주어진 직관적 증거를 (자동으로) 찾을 수 있습니다.
Radu GRIGore

1
Π20PAHA

1
Andrej Bauer는 자신의 블로그 에 Coq에서 Godel의 Dialectica Interpretation 을 증명하는 새로운 흥미로운 게시물을 가지고 있습니다.
Kaveh

18

첫 번째 질문에서 묻는 것은 때때로 "확인 컴파일러"라고하며, 몇 년 전 Tony Hoare는이 를 컴퓨팅 연구를위한 커다란 도전 으로 제공했습니다 . 어느 정도까지는 이미 존재하며 Coq theorem prover 와 같은 도구에서 적극적으로 사용되고 있으며 , 이는 유형 이론유형별 제안 원칙 ( " Curry-Howard ")을 통해 문제를 구성합니다 .

편집 : "어느 정도"에 중점을두고 싶었습니다. 이것은 해결 된 문제와는 거리가 멀지 만 Coq의 성공은 그것이 파이프 꿈이 아니라는 희망을줍니다.


8
검증 된 소프트웨어를 구축하는 것이 1956 년에 기존의 소프트웨어를 구축하는 곳이라고 말할 수 있습니다. 소프트웨어가 매우 중요하다는 것은 이미 명백했으며, 이미 중요한 성공 사례가있었습니다. 그러나 사람들은 여전히 ​​많은 기본 개념이 빠져 있었으며 (예를 들어 어떤 절차와 변수가 무엇인지에 대한 명확한 이해) 이론에서 실제까지의 거리는 정리에서 코드를 프로그래밍하여 Lisp를 구현하는 것만 큼 짧을 수 있습니다. 언어와 검증 작업에있어 매우 흥미로운 시간입니다.
Neel Krishnaswami

12

프로그램이 올바른지 확인하는 도구를 프로그램 검증기라고도합니다. 이러한 맥락에서 "올바른"은 일반적으로 두 가지를 의미합니다. 프로그램은 특정 출력을 생성하지 않으며 (세그먼트 오류, NullPointerException 등) 사양에 동의합니다.

코드와 사양은 동의하고 여전히 잘못된 것으로 인식 될 수 있습니다. 어떤 의미에서 개발자에게 사양 작성을 요청하는 것은 두 개발자에게 문제를 해결하도록 요청하는 것과 같습니다. 두 가지 구현이 모두 동의하면 정상이라는 확신을 갖게됩니다. 그러나 다른 의미에서 사양은 두 번째 구현보다 낫습니다. 사양은 효율적이거나 실행 가능할 필요가 없기 때문에 훨씬 간결 해져서 잘못 이해하기가 더 어려울 수 있습니다.

이러한 경고를 염두에두고 Spec # 프로그램 검증기 를 살펴 보는 것이 좋습니다 .


Spec # (및 확장명 Sing #)을 이해하는 한 프로그래머는 어설 션을 정적으로 확인할 수 있지만 프로그래머는이를 요구하지 않으며 코드의 임의의 속성을 증명할 수 없습니다.
Alex ten Brink

원칙적으로 임의의 속성을 다음과 같이 인코딩 할 수 있습니다. 도구가 무엇을 원하는지 잘 모르겠습니다. 스펙이 모든 가능한 입력에 대해 출력이 무엇인지 말하도록 하시겠습니까?
Radu GRIGore

4

일반적으로 알고리즘이 사양과 같은지 확인하는 알고리즘을 만드는 것은 불가능합니다. 이것은 비공식 증거입니다.

거의 모든 프로그래밍 언어는 Turing-complete입니다. 따라서 TM에 의해 결정된 모든 언어는이 언어로 작성된 프로그램에 의해 결정될 수도 있습니다.

Equivalence/TM

Equivalence/TMNonemptiness/TMEmptiness/TMEmptiness/TMEquivalence/TMEquivalence/TM또한 용납 할 수 없습니다. 따라서 두 시스템이 같지 않은지 여부에 관계없이 알고리즘을 사용할 수 있지만 해당 시스템이 동등한 지 또는 알고리즘에 충분한 시간을 제공하지 않았는지 확신 할 수 없습니다.

그러나 이것은 일반적인 경우에만 해당됩니다. 보다 편안한 버전의 문제를 해결하여 사양이 프로그램과 동등한 지 여부를 결정할 수 있습니다. 예를 들어, 많은 입력 만 조사하거나 두 프로그램이 약간의 불확실성과 동일하다고 말할 수 있습니다. 이것이 바로 소프트웨어 테스트의 핵심입니다.

나머지 질문에 관해서는 :

참고 :이 부분은 설명을 위해 편집되었습니다. 내가 피하려고했던 실수를 저지른 것으로 밝혀졌습니다. 죄송합니다.

TrueRTrueRR

ProvableR=TrueRProvableRTrueRTrueRProvableRAϵTrueRAAAϵProvableR

비공식적으로 이것은 다음과 같이 요약 될 수 있습니다. 언어가 입증 될 때까지 언어를 결정할 수 있다는 것을 모릅니다. 따라서 공식적인 시스템에서 언어를 결정할 수 있다는 지식을 가지고 있다면이 지식도이를 증명할 수 있습니다. 따라서 언어를 결정할 수 있고 증명할 수 없다는 사실을 동시에 알 수는 없습니다.이 두 문장은 상호 배타적입니다.

RProvableRProvableRRR

@Kaveh는 그것을 가장 잘 요약합니다 : Provable은 항상 일부 시스템 / 이론에서 입증 가능하며 일반적으로 진실과 일치하지 않습니다.

다른 복잡성 클래스도 마찬가지입니다. 멤버십을 확인하려면 먼저 증명이 필요합니다. 그렇기 때문에 두 번째 질문은 언어가 갖고 싶은 속성에 따라 복잡성 이론뿐만 아니라 계산 이론도 포함하기 때문에 너무 일반적이라고 생각합니다.


1
RProvableRΣ30Σ10

1
증명은 항상 어떤 시스템 / 이론에서 증명할 수 있으며 일반적으로 진실과 일치하지 않습니다.
Kaveh

1
나는 내 질문이 흥미 롭기 때문에 결정 가능한 언어 세트가 아니라 정지 튜링 머신 세트에 대해 이야기해야한다는 것을 알았습니다.
Alex ten Brink

1
@Alex 글쎄, 당신은 언어에 대해 이야기 할 수있는 방법이 필요하지만, 셀 수없이 많습니다. 따라서 증거와 같은 유한 객체에 연결된 언어에 대해 이야기하려면 TM과 같은 유한 객체로 식별 가능한 언어로 자신을 제한해야합니다.
Mark Reitblatt

2
R

3

다음 고전 논문은 거의 정확히 두 번째 질문입니다.

Hartmanis, J. 실현 가능한 계산 및 입증 가능한 복잡성 속성 , 응용 수학에서의 CBMS-NSF 지역 회의 시리즈, 30. SIAM (Society for Industrial and Applied Mathematics), 미국 펜실베이니아 주 필라델피아, 1978.

{L(Mi)|Ti(n)T(n) is provable in F}MiTi(n)Min

T(n)nlog(n)g(n)1FTIME[T(n)]TIME[T(n)g(n)]

T(n)FTIME[T(n)]TIME[T(n)]

T(n)nlog(n)TIME[T(n)]={L(Mi)|F proves(j)[L(Mj)=L(Mi)Tj(n)T(n)]}

그러나 공간의 경우 상황이 더 잘 제어됩니다.

s(n)nSPACE[s(n)]=FSPACE[s(n)]

SPACE[S(n)]=FSPACE[S(n)]S(n)ns(n)SPACE[S(n)]=SPACE[s(n)]


1

질문은 올바르게 제기되어야합니다. 예를 들어, 실제 프로그램이 무한 메모리와 주어진 메모리에 접근 할 수있는 방법을 알고 싶어하는 사람은 없습니다 (기본 주소를 일부 숫자만큼 이동시키는 작업 일 수 있습니다). 튜링의 정리는 구체적인 의미에서 프로그램의 정확성과 관련이 없으며 프로그램 검증의 장벽으로 인용하는 사람들은 두 가지 다른 것을 혼동합니다. 엔지니어 / 프로그래머가 프로그램 정확성에 대해 이야기 할 때 유한 속성에 대해 알고 싶어합니다. 이것은 또한 무언가 가능성이 있는지에 관심이있는 수학자에게도 마찬가지입니다. Godel의 편지 http://vyodaiken.com/2009/08/28/godels-lost-letter/ 는 이것을 자세히 설명합니다.

즉, 엔 치도 문제의 결정 불가능 함에도 불구하고, 예 또는 아니오 질문에 관한 수학자의 정신 연구는 기계로 완전히 대체 될 수 있음을 의미합니다. 결국, 자연수 n을 너무 크게 선택하여 기계가 결과를 제공하지 않을 때 문제에 대해 더 많이 생각하는 것은 의미가 없습니다.

실제 컴퓨터에서 실행되는 프로그램의 거대한 상태 세트를 검사하고 불량 상태를 감지하는 것은 불가능할 수 있습니다. 이론적으로는 불가능한 이유가 없습니다. 실제로이 분야에서 많은 진전이있었습니다. 예를 들어 http://www.cs.cornell.edu/gomes/papers/SATSolvers-KR-book-draft-07.pdf(Neil Immerman에게 감사드립니다) 이것에 대해 말해줘)

다른 어려운 문제는 프로그램이 올바르게하기 위해 원하는 속성을 정확하게 지정하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.