Як поводитися з масивами під час доказів правильності стилю Хоара


11

У дискусії навколо цього питання Жилл правильно зазначає, що будь-яке підтвердження коректності алгоритму, який використовує масиви, повинен довести, що немає доступу до масиву поза межами; Залежно від моделі часу виконання, це призведе до помилки виконання або доступу до елементів, що не мають масиву.

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

Я можу собі додати аксіоми форми

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

Тим НЕ менше, мені не зрозуміло , як би ви мати справу з доступом масиву на правій стороні, тобто якщо вона є частиною складного виразу E в деякому заяві x:=E .

Як можна моделювати доступ до масивів у логіці Хоара, щоб відсутність недійсних доходів могла і повинна бути доведена для коректності програми?

Відповіді можуть припускати, що ми забороняємо елементи масиву використовувати в операторах, відмінних від A[i]:=E або як частина деяких E в x:=E оскільки це не обмежує виразність; ми завжди можемо призначити тимчасовій змінній потрібне значення, тобто записати t:=A[i]; if(t>0) замість if(A[i]>0).

Відповіді:


8

Ваша аксіома насправді не є аксіомою, у ній відсутні гіпотези. Прості презентації логіки Хоара маніпулюють формулами форми де P і P ' - логічні формули, а C - команда. Вам потрібно переконатися, що C добре сформований . У простих мовах, таких як, які часто використовуються для першого вступу до логіки Хоара, добре сформована синтаксичність: зазвичай це питання перевірити, що C{P}C{P}PPCCCвідповідає без контекстній граматиці і, можливо, вільні змінні знаходяться в межах дозволеного набору. Якщо мова включає конструкції, які мають семантичну правильність, наприклад, доступ до елементів масиву, вам потрібно додати гіпотези, щоб висловити цю смислову правильність.

Формально ви можете додавати судження, щоб висловити виправлення виразів і команд. Якщо вирази не мають побічних ефектів, вони не потребують жодних пост-умов, а лише передумов. Наприклад, ви можете написати добре сформовані правила, такі як і дозволяють лише добре сформовані вирази в командах: {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}

Ще один підхід полягає в тому, щоб вважати трійку Хоара дотриманою, лише якщо програма закінчується правильно. Це звичайний підхід для нетермінових програм: післязастереження виконується, коли команда припиняється, що може не завжди траплятися. Якщо ви ставитесь до помилок під час запуску як до припинення, ви змітаєте всі проблеми з правильністю під кришкою. Вам все одно доведеться якось доводити правильність програми, але це не повинно бути в логіці Хоара, якщо ви віддаєте перевагу якомусь іншому формалізму для цього завдання.

До речі, зауважте, що вираження того, що відбувається при зміні складної змінної, наприклад масиву, більше пов'язане з тим, що ви написали. Нехай було, скажімо, : заміна не зміниться , але привласнення може привести до анулювання . Навіть якщо ви обмежуєте синтаксис предикатів говорити лише про атоми, розгляньте призначення під умовою : ви не можете зробити просту заміну, щоб отримати правильну пост-умову , вам потрібно оцінитиI s S o r t e d ( A ) A [ i ] E P A [ 1 ] = 1 A [ 0 ] A [ 0 ] A A [ i E ]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]може бути замінена на v("якщо ви отримаєте доступ до го елемента, який ви тільки що оновили, поверніть присвоєне значення").i

Я думаю, що для того, щоб довести, що програма з масивами є правильною ("немає позамежних доступу"), наведених вище аксіом достатньо. Розглянемо програму:

...
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.