-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
import Std.Tactic.Do
def change_between (xs : Array Nat) (i s : Nat) : Array Nat := Id.run do
let mut xs := xs
for k in List.range' i s do
xs := xs.modify k (· * 3)
return xs
def equiv_change_between (xs : Array Nat) (i s : Nat) : Array Nat :=
Array.ofFn fun (k : Fin xs.size) =>
if ↑k ∈ List.range' i s then
xs[k] * 3
else
xs[k]
#eval equiv_change_between #[1, 2, 3, 4, 5, 6] 2 3
#eval change_between #[1, 2, 3, 4, 5, 6] 2 3
open Std.Do in
def change_between_spec (xs : Array Nat) (i s : Nat) :
change_between xs i s = equiv_change_between xs i s := by
simp [equiv_change_between]
generalize h : change_between xs i s = x
apply Id.of_wp_run_eq h
mvcgen invariants
· ⇓⟨c, xs'⟩ => ⌜xs.size = xs'.size ∧ xs' = (Array.ofFn fun (k : Fin xs.size) =>
if k < i + c.prefix.length ∧ ↑k ∈ List.range' i s then
xs[k] * 3
else
xs[k])⌝
all_goals expose_names
· constructor
· grind
· simp [h_2.2]
ext <;> simp [Array.getElem_modify]
grind
· simp
ext <;> simp
grind
· grind