55 lines
1.4 KiB
Text
55 lines
1.4 KiB
Text
def f91 (n : Nat) : Option Nat :=
|
||
if n > 100
|
||
then pure (n - 10)
|
||
else f91 (n + 11) >>= f91
|
||
partial_fixpoint
|
||
|
||
section partial_correctness
|
||
|
||
-- #check f91.partial_correctness
|
||
|
||
theorem f91_partial_spec (n r : Nat) :
|
||
f91 n = some r → r = if n > 100 then n - 10 else 91 := by
|
||
apply f91.partial_correctness
|
||
intro f91 ih n r h
|
||
split at *
|
||
· simp_all
|
||
· simp only [Option.bind_eq_bind, Option.bind_eq_some] at h
|
||
obtain ⟨r', hr1, hr2⟩ := h
|
||
replace hr1 := ih _ _ hr1
|
||
replace hr2 := ih _ _ hr2
|
||
clear ih
|
||
subst hr1
|
||
subst hr2
|
||
split
|
||
· simp; omega
|
||
· simp
|
||
|
||
end partial_correctness
|
||
|
||
section total_correctness
|
||
|
||
theorem f91_spec_high (n : Nat) (h : 100 < n) : f91 n = some (n - 10) := by
|
||
unfold f91; simp [*]
|
||
|
||
theorem f91_spec_low (n : Nat) (h₂ : n ≤ 100) : f91 n = some 91 := by
|
||
unfold f91
|
||
have : ¬ (100 < n) := by simp [*]
|
||
simp [*]
|
||
by_cases n < 90
|
||
· rw [f91_spec_low (n + 11) (by omega)]
|
||
simp only [Option.some_bind]
|
||
rw [f91_spec_low 91 (by omega)]
|
||
· rw [f91_spec_high (n + 11) (by omega)]
|
||
simp only [Nat.reduceSubDiff, Option.some_bind]
|
||
by_cases h : n = 100
|
||
· simp [*, f91]
|
||
· exact f91_spec_low (n + 1) (by omega)
|
||
|
||
theorem f91_spec (n : Nat) :
|
||
f91 n = some (if n ≤ 100 then 91 else n - 10) := by
|
||
by_cases h100 : n ≤ 100
|
||
· simp [f91_spec_low, *]
|
||
· simp [f91_spec_high, Nat.lt_of_not_le ‹_›, *]
|
||
|
||
end total_correctness
|