Hoare 스타일 정확성 증명 중 배열 처리 방법


11

이 질문에 대한 토론 에서 Gilles는 배열을 사용하는 알고리즘의 정확성 증명이 범위를 벗어난 배열 액세스가 없음을 증명해야한다고 올바르게 언급합니다. 런타임 모델에 따라 런타임 오류가 발생하거나 배열이 아닌 요소에 액세스 할 수 있습니다.

이러한 정확성 증명을 수행하는 일반적인 기술 중 하나는 (최소 저학년 연구 및 아마도 자동화 된 검증에서) Hoare 논리 를 사용하는 것 입니다. 표준 규칙 집합에 배열과 관련된 내용이 포함되어 있음을 알 수 없습니다. 그들은 모나 딕 변수로 제한되어있는 것 같습니다.

형태의 공리를 추가하는 것을 상상할 수 있습니다

{0i<A.lengthP[A[i]/E]} A[i]:=E; {P}

그러나 오른쪽에서 배열 액세스를 처리하는 방법, 즉 일부 명령문 에서 복잡한 표현식 의 일부 인지 여부는 분명하지 않습니다 .Ex:=E

Hoare 로직에서 어레이 액세스를 모델링하여 유효하지 않은 액세스가없는 경우 프로그램 정확성을 입증 할 수있는 방법은 무엇입니까?

답은 배열 요소가 이외 명령문에서 사용되는 것을 허용하지 않는다고 가정 할 수 있습니다A[i]:=E 또는 일부의 일부로 E 에서 x:=E 이 표현을 제한하지 않기 때문에; 우리는 항상 임시 변수에 원하는 값을 할당 할 수 있습니다. 즉, t:=A[i]; if(t>0) 대신 if(A[i]>0) .

답변:


8

당신의 공리는 실제로 공리가 아니며, 가설이 빠져 있습니다. Hoare 논리의 간단한 표현은 형식의 공식을 조작합니다. 여기서 PP ' 는 논리적 인 공식이고 C 는 명령입니다. C 가 올바른지 확인 해야합니다 . Hoare 논리에 대한 첫 번째 소개에 자주 사용되는 언어와 같은 간단한 언어에서 올바른 형식은 구문 적입니다. 일반적으로 C 를 확인하는 문제입니다.{P}C{P}PPCCC문맥이없는 문법을 준수하며 자유 변수가 허용 된 세트 내에있을 수 있습니다. 언어에 배열 요소에 대한 액세스와 같이 시맨틱 정확성이있는 구문이 포함 된 경우이 시맨틱 정확성을 표현하기 위해 가설을 추가해야합니다.

공식적으로 표현과 명령의 수정을 표현하기 위해 판단을 추가 할 수 있습니다. 표현식에 부작용이 없으면 사후 조건이 필요하지 않으며 전제 조건 만 필요합니다. 예를 들어 { P } 와 같은 올바른 규칙을 작성할 수 있습니다. 이며 명령에서 올바른 형식의 표현식 만 허용합니다. {P[xE]}

{P}E wf{P0E<length(A)}A[E] wf{P}E1 wf{P}E2 wf{P}E1+E2 wf
{P[xE]}E wf{P[xE]}x:=E{P}

errorerrorError¬Error

{P[xE]}x:=E{PError}P[xE]Eerror{P[xE]}x:=E{P}

또 다른 접근법은 프로그램이 올바르게 종료 된 경우에만 Hoare triple을 유지하는 것입니다. 이것은 종료되지 않는 프로그램에 대한 일반적인 접근 방식입니다. 명령이 종료 될 때 사후 조건이 유지되므로 항상 발생하지는 않습니다. 런타임 오류를 종료가 아닌 것으로 취급하면 모든 정확성 문제를 해결해야합니다. 여전히 프로그램의 정확성을 증명해야하지만, 해당 작업에 다른 형식을 선호하는 경우 Hoare 논리에있을 필요는 없습니다.

PIsSorted(A)A[i]EPA[i]PPA[A[0]1]:=A[0]A[0]=2A[1]=3A[0]=1A[1]=1A[0]A[0]AA[iE]


0

Gilles가 언급했듯이 배열 할당 공리가 있습니다 ( Gordon 's notes, Sec. 2.1.10 참조 ).

{Q[AA.store(i,expr)]}A[i]=expr{Q}
A.store(i,expr)iexprA.store(i,vi)A[j]=vjA.store(j,vj).store(i,vi)

A.store(i,v)[i]vi

나는 배열을 가진 프로그램이 정확하다는 것을 증명하기 위해 ( "아웃 바운드 액세스 없음") 위의 공리로 충분하다고 생각한다. 프로그램을 고려하자 :

...
A[i] = 12
...

이 프로그램에 주석을 달 것입니다.

...
@ {0<i<A_length}
A[i] = 12
...

여기서 A_length배열 길이를 지정하는 변수입니다. 이제 주석을 증명하십시오. 즉, Hoare 증명에서 "일반적으로"아래쪽에서 위쪽으로 주석 처리하십시오. 상단에 도달 {false}하면 범위를 벗어난 액세스가 발생할 수 있습니다. 그렇지 않으면 가져온 식은 범위를 벗어난 액세스가 불가능한 전제 조건입니다. (또한 우리 int A=int[10];는 사후 조건에서 와 같이 배열을 만들 때 우리가 가지고 있는지 확인해야합니다 {A_length==10}).


공리는 범위를 벗어난 액세스를 모델링하지 않습니다. 길이를 언급하지도 않습니다! 당신의 예제 프로그램에서, 당신은 어떻게 관련 length되어 A있습니까?
Gilles 'SO- 악마 그만해

공리는 바운드 액세스를 모델링하지 않습니다. 먼저 프로그램이 올바른지 증명하기 위해 액세스가 범위 내에 있어야하는 주석을 추가합니다. ( length이름이 바뀌 었습니다 A_length.) 둘째, 우리는 같은 배열 "창조"공리가 필요합니다 int[] a = int[length] {a_length==length}. 이것으로 충분하다고 생각합니다.
Ayrat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.