[英]Optimal placement of assert statements to assure correctness using invariant
我試圖通過用 Python 編寫的真實示例來理解編程中的不變量。 我很困惑在哪里放置assert
語句來檢查不變量。
我的研究顯示了在何處檢查不變量的不同模式。 舉些例子:
before the loop starts
before each iteration of the loop
after the loop terminates
對比
... // the Loop Invariant must be true here
while ( TEST CONDITION ) {
// top of the loop
...
// bottom of the loop
// the Loop Invariant must be true here
}
// Termination + Loop Invariant = Goal
下面我為數學書中的一個不變的例子放了代碼。 有兩個版本,一個使用 function,一個不使用。 我希望這沒有什么區別,但我想徹底。
我的問題是:
理想情況下,我希望看到我的代碼被重寫,以包括最佳實踐和對我迄今為止在工作中可能忽略的任何問題的關注。
非常感謝任何輸入。
這是練習:
E2。 假設正 integer n 是奇數。 首先,Al 在黑板上寫下數字 1、2、...、2n。 然后他選擇任意兩個數字 a、b,將它們擦掉,然后寫成 |a − b|。 證明最后會保留一個奇數。
解決方案。 假設 S 是黑板上所有數字的總和。 最初,這個和是 S = 1+2+···+2n = n(2n+1),一個奇數。 每一步將 S 減少 2 min(a, b),這是一個偶數。 所以 S 的奇偶性是一個不變量。 在整個歸約過程中,我們有 S ≡ 1 mod 2。最初奇偶校驗是奇數。 所以,最后也會很奇怪。
import random
def invariant_example(n):
xs = [x for x in range(1, 2*n+1)]
print(xs)
assert sum(xs) % 2 == 1
while len(xs) >= 2:
assert sum(xs) % 2 == 1
a, b = random.sample(xs, 2)
print(f"a: {a}, b: {b}, xs: {xs}")
xs.remove(a)
xs.remove(b)
xs.append(abs(a - b))
assert sum(xs) % 2 == 1
assert sum(xs) % 2 == 1
return xs
print(invariant_example(5))
n = 5
xs = [x for x in range(1, 2*n+1)]
print(xs)
assert sum(xs) % 2 == 1
while len(xs) >= 2:
assert sum(xs) % 2 == 1
a, b = random.sample(xs, 2)
print(f"a: {a}, b: {b}, xs: {xs}")
xs.remove(a)
xs.remove(b)
xs.append(abs(a - b))
assert sum(xs) % 2 == 1
assert sum(xs) % 2 == 1
print(xs)
您擁有的唯一技術上冗余的assert
語句是循環中的任何一個。 如在,你並不真的需要他們兩個。
例如:
如果兩者都有,while 循環中的第一個assert
將在第二個斷言之后立即執行(因為代碼將返回到循環的頂部)。 這些調用之間沒有值更改,因此第一個assert
語句將始終與第二個語句具有相同的結果。
最佳實踐可能是將assert
保持在循環的頂部,以防止循環內的代碼在循環不變量被違反時執行。
編輯:正如凱利邦迪所指出的,最后的斷言語句還應該包括循環退出條件。 我忘了在上面提到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.