Skip to content

Commit d6e9138

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. Fixes #1784.
1 parent fef1087 commit d6e9138

File tree

3 files changed

+148
-1
lines changed

3 files changed

+148
-1
lines changed

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

+117-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
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.
14+
Import VectorNotations.
915

1016
Fixpoint Nat_cases2_match a f1 f2 f3 (x y : nat) : a :=
1117
match (x, y) with
@@ -68,6 +74,116 @@ Proof.
6874
intro n. reflexivity.
6975
Qed.
7076

77+
Lemma Vec_0_nil :
78+
forall (a : Type) (v : Vec 0 a),
79+
v = [].
80+
Proof.
81+
intros a v.
82+
apply (case0 (fun v' => v' = [])).
83+
reflexivity.
84+
Qed.
85+
86+
Lemma Vec_S_cons :
87+
forall (n : nat) (a : Type) (v : Vec (S n) a),
88+
exists (x : a) (xs : Vec n a),
89+
v = x::xs.
90+
Proof.
91+
intros n a v.
92+
apply (caseS (fun n' v' => exists (x : a) (xs : Vec n' a), v' = x::xs)).
93+
intros x m xs.
94+
exists x. exists xs.
95+
reflexivity.
96+
Qed.
97+
98+
Lemma bvToNat_bvNat (w n : nat) :
99+
n < 2^w -> bvToNat w (bvNat w n) = n.
100+
Admitted.
101+
102+
Lemma bvToNat_bounds (w : nat) (x : bitvector w) :
103+
bvToNat w x < 2^w.
104+
Proof.
105+
holds_for_bits_up_to_3; try repeat constructor.
106+
Qed.
107+
108+
Lemma at_gen_Vec :
109+
forall (n : nat) (a : Type)
110+
(f : forall i : nat, IsLtNat i n -> a)
111+
(ix : nat) (pf : IsLtNat ix n),
112+
atWithProof n a (genWithProof n a f) ix pf = f ix pf.
113+
Proof.
114+
intros n a f.
115+
induction n; intros ix pf.
116+
- destruct (Nat.nlt_0_r ix pf).
117+
- induction ix.
118+
+ simpl.
119+
rewrite (le_unique _ _ (le_n_S 0 n (le_0_n n)) pf).
120+
reflexivity.
121+
+ simpl.
122+
rewrite IHn.
123+
rewrite (le_unique _ _ (le_n_S (Succ ix) n (le_S_n (S ix) n pf)) pf).
124+
reflexivity.
125+
Qed.
126+
127+
Lemma gen_at_Vec :
128+
forall (n : nat) (a : Type) (x : Vec n a),
129+
genWithProof n a (atWithProof n a x) = x.
130+
Proof.
131+
intros n a x.
132+
induction n.
133+
- rewrite (Vec_0_nil a x). reflexivity.
134+
- destruct (Vec_S_cons n a x) as [y [ys Yeq]].
135+
subst x. simpl.
136+
rewrite <- (IHn ys) at 1.
137+
do 2 f_equal.
138+
extensionality i. extensionality prf.
139+
rewrite (le_unique _ _ (le_S_n (S i) n (le_n_S (Succ i) n prf)) prf).
140+
reflexivity.
141+
Qed.
142+
143+
Theorem at_gen_BVVec :
144+
forall (n : nat) (len : bitvector n) (a : Type)
145+
(f : forall i : bitvector n, is_bvult n i len -> a)
146+
(ix : bitvector n) (pf : is_bvult n ix len),
147+
atBVVec n len a (genBVVec n len a f) ix pf = f ix pf.
148+
Proof.
149+
intros n len a f ix pf.
150+
unfold atBVVec, genBVVec.
151+
rewrite at_gen_Vec.
152+
generalize (IsLtNat_to_bvult n len (bvToNat n ix)
153+
(bvult_to_IsLtNat n len (bvToNat n ix)
154+
(trans bool (bvult n (bvNat n (bvToNat n ix)) len) (bvult n ix len) 1%bool
155+
(eq_cong (bitvector n) (bvNat n (bvToNat n ix)) ix (bvNat_bvToNat_id n ix) bool
156+
(fun y : bitvector n => bvult n y len)) pf))) as pf2.
157+
rewrite (bvNat_bvToNat n ix).
158+
intros pf2.
159+
rewrite (UIP_dec Bool.bool_dec pf2 pf).
160+
reflexivity.
161+
Qed.
162+
163+
Lemma gen_at_BVVec :
164+
forall (n : nat) (len : bitvector n) (a : Type) (x : BVVec n len a),
165+
genBVVec n len a (atBVVec n len a x) = x.
166+
Proof.
167+
intros n len a x.
168+
unfold genBVVec, atBVVec.
169+
rewrite <- (gen_at_Vec _ _ x) at 1.
170+
f_equal. extensionality i. extensionality pf.
171+
generalize (bvult_to_IsLtNat n len (bvToNat n (bvNat n i))
172+
(trans bool (bvult n (bvNat n (bvToNat n (bvNat n i))) len) (bvult n (bvNat n i) len) 1%bool
173+
(eq_cong (bitvector n) (bvNat n (bvToNat n (bvNat n i))) (bvNat n i)
174+
(bvNat_bvToNat_id n (bvNat n i)) bool (fun y : bitvector n => bvult n y len))
175+
(IsLtNat_to_bvult n len i pf))) as pf2.
176+
assert (X : bvToNat n (bvNat n i) = i).
177+
{ apply bvToNat_bvNat.
178+
transitivity (bvToNat n len).
179+
- exact pf.
180+
- apply bvToNat_bounds.
181+
}
182+
rewrite X. intros pf2.
183+
rewrite (le_unique _ _ pf2 pf).
184+
reflexivity.
185+
Qed.
186+
71187

72188
Theorem fold_unfold_IRT As Ds D : forall x, foldIRT As Ds D (unfoldIRT As Ds D x) = x.
73189
Proof.
@@ -91,4 +207,4 @@ Proof.
91207
and the fact that genBVVec and atBVVec define an isomorphism *)
92208
etransitivity; [ | apply gen_at_BVVec ].
93209
f_equal; repeat (apply functional_extensionality_dep; intro); eauto.
94-
Qed.
210+
Qed.

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

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ text = pretty
9797
preamble :: TranslationConfiguration -> Doc ann
9898
preamble (TranslationConfiguration { vectorModule, postPreamble }) = text [i|
9999
(** Mandatory imports from saw-core-coq *)
100+
From Coq Require Import Arith.PeanoNat.
100101
From Coq Require Import Lists.List.
101102
From Coq Require Import String.
102103
From Coq Require Import Vectors.Vector.

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

+30
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ sawCorePreludeSpecialTreatmentMap configuration =
370370
++
371371
[ ("EmptyVec", mapsTo vectorsModule "EmptyVec")
372372
, ("at", rename "sawAt") -- `at` is a reserved keyword in Coq
373+
, ("at_gen_BVVec", mapsTo preludeExtraModule "at_gen_BVVec")
373374
, ("atWithDefault", mapsTo vectorsModule "atWithDefault")
374375
, ("at_single", skip) -- is boring, could be proved on the Coq side
375376
, ("bvAdd", mapsTo vectorsModule "bvAdd")
@@ -394,6 +395,7 @@ sawCorePreludeSpecialTreatmentMap configuration =
394395
, ("eq_Vec", skip)
395396
, ("foldr", mapsTo vectorsModule "foldr")
396397
, ("foldl", mapsTo vectorsModule "foldl")
398+
, ("gen_at_BVVec", mapsTo preludeExtraModule "gen_at_BVVec")
397399
, ("scanl", mapsTo vectorsModule "scanl")
398400
, ("gen", mapsTo vectorsModule "gen")
399401
, ("rotateL", mapsTo vectorsModule "rotateL")
@@ -405,6 +407,10 @@ sawCorePreludeSpecialTreatmentMap configuration =
405407
-- used by other definitions in the same file, so it can neither be pre- nor
406408
-- post-defined.
407409
, ("zip", realize zipSnippet)
410+
-- Similarly for {at,gen}WithProof, as they depend on IsLtNat (generated in
411+
-- SAWCorePrelude) and is used by {at,gen}BVVec (defined in SAWCorePrelude).
412+
, ("atWithProof", realize atWithProofSnippet)
413+
, ("genWithProof", realize genWithProofSnippet)
408414
-- cannot map directly to Vector.t because arguments are in a different order
409415
, ("Vec", mapsTo vectorsModule "Vec")
410416
]
@@ -604,3 +610,27 @@ Fixpoint zip (a b : sort 0) (m n : nat) (xs : Vec m a) (ys : Vec n b)
604610
end
605611
.
606612
|]
613+
614+
atWithProofSnippet :: String
615+
atWithProofSnippet = [i|
616+
Fixpoint atWithProof (n : nat) (a : Type) (v : Vec n a) (i : nat) :
617+
IsLtNat i n -> a :=
618+
match i as i', n as n' return Vec n' a -> IsLtNat i' n' -> a with
619+
| _, O => fun _ prf =>
620+
match Nat.nlt_0_r _ prf with end
621+
| O, S y => fun v' prf => Vector.hd v'
622+
| S x, S y => fun v' prf => atWithProof y a (Vector.tl v') x (le_S_n _ _ prf)
623+
end v.
624+
|]
625+
626+
genWithProofSnippet :: String
627+
genWithProofSnippet = [i|
628+
Fixpoint genWithProof (n : nat) (a : Type) :
629+
(forall (i : nat), IsLtNat i n -> a) -> Vec n a :=
630+
match n as n' return (forall (i : nat), IsLtNat i n' -> a) -> Vec n' a with
631+
| O => fun _ => Vector.nil a
632+
| S m => fun f => Vector.cons a (f 0 (le_n_S _ _ (le_0_n _)))
633+
m (genWithProof m a
634+
(fun i prf => f (S i) (le_n_S _ _ prf)))
635+
end.
636+
|]

0 commit comments

Comments
 (0)