Skip to content

Commit 0c699f3

Browse files
committed
saw-core-coq: Explicitly define atWithProof, genWithProof, and friends
This provides explicit Coq definitions for SAWCore's `atWithProof` and `genWithProof` functions, which allow them to compute. It also proves the auxiliary `at_gen_BVVec` and `gen_at_BVVec` lemmas, a feat which is now possible thanks to the aforementioned computability. To make this work with the current module ordering, I needed to wire in the definition of `IsLtNat` into `SAWCoreScaffolding`, which proves straightforward. Fixes #1784.
1 parent 17eb56e commit 0c699f3

File tree

5 files changed

+147
-1
lines changed

5 files changed

+147
-1
lines changed

heapster-saw/examples/mbox_proofs.v

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ From CryptolToCoq Require Import SAWCoreScaffolding.
66
From CryptolToCoq Require Import SAWCoreVectorsAsCoqVectors.
77
From CryptolToCoq Require Import SAWCoreBitvectors.
88
From CryptolToCoq Require Import SAWCorePrelude.
9+
From CryptolToCoq Require Import SAWCorePreludeExtra.
910
From CryptolToCoq Require Import SpecMExtra.
1011
From EnTree Require Import Automation.
1112
Import SAWCorePrelude.

saw-core-coq/coq/handwritten/CryptolToCoq/SAWCorePreludeExtra.v

+59
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
From Coq Require Import Arith.Peano_dec.
2+
From Coq Require Import Arith.PeanoNat.
13
From Coq Require Import Lists.List.
4+
From Coq Require Import Logic.Eqdep_dec.
25
From Coq Require Import Logic.FunctionalExtensionality.
36
Import ListNotations.
47
From Coq Require Import String.
58
From Coq Require Import Vectors.Vector.
9+
From CryptolToCoq Require Import SAWCoreBitvectors.
610
From CryptolToCoq Require Import SAWCoreScaffolding.
711
From CryptolToCoq Require Import SAWCorePrelude.
12+
From CryptolToCoq Require Import SAWCoreVectorsAsCoqVectors.
813
Import SAWCorePrelude.
914

1015
Fixpoint Nat_cases2_match a f1 f2 f3 (x y : nat) : a :=
@@ -68,6 +73,60 @@ Proof.
6873
intro n. reflexivity.
6974
Qed.
7075

76+
Lemma bvToNat_bvNat (w n : nat) :
77+
n < 2^w -> bvToNat w (bvNat w n) = n.
78+
Admitted.
79+
80+
Lemma bvToNat_bounds (w : nat) (x : bitvector w) :
81+
bvToNat w x < 2^w.
82+
Proof.
83+
holds_for_bits_up_to_3; try repeat constructor.
84+
Qed.
85+
86+
Theorem at_gen_BVVec :
87+
forall (n : nat) (len : bitvector n) (a : Type)
88+
(f : forall i : bitvector n, is_bvult n i len -> a)
89+
(ix : bitvector n) (pf : is_bvult n ix len),
90+
atBVVec n len a (genBVVec n len a f) ix pf = f ix pf.
91+
Proof.
92+
intros n len a f ix pf.
93+
unfold atBVVec, genBVVec.
94+
rewrite at_gen_Vec.
95+
generalize (IsLtNat_to_bvult n len (bvToNat n ix)
96+
(bvult_to_IsLtNat n len (bvToNat n ix)
97+
(trans bool (bvult n (bvNat n (bvToNat n ix)) len) (bvult n ix len) 1%bool
98+
(eq_cong (bitvector n) (bvNat n (bvToNat n ix)) ix (bvNat_bvToNat n ix) bool
99+
(fun y : bitvector n => bvult n y len)) pf))) as pf2.
100+
rewrite (bvNat_bvToNat n ix).
101+
intros pf2.
102+
rewrite (UIP_dec Bool.bool_dec pf2 pf).
103+
reflexivity.
104+
Qed.
105+
106+
Lemma gen_at_BVVec :
107+
forall (n : nat) (len : bitvector n) (a : Type) (x : BVVec n len a),
108+
genBVVec n len a (atBVVec n len a x) = x.
109+
Proof.
110+
intros n len a x.
111+
unfold genBVVec, atBVVec.
112+
rewrite <- (gen_at_Vec _ _ x) at 1.
113+
f_equal. extensionality i. extensionality pf.
114+
generalize (bvult_to_IsLtNat n len (bvToNat n (bvNat n i))
115+
(trans bool (bvult n (bvNat n (bvToNat n (bvNat n i))) len) (bvult n (bvNat n i) len) 1%bool
116+
(eq_cong (bitvector n) (bvNat n (bvToNat n (bvNat n i))) (bvNat n i)
117+
(bvNat_bvToNat n (bvNat n i)) bool (fun y : bitvector n => bvult n y len))
118+
(IsLtNat_to_bvult n len i pf))) as pf2.
119+
assert (X : bvToNat n (bvNat n i) = i).
120+
{ apply bvToNat_bvNat.
121+
transitivity (bvToNat n len).
122+
- exact pf.
123+
- apply bvToNat_bounds.
124+
}
125+
rewrite X. intros pf2.
126+
rewrite (le_unique _ _ pf2 pf).
127+
reflexivity.
128+
Qed.
129+
71130

72131
Theorem fold_unfold_IRT As Ds D : forall x, foldIRT As Ds D (unfoldIRT As Ds D x) = x.
73132
Proof.

saw-core-coq/coq/handwritten/CryptolToCoq/SAWCoreScaffolding.v

+5
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ Definition IsLeNat__rec
224224
| le_S _ m H => Hstep m H (rec m H)
225225
end.
226226

227+
(* We could have SAW autogenerate this definition in SAWCorePrelude, but it is
228+
convenient to place it here so that it can be used in
229+
SAWCoreVectorsAsCoqVectors.v, which cannot import SAWCorePrelude. *)
230+
Definition IsLtNat := @lt.
231+
227232
(* Definition minNat := Nat.min. *)
228233

229234
Definition uncurry (a b c : Type) (f : a -> b -> c) (p : a * (b * unit)) : c :=

saw-core-coq/coq/handwritten/CryptolToCoq/SAWCoreVectorsAsCoqVectors.v

+76
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
From Bits Require Import operations.
22
From Bits Require Import spec.
33

4+
From Coq Require Import FunctionalExtensionality.
45
From Coq Require Import Lists.List.
56
From Coq Require Numbers.NatInt.NZLog.
7+
From Coq Require Import Peano_dec.
68
From Coq Require Import PeanoNat.
79
From Coq Require Import Strings.String.
810
From Coq Require Import Vectors.Vector.
@@ -36,6 +38,27 @@ Constraint Vec.u1 <= mkrel.u0.
3638
Constraint Vec.u1 <= mkapp.u0.
3739
Constraint Vec.u1 <= mkapp.u1.
3840

41+
Lemma Vec_0_nil :
42+
forall (a : Type) (v : Vec 0 a),
43+
v = [].
44+
Proof.
45+
intros a v.
46+
apply (case0 (fun v' => v' = [])).
47+
reflexivity.
48+
Qed.
49+
50+
Lemma Vec_S_cons :
51+
forall (n : nat) (a : Type) (v : Vec (S n) a),
52+
exists (x : a) (xs : Vec n a),
53+
v = x::xs.
54+
Proof.
55+
intros n a v.
56+
apply (caseS (fun n' v' => exists (x : a) (xs : Vec n' a), v' = x::xs)).
57+
intros x m xs.
58+
exists x. exists xs.
59+
reflexivity.
60+
Qed.
61+
3962
Fixpoint gen (n : nat) (a : Type) (f : nat -> a) {struct n} : Vec n a.
4063
refine (
4164
match n with
@@ -115,6 +138,15 @@ Fixpoint atWithDefault (n : nat) (a : Type) (default : a) (v : Vec n a) (index :
115138
).
116139
Defined.
117140

141+
Fixpoint atWithProof (n : nat) (a : Type) (v : Vec n a) (i : nat) :
142+
IsLtNat i n -> a :=
143+
match i as i', n as n' return Vec n' a -> IsLtNat i' n' -> a with
144+
| _, O => fun _ prf =>
145+
match Nat.nlt_0_r _ prf with end
146+
| O, S y => fun v' prf => Vector.hd v'
147+
| S x, S y => fun v' prf => atWithProof y a (Vector.tl v') x (le_S_n _ _ prf)
148+
end v.
149+
118150
Definition map (a b : Type) (f : a -> b) (n : nat) (xs : Vec n a) :=
119151
VectorDef.map f xs.
120152

@@ -175,6 +207,15 @@ Proof.
175207
}
176208
Qed.
177209

210+
Fixpoint genWithProof (n : nat) (a : Type) :
211+
(forall (i : nat), IsLtNat i n -> a) -> Vec n a :=
212+
match n as n' return (forall (i : nat), IsLtNat i n' -> a) -> Vec n' a with
213+
| O => fun _ => Vector.nil a
214+
| S m => fun f => Vector.cons a (f 0 (le_n_S _ _ (le_0_n _)))
215+
m (genWithProof m a
216+
(fun i prf => f (S i) (le_n_S _ _ prf)))
217+
end.
218+
178219
(* NOTE: This version of `zip` accepts two vectors of different size, unlike the
179220
* one in `CoqVectorsExtra.v` *)
180221
Fixpoint zipFunctional (a b : sort 0) (m n : nat) (xs : Vec m a) (ys : Vec n b)
@@ -199,6 +240,41 @@ Definition zipWithFunctional
199240
(a b c : Type) (f : a -> b -> c) (n : nat) (xs : Vec n a) (ys : Vec n b) :=
200241
VectorDef.map (fun p => f (fst p) (snd p)) (zipFunctional _ _ _ _ xs ys).
201242

243+
Lemma at_gen_Vec :
244+
forall (n : nat) (a : Type)
245+
(f : forall i : nat, IsLtNat i n -> a)
246+
(ix : nat) (pf : IsLtNat ix n),
247+
atWithProof n a (genWithProof n a f) ix pf = f ix pf.
248+
Proof.
249+
intros n a f.
250+
induction n; intros ix pf.
251+
- destruct (Nat.nlt_0_r ix pf).
252+
- induction ix.
253+
+ simpl.
254+
rewrite (le_unique _ _ (le_n_S 0 n (le_0_n n)) pf).
255+
reflexivity.
256+
+ simpl.
257+
rewrite IHn.
258+
rewrite (le_unique _ _ (le_n_S (Succ ix) n (le_S_n (S ix) n pf)) pf).
259+
reflexivity.
260+
Qed.
261+
262+
Lemma gen_at_Vec :
263+
forall (n : nat) (a : Type) (x : Vec n a),
264+
genWithProof n a (atWithProof n a x) = x.
265+
Proof.
266+
intros n a x.
267+
induction n.
268+
- rewrite (Vec_0_nil a x). reflexivity.
269+
- destruct (Vec_S_cons n a x) as [y [ys Yeq]].
270+
subst x. simpl.
271+
rewrite <- (IHn ys) at 1.
272+
do 2 f_equal.
273+
extensionality i. extensionality prf.
274+
rewrite (le_unique _ _ (le_S_n (S i) n (le_n_S (Succ i) n prf)) prf).
275+
reflexivity.
276+
Qed.
277+
202278
Notation bitvector n := (Vec n bool).
203279

204280
(* NOTE BITS are stored in reverse order than bitvector *)

saw-core-coq/src/Verifier/SAW/Translation/Coq/SpecialTreatment.hs

+6-1
Original file line numberDiff line numberDiff line change
@@ -337,12 +337,13 @@ sawCorePreludeSpecialTreatmentMap configuration =
337337
, ("Refl", mapsToExpl logicModule "eq_refl")
338338
]
339339

340-
-- Nat le
340+
-- Nat le/lt
341341
++
342342
[ ("IsLeNat" , mapsTo sawDefinitionsModule "IsLeNat")
343343
, ("IsLeNat__rec", mapsTo sawDefinitionsModule "IsLeNat__rec")
344344
, ("IsLeNat_base", mapsTo sawDefinitionsModule "IsLeNat_base")
345345
, ("IsLeNat_succ", mapsTo sawDefinitionsModule "IsLeNat_succ")
346+
, ("IsLtNat" , mapsTo sawDefinitionsModule "IsLtNat")
346347
]
347348

348349
-- Strings
@@ -370,7 +371,9 @@ sawCorePreludeSpecialTreatmentMap configuration =
370371
++
371372
[ ("EmptyVec", mapsTo vectorsModule "EmptyVec")
372373
, ("at", rename "sawAt") -- `at` is a reserved keyword in Coq
374+
, ("at_gen_BVVec", mapsTo preludeExtraModule "at_gen_BVVec")
373375
, ("atWithDefault", mapsTo vectorsModule "atWithDefault")
376+
, ("atWithProof", mapsTo vectorsModule "atWithProof")
374377
, ("at_single", skip) -- is boring, could be proved on the Coq side
375378
, ("bvAdd", mapsTo vectorsModule "bvAdd")
376379
, ("bvLg2", mapsTo vectorsModule "bvLg2")
@@ -394,6 +397,8 @@ sawCorePreludeSpecialTreatmentMap configuration =
394397
, ("eq_Vec", skip)
395398
, ("foldr", mapsTo vectorsModule "foldr")
396399
, ("foldl", mapsTo vectorsModule "foldl")
400+
, ("gen_at_BVVec", mapsTo preludeExtraModule "gen_at_BVVec")
401+
, ("genWithProof", mapsTo vectorsModule "genWithProof")
397402
, ("scanl", mapsTo vectorsModule "scanl")
398403
, ("gen", mapsTo vectorsModule "gen")
399404
, ("rotateL", mapsTo vectorsModule "rotateL")

0 commit comments

Comments
 (0)