답변:
실제로 그런 의미에서가 아니라 순수한 기능 프로그래밍이이 영역에서 좋습니다. Haskell을 사용하면 코드가 컴파일되면 프로그램이 올바른 것일 수 있습니다. IO를 제외하고 좋은 유형의 시스템이 도움이됩니다.
계약 프로그래밍도 도움이 될 수 있습니다. Microsoft 코드 계약 참조
가장 사소한 프로그램을 제외한 모두
합리적인 노력으로 옳다는 것을 완전히 증명할 수는 없습니다. 공식적인 정확성 증명을 위해서는 최소한 공식적인 사양이 필요하며 해당 사양은 완전하고 정확해야합니다. 일반적으로 대부분의 실제 프로그램에서 쉽게 만들 수있는 것은 아닙니다. 예를 들어,이 토론 사이트의 사용자 인터페이스와 같은 사양을 작성하면 무슨 의미인지 알 수 있습니다.
여기서 나는 주제에 관한 좋은 기사를 찾았습니다.
http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html
printf("1")
이 정확하거나 그렇지 않은 경우 (예를 들어, 요구 사항이 "1에서 6까지 균등하게 분포 된 난수를 인쇄하기 때문에") 이러한 정적 분석기로 결정할 수 없습니다.
공식적인 증거의 문제는 단지 문제를 한 단계 뒤로 이동 시킨다는 것입니다.
프로그램이 올바르다는 것은 프로그램이해야 할 일을하는 것과 같습니다. 프로그램이 어떻게해야하는지 어떻게 정의합니까? 지정하십시오. 그리고 스펙이 다루지 않는 엣지 케이스에서 프로그램이 어떻게해야하는지 어떻게 정의합니까? 그렇다면 스펙을 더 자세하게 만들어야합니다.
따라서 전체 프로그램의 모든 측면에 대한 올바른 동작을 설명 할 수있을 정도로 사양이 상세 해집니다. 이제 증명 도구를 이해하는 방법이 필요합니다. 따라서 사양을 교정 도구가 이해할 수있는 일종의 공식 언어로 변환해야합니다. 잠시만 기다려주십시오!
공식 검증은 먼 길을 갔지만 일반적으로 업계 / 일반적으로 사용되는 도구는 최신 연구보다 뒤떨어져 있습니다. 이 방향으로 최근 몇 가지 노력이 있습니다.
Spec # http://research.microsoft.com/en-us/projects/specsharp/ 코드 계약 (사전 / 사후 조건 및 불변)을 지원하는 C #의 확장이며이 계약을 사용하여 다양한 유형의 정적 분석을 수행 할 수 있습니다. .
Java 용 JML과 같은 다른 언어에서도 이와 유사한 프로젝트가 존재하며 Eiffel에는 거의 내장되어 있습니다.
더 나아가서, 슬램 및 블래스트 와 같은 프로젝트 는 최소한의 프로그래머 주석 / 중재로 특정 행동 속성을 검증하는 데 사용될 수 있지만, 현대 언어의 전체 일반성을 처리 할 수는 없습니다 (정수 오버플로 / 포인터 산술과 같은 것은 모델링되지 않음).
앞으로이 기술들이 훨씬 더 많이 사용될 것으로 믿습니다. 주된 장벽은 프로그램 불변이 수동 주석없이 추론하기가 어렵다는 점이며, 프로그래머는 이러한 주석을 제공하는 것이 너무 지루하고 시간이 많이 걸리기 때문에 일반적으로 이러한 주석을 제공하지 않습니다.
광범위한 개발자 작업없이 코드를 자동으로 증명하는 방법이 없다면 그렇지 않습니다.
일부 공식적인 방법 도구 (예 : 중요한 임베디드 C 소프트웨어의 경우 Frama-C )는 주어진 소프트웨어의 (정확한) 증거를 제공하거나 (정렬) 확인하는 것으로 볼 수 있습니다. (Frama-C는 어떤 방식 으로든 프로그램이 공식화 된 사양을 준수하고 프로그램에서 명시 적으로 주석이 달린 불변량을 존중하는지 확인합니다).
일부 부문에서는 민간 항공기의 중요 소프트웨어에 대한 DO-178C 와 같은 공식적인 방법이 가능합니다 . 따라서 어떤 경우에는 그러한 접근법이 가능하고 도움이됩니다.
물론 버그가 적은 소프트웨어를 개발하는 것은 비용이 많이 듭니다. 그러나 공식적인 방법론은 어떤 종류의 소프트웨어에 적합합니다. 비관적 인 경우 버그가 코드에서 공식 사양으로 이동했다고 생각할 수 있습니다 (소프트웨어의 의도 된 동작을 공식화하는 것이 어렵고 오류가 발생하기 때문에 일부 "버그"가있을 수 있음).
나는이 질문에 걸려 넘어 졌고이 링크가 흥미로울 것이라고 생각합니다.
Airbus에서 2003 년에 130K 이상의 코드 라인을 사용하는 시스템에 RTE가 없음을 증명하는 것은 나쁘지 않은 것으로 보이며 이것이 현실이 아니라고 말하는 사람이 있을지 궁금합니다.
아닙니다. 이것에 대한 일반적인 속담은 "이론에서 이론과 실제는 동일합니다. 실제로는 아닙니다."
하나의 매우 간단한 예 : 오타.
실제로 단위 테스트를 통해 코드를 실행하면 거의 즉시 그러한 것들을 발견 할 수 있으며, 일련의 테스트를 통해 공식적인 증거가 필요하지 않습니다. 모든 유스 케이스 (좋은, 나쁜, 오류 및 엣지 케이스)는 단위 테스트에서 열거되어야하며, 이는 코드와 분리 된 그러한 증거보다 코드의 정확성이 더 우수하다는 결과를 낳습니다.
특히 요구 사항이 변경되거나 버그를 수정하기 위해 알고리즘이 업데이트되는 경우 코드 주석이 자주 얻는 것과 같이 공식적인 증거가 만료 될 가능성이 높습니다.
중지 문제로 인해 정확성 증명에 부과되는 한계 는 정확성 증명이 주류가되는 가장 큰 장벽이 될 수 있다고 생각합니다 .
이미 모든 사람이 사용하고 있습니다. 프로그래밍 언어의 유형 검사를 사용할 때마다 기본적으로 프로그램의 정확성을 수학적으로 증명합니다. 이것은 이미 잘 작동합니다. 사용하는 모든 함수와 데이터 구조에 맞는 유형을 선택하면됩니다. 유형이 정확할수록 더 잘 확인할 수 있습니다. 프로그래밍 언어로 제공되는 기존 유형에는 이미 거의 모든 동작을 설명 할 수있는 강력한 도구가 있습니다. 이것은 사용 가능한 모든 언어로 작동합니다. C ++과 정적 언어는 컴파일 타임에 검사를 수행하는 반면, 파이썬과 같은 더 동적 인 언어는 프로그램이 실행될 때 수행합니다. 수표는 여전히 모든 언어로 존재합니다. (예를 들어, C ++는 이미 haskell과 동일한 방식으로 부작용 검사를 지원합니다.
mutable
또는 const_cast
. 나는 확실히 당신이 거기에 연결을보고 있지만, 두 가지 접근법의 맛은 나에게 다소 다르게 보입니다.