Skip to content

Commit 4c2257f

Browse files
authored
Merge pull request #772 from formal-land/guillaume-claret@add-simulate-get_or_zero-example
Simulate: add get_or_zero example
2 parents 3aa65e3 + f6c7035 commit 4c2257f

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

CoqOfRust/core/links/array.v

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,18 @@ Module ArrayPairs.
2626
| S length, {| ArrayPair.x := x; ArrayPair.xs := xs |} => φ x :: to_values xs
2727
end.
2828

29+
Fixpoint to_tuple_rev_Set (A : Set) (length : nat) : Set :=
30+
match length with
31+
| O => unit
32+
| S length => to_tuple_rev_Set A length * A
33+
end.
34+
35+
Fixpoint to_tuple_rev {A : Set} {length : nat} (xs : t A length) : to_tuple_rev_Set A length :=
36+
match length, xs with
37+
| O, ArrayEmpty.Make => tt
38+
| S length, {| ArrayPair.x := x; ArrayPair.xs := xs |} => (to_tuple_rev xs, x)
39+
end.
40+
2941
Fixpoint of_list {A : Set} (xs : list A) : t A (List.length xs) :=
3042
match xs with
3143
| [] => ArrayEmpty.Make

CoqOfRust/examples/default/examples/custom/simulate/loops_free.v

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Require Import CoqOfRust.CoqOfRust.
22
Require Import CoqOfRust.links.M.
33
Require Import CoqOfRust.simulate.M.
4+
Require Import core.links.array.
45
Require Import examples.default.examples.custom.links.loops_free.
56

67
Definition max2 (a b : U32.t) : U32.t :=
@@ -61,3 +62,72 @@ Proof.
6162
{ apply Run.Pure. }
6263
Qed.
6364
Global Opaque run_max2.
65+
66+
Definition get_or_zero (xs : array.t U32.t {| Integer.value := 4 |}) (i : Usize.t) : U32.t :=
67+
let i := i.(Integer.value) in
68+
let xs := ArrayPairs.to_tuple_rev xs.(array.value) in
69+
match xs with
70+
| (tt, x3, x2, x1, x0) =>
71+
if i =? 0 then
72+
x0
73+
else if i =? 1 then
74+
x1
75+
else if i =? 2 then
76+
x2
77+
else if i =? 3 then
78+
x3
79+
else
80+
{| Integer.value := 0 |}
81+
end.
82+
83+
Lemma get_or_zero_eq
84+
(xs : array.t U32.t {| Integer.value := 4 |}) (i : Usize.t)
85+
(H_i : 0 <= i.(Integer.value)) :
86+
let ref_xs := make_ref 0 in
87+
let stack := (xs, tt) in
88+
{{
89+
SimulateM.eval_f (Stack := [_]) (run_get_or_zero ref_xs i) stack 🌲
90+
(Output.Success (get_or_zero xs i), stack)
91+
}}.
92+
Proof.
93+
destruct xs as [[x0 [x1 [x2 [x3 []]]]]].
94+
destruct i as [i]; cbn in H_i.
95+
unfold get_or_zero; cbn.
96+
eapply Run.Call; cbn. {
97+
apply Run.Pure.
98+
}
99+
cbn.
100+
eapply Run.Call; cbn. {
101+
apply Run.Pure.
102+
}
103+
cbn.
104+
destruct (_ <? 4) eqn:?; cbn.
105+
{ progress repeat get_can_access.
106+
unfold ArrayPairs.to_tuple_rev, Pos.to_nat; cbn.
107+
destruct (i =? 0) eqn:?. {
108+
replace i with 0 by lia; cbn.
109+
apply Run.Pure.
110+
}
111+
destruct (i =? 1) eqn:?. {
112+
replace i with 1 by lia; cbn.
113+
apply Run.Pure.
114+
}
115+
destruct (i =? 2) eqn:?. {
116+
replace i with 2 by lia; cbn.
117+
apply Run.Pure.
118+
}
119+
destruct (i =? 3) eqn:?. {
120+
replace i with 3 by lia; cbn.
121+
apply Run.Pure.
122+
}
123+
lia.
124+
}
125+
{ unfold ArrayPairs.to_tuple_rev, Pos.to_nat; cbn.
126+
destruct (i =? 0) eqn:?; [lia|].
127+
destruct (i =? 1) eqn:?; [lia|].
128+
destruct (i =? 2) eqn:?; [lia|].
129+
destruct (i =? 3) eqn:?; [lia|].
130+
apply Run.Pure.
131+
}
132+
Qed.
133+
Global Opaque run_get_or_zero.

0 commit comments

Comments
 (0)