이론적으로 버그가없는 프로그램


12

나는 코드에 버그가 없다고 말하는 많은 기사를 읽었으며 이러한 이론에 대해 이야기하고 있습니다.

실제로 라이스 정리는 정지 문제에 대한 함의로 보이며 정지 문제는 고델의 불완전 정리와 밀접한 관련이 있습니다.

이것은 모든 프로그램이 의도하지 않은 동작을 하나 이상 가질 것이라는 것을 의미합니까? 아니면 그것을 확인하기 위해 코드를 작성할 수 없다는 것을 의미합니까? 재귀 검사는 어떻습니까? 두 개의 프로그램이 있다고 가정 해 봅시다. 둘 다 버그가 있지만 동일한 버그를 공유하지 않습니다. 동시에 실행하면 어떻게됩니까?

물론 대부분의 토론은 튜링 머신에 대해 이야기했습니다. 선형 경계 자동화 (실제 컴퓨터)는 어떻습니까?


10
나는이 파이썬 프로그램이 의도 한 모든 것을하고 더 이상하지 않는다고 확신합니다 : print "Hello, World!"... 좀 더 명확 할 수 있습니까?
durron597

2
@ durron597 : 그러한 소프트웨어를위한 시장이 있습니까? 전 세계 프린터, 새로 고침 된 버전? 이제 더 많은 안녕하세요와 더 많은 세계가 있습니까?
JensG

1
@Phoshi faugh. 버그가없는 프로세스의 전체 범위를 한 번에 볼 수있는 간단한 프로그램 (예 : 브레드 보드에 와이어를 사용하여)을 작성하는 것이 가능합니다. 당신은 내 요점을 다루지 않고 내 의견의 세부 사항을 공격하고 있습니다. 즉 버그가없는 매우 간단한 프로그램을 작성할 수 있습니다.
durron597

2
@Phoshi "파이썬 인터프리터에 버그가 없음을 증명하십시오." 파이썬 구현의 버그는 프로그램을 잘못 만들지 않습니다 . 파이썬 구현이 언어 사양을 준수한다고 가정하면 프로그램이 올바른 것입니다. 모든 증거는 공리로 몇 가지 사항을 취합니다. 예를 들어, 프로그램 실행 전체에서 유니버스가 계속 존재한다고 가정해야합니다. CPython에 버그가 있으면 결과가 잘못되었지만 오류는 프로그램에 없었습니다.
Doval

11
이러한 이론 중 어느 것도 버그 나 버그가없는 프로그램의 존재와 관련이 없습니다. 그들은 계산으로 어떤 질문에 대답 할 수 있는지에 대한 이론입니다. 이 정리가 있다는 것을 보여 일부 계산 될 수없는 문제점 및 일부 둘 입증하거나 반증 할 수있는 수학적 명제는하지만 확실히 말할하지 않는 모든 프로그램이 버그가 있거나 특정 프로그램이 올바른 증명 될 수 없다.
Charles E. Grant

답변:


18

프로그램에 버그가없는 것은 아닙니다. 증명하려는 프로그램이 사소한 것이 아니라면 증명하기가 매우 어렵습니다.

노력이 부족하지 않기 때문에 당신을 염두에 두십시오. 타입 시스템은 약간의 보증을 제공해야합니다. Haskell은 고도로 정교한 유형 시스템을 가지고 있습니다. 그러나 모든 불확실성을 제거 할 수는 없습니다.

다음 기능을 고려하십시오.

int add(int a, int b) { return a + b; }

이 기능으로 무엇이 잘못 될 수 있습니까? 나는 당신이 무엇을 생각하는지 이미 알고 있습니다. 오버플로 확인 등과 같은 모든 기반을 다룬다 고 가정 해 봅시다. 우주 광선이 프로세서에 충돌하여 프로세서가 실행되면 어떻게됩니까?

LaunchMissiles();

대신?

좋아, 아마도 조금 생각이 나겠지. 그러나 add위의 기능과 같은 간단한 기능조차도 프로세서가 지속적으로 컨텍스트를 변경하고 여러 스레드와 코어를 전환하는 환경에서 작동해야합니다. 그런 환경에서는 어떤 일이든 일어날 수 있습니다. 의심스러운 경우 RAM이 오류가 없기 때문에가 아니라 필연적으로 발생하는 비트 오류를 ​​수정하는 시스템이 내장되어 있기 때문에 RAM이 안정적이라고 생각 하십시오.

무슨 생각하는지 알아 "하지만 하드웨어가 아니라 소프트웨어에 대해 이야기하고 있습니다."

소프트웨어가 예상대로 작동한다는 신뢰 수준을 향상시킬 수있는 많은 기술이 있습니다. 함수형 프로그래밍이 그 중 하나입니다. 함수형 프로그래밍을 사용하면 동시성에 대한 더 나은 추론을 할 수 있습니다. 그러나 함수형 프로그래밍은 단위 테스트 이상의 증거아닙니다 .

왜? 엣지 케이스 라고 불리는 것들이 있기 때문 입니다.

그리고의 단순성을 약간 넘어 서면 프로그램의 정확성 return a + b증명 하는 것이 매우 어려워집니다 .

더 읽을 거리
그들은 올바른 물건을 쓴다
Ariane 5 폭발


6
완전히 타입이 올바른 함수를 생각해보십시오 : int add(int a, int b) { return a - b; }
Donal Fellows가

@DonalFellows : 이것이 정확히 내가 Ariane 5에 관한 링크를 포함시킨 이유입니다.
Robert Harvey

2
@DonalFellows-수학 특성화로 문제를 해결할 수 없으며 다른 곳으로 만 이동합니다. 수학적 모델이 실제로 고객의 요구를 나타냄을 어떻게 증명합니까?
mouviciel

1
@JohnGaughan 모듈 간의 상호 의존성을 가정합니다. 정확하고 서로 독립적 인 것으로 입증 된 모듈을 사용하면 정확하고 독립적 인 광고 무한대로 알려진 더 큰 모듈로 재귀 적으로 구성 할 수 있습니다.
Doval

1
@JohnGaughan 모듈의 통합으로 버그가 발생하면 독립성을 증명하지 못한 것입니다. 기존의 증거로 새로운 증거를 만드는 것은 공리에서 증거를 만드는 것보다 어렵지 않습니다. 수학이 기하 급수적으로 어려워 졌다면, 수학자들은 망하게 될 것입니다. 빌드 스크립트에 버그가있을 수 있지만 별도의 프로그램입니다. 구성하려고 할 때 잘못되는 미스터리 요소는 없지만 부작용의 수에 따라 공유 상태가 없음을 증명하기가 어려울 수 있습니다.
Doval

12

먼저, 이에 대해 논의하고자하는 맥락을 설정하자. Stack Exchange의 프로그래머 Q & A는 이론적 결과와 컴퓨터 과학 이론 보다는 실제 도구 / 언어의 존재에 관심이 있다고 제안한다 .

코드에 버그가 없어서는 안되는 기사를 많이 읽었습니다.

그러한 진술이 잘못 되었기 때문에 나는 희망하지 않습니다. 대부분의 대규모 응용 프로그램 에는 내가 아는 한도 내 지식과 경험으로 버그 가없는 것이 일반적 입니다.

Turing-complete 프로그래밍 언어 로 작성된 프로그램에 버그가 없는지 여부를 완벽하게 결정하는 도구가 존재 하지 않는 것 (즉, 존재 하지 않음) 이 더 일반적으로 받아 들여 집니다 .

비 증거는 일상적인 경험의 관찰 데이터와 결합 된 Halting Problem을 직관적으로 확장 한 것입니다.

수행 "의 증거 할 수있는 존재 소프트웨어 정확성 프로그램이 해당 충족하는지 확인" 공식 프로그램에 대한 사양.

이것은 모든 프로그램이 의도하지 않은 동작을 하나 이상 가질 것이라는 것을 의미합니까?

아닙니다. 대부분의 응용 프로그램에는 버그가 하나 이상 있거나 의도하지 않은 동작이있는 것으로 나타났습니다.

아니면 그것을 확인하기 위해 코드를 작성할 수 없다는 것을 의미합니까?

아니요, 공식 사양 및 교정 보조를 사용 하여 사양을 따르는 지 확인할 수 있지만, 경험에 따르면 사양 외부의 요소 (소스 코드 번역기 및 하드웨어)와 같은 전체 시스템에 여전히 실수가있을 수 있으며 가장 자주 실수가 발생합니다. 사양 자체에서.

자세한 내용은 Coq is a tool / language / system을 참조하십시오 .

재귀 검사는 어떻습니까?

모르겠어요 나는 그것에 익숙하지 않으며 그것이 계산 문제 또는 컴파일러 최적화 문제인지 확실하지 않습니다.


1
공식 사양 및 교정 보조에 대해 처음 이야기하는 +1 이것은 이전 답변에서 누락 된 중요한 포인트입니다.
Arseni Mourzenko 19:01에

6

묻고 싶습니다. 모든 코드가 의도하지 않은 동작을 적어도 하나는 받는다는 것을 의미합니까?

아닙니다. 올바른 프로그램을 작성하고 작성할 수 있습니다. 프로그램은 정확할 수 있지만 물리적 상황 (예 : 사용자 Robert Harvey가 여기에 답을 썼음)으로 인해 실행이 실패 할 수 있지만 이는 분명한 문제입니다. 해당 프로그램의 코드는 여전히 옳습니다. 더 정확히하기 위해, 오류가 a로 일으키지 않는 장애 또는 오류 프로그램 자체 만, 기초 시스템에 실행하는 것이 (*).

(*) 각각의 정적 결함, 잘못된 내부 상태 및 사양에 따라 잘못된 외부 관찰 된 행동으로 각각 신뢰성 필드에서 오류 , 오류실패에 대한 정의를 빌리고 있습니다 (<해당 필드의 모든 용지> 참조) .

아니면 코드를 작성할 수 없다는 것을 의미합니까?

위의 진술에서 일반적인 경우를 참조하십시오.

특정 X 프로그램이 올바른지 확인하는 프로그램을 작성할 수 있습니다. 예를 들어, "hello world"프로그램을 순서대로 두 개의 명령어가있는 프로그램으로 정의하면, 즉 print("hello world")exit이 입력이이 두 명령어로 구성된 프로그램인지 순서대로 확인하는 프로그램을 작성할 수 있습니다. "hello world"프로그램을 수정하십시오.

현재 공식을 사용하여 수행 할 수없는 것은 임의의 프로그램이 중지되는지 확인하는 프로그램을 작성하는 것입니다. 일반적인 경우 정확성을 테스트 할 수 없습니다.


4

동일한 프로그램의 둘 이상의 변형을 실행하는 것은 N- 변형 (또는 N- 버전) 프로그래밍이라고하는 잘 알려진 결함 허용 기술입니다. 소프트웨어에 버그가 있음을 인정합니다.

일반적으로 이러한 변형은 서로 다른 컴파일러를 사용하여 서로 다른 개발 팀에 의해 코딩되며 때로는 OS가 다른 서로 다른 CPU에서 실행됩니다. 결과는 사용자에게 출력되기 전에 투표됩니다. 보잉과 에어 버스는 이런 종류의 건축물을 좋아합니다.

두 개의 약한 링크가 남아 공통 모드 버그가 발생합니다.

  • 하나의 사양 만 있습니다.
  • 투표 시스템은 독특하거나 복잡합니다.

5
NASA 또는 다른 우주 프로그램은 N- 변형이 너무 자주 프로그래머가 생각하는 문제로 고통 받고 결함이 가장 사소한 수준을 넘어 서면 일반적인 결함이있는 동등한 프로그램 근처에서 독립적으로 쓰는 결과를 초래한다고 제안했습니다. 예를 들어, 동일한 참조 정보 ( 이진 검색의 장기 버그 참조)를 참조 하고 동일한 알고리즘을 사용하는 경향이 있으며 동일한 종류의 실수를 범합니다.
mctylr

@mctylr-아주 좋은 지적입니다. 그러나 실제로 최근까지 우주선에 하나 이상의 소프트웨어 변형을 저장할 메모리 공간이 충분하지 않았습니다. 그들의 대답은 테스트, 테스트, 테스트, 헹굼, 반복입니다.
mouviciel

우주 왕복선 프로그램은 3 개의 독립적 인 시스템 투표 구성을 사용했습니다. 반대 의견 표결은 시스템이 더 이상 정확하지 않으며 오프라인 상태임을 의미합니다.

4

프로그램은 사양이 있으며 일부 환경에서 실행됩니다.

(변경 다른 답변에서 우주선 예 add로는 FireMissiles 은 "환경"의 일부를 생각 될 수있다)

당신이 공식적으로 프로그램의 의도 된 행동 (즉, 그 사양)과 그 환경을 지정할 수 있습니다 가정하면, 당신은 할 수 가끔 정식 프로그램 (무료 그 정확한 센스 - 버그 -in임을 증명의 행동이나 출력면 공식화에서의 사양의 형식화 그래서 환경).

특히 Frama-C 와 같은 사운드 정적 소스 분석기를 사용할 수 있습니다 .

(그러나 이러한 분석기의 최신 기술은 전체 프로그램 분석 및 GCC 컴파일러, Firefox 브라우저 또는 Linux 커널과 같은 대규모 프로그램의 증거를 허용하지 않습니다. 내 믿음 은 그러한 증거가 평생에 일어날 수 없다는 것입니다 나는 1959 년에 태어났다)

그러나 당신이 증명 한 것은 일부 환경 클래스에서 특정 사양을 가진 프로그램의 올바른 동작입니다.

실제로, 당신은 (그리고 NASA 또는 ESA는 아마도 일부 우주선 소프트웨어가 정확하고 공식화 된 사양을 가진 "버그가 없다"는 것을 증명할 수있다. 그렇다고 시스템이 항상 원하는대로 작동한다는 의미는 아닙니다.

간단히 말해서, 우주선 로봇이 일부 ET를 충족시키고이를 지정하지 않은 경우, 로봇이 실제로 원하는 것처럼 행동 할 수있는 방법은 없습니다.

J.Pitrat의 블로그 항목 도 읽으십시오 .

BTW, Halting 문제 또는 Gödel의 정리는 아마도 인간의 뇌 또는 심지어 인간 종에도 적용됩니다.


아마 SEU의 더 나은 예는 전화를 변경하면 할 Add수 있습니다 LaunchMissiles결국에 잘못된 호출 결과 몇 가지 데이터 값을 변경하는 SEU 될 것이다 LaunchMissiles. SEU는 우주로 들어오는 컴퓨터의 문제입니다. 이것이 현대 우주선이 종종 여러 대의 컴퓨터를 비행하는 이유입니다. 새로운 문제, 동시성 및 중복 관리가 추가되었습니다.
David Hammen

3

이것은 모든 프로그램이 의도하지 않은 동작을 하나 이상 가질 것이라는 것을 의미합니까?

아니.

정지 문제는 모든 프로그램이 제한된 시간 안에 정지하는지 테스트하는 프로그램을 작성하는 것은 불가능하다고 말합니다. 그렇다고 일부 프로그램을 정지로, 다른 프로그램을 정지하지 않은 것으로 분류 할 수있는 프로그램을 작성하는 것이 불가능하다는 의미는 아닙니다. 의미하는 것은 정지 분석기가 어떤 방식 으로든 분류 할 수없는 일부 프로그램이 항상 존재한다는 것입니다.

괴델의 불완전 성 정리는 회색 영역과 비슷합니다. 충분한 복잡성의 수학적 시스템이 주어지면, 그 시스템의 맥락에서 진실성을 평가할 수없는 진술이있을 것이다. 그렇다고 수학자들이 증거에 대한 생각을 포기해야한다는 의미는 아닙니다. 증거는 수학의 초석으로 남아 있습니다.

일부 프로그램은 올바른 것으로 입증 될 수 있습니다. 쉽지는 않지만 할 수 있습니다. 그것이 공식 정리 증명의 목표입니다 (공식적인 방법의 일부). 괴델의 불완전 성 정리는 여기서 파업한다 : 모든 프로그램이 정확한 것으로 입증 될 수있는 것은 아니다. 그렇다고 일부 프로그램이 공식적으로 올바른 것으로 입증 될 수 있기 때문에 공식적인 방법을 사용하는 것이 전적으로 무의미하다는 의미는 아닙니다.

참고 : 공식적인 방법은 우주 광선이 프로세서를 쳐서 launch_missiles()대신 실행할 가능성을 배제합니다 a+b. Robert Harvey의 우주 광선과 같은 단일 이벤트에 영향을받는 실제 시스템이 아닌 추상 시스템의 맥락에서 프로그램을 분석합니다.


1

이 좋은 답변이 많이 여기에 있습니다,하지만 그들은 모두이되는 중요한 지점 주위 치마 같다 : 그 정리의 모든 유사한 구조를 가지고 비슷한 말을하고, 그들이 말하는 것은 하지를 "아마 올바른 쓰기 불가능 프로그램 "(일부 특정 값에 대한"올바른 "와"프로그램 "경우에 경우에 따라 다름),하지만 그들이 ("말 것은 "이 사람이 우리가 잘못된 것을 입증 할 수 없다는 잘못된 프로그램을 작성을 방지하는 것은 불가능합니다 기타).

중지 문제의 구체적인 예를 들자면 그 차이는 더 분명해집니다. 분명히 중단 될 수있는 프로그램과 중단되지 않는 다른 프로그램이 있습니다. 우리가하고 싶은 모든 것이 그 클래스에 속하는 프로그램을 작성하는 것을 피할 수 있기 때문에, 중지하려는 프로그램을 작성하는 것만으로도 행동이 결정될 수없는 프로그램의 세 번째 클래스가 있다는 것입니다.

라이스 정리도 마찬가지입니다. 그렇습니다. 프로그램의 사소한 속성에 대해 해당 속성을 true 또는 false로 입증 할 수없는 프로그램을 작성할 수 있습니다. 또한 프로그램이 가능한지 판단 할 수 있기 때문에 그러한 프로그램을 작성하지 않아도됩니다.


0

저의 대답은 실제 비즈니스의 관점과 모든 개발 팀이 직면 한 과제에서 비롯됩니다. 이 질문과 많은 답변에서 볼 수있는 것은 실제로 결함 제어에 관한 것입니다.

코드에 버그가 없을 수 있습니다. 모든 프로그래밍 언어에 대한 "Hello World"코드 샘플을 가져 와서 원하는 플랫폼에서 실행하면 일관성있게 작동하며 원하는 결과를 얻을 수 있습니다. 버그가없는 코드의 불가능성에 대한 이론은 끝납니다.

논리가 복잡 해짐에 따라 잠재적 인 버그가 발생합니다. 간단한 Hello World 예제에는 논리가 없으며 매번 동일한 정적 작업을 수행합니다. 논리 중심의 동적 동작을 추가하자마자 복잡성이 발생하여 버그가 발생합니다. 로직 자체에 결함이 있거나 로직에 입력되는 데이터가 로직이 처리하지 않는 방식으로 달라질 수 있습니다.

최신 응용 프로그램은 또한 런타임 라이브러리, CLR, 미들웨어, 데이터베이스 등 레이어에 의존합니다. 레이어는 전체 개발 시간을 절약하면서도 해당 레이어 내의 버그가 존재할 수있는 레이어이며 개발 및 UAT 테스트를 통해 프로덕션으로 감지되지 않습니다.

마지막으로, 응용 프로그램이 논리를 공급하는 데이터를 사용하는 응용 프로그램 / 시스템 체인은 논리 내에서 또는 논리가 사용하는 소프트웨어 스택 또는 데이터를 소비하는 업스트림 시스템 내의 모든 잠재적 버그의 원인입니다.

개발자는 응용 프로그램의 논리를 지원하는 모든 움직이는 부분을 100 % 제어 할 수 없습니다. 실제로 우리는 많은 것을 통제하지 않습니다. 그렇기 때문에 단위 테스트가 중요하고 구성 및 변경 관리는 중요한 프로세스이므로 무시하거나 게으르지 않아야합니다.

또한 제어 할 수없는 소스에서 데이터를 소비하는 애플리케이션 간의 문서화 된 계약, 전송 된 데이터의 특정 형식 및 사양, 시스템이 소스 시스템이 출력을 보장 할 책임이 있다고 가정하는 제한 또는 제약 조건을 정의합니다. 그 한계.

실제 소프트웨어 엔지니어링 응용 프로그램에서는 이론적으로 응용 프로그램에 버그가없는 이유를 비즈니스에 설명하여이를 즉시 구현할 수 없습니다. 기술과 비즈니스 사이의 이러한 특성에 대한 논의는 비즈니스의 돈을 버는 능력, 돈을 잃는 것을 막고 및 / 또는 사람들의 생존을 유지하는 능력에 영향을 준 기술적 오작동 이후를 제외하고는 결코 일어나지 않을 것입니다. "어떻게 이런 일이 일어날 수 있을까요?"에 대한 대답은 "이 이론을 설명 할 수 있도록 이해할 수 없습니다."

이론적으로 계산을 수행하고 결과를 얻는 데 영원히 걸릴 수있는 대규모 계산의 관점에서, 결과를 끝내고 반환 할 수없는 응용 프로그램은 버그입니다. 계산의 특성상 시간이 많이 걸리고 계산이 많이 필요한 경우에는 해당 요청을 가져 와서 결과를 검색 할 수있는 방법 / 언제나 병렬 스레드를 시작하여 사용자에게 피드백을 제공하십시오. 이 작업이 한 서버에서 수행 할 수있는 것보다 빠르며 비즈니스에서 충분히 중요한 경우 필요한만큼 많은 시스템으로 확장 할 수 있습니다. 그렇기 때문에 클라우드가 매우 매력적이며 노드를 가동하여 작업을 수행하고 완료되면 스핀 다운 할 수 있습니다.

계산 능력이 충분하지 않다는 요청을받을 가능성이있는 경우, 비즈니스 프로세스가 유한 문제라고 생각하는 것에 대한 응답을 기다리는 비즈니스 프로세스로 무한대로 실행해서는 안됩니다.


-2

코드가 실제로 완료되지 않았기 때문에 코드에 100 % 버그가 없다고 생각하지 않습니다. 당신은 항상 당신이 쓰는 것을 향상시킬 수 있습니다.

프로그래밍은 과학 및 수학 분야이며,이 경우 모두 끝이 없습니다. 개발자가되는 것의 가장 큰 장점은 우리의 일이 끝이 없다는 것입니다.

한 줄의 코드를 작성하는 방법에는 수천 가지가 있습니다. 아이디어는 해당 코드 줄의 가장 최적화 된 버전을 작성하는 것이지만 버그가없는 것은 아닙니다. 버그 프리는 코드가 깨지지 않으며 모든 코드가 어느 정도 또는 방법으로 손상 될 수 있다는 아이디어를 말합니다.

코드가 효율적일 수 있습니까? 예.
코드를 끝없이 최적화 할 수 있습니까? 예.
코드에 버그가 없습니까? 아니요, 당신은 아직 그것을 깨는 방법을 찾지 못했습니다.
즉, 자신과 코드 작성 방법을 개선하기 위해 노력하면 코드를 깨기가 어렵습니다.


이 게시물은 읽기 어렵습니다 (텍스트의 벽). 더 나은 형태로 편집 하시겠습니까 ?
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.