Hoare tarzı doğruluk kanıtları sırasında dizilerle nasıl başa çıkılır?


11

Bu sorunun etrafındaki tartışmada Gilles, dizileri kullanan bir algoritmanın herhangi bir doğruluk kanıtının, sınır ötesi dizi erişiminin olmadığını kanıtlamak zorunda olduğunu; çalışma zamanı modeline bağlı olarak, bu bir çalışma zamanı hatasına veya dizi olmayan öğelere erişime neden olur.

Bu tür doğruluk kanıtlarını gerçekleştirmek için yaygın bir teknik (en azından lisans çalışmalarında ve muhtemelen otomatik doğrulamada) Hoare mantığını kullanmaktır . Standart kurallar dizisinin dizilerle ilgili herhangi bir şey içerdiğinin farkında değilim; monadik değişkenlerle sınırlı görünmektedirler.

Formun aksiyomlarını eklediğimizi hayal edebiliyorum

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

Ancak, sağ taraftaki dizi erişimiyle nasıl başa çıkacağınız net değil, yani bazı ifadelerde x : = E ifadesinde karmaşık bir ifadenin parçasıysa .Ex:=E

Dizilerin erişimi Hoare mantığında nasıl modellenebilir, böylece geçersiz erişimin olmaması programın doğruluğu için kanıtlanabilir ve kanıtlanabilir mi?

Yanıtlar, dizi öğelerinin dışındaki ifadelerde A[i]:=Eveya x : = E içindeki bazı parçası olarak kullanılmasına izin vermediğimizi varsayabilir; çünkü bu, ifadeyi kısıtlamaz; her zaman istenen değeri geçici bir değişkene atayabiliriz, yani şunu yazın : t : = A [ i ] ; i f ( t > 0 ) ... yerine i f ( A [ i ] > 0 ) ...Ex:=Et:=A[i]; if(t>0)if(A[i]>0).

Yanıtlar:


8

{P}C{P}PPCCCbağlamdan bağımsız bir gramer ile uyumludur ve muhtemelen serbest değişkenlerin izin verilen bir kümede olduğu anlamına gelir. Dil, dizi öğelerine erişim gibi semantik bir doğruluğa sahip yapılar içeriyorsa, bu semantik doğruluğu ifade etmek için hipotezler eklemeniz gerekir.

Resmi olarak, ifadelerin ve komutların düzeltilmesini ifade etmek için kararlar ekleyebilirsiniz. İfadelerin hiçbir yan etkisi yoksa, son koşullara değil, yalnızca ön koşullara ihtiyaç duyarlar. Örneğin, gibi iyi biçimlilik kuralları yazabilirsiniz

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

Yine başka bir yaklaşım, Hoare'nin ancak programın doğru bir şekilde sona erdirilmesi durumunda üç katına çıkarılmasıdır. Sona ermeyen programlar için olağan yaklaşım budur: son durum, komut her zaman gerçekleşmeyecek şekilde sona erdiğinde geçerlidir. Çalışma zamanı hatalarını sonlandırma yapmazsanız, başlık altındaki tüm doğruluk sorunlarını süpürürsünüz. Yine de programın doğruluğunu bir şekilde kanıtlamanız gerekecek, ancak bu görev için başka bir formalizm tercih ederseniz Hoare mantığında olması gerekmez.

Bu arada, bir dizi gibi bir bileşik değişkeni değiştirildiğinde ne olacağını ifade etmenin, yazdıklarınızla daha fazla ilgili olduğunu unutmayın. Varsayalım mesela, olduğu ikame içerir: değişiklik olmaz , henüz tahsis geçersiz kılabilir . Tahminlerin söz dizimini sadece atomlar hakkında konuşmakla kısıtlasanız bile, ön koşulu altında ödevini göz önünde bulundurun : doğru hedefşart elde etmek için basit ikame yapamaz , değerlendirmek için gerekenPIsSorted(A)A[i]EPA[i]PPA[A[0]1]:=A[0]A[0]=2A[1]=3A[0]=1A[1]=1A[0](önkoşul için tek bir olası değer belirtmeyebileceğinden genel olarak zor olabilir ). işlemini dizinin kendisinde gerçekleştirmeniz gerekir: . Mike Gordon'un ders notlarında dizilerle iyi bir sunum Hoare mantığı var (ancak hata kontrolü olmadan).A[0]AA[iE]


0

Gilles'in belirttiği gibi, bir dizi ataması aksiyomu vardır (bkz. Gordon'un notları, Bölüm 2.1.10 ): Kelimelerde, bir dizi atamanız varsa, orijinal diziyi , değeri konumdaki diziye göre değiştirin . Eğer gönderi üzerinde zaten varsa ve atama , o zaman ön olarak almak gerektiğini unutmayın (evet, bu sırayla - son güncelleme ilk yürütülür!).

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

Ayrıca, dizi erişim aksiyomuna gerekir: A.store(i,v)[i]ile değiştirilebilir v( "eriştiğiniz takdirde sadece güncellenen bu inci elemanı, daha sonra atanan değer döndürmek").i

Bence dizilerle bir programın doğru olduğunu kanıtlamak için ("sınırsız erişim yok"), yukarıdaki aksiyomlar yeterlidir. Programı düşünelim:

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

Bu programa açıklama ekleriz:

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

Burada A_lengthdizi uzunluğunu belirten bir değişkendir. Şimdi ek açıklamayı kanıtlamaya çalışın - yani, geriye doğru çalışın (aşağıdan yukarı, Hoare kanıtlarında "genellikle" gibi). Üstte alırsanız {false}, o zaman sınırsız erişim gerçekleşebilir, aksi takdirde, aldığınız ifade, altında sınırsız erişimin mümkün olmadığı ön koşuldur. (ayrıca, dizi oluşturulduktan int A=int[10];sonra sahip olduğumuz post-koşulda olduğundan emin olmamız gerekir {A_length==10}).


Aksiyomlarınız sınır dışı erişimi modellemez: uzunluktan bile bahsetmezler! Örnek programınızda nasıl bir ilişkiniz lengthvar A?
Gilles 'SO- kötü olmayı bırak

Doğru, aksiyomlar bağlı erişimlerin dışında bir model oluşturmaz. İlk olarak, bir programın doğru olduğunu kanıtlamak için bir erişimin sınırlar içinde olmasını gerektiren ek açıklamalar ekliyorum. ( lengthyeniden adlandırıldı A_length.) İkincisi, dizi "oluşturma" gibi aksiyomlara ihtiyacımız var int[] a = int[length] {a_length==length}. Bence bu yeterli olmalı.
Ayrat
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.