Dokazovanje pravilnosti
Naloga: pravilnost I
Pojasni, kaj o programu P
pove izjava
[ true ]
P
[ false ]
Rešitev
Program P
se ustavi, po koncu izvajanja pa velja false
. Tak program ne obstaja.
Naloga: pravilnost II
Dokaži delno pravilnost programa:
{ x > 2 }
y := x + 1
if x > y then
z := x*x - y*y
else
z := y*y - x*x
end
{ 1 ≤ z }
Rešitev
{ x > 2 }
y := x + 1
{ x > 2 ∧ y = x + 1 }
if x > y then
{ x > 2 ∧ y = x + 1 ∧ x > y }
z := x*x - y*y
{ z = x² - y² ∧ x > 2 ∧ y = x + 1 ∧ x > y } # A
else
{ x > 2 ∧ y = x + 1 ∧ x ≤ y }
z := y*y - x*x
{ z = y² - x² ∧ x > 2 ∧ y = x + 1 ∧ x ≤ y }
{ z = (x+1)² - x² ∧ x > 2 }
{ z = x² + 2x + 1 - x² ∧ x > 2 }
{ z = 2x + 1 ∧ x > 2 }
{ z > 5 ∧ x > 2 } # B
end
# velja: (A ⇒ 1 ≤ z) ∧ (B ⇒ 1 ≤ z), ker A ⇔ false
{ 1 ≤ z }
Naloga: pravilnost III
Dokaži delno pravilnost programa:
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z }
if x < y then
if x < z then
m := x
else
m := z
end
else
if y <= z then
m := y
else
m := z
end
end
{ 0 ≤ m ≤ x }
Rešitev
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z }
if x < y then
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x < y }
if x < z then
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x < y ∧ x < z }
m := x
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x < y ∧ x < z ∧ m = x }
{ 0 ≤ m ≤ x }
else
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x < y ∧ x ≥ z }
m := z
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ m ∧ x < y ∧ x ≥ m }
{ 0 ≤ m ≤ x }
end
{ 0 ≤ m ≤ x }
else
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x ≥ y }
if y <= z then
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x ≥ y ∧ y ≤ z }
m := y
{ 0 ≤ x ∧ 0 ≤ m ∧ 0 ≤ z ∧ x ≥ m ∧ m ≤ z }
{ 0 ≤ m ≤ x }
else
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x ≥ y ∧ y > z }
m := z
{ 0 ≤ x ∧ 0 ≤ y ∧ 0 ≤ z ∧ x ≥ y ∧ y > z ∧ m = z }
{ 0 ≤ m ≤ x }
end
{ 0 ≤ m ≤ x }
end
{ 0 ≤ m ≤ x }
Naloga: pravilnost IV
Dokažite delno pravilnost programa:
{ 0 < a ∧ 0 < b }
k := 0
while not (a * k = b) do
k := k + 1
done
{ b = a * k }
Ali velja tudi popolna pravilnost? (Se pravi, da { ⋯ }
nadomestimo z [ ⋯ ]
.) Odgovor
utemeljite.
Rešitev
Negacija zančnega pogoja je enaka končnemu pogoju: če se zanka izteče, mora veljati končni pogoj.
{ 0 < a ∧ 0 < b }
k := 0
while not (a * k = b) do
k := k + 1
done
{ a * k = b }
Popolna pravilnost ne velja; program se zacikla, če a
ne deli b
.
Naloga: pravilnost V
Dokažite popolno pravilnost programa:
[ 0 < a ∧ 0 < b ]
k := 0
while a * k < b do
k := k + 1
done
[ a * (k - 1) < b ≤ a * k ]
Rešitev
Najprej pokažemo delno pravilnost:
{ 0 < a ∧ 0 < b }
k := 0
{ 0 < a ∧ 0 < b ∧ k = 0 }
{ a * (k - 1) < b } # zančna invarianta
while a * k < b do
{ a * (k - 1) < b ∧ a * k < b }
{ a * (k + 1 - 2) < b ∧ a * (k + 1 - 1) < b }
k := k + 1
{ a * (k - 2) < b ∧ a * (k - 1) < b }
{ a * (k - 1) < b } # po tem, ko se izvede telo zanke, invarianta še zmeraj velja
done
{ a * (k - 1) < b ∧ ¬(a * k < b) }
{ a * (k - 1) < b ≤ a * k }
Za popolno pravilnost pokažemo, da se količina d = b - k*a
zmanjšuje (in je navzdol omejena z zančnim pogojem):
while a * k < b do
{ 0 < a ∧ d = b - k*a }
{ 0 < a ∧ d - a = b - (k+1)*a }
k := k + 1
{ 0 < a ∧ d - a = b - k*a } # d - a < d
done
Zadnja sprememba: sobota, 18. marec 2023, 15.26