Как обращаться с массивами во время корректных проверок в стиле Хоара


11

В дискуссии вокруг этого вопроса Жиль правильно упоминает, что любое доказательство правильности алгоритма, использующего массивы, должно доказывать, что нет доступа к массиву вне пределов; в зависимости от модели времени выполнения это может вызвать ошибку времени выполнения или доступ к элементам, не являющимся массивами.

Один общий метод для выполнения таких доказательств корректности (по крайней мере в старшекурснике исследований и , возможно , в автоматизированной верификации) заключается в использовании Хоаром логики . Я не знаю , что стандартный набор правил containes ничего , относящееся к массивам; кажется, что они ограничены монадическими переменными.

Я могу представить себе добавление аксиом вида

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

Тем не менее, мне не понятно , как бы вы иметь дело с доступом массива на правой стороне, то есть если она является частью сложного выражения в некотором заявлении х : = Е .Ex:=E

Как можно получить доступ к массивам в логике Хоара, чтобы можно было и нужно доказать правильность программы отсутствие недопустимых доступов?

Ответы можно считать , что мы запретить элементы массива , которые будут использоваться в других , чем заявлениях или как часть некоторых Е в й : = Е , так как это не ограничивает выразительность; всегда можно присвоить временной переменной нужное значение, т.е. запись т : = [ я ] ; я е ( т > 0 ) ... а я е ( [ я ] > 0 ) ...A[i]:=EEx:=Et:=A[i]; if(t>0)if(A[i]>0),

Ответы:


8

Ваша аксиома на самом деле не аксиома, в ней отсутствуют гипотезы. Простые представления логики Хоара управляют формулами вида где P и P - логические формулы, а C - команда. Вы должны убедиться, что C правильно сформирован . В простых языках, таких как те, которые часто используются для первого введения в логику Хоара, правильная форма синтаксиса: обычно это вопрос проверки того, что C{P}C{P}PPCCCсоответствует грамматике без контекста и, возможно, что свободные переменные находятся в пределах допустимого набора. Если язык включает конструкции, которые имеют семантическую корректность, такую ​​как доступ к элементам массива, вам необходимо добавить гипотезы для выражения этой семантической корректности.

Формально вы можете добавить суждения, чтобы выразить исправление выражений и команд. Если выражения не имеют побочных эффектов, им не нужны постусловия, только предусловия. Например, вы можете написать правила правильной формы, такие как

{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}

Другой подход заключается в лечении всех выражений , как хорошо сформирован, но чтобы сделать любое выражение , включающее в плохо сформированную расчет имеет особое значение . В языках с во время выполнения проверки границ, е т р о ¨R означает «эта программа подняла неустранимое исключение». Затем вы должны следить за ли ошибочную программу через предикат E т р о г ; программа действует только , если вы можете доказать , что его Постусловие означает ¬ Е г р о г . errorerrorError¬Error

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

Еще один подход заключается в рассмотрении Хора тройная держать только если программа завершается корректно. Это обычный подход для программ без прерывания: постусловие выполняется, когда команда завершается, что не всегда может происходить. Если вы рассматриваете ошибки во время выполнения как не завершающиеся, вы скрываете все проблемы с корректностью. Вы все еще должны доказать правильность программы каким-то образом, но это не должно быть в логике Хоара, если вы предпочитаете какой-то другой формализм для выполнения этой задачи.

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

Как упоминал Жиль, существует аксиома присвоения массивов (см . Примечания Гордона, раздел 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переменная, которая определяет длину массива. Теперь попробуйте доказать аннотацию, а именно отработать ее задом наперед (снизу вверх, «как обычно» в доказательствах Хоара). Если вы получаете {false}доступ сверху , то может произойти доступ из-за границы, в противном случае полученное вами выражение является предварительным условием, при котором невозможен доступ из-за границы. (Кроме того, нам нужно убедиться, что когда массив создается как int A=int[10];тогда в пост-условии, которое мы имеем {A_length==10}).


Ваши аксиомы не моделируют заграничный доступ: они даже не упоминают длину! В вашей программе-примере, как вы lengthотноситесь к A?
Жиль "ТАК - перестань быть злым"

Правильно, аксиомы не моделируются из ограниченного доступа. Во-первых, чтобы доказать правильность программы, я добавляю аннотации, которые требуют, чтобы доступ был в пределах границ. ( lengthбыл переименован A_length.) Во-вторых, нам нужны аксиомы «создания» массива, такие как int[] a = int[length] {a_length==length}. Я думаю, этого должно быть достаточно.
Айрат
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.