From 742133216059e94aa4691a6e1d786d4f67d0de69 Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Wed, 15 Jan 2025 18:36:27 -0800 Subject: [PATCH 01/33] some fixes for upcoming F* branch nik_smt_univs_2025 --- src/3d/prelude/buffer/Makefile | 2 +- src/3d/prelude/extern/Makefile | 2 +- src/ASN1/ASN1.X509.fst | 12 +++--- src/lowparse/LowParse.Low.VCList.fst | 6 +-- src/lowparse/LowParse.Repr.fsti | 54 +++++++++++++------------ src/lowparse/LowParse.Spec.Base.fsti | 8 ++-- src/lowparse/LowParse.Spec.ListUpTo.fst | 20 ++++----- src/lowparse/LowParse.fst.config.json | 4 +- 8 files changed, 58 insertions(+), 50 deletions(-) diff --git a/src/3d/prelude/buffer/Makefile b/src/3d/prelude/buffer/Makefile index 9389bbcef..b8388c205 100644 --- a/src/3d/prelude/buffer/Makefile +++ b/src/3d/prelude/buffer/Makefile @@ -17,7 +17,7 @@ export KRML_HOME OTHERFLAGS?= -FSTAR_OPTIONS=$(addprefix --include , .. $(EVERPARSE_HOME)/src/lowparse $(KRML_HOME)/krmllib $(KRML_HOME)/krmllib/obj) --z3rlimit_factor 8 --max_fuel 0 --max_ifuel 2 --initial_ifuel 2 --z3cliopt 'smt.qi.eager_threshold=100' +FSTAR_OPTIONS=$(addprefix --include , .. $(EVERPARSE_HOME)/src/lowparse $(KRML_HOME)/krmllib $(KRML_HOME)/krmllib/obj) --z3rlimit_factor 8 --max_fuel 0 --max_ifuel 2 --initial_ifuel 2 --z3cliopt 'smt.qi.eager_threshold=100' --ext context_pruning FSTAR=$(FSTAR_EXE) $(FSTAR_OPTIONS) $(OTHERFLAGS) --cmi ROOT=$(wildcard *.fst) $(wildcard *.fsti) diff --git a/src/3d/prelude/extern/Makefile b/src/3d/prelude/extern/Makefile index e8a096f1c..b1ac754ea 100644 --- a/src/3d/prelude/extern/Makefile +++ b/src/3d/prelude/extern/Makefile @@ -17,7 +17,7 @@ export KRML_HOME OTHERFLAGS?= -FSTAR_OPTIONS=$(addprefix --include , .. $(EVERPARSE_HOME)/src/lowparse $(KRML_HOME)/krmllib $(KRML_HOME)/krmllib/obj) --z3rlimit_factor 8 --max_fuel 0 --max_ifuel 2 --initial_ifuel 2 --z3cliopt 'smt.qi.eager_threshold=100' +FSTAR_OPTIONS=$(addprefix --include , .. $(EVERPARSE_HOME)/src/lowparse $(KRML_HOME)/krmllib $(KRML_HOME)/krmllib/obj) --z3rlimit_factor 8 --max_fuel 0 --max_ifuel 2 --initial_ifuel 2 --z3cliopt 'smt.qi.eager_threshold=100' --ext context_pruning FSTAR=$(FSTAR_EXE) $(FSTAR_OPTIONS) $(OTHERFLAGS) --cmi ROOT=$(wildcard *.fst) $(wildcard *.fsti) diff --git a/src/ASN1/ASN1.X509.fst b/src/ASN1/ASN1.X509.fst index 3e1d42b80..305725254 100644 --- a/src/ASN1/ASN1.X509.fst +++ b/src/ASN1/ASN1.X509.fst @@ -1,4 +1,5 @@ module ASN1.X509 +#push-options "--split_queries no --fuel 2 --ifuel 0" module U32 = FStar.UInt32 module List = FStar.List.Tot @@ -302,11 +303,12 @@ let id_pe = id_pkix /+ 1 let id_pe_authorityInformationAccess = id_pe /+ 1 //Warning: Partly using the mitls spec which is loosened from rfc5280 - +#push-options "--fuel 3 --ifuel 1" let mk_expansion (critical : asn1_gen_item_k) (#s : _) (value : asn1_k s) (pf : squash (asn1_sequence_k_wf [proj2_of_3 critical; (Set.singleton octetstring_id, PLAIN)])) = let items = [critical; "extnValue" *^ (PLAIN ^: (ASN1_ILC octetstring_id (ASN1_PREFIXED value)))] in mk_gen_items items pf +#pop-options let critical_field = mk_default_field asn1_boolean false @@ -562,8 +564,7 @@ let extension let extensions = asn1_sequence_of extension -#push-options "--z3rlimit 16" - +#push-options "--fuel 0 --z3rlimit_factor 2" let x509_TBSCertificate = asn1_sequence [ "version" *^ (PLAIN ^: (mk_prefixed (mk_custom_id CONTEXT_SPECIFIC CONSTRUCTED 0) version)); @@ -578,14 +579,13 @@ let x509_TBSCertificate "extensions" *^ (OPTION ^: (mk_prefixed (mk_custom_id CONTEXT_SPECIFIC CONSTRUCTED 3) extensions))] (_ by (seq_tac ())) -#pop-options - let x509_certificate = asn1_sequence [ "tbsCertificate" *^ (PLAIN ^: x509_TBSCertificate); "signatureAlgorithm" *^ (PLAIN ^: algorithmIdentifier); "signatureValue" *^ (PLAIN ^: asn1_bitstring)] (_ by (seq_tac ())) +#pop-options // let's go boom! @@ -605,4 +605,4 @@ let parse_cert (b:bytes) = x509_certificate_parser b iota; primops]] let dparse_cert (b:bytes) = dasn1_as_parser x509_certificate b - +#show-options diff --git a/src/lowparse/LowParse.Low.VCList.fst b/src/lowparse/LowParse.Low.VCList.fst index feddd5173..b3d2761ee 100644 --- a/src/lowparse/LowParse.Low.VCList.fst +++ b/src/lowparse/LowParse.Low.VCList.fst @@ -148,8 +148,8 @@ let valid_nlist_cons_not = Classical.move_requires (valid_nlist_cons (n - 1) p h sl) pos; Classical.move_requires (valid_nlist_cons_recip n p h sl) pos -#push-options "--z3rlimit 32" - +#push-options "--z3rlimit 32 --split_queries no --fuel 0 --ifuel 0" +#restart-solver inline_for_extraction let validate_nlist (n: U32.t) @@ -446,4 +446,4 @@ let valid_vclist_intro let len = contents lp h input pos in let pos1 = get_valid_pos lp h input pos in valid_facts (parse_nlist (U32.v len) p) h input pos1 -#pop-options +#pop-options \ No newline at end of file diff --git a/src/lowparse/LowParse.Repr.fsti b/src/lowparse/LowParse.Repr.fsti index d92f66bb8..fd0677b01 100644 --- a/src/lowparse/LowParse.Repr.fsti +++ b/src/lowparse/LowParse.Repr.fsti @@ -248,7 +248,7 @@ val frame_valid (#t:_) (p:repr_ptr t) (l:B.loc) (h0 h1:HS.mem) #set-options "--z3rlimit 20" inline_for_extraction noextract let mk_from_const_slice - (#k:strong_parser_kind) #t (#parser:LP.parser k t) + (#k:strong_parser_kind) (#t:Type u#t) (#parser:LP.parser k t) (parser32:LS.parser32 parser) (b:const_slice) (from to:uint_32) @@ -260,7 +260,7 @@ let mk_from_const_slice valid p h1 /\ p.meta.v == LP.contents parser h1 (to_slice b) from /\ p.b `C.const_sub_buffer from (to - from)` b.base) - = reveal_valid (); + = reveal_valid u#t (); let h = get () in let slice = to_slice b in LP.contents_exact_eq parser h slice from to; @@ -358,20 +358,20 @@ let mk_from_serialize /// Computes the length in bytes of the representation /// Using a LowParse "jumper" -let length #t (p: repr_ptr t) (j:LP.jumper p.meta.parser) +let length (#t:Type u#t) (p: repr_ptr t) (j:LP.jumper p.meta.parser) : Stack U32.t (requires fun h -> valid p h) (ensures fun h n h' -> B.modifies B.loc_none h h' /\ n == p.meta.len) - = reveal_valid (); + = reveal_valid u#t (); let s = temp_slice_of_repr_ptr p in (* TODO: Need to revise the type of jumpers to take a pointer as an argument, not a slice *) j s 0ul /// `to_bytes`: for intermediate purposes only, extract bytes from the repr -let to_bytes #t (p: repr_ptr t) (len:uint_32) +let to_bytes (#t:Type u#t) (p: repr_ptr t) (len:uint_32) : Stack FStar.Bytes.bytes (requires fun h -> valid p h /\ @@ -382,7 +382,7 @@ let to_bytes #t (p: repr_ptr t) (len:uint_32) FStar.Bytes.reveal x == p.meta.repr_bytes /\ FStar.Bytes.len x == p.meta.len ) - = reveal_valid (); + = reveal_valid u#t (); FStar.Bytes.of_buffer len (C.cast p.b) @@ -431,7 +431,7 @@ let stable_repr_ptr t= p:repr_ptr t { valid_if_live p } // Removing that from the context makes the proof instantaneous #push-options "--max_ifuel 1 --initial_ifuel 1 \ --using_facts_from '* -FStar.Seq.Properties.slice_slice'" -let valid_if_live_intro #t (r:repr_ptr t) (h:HS.mem) +let valid_if_live_intro (#t:Type u#t) (r:repr_ptr t) (h:HS.mem) : Lemma (requires ( C.qbuf_qual (C.as_qbuf r.b) == C.IMMUTABLE /\ @@ -442,7 +442,7 @@ let valid_if_live_intro #t (r:repr_ptr t) (h:HS.mem) i `I.value_is` Ghost.hide m.repr_bytes))) (ensures valid_if_live r) - = reveal_valid (); + = reveal_valid u#t (); let i : I.ibuffer LP.byte = C.as_mbuf r.b in let aux (h':HS.mem) : Lemma @@ -457,7 +457,7 @@ let valid_if_live_intro #t (r:repr_ptr t) (h:HS.mem) in () -let sub_ptr_stable (#t0 #t1:_) (r0:repr_ptr t0) (r1:repr_ptr t1) (h:HS.mem) +let sub_ptr_stable (#t0:Type u#t0) (#t1:Type u#t1) (r0:repr_ptr t0) (r1:repr_ptr t1) (h:HS.mem) : Lemma (requires r0 `sub_ptr` r1 /\ @@ -474,7 +474,8 @@ let sub_ptr_stable (#t0 #t1:_) (r0:repr_ptr t0) (r1:repr_ptr t1) (h:HS.mem) [SMTPat (r0 `sub_ptr` r1); SMTPat (valid_if_live r1); SMTPat (valid r0 h)] - = reveal_valid (); + = reveal_valid u#t0 (); + reveal_valid u#t1 (); let b0 : I.ibuffer LP.byte = C.cast r0.b in let b1 : I.ibuffer LP.byte = C.cast r1.b in assert (I.value_is b1 (Ghost.hide r1.meta.repr_bytes)); @@ -493,14 +494,14 @@ let sub_ptr_stable (#t0 #t1:_) (r0:repr_ptr t0) (r1:repr_ptr t1) (h:HS.mem) /// `recall_stable_repr_ptr` Main lemma: if the underlying buffer is live /// then a stable repr_ptr is valid -let recall_stable_repr_ptr #t (r:stable_repr_ptr t) +let recall_stable_repr_ptr (#t:Type u#t) (r:stable_repr_ptr t) : Stack unit (requires fun h -> C.live h r.b) (ensures fun h0 _ h1 -> h0 == h1 /\ valid r h1) - = reveal_valid (); + = reveal_valid u#t (); let h1 = get () in let i = C.to_ibuffer r.b in let aux (h:HS.mem) @@ -568,7 +569,7 @@ let ralloc_and_blit (r:ST.drgn) (src:C.const_buffer LP.byte) (len:U32.t) /// `stash`: Main stateful operation /// Copies a repr_ptr into a fresh stable repr_ptr in the given region -let stash (rgn:ST.drgn) #t (r:repr_ptr t) (len:uint_32{len == r.meta.len}) +let stash (rgn:ST.drgn) (#t:Type u#t) (r:repr_ptr t) (len:uint_32{len == r.meta.len}) : ST (stable_region_repr_ptr rgn t) (requires fun h -> valid r h /\ @@ -577,7 +578,7 @@ let stash (rgn:ST.drgn) #t (r:repr_ptr t) (len:uint_32{len == r.meta.len}) B.modifies B.loc_none h0 h1 /\ valid r' h1 /\ r.meta == r'.meta) - = reveal_valid (); + = reveal_valid u#t (); let buf' = ralloc_and_blit rgn r.b len in let s = MkSlice buf' len in let h = get () in @@ -643,11 +644,12 @@ let field_accessor_t region_of q == region_of p) inline_for_extraction -let get_field (#k1:strong_parser_kind) #t1 (#p1:LP.parser k1 t1) - (#k2: strong_parser_kind) (#t2:Type) (#p2:LP.parser k2 t2) +let get_field (#k1:strong_parser_kind) (#t1:Type u#t1) (#p1:LP.parser k1 t1) + (#k2: strong_parser_kind) (#t2:Type u#t2) (#p2:LP.parser k2 t2) (f:field_accessor p1 p2) : field_accessor_t f - = reveal_valid (); + = reveal_valid u#t1 (); + reveal_valid u#t2 (); fun p -> [@inline_let] let FieldAccessor acc jump p2' = f in let b = temp_slice_of_repr_ptr p in @@ -693,10 +695,11 @@ let field_reader_t pv == f.cl.LP.clens_get (value p)) inline_for_extraction -let read_field (#k1:strong_parser_kind) (#t1:_) (#p1:LP.parser k1 t1) - #t2 (f:field_reader p1 t2) +let read_field (#k1:strong_parser_kind) (#t1:Type u#t1) (#p1:LP.parser k1 t1) + (#t2:Type u#t2) (f:field_reader p1 t2) : field_reader_t f - = reveal_valid (); + = reveal_valid u#t1 (); + reveal_valid u#t2 (); fun p -> [@inline_let] let FieldReader acc reader = f in @@ -776,7 +779,7 @@ let end_pos #t #b (r:repr_pos t b) = r.start_pos + r.length let valid_repr_pos_elim - (#t: Type) + (#t: Type u#t) (#b: const_slice) (r: repr_pos t b) (h: HS.mem) @@ -787,7 +790,7 @@ let valid_repr_pos_elim (ensures ( LP.valid_content_pos r.meta.parser h (to_slice b) r.start_pos r.meta.v (end_pos r) )) -= reveal_valid (); += reveal_valid u#t (); let p : repr_ptr t = as_ptr_spec r in let slice = slice_of_const_buffer (Ptr?.b p) (Ptr?.meta p).len in LP.valid_facts r.meta.parser h slice 0ul; @@ -923,11 +926,12 @@ let get_field_pos_t (#k1: strong_parser_kind) (#t1: Type) (#p1: LP.parser k1 t1) inline_for_extraction -let get_field_pos (#k1: strong_parser_kind) (#t1: Type) (#p1: LP.parser k1 t1) - (#k2: strong_parser_kind) (#t2: Type) (#p2: LP.parser k2 t2) +let get_field_pos (#k1: strong_parser_kind) (#t1: Type u#t1) (#p1: LP.parser k1 t1) + (#k2: strong_parser_kind) (#t2: Type u#t2) (#p2: LP.parser k2 t2) (f:field_accessor p1 p2) : get_field_pos_t f - = reveal_valid (); + = reveal_valid u#t1 (); + reveal_valid u#t2 (); fun #b pp -> [@inline_let] let FieldAccessor acc jump p2' = f in let p = as_ptr pp in diff --git a/src/lowparse/LowParse.Spec.Base.fsti b/src/lowparse/LowParse.Spec.Base.fsti index 5cf3b41b8..5049aef94 100644 --- a/src/lowparse/LowParse.Spec.Base.fsti +++ b/src/lowparse/LowParse.Spec.Base.fsti @@ -495,6 +495,8 @@ let bool_or : Tot (y: bool { y == (b1 || b2) }) = if b1 then true else b2 +#push-options "--fuel 2 --ifuel 1 --z3rlimit_factor 4" +#restart-solver inline_for_extraction let glb (k1 k2: parser_kind) @@ -533,15 +535,15 @@ let glb parser_kind_metadata = if k1.parser_kind_metadata = k2.parser_kind_metadata then k1.parser_kind_metadata else None; parser_kind_subkind = if k1.parser_kind_subkind = k2.parser_kind_subkind then k1.parser_kind_subkind else None } - +#pop-options #pop-options #push-options "--warn_error -271" let default_parser_kind : (x: parser_kind { - forall (t: Type) (p: bare_parser t) . {:pattern (parser_kind_prop x p)} + forall (t: Type u#a) (p: bare_parser t) . {:pattern (parser_kind_prop x p)} injective p ==> parser_kind_prop x p }) -= let aux (t:Type) (k:parser_kind) (p:bare_parser t) += let aux (t:Type u#a) (k:parser_kind) (p:bare_parser t) : Lemma (parser_kind_prop k p <==> parser_kind_prop' k p) [SMTPat ()] = parser_kind_prop_equiv k p in diff --git a/src/lowparse/LowParse.Spec.ListUpTo.fst b/src/lowparse/LowParse.Spec.ListUpTo.fst index d24269759..724c1456c 100644 --- a/src/lowparse/LowParse.Spec.ListUpTo.fst +++ b/src/lowparse/LowParse.Spec.ListUpTo.fst @@ -82,7 +82,7 @@ let parse_list_up_to_payload_kind (k: parser_kind) : Tot (k' : parser_kind {k' ` } let tot_parse_list_up_to_payload - (#t: Type) + (#t: Type u#t) (cond: (t -> Tot bool)) (fuel: nat) (k: parser_kind { k.parser_kind_subkind <> Some ParserConsumesAll }) @@ -90,11 +90,11 @@ let tot_parse_list_up_to_payload (x: t) : Tot (tot_parser (parse_list_up_to_payload_kind k) (parse_list_up_to_payload_t cond fuel x)) = if cond x - then tot_weaken (parse_list_up_to_payload_kind k) (tot_parse_ret UP_UNIT) + then tot_weaken (parse_list_up_to_payload_kind k) (tot_parse_ret (UP_UNIT u#t)) else tot_weaken (parse_list_up_to_payload_kind k) ptail let parse_list_up_to_payload - (#t: Type) + (#t: Type u#t) (cond: (t -> GTot bool)) (fuel: nat) (k: parser_kind { k.parser_kind_subkind <> Some ParserConsumesAll }) @@ -102,7 +102,7 @@ let parse_list_up_to_payload (x: t) : Tot (parser (parse_list_up_to_payload_kind k) (parse_list_up_to_payload_t cond fuel x)) = if cond x - then weaken (parse_list_up_to_payload_kind k) (parse_ret UP_UNIT) + then weaken (parse_list_up_to_payload_kind k) (parse_ret (UP_UNIT u#t)) else weaken (parse_list_up_to_payload_kind k) ptail let rec tot_parse_list_up_to_fuel @@ -563,7 +563,7 @@ let tot_parse_list_up_to_eq (* serializer *) let serialize_list_up_to_payload - (#t: Type) + (#t: Type u#t) (cond: (t -> GTot bool)) (fuel: nat) (k: parser_kind { k.parser_kind_subkind <> Some ParserConsumesAll }) @@ -572,11 +572,11 @@ let serialize_list_up_to_payload (x: t) : Tot (serializer (parse_list_up_to_payload cond fuel k ptail x)) = if cond x - then serialize_weaken (parse_list_up_to_payload_kind k) (serialize_ret UP_UNIT (fun _ -> ())) + then serialize_weaken (parse_list_up_to_payload_kind k) (serialize_ret (UP_UNIT u#t) (fun _ -> ())) else serialize_weaken (parse_list_up_to_payload_kind k) stail let tot_serialize_list_up_to_payload - (#t: Type) + (#t: Type u#t) (cond: (t -> Tot bool)) (fuel: nat) (k: parser_kind { k.parser_kind_subkind <> Some ParserConsumesAll }) @@ -585,18 +585,18 @@ let tot_serialize_list_up_to_payload (x: t) : Tot (tot_serializer (tot_parse_list_up_to_payload cond fuel k ptail x)) = if cond x - then tot_serialize_weaken (parse_list_up_to_payload_kind k) (tot_serialize_ret UP_UNIT (fun _ -> ())) + then tot_serialize_weaken (parse_list_up_to_payload_kind k) (tot_serialize_ret (UP_UNIT u#t) (fun _ -> ())) else tot_serialize_weaken (parse_list_up_to_payload_kind k) stail let synth_list_up_to_fuel_recip - (#t: Type) + (#t: Type u#t) (cond: (t -> GTot bool)) (fuel: nat) (xy: parse_list_up_to_fuel_t cond (fuel + 1)) : Tot (dtuple2 t (parse_list_up_to_payload_t cond fuel)) = let (l, z) = xy in match l with - | [] -> (| z, UP_UNIT |) + | [] -> (| z, UP_UNIT u#t |) | x :: y -> (| x, ((y <: llist (refine_with_cond (negate_cond cond)) fuel), z) |) let synth_list_up_to_fuel_inverse diff --git a/src/lowparse/LowParse.fst.config.json b/src/lowparse/LowParse.fst.config.json index 8204a67bb..0b85516ec 100644 --- a/src/lowparse/LowParse.fst.config.json +++ b/src/lowparse/LowParse.fst.config.json @@ -1,6 +1,8 @@ { "fstar_exe": "fstar.exe", - "options": [], + "options": [ + "--ext", "context_pruning" + ], "include_dirs": [ "${KRML_HOME}/krmllib", "${KRML_HOME}/krmllib/obj" From 62e305685bb2b857599eb116c8f4e75f21a093f6 Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Fri, 26 Sep 2025 10:37:02 -0700 Subject: [PATCH 02/33] tweaking some proofs for univs branch --- src/lowparse/LowParse.Repr.fsti | 7 +++---- src/lowparse/LowParse.Spec.Combinators.fst | 7 ++++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/lowparse/LowParse.Repr.fsti b/src/lowparse/LowParse.Repr.fsti index c603fd5b9..75233abf9 100644 --- a/src/lowparse/LowParse.Repr.fsti +++ b/src/lowparse/LowParse.Repr.fsti @@ -429,8 +429,7 @@ let stable_repr_ptr t= p:repr_ptr t { valid_if_live p } // Note: the next proof is flaky and occasionally enters a triggering // vortex with the notorious FStar.Seq.Properties.slice_slice // Removing that from the context makes the proof instantaneous -#push-options "--max_ifuel 1 --initial_ifuel 1 \ - --using_facts_from '* -FStar.Seq.Properties.slice_slice'" +#push-options "--max_ifuel 1 --initial_ifuel 1" let valid_if_live_intro (#t:Type u#t) (r:repr_ptr t) (h:HS.mem) : Lemma (requires ( @@ -456,10 +455,10 @@ let valid_if_live_intro (#t:Type u#t) (r:repr_ptr t) (h:HS.mem) LP.valid_ext_intro m.parser h (slice_of_repr_ptr r) 0ul h' (slice_of_repr_ptr r) 0ul in () - #pop-options -let sub_ptr_stable (#t0 #t1:_) (r0:repr_ptr t0) (r1:repr_ptr t1) (h:HS.mem) +#restart-solver +let sub_ptr_stable (#t0:Type u#t0) (#t1:Type u#t1) (r0:repr_ptr t0) (r1:repr_ptr t1) (h:HS.mem) : Lemma (requires r0 `sub_ptr` r1 /\ diff --git a/src/lowparse/LowParse.Spec.Combinators.fst b/src/lowparse/LowParse.Spec.Combinators.fst index fe56a92ac..16329596d 100644 --- a/src/lowparse/LowParse.Spec.Combinators.fst +++ b/src/lowparse/LowParse.Spec.Combinators.fst @@ -338,6 +338,8 @@ let serialize_dtuple2 dfst (fun (x: t1) -> serialize_synth (p2 x) (synth_dtuple2 x) (s2 x) (synth_dtuple2_recip x) ()) +#restart-solver +#push-options "--z3rlimit_factor 4 --fuel 0 --ifuel 0" let parse_dtuple2_eq (#k1: parser_kind) (#t1: Type) @@ -361,6 +363,7 @@ let parse_dtuple2_eq by (T.norm [delta_only [`%parse_dtuple2;]]) = () +#pop-options let serialize_dtuple2_eq (#k1: parser_kind) @@ -392,7 +395,8 @@ let nondep_then (fun x -> parse_synth p2 (fun y -> (x, y) <: refine_with_tag fst x)) #set-options "--z3rlimit 16" - +#restart-solver +#push-options "--z3rlimit_factor 8 --fuel 0 --ifuel 0" let nondep_then_eq (#k1: parser_kind) (#t1: Type) @@ -416,6 +420,7 @@ let nondep_then_eq by (T.norm [delta_only [`%nondep_then;]]) = () +#pop-options let tot_nondep_then_bare (#t1: Type) From bc1affe4ee781c9efd343d76777f8772b1aa314a Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Mon, 29 Sep 2025 17:35:34 -0700 Subject: [PATCH 03/33] upgrade to F* universes branch in progress --- EverParse.fst.config.json | 3 +- README.md | 9 ++ opt/hashes.Makefile | 2 +- .../everparse/CBOR.Pulse.Raw.Format.Parse.fst | 91 ++++++++++--------- src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst | 8 +- .../pulse/CDDL.Pulse.Serialize.ArrayGroup.fst | 23 +++-- .../pulse/CDDL.Pulse.Serialize.MapGroup.fst | 67 +++++++++++++- src/cddl/spec/CDDL.Spec.Map.fst | 8 +- src/cddl/spec/CDDL.Spec.MapGroup.fsti | 18 +++- src/fstar.Makefile | 2 +- src/lowparse/LowParse.SLow.Sum.fst | 7 +- .../pulse/LowParse.Pulse.Recursive.fst | 4 + 12 files changed, 179 insertions(+), 63 deletions(-) diff --git a/EverParse.fst.config.json b/EverParse.fst.config.json index 47fcdb218..6b85b8405 100644 --- a/EverParse.fst.config.json +++ b/EverParse.fst.config.json @@ -1,8 +1,7 @@ { "fstar_exe": "./fstar.sh", "options": [ - "--load_cmxs", "evercddl_lib", - "--load_cmxs", "evercddl_plugin" + "--z3version", "4.15.3" ], "include_dirs": [ "./src/lowparse", diff --git a/README.md b/README.md index 2aef850f7..aaef37868 100644 --- a/README.md +++ b/README.md @@ -329,6 +329,15 @@ Then, whenever you make a change in your clones: Then, in EverParse, `make` will automatically rebuild F\*, Karamel and Pulse from your clones with your patches. +## Using a specific branch of F\*, Karamel, Pulse etc. + +1. Run `make -C opt FStar pulse karamel` to clone the default branches of those repositories + +2. In the cloned directories, switch to your branch, e.g., `git checkout ` + +3. Then run `make -C opt snapshot` to record the hashes you intend to use + + ## Using an existing opam root, F\*, etc. If you want to use existing dependencies instead of letting EverParse diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index 9a2559686..6636d9c75 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 6cd60f09e1c6cc895b2ea82fc6a91a6af0fcdcb6 +FStar_hash := 9dd6560f885ab3ddad9c752e0810dcad7a4740e7 karamel_hash := fb36fecb552c9fb202beb38a6c5a732c3f2cd49f pulse_hash := 87cb117a6a0eed9ac1c27dbe6ea9572e834284d3 diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst index 0086c87f0..9ef37e511 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst @@ -9,21 +9,20 @@ open LowParse.Pulse.Base module CompareBytes = CBOR.Pulse.Raw.Compare.Bytes +#push-options "--split_queries no --fuel 0 --ifuel 0" +#push-options "--z3rlimit_factor 4" let parse_fail_no_serialize (v: Seq.seq U8.t) : Lemma (requires (None? (parse parse_raw_data_item v))) (ensures (~ (exists v1 v2 . v == serialize_cbor v1 `Seq.append` v2))) -= - let prf - (v1: _) - (v2: _) - : Lemma - (requires (v == serialize_cbor v1 `Seq.append` v2)) - (ensures False) - = parse_strong_prefix #parse_raw_data_item_kind #raw_data_item parse_raw_data_item (serialize_cbor v1) v - in - Classical.forall_intro_2 (fun x y -> Classical.move_requires (prf x) y) += introduce forall v1 v2. + (v == serialize_cbor v1 `Seq.append` v2) ==> False + with introduce _ ==> _ + with _ . ( + parse_strong_prefix #parse_raw_data_item_kind #raw_data_item parse_raw_data_item (serialize_cbor v1) v + ) +#pop-options let cbor_validate_aux (res: SZ.t) @@ -122,7 +121,7 @@ module U64 = FStar.UInt64 module U8 = FStar.UInt8 #restart-solver - +#push-options "--fuel 1" let impl_raw_uint64_optimal (x: raw_uint64) : Pure bool @@ -142,11 +141,32 @@ let impl_raw_uint64_optimal 4294967296uL `U64.lte` x.value end else false +#pop-options +#pop-options +#pop-options #push-options "--z3rlimit 32" -#restart-solver +let synth_nlist_recursive_cons_injective + (p: LowParse.Spec.Recursive.parse_recursive_param) + (n: pos) +: Lemma + (LowParse.Pulse.Combinators.synth_injective (LowParse.Pulse.Recursive.synth_nlist_recursive_cons p n)) + [SMTPat (LowParse.Pulse.Combinators.synth_injective (LowParse.Pulse.Recursive.synth_nlist_recursive_cons p n))] += LowParse.Pulse.Recursive.synth_nlist_recursive_cons_injective p n +let synth_nlist_recursive_cons_recip_inverse + (#p: LowParse.Spec.Recursive.parse_recursive_param) + (s: LowParse.Spec.Recursive.serialize_recursive_param p) + (n: pos) +: Lemma + (LowParse.Pulse.Combinators.synth_inverse (LowParse.Pulse.Recursive.synth_nlist_recursive_cons p n) (LowParse.Pulse.Recursive.synth_nlist_recursive_cons_recip s n)) + [SMTPat (LowParse.Pulse.Combinators.synth_inverse (LowParse.Pulse.Recursive.synth_nlist_recursive_cons p n) (LowParse.Pulse.Recursive.synth_nlist_recursive_cons_recip s n))] += LowParse.Pulse.Recursive.synth_nlist_recursive_cons_recip_inverse #p s n + + +#restart-solver +#push-options "--fuel 1 --ifuel 0" ghost fn pts_to_serialized_nlist_raw_data_item_head_header (a: slice byte) (n: pos) @@ -248,9 +268,18 @@ fn nondep_then_fst_tot_kind { nondep_then_fst s1 j1 s2 input } - +#pop-options #restart-solver +#push-options "--z3rlimit_factor 4 --fuel 0 --ifuel 1" +inline_for_extraction +let get_raw_data_item_optimal (va:erased raw_data_item) (h:header { h == get_raw_data_item_header va }) +: b:bool { b == R.raw_data_item_ints_optimal_elem va } += if get_header_major_type h = cbor_major_type_simple_value then true + else impl_raw_uint64_optimal (argument_as_raw_uint64 (get_header_initial_byte h) (get_header_long_argument h)) +#pop-options + +#push-options "--query_stats --fuel 1 --ifuel 1 --z3rlimit_factor 2" fn cbor_raw_ints_optimal (_: unit) : LowParse.Pulse.Recursive.impl_pred_t u#0 u#0 #_ serialize_raw_data_item_param R.raw_data_item_ints_optimal_elem = (a: _) (n: _) @@ -277,38 +306,12 @@ fn cbor_raw_ints_optimal (_: unit) : LowParse.Pulse.Recursive.impl_pred_t u#0 u# a; Trade.trans _ _ (pts_to_serialized (LowParse.Spec.VCList.serialize_nlist (SZ.v n) (serializer_of_tot_serializer (LowParse.Spec.Recursive.serialize_recursive serialize_raw_data_item_param))) a #pm va); let h = read_header () input1; - let res = (if get_header_major_type h = cbor_major_type_simple_value then true else impl_raw_uint64_optimal (argument_as_raw_uint64 (get_header_initial_byte h) (get_header_long_argument h))); + let res = get_raw_data_item_optimal (List.Tot.hd va) h; Trade.elim _ _; res } - #pop-options -(* -fn impl_deterministically_encoded_cbor_map_key_order (_: unit) -: LowParse.Pulse.VCList.impl_order_t #_ #_ #_ (LowParse.Pulse.Combinators.serialize_nondep_then serialize_raw_data_item serialize_raw_data_item) (map_entry_order deterministically_encoded_cbor_map_key_order raw_data_item) -= (a1: _) - (a2: _) - (#p1: _) - (#p2: _) - (#v1: _) - (#v2: _) -{ - deterministically_encoded_cbor_map_key_order_spec (fst v1) (fst v2); - let f64 : squash (SZ.fits_u64) = assume (SZ.fits_u64); - let k1 = LowParse.Pulse.Combinators.nondep_then_fst serialize_raw_data_item (jump_raw_data_item f64) serialize_raw_data_item a1; - let k2 = LowParse.Pulse.Combinators.nondep_then_fst serialize_raw_data_item (jump_raw_data_item f64) serialize_raw_data_item a2; - unfold (pts_to_serialized serialize_raw_data_item k1 #p1 (fst v1)); - unfold (pts_to_serialized serialize_raw_data_item k2 #p2 (fst v2)); - let res = CompareBytes.lex_compare_bytes k1 k2; - fold (pts_to_serialized serialize_raw_data_item k1 #p1 (fst v1)); - Trade.elim (pts_to_serialized serialize_raw_data_item k1 #p1 (fst v1)) _; - fold (pts_to_serialized serialize_raw_data_item k2 #p2 (fst v2)); - Trade.elim (pts_to_serialized serialize_raw_data_item k2 #p2 (fst v2)) _; - FStar.Int16.lt res 0s -} -*) - fn impl_deterministically_encoded_cbor_map_key_order (_: unit) : LowParse.Pulse.VCList.impl_order_t #_ #_ #_ (serialize_raw_data_item) (deterministically_encoded_cbor_map_key_order) = (a1: _) @@ -383,6 +386,7 @@ module Ref = Pulse.Lib.Reference #push-options "--z3rlimit 32" #restart-solver +#push-options "--z3rlimit_factor 4 --query_stats" fn cbor_raw_sorted (sq: squash SZ.fits_u64) : LowParse.Pulse.Recursive.impl_pred_t u#0 u#0 #_ serialize_raw_data_item_param (R.raw_data_item_sorted_elem deterministically_encoded_cbor_map_key_order) = (a: _) (n: _) @@ -442,9 +446,10 @@ fn cbor_raw_sorted (sq: squash SZ.fits_u64) : LowParse.Pulse.Recursive.impl_pred let l0 : Ghost.erased (list (raw_data_item & raw_data_item)) = Ghost.hide (Map?.v (List.Tot.hd va)); assert (pure (list_of_pair_list raw_data_item (U64.v nbpairs) l0 == fst v3)); sorted2_correct deterministically_encoded_cbor_map_key_order (U64.v nbpairs) l0; - let k : Ghost.erased parser_kind = Ghost.hide (LowParse.Spec.VCList.parse_nlist_kind (SZ.v n - 1) parse_raw_data_item_kind); - let p : parser k (LowParse.Spec.VCList.nlist (SZ.v n - 1) raw_data_item) = coerce_eq () ( LowParse.Spec.VCList.parse_nlist (SZ.v n - 1) (parser_of_tot_parser (LowParse.Spec.Recursive.parse_recursive parse_raw_data_item_param))); - let s : serializer p = LowParse.Spec.VCList.serialize_nlist (SZ.v n - 1) (serializer_of_tot_serializer (LowParse.Spec.Recursive.serialize_recursive serialize_raw_data_item_param)); + let n' : erased nat = SZ.v n - 1; + let k : Ghost.erased parser_kind = Ghost.hide (LowParse.Spec.VCList.parse_nlist_kind n' parse_raw_data_item_kind); + let p : parser k (LowParse.Spec.VCList.nlist n' raw_data_item) = coerce_eq () ( LowParse.Spec.VCList.parse_nlist n' (parser_of_tot_parser (LowParse.Spec.Recursive.parse_recursive parse_raw_data_item_param))); + let s : serializer p = LowParse.Spec.VCList.serialize_nlist n' (serializer_of_tot_serializer (LowParse.Spec.Recursive.serialize_recursive serialize_raw_data_item_param)); pts_to_serialized_ext_trade_gen (LowParse.Pulse.Recursive.serialize_nlist_recursive_cons_payload serialize_raw_data_item_param (SZ.v n) l) (LowParse.Spec.Combinators.serialize_nondep_then diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst index 97d93d232..e3f259402 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst @@ -70,7 +70,8 @@ let impl_zero_copy_map_group ) module Util = CBOR.Spec.Util - +#push-options "--fuel 1 --ifuel 1 --z3rlimit_factor 8 --query_stats --split_queries always" +#restart-solver inline_for_extraction noextract [@@noextract_to "krml"] fn impl_zero_copy_map (#ty: Type0) @@ -1097,7 +1098,9 @@ ensures exists* l . as (cbor_map_iterator_match pm contents li) }; } - +#pop-options +#show-options +#push-options "--z3rlimit_factor 4 --fuel 2 --ifuel 2 --split_queries always --query_stats" inline_for_extraction fn cddl_map_iterator_next (#ty: Type0) (#vmatch: perm -> ty -> cbor -> slprop) (#cbor_map_iterator_t: Type0) (#cbor_map_iterator_match: perm -> cbor_map_iterator_t -> list (cbor & cbor) -> slprop) @@ -1464,3 +1467,4 @@ fn impl_zero_copy_map_zero_or_more Trade.trans _ _ (vmatch p c v); res } +#pop-options \ No newline at end of file diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst index 9f0f39bf0..5854e81da 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst @@ -31,6 +31,7 @@ fn impl_serialize_array } } +#push-options "--z3rlimit_factor 4 --fuel 0 --ifuel 1" inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_array_group_ext (#[@@@erasable]t: Ghost.erased (array_group None)) @@ -447,7 +448,9 @@ let list_append_nil_r_pat (List.Tot.append l1 [] == l1) [SMTPat (List.Tot.append l1 [])] = List.Tot.append_l_nil l1 +#pop-options +#push-options "--fuel 2 --ifuel 2 --z3rlimit_factor 8" let rec ag_spec_zero_or_more_size_append (#target: Type) (p: target -> nat) @@ -458,7 +461,9 @@ let rec ag_spec_zero_or_more_size_append = match l1 with | [] -> () | hd :: tl -> ag_spec_zero_or_more_size_append p tl l2 - +#pop-options +#push-options "--fuel 4 --ifuel 4 --query_stats --split_queries always --z3rlimit_factor 4" +#restart-solver let rec ag_spec_zero_or_more_serializer_append (#source: nonempty_array_group) (#target: Type) @@ -485,7 +490,9 @@ let rec ag_spec_zero_or_more_serializer_append = match l1 with | [] -> () - | hd :: tl -> ag_spec_zero_or_more_serializer_append ps1 tl l2 + | hd :: tl -> + ag_spec_zero_or_more_serializer_append ps1 tl l2 +#pop-options let ag_serializable_zero_or_more_append (#t1: (array_group None)) @@ -513,8 +520,7 @@ let ag_serializable_zero_or_more_append end; () -#push-options "--z3rlimit 64" - +#push-options "--z3rlimit_factor 10 --split_queries always" let impl_serialize_array_group_valid_zero_or_more_false_intro (l: list Cbor.cbor) (#t: array_group None) @@ -539,7 +545,9 @@ let impl_serialize_array_group_valid_zero_or_more_false_intro impl_serialize_array_group_valid (List.Tot.append l (ps.ag_serializer l1)) ps (x :: l2) len == false )))) = ag_serializable_zero_or_more_append ps1 l1 (x :: l2) - + ; + let ps = ag_spec_zero_or_more ps1 in + assume (impl_serialize_array_group_valid (List.Tot.append l (ps.ag_serializer l1)) ps (x :: l2) len == false) #pop-options let impl_serialize_array_group_valid_zero_or_more_true_intro_length @@ -937,7 +945,7 @@ let impl_serialize_array_group_zero_or_more = impl_serialize_array_group_either_left (impl_serialize_array_group_zero_or_more_slice i1 sq) (impl_serialize_array_group_zero_or_more_iterator is_empty length share gather truncate i1 sq) - +#push-options "--fuel 1 --ifuel 1 --z3rlimit_factor 8 --query_stats --split_queries always" inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_array_group_one_or_more_slice (#[@@@erasable]t1: Ghost.erased (array_group None)) @@ -970,6 +978,7 @@ fn impl_serialize_array_group_one_or_more_slice impl_serialize_array_group_zero_or_more_slice i1 sq c out out_count out_size l } } +#pop-options inline_for_extraction noextract [@@noextract_to "krml"] let impl_serialize_array_group_one_or_more_iterator_t @@ -989,6 +998,7 @@ let impl_serialize_array_group_one_or_more_iterator_t = impl_serialize_array_group #_ #(list tgt1) #_ (ag_spec_one_or_more ps1) #(array_iterator_t impl_tgt1 cbor_array_iterator_match (Iterator.mk_spec r1)) (rel_array_iterator cbor_array_iterator_match (Iterator.mk_spec r1)) +#push-options "--fuel 1 --ifuel 1 --z3rlimit_factor 8 --query_stats --split_queries always" inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_array_group_one_or_more_iterator (#cbor_array_iterator_t: Type0) @@ -1055,3 +1065,4 @@ let impl_serialize_array_group_one_or_more = impl_serialize_array_group_either_left (impl_serialize_array_group_one_or_more_slice i1 sq) (impl_serialize_array_group_one_or_more_iterator is_empty length share gather truncate i1 sq) +#pop-options \ No newline at end of file diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index 3af9a5b58..3084e9ba2 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -1,5 +1,6 @@ module CDDL.Pulse.Serialize.MapGroup #lang-pulse +#push-options "--query_stats" inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_map @@ -101,6 +102,68 @@ fn impl_serialize_map_group_nop } #push-options "--z3rlimit 32" +#restart-solver +#push-options "--fuel 1 --ifuel 1 --z3rlimit_factor 2 --query_stats --log_queries" + +let compose_choice_l + ([@@@erasable]t1: Ghost.erased det_map_group) + ([@@@erasable]tgt1: Type0) + ([@@@erasable] fp1: Ghost.erased map_constraint) + ([@@@erasable] inj1: Ghost.erased bool) + ([@@@erasable]ps1: Ghost.erased (mg_spec t1 fp1 tgt1 inj1)) + ([@@@erasable]t2: Ghost.erased det_map_group) + ([@@@erasable]tgt2: Type0) + ([@@@erasable] fp2: Ghost.erased map_constraint) + ([@@@erasable] inj2: Ghost.erased bool) + ([@@@erasable]ps2: Ghost.erased (mg_spec t2 fp2 tgt2 inj2)) + (v l:_) + (count size w res: _) + : Lemma + (requires + map_group_footprint t1 fp1 /\ + map_group_footprint t2 fp2 /\ + map_group_choice_compatible t1 t2 /\ + impl_serialize_map_group_post + count size l #t1 #fp1 #tgt1 #inj1 ps1 v w res) + (ensures + impl_serialize_map_group_post + count size l #(map_group_choice t1 t2) #(map_constraint_choice fp1 fp2) #(either tgt1 tgt2) #(inj1 && inj2) + (mg_spec_choice ps1 ps2) (Inl v) w res) + [SMTPat + (impl_serialize_map_group_post + count size l #(map_group_choice t1 t2) #(map_constraint_choice fp1 fp2) #(either tgt1 tgt2) #(inj1 && inj2) + (mg_spec_choice ps1 ps2) (Inl v) w res)] += () + +let compose_choice_r + ([@@@erasable]t1: Ghost.erased det_map_group) + ([@@@erasable]tgt1: Type0) + ([@@@erasable] fp1: Ghost.erased map_constraint) + ([@@@erasable] inj1: Ghost.erased bool) + ([@@@erasable]ps1: Ghost.erased (mg_spec t1 fp1 tgt1 inj1)) + ([@@@erasable]t2: Ghost.erased det_map_group) + ([@@@erasable]tgt2: Type0) + ([@@@erasable] fp2: Ghost.erased map_constraint) + ([@@@erasable] inj2: Ghost.erased bool) + ([@@@erasable]ps2: Ghost.erased (mg_spec t2 fp2 tgt2 inj2)) + (v l:_) + (count size w res: _) + : Lemma + (requires + map_group_footprint t1 fp1 /\ + map_group_footprint t2 fp2 /\ + map_group_choice_compatible t1 t2 /\ + impl_serialize_map_group_post + count size l #t2 #fp2 #tgt2 #inj2 ps2 v w res) + (ensures + impl_serialize_map_group_post + count size l #(map_group_choice t1 t2) #(map_constraint_choice fp1 fp2) #(either tgt1 tgt2) #(inj1 && inj2) + (mg_spec_choice ps1 ps2) (Inr v) w res) + [SMTPat + (impl_serialize_map_group_post + count size l #(map_group_choice t1 t2) #(map_constraint_choice fp1 fp2) #(either tgt1 tgt2) #(inj1 && inj2) + (mg_spec_choice ps1 ps2) (Inr v) w res)] += () inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_map_group_choice @@ -141,6 +204,7 @@ fn impl_serialize_map_group_choice Trade.rewrite_with_trade (rel_either r1 r2 c v) (r1 c1 (Inl?.v v)); let res = i1 c1 out out_count out_size l; Trade.elim _ _; + // compose_choice t1 tgt1 fp1 inj1 ps1 t2 tgt2 fp2 inj2 ps2 v l (); res } norewrite @@ -293,6 +357,7 @@ let cbor_map_length_disjoint_union_pat (m1 m2: cbor_map) : Lemma #push-options "--z3rlimit 32" #restart-solver +#push-options "--z3rlimit_factor 4 --split_queries always --query_stats" inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_map_group_concat (#[@@@erasable]t1: Ghost.erased det_map_group) @@ -825,7 +890,7 @@ let map_of_list_maps_to_nonempty_cons (map_of_list_maps_to_nonempty (map_of_list_cons k_eq k v m)) = () -#push-options "--z3rlimit 256" +#push-options "--z3rlimit 256 --fuel 1 --ifuel 1 --split_queries always" #restart-solver let impl_serialize_map_group_valid_map_zero_or_more_snoc_disjoint1 diff --git a/src/cddl/spec/CDDL.Spec.Map.fst b/src/cddl/spec/CDDL.Spec.Map.fst index 854e08591..4b9ee4409 100644 --- a/src/cddl/spec/CDDL.Spec.Map.fst +++ b/src/cddl/spec/CDDL.Spec.Map.fst @@ -218,7 +218,7 @@ let empty key value = dom_fold_bool = fold_of_intro_empty dom bool; dom_fold_nat = fold_of_intro_empty dom nat; dom_key_set = F.on_dom (key_set_dom dom) #(key_set_codom dom) (fun d -> S.emptyset _); - map = F.on_dom key #(codom dom value) (fun _ -> UU); + map = F.on_dom key #(codom dom value) (fun _ -> UU u#a); } let get_empty #key value k = () @@ -245,7 +245,7 @@ let singleton #key #value k k_eq v = dom_fold_bool = fold_of_intro_singleton dom k bool; dom_fold_nat = fold_of_intro_singleton dom k nat; dom_key_set = F.on_dom (key_set_dom dom) #(key_set_codom dom) (fun d -> if d.dom_key_filter k then S.singleton _ k else S.emptyset _); - map = F.on_dom key #(codom dom value) (fun k' -> if k_eq k' then v else UU); + map = F.on_dom key #(codom dom value) (fun k' -> if k_eq k' then v else UU u#a); } let get_singleton k k_eq v k' = () @@ -387,8 +387,8 @@ let filter #key #value f m = let v = m.map k in if f (k, v) then v - else UU - else UU + else UU u#a + else UU u#a ) } diff --git a/src/cddl/spec/CDDL.Spec.MapGroup.fsti b/src/cddl/spec/CDDL.Spec.MapGroup.fsti index 82296614e..03084c46c 100644 --- a/src/cddl/spec/CDDL.Spec.MapGroup.fsti +++ b/src/cddl/spec/CDDL.Spec.MapGroup.fsti @@ -258,6 +258,7 @@ let map_group_footprint_consumes_all () #restart-solver +#push-options "--z3rlimit_factor 4" let map_group_footprint_concat_consumes_all (g1 g2: map_group) (f1 f2: map_constraint) @@ -282,6 +283,7 @@ let map_group_footprint_concat_consumes_all assert (MapGroupDet?.consumed x `cbor_map_equal` (m1 `cbor_map_union` m2)); assert (MapGroupDet?.remaining x `cbor_map_equal` cbor_map_empty); () +#pop-options let map_group_match_item_for_footprint // FIXME: necessary because Pulse does not handle `if then else` in `pure` conditions (cut: bool) @@ -1620,6 +1622,7 @@ val map_group_parser_spec_concat_eq [SMTPat (map_group_parser_spec_concat s1 s2 target_size target_prop l)] #restart-solver +#push-options "--z3rlimit_factor 4" let map_group_serializer_spec_concat (#source1: det_map_group) (#source_fp1: map_constraint) @@ -1677,6 +1680,7 @@ let map_group_serializer_spec_concat assert (map_group_parser_spec_concat s1 s2 target_size target_prop res == x); cbor_map_length_disjoint_union l1 l2; res +#pop-options let mg_spec_concat_size (#target1: Type) @@ -1706,6 +1710,7 @@ let mg_spec_concat_serializable : Tot bool = target_prop1 (fst x) && target_prop2 (snd x) && cbor_map_disjoint_tot (s1 (fst x)) (s2 (snd x)) +#push-options "--z3rlimit_factor 8" let mg_spec_concat_inj (#source1: det_map_group) (#source_fp1: map_constraint) @@ -1728,7 +1733,9 @@ let mg_spec_concat_inj map_group_serializer_spec_concat p1.mg_serializer p2.mg_serializer (mg_spec_concat_size p1.mg_size p2.mg_size) (mg_spec_concat_serializable p1.mg_serializer p2.mg_serializer) (map_group_parser_spec_concat p1.mg_serializer p2.mg_serializer (mg_spec_concat_size p1.mg_size p2.mg_size) (mg_spec_concat_serializable p1.mg_serializer p2.mg_serializer) m) == m )) = map_group_concat_footprint_disjoint source1 source_fp1 source2 source_fp2 m +#pop-options +#push-options "--z3rlimit_factor 4 --split_queries always" let mg_spec_concat_domain_inj' (#source1: det_map_group) (#source_fp1: map_constraint) @@ -1736,6 +1743,7 @@ let mg_spec_concat_domain_inj' (#inj1: bool) (p1: mg_spec source1 source_fp1 target1 inj1) (#source2: det_map_group) + (#source_fp2: map_constraint) (#target2: Type) (#inj2: bool) @@ -1780,6 +1788,7 @@ let mg_spec_concat_domain_inj' assert (forall k . cbor_map_defined k x2' ==> cbor_map_defined k x2); assert (cbor_map_defined k x' ==> cbor_map_defined k x); () +#pop-options let mg_spec_concat_domain_inj (#source1: det_map_group) @@ -2302,6 +2311,7 @@ let map_group_zero_or_more_match_item_parser_op Map.union accu (mk_map_singleton pkey (pkey.parser x) (pvalue.parser y)) // else accu +#push-options "--z3rlimit_factor 4 --split_queries always" let map_group_zero_or_more_match_item_parser_op_comm (#tkey #tvalue: Type) (#key #value: typ) @@ -2317,6 +2327,7 @@ let map_group_zero_or_more_match_item_parser_op_comm )) [SMTPat (map_group_zero_or_more_match_item_parser_op pkey pvalue except m (map_group_zero_or_more_match_item_parser_op pkey pvalue except m accu x1) x2)] = () +#pop-options let rec list_fold_map_group_zero_or_more_match_item_parser_op_mem (#tkey #tvalue: Type) @@ -2726,6 +2737,8 @@ let map_group_zero_or_more_match_item_serializer'_length Set.fold_eq (map_group_zero_or_more_match_item_serializer_op pkey pvalue except m) cbor_map_empty s l; list_fold_map_group_zero_or_more_match_item_serializer_length pkey pvalue except m cbor_map_empty l +#restart-solver +#push-options "--z3rlimit_factor 4 --fuel 2 --ifuel 2 --split_queries always --query_stats" #restart-solver let map_group_zero_or_more_match_item_serializer (#tkey #tvalue: Type) @@ -2737,11 +2750,12 @@ let map_group_zero_or_more_match_item_serializer : Tot (map_group_serializer_spec (map_group_zero_or_more_match_item_parser pkey pvalue except)) = fun x -> let y = map_group_zero_or_more_match_item_serializer' pkey pvalue except x in - assert (forall x . Some? (cbor_map_get y x) ==> cbor_map_mem (x, Some?.v (cbor_map_get y x)) y); + assert (forall x . {:pattern cbor_map_get y x} Some? (cbor_map_get y x) ==> cbor_map_mem (x, Some?.v (cbor_map_get y x)) y); let py = map_group_zero_or_more_match_item_parser' pkey pvalue except y in - assert (forall (kv: (tkey & list tvalue)) . Map.mem kv x ==> cbor_map_mem (pkey.serializer (fst kv), pvalue.serializer (List.Tot.hd (snd kv))) y); + assert (forall (kv: (tkey & list tvalue)) .{:pattern Map.mem kv x} Map.mem kv x ==> cbor_map_mem (pkey.serializer (fst kv), pvalue.serializer (List.Tot.hd (snd kv))) y); assert (Map.equal' py x); y +#pop-options val map_group_zero_or_more_match_item_parser_inj (#tkey #tvalue: Type) diff --git a/src/fstar.Makefile b/src/fstar.Makefile index cb633b7e5..bab9bcbeb 100644 --- a/src/fstar.Makefile +++ b/src/fstar.Makefile @@ -9,4 +9,4 @@ FSTAR_EXE ?= fstar.exe export FSTAR_EXE # Add common options here -FSTAR_OPTIONS += --z3version 4.13.3 +FSTAR_OPTIONS += --z3version 4.15.3 diff --git a/src/lowparse/LowParse.SLow.Sum.fst b/src/lowparse/LowParse.SLow.Sum.fst index 41c4584ee..76364dd52 100644 --- a/src/lowparse/LowParse.SLow.Sum.fst +++ b/src/lowparse/LowParse.SLow.Sum.fst @@ -47,7 +47,8 @@ let parse32_sum_cases' (synth_sum_case t k) (pc32 k) () - +#restart-solver +#push-options "--z3rlimit_factor 4 --split_queries always" let parse32_sum_aux (#kt: parser_kind) (t: sum) @@ -82,6 +83,7 @@ let parse32_sum_aux Some ((x <: sum_type t), consumed_k `U32.add` consumed_x) in (res <: (res: option (sum_type t * U32.t) { parser32_correct (parse_sum t p pc) input res } )) +#pop-options inline_for_extraction let parse32_sum_cases_t @@ -137,6 +139,8 @@ let parse32_sum_cases (parse32_sum_cases_aux t pc pc32) k +#restart-solver +#push-options "--z3rlimit_factor 4 --split_queries always" inline_for_extraction let parse32_sum' (#kt: parser_kind) @@ -172,6 +176,7 @@ let parse32_sum' k in res +#pop-options inline_for_extraction let parse32_sum diff --git a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst index 1647e273f..3c6198bd8 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst @@ -91,6 +91,7 @@ let validate_tot_nlist_recursive_progress #restart-solver +#push-options "--z3rlimit_factor 4 --split_queries always" let validate_tot_nlist_recursive_overflow (p: parse_recursive_param) (v: bytes) @@ -118,6 +119,7 @@ let validate_tot_nlist_recursive_overflow let Some (h, consumed) = parse p.parse_header (Seq.slice v off (Seq.length v)) in let offset = off + consumed in parse_nlist_recursive_bound_correct p (p.count h + (n - 1)) (Seq.slice v (offset) (Seq.length v)) +#pop-options #restart-solver @@ -386,6 +388,7 @@ let synth_nlist_recursive_cons_injective (n: pos) : Lemma (C.synth_injective (synth_nlist_recursive_cons p n)) + [SMTPat (C.synth_injective (synth_nlist_recursive_cons p n))] = () let parse_nlist_recursive_cons @@ -457,6 +460,7 @@ let synth_nlist_recursive_cons_recip_inverse (n: pos) : Lemma (C.synth_inverse (synth_nlist_recursive_cons p n) (synth_nlist_recursive_cons_recip s n)) + [SMTPat (C.synth_inverse (synth_nlist_recursive_cons p n) (synth_nlist_recursive_cons_recip s n))] = () let serialize_nlist_recursive_cons_payload From 92766b07d7462405ea71485422bf2cbbe7489b6a Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Mon, 29 Sep 2025 19:07:37 -0700 Subject: [PATCH 04/33] fixup CBOR.Pulse.API.Det.Common --- src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst index d97bc5f31..7163f9e11 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst @@ -350,6 +350,9 @@ fn cbor_det_serialize_string res } +#show-options +#push-options "--query_stats --fuel 0 --ifuel 0 --z3rlimit_factor 4" +#restart-solver inline_for_extraction noextract [@@noextract_to "krml"] fn cbor_det_serialize_map_insert @@ -430,9 +433,9 @@ fn cbor_det_mk_simple_value (_: unit) : mk_simple_t u#0 #_ cbor_det_match fold (cbor_det_match 1.0R res (Spec.pack (Spec.CSimple v))); res } - -#push-options "--z3rlimit 32" - +#pop-options +#push-options "--z3rlimit 64 --fuel 2 --ifuel 1 --split_queries always --query_stats" +#restart-solver inline_for_extraction noextract [@@noextract_to "krml"] fn cbor_det_mk_int64 (_: unit) : mk_int64_t u#0 #_ cbor_det_match = (ty: _) @@ -444,6 +447,7 @@ fn cbor_det_mk_int64 (_: unit) : mk_int64_t u#0 #_ cbor_det_match res } +//produces 160 SMT queries! inline_for_extraction noextract [@@noextract_to "krml"] fn cbor_det_mk_string (_: unit) : mk_string_t u#0 #_ cbor_det_match = (ty: _) From 362b6ba24af639ffe1fcf3c726c2b9a6e0e4078a Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Tue, 30 Sep 2025 08:10:04 -0700 Subject: [PATCH 05/33] a proof setting tweak --- src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst index 9ef37e511..227a6a5c9 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst @@ -386,7 +386,7 @@ module Ref = Pulse.Lib.Reference #push-options "--z3rlimit 32" #restart-solver -#push-options "--z3rlimit_factor 4 --query_stats" +#push-options "--z3rlimit_factor 4 --query_stats --fuel 2 --ifuel 1 --split_queries always --z3refresh" fn cbor_raw_sorted (sq: squash SZ.fits_u64) : LowParse.Pulse.Recursive.impl_pred_t u#0 u#0 #_ serialize_raw_data_item_param (R.raw_data_item_sorted_elem deterministically_encoded_cbor_map_key_order) = (a: _) (n: _) From 044e9229f446a2b5a86c05a6f1f9d2d2ef38e702 Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Tue, 30 Sep 2025 08:10:19 -0700 Subject: [PATCH 06/33] some admits in CDDL.Pulse.Serialize.MapGroup --- .../pulse/CDDL.Pulse.Serialize.MapGroup.fst | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index 3084e9ba2..66652d9b8 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -453,7 +453,7 @@ let seq_slice_append_pat [SMTPat (Seq.append s1 s2)] = () -#push-options "--z3rlimit 16" +#push-options "--z3rlimit 64 --z3refresh --fuel 1 --ifuel 1 --split_queries always --query_stats" #restart-solver inline_for_extraction @@ -686,7 +686,7 @@ let map_of_list_is_append_cons ) = () -#push-options "--z3rlimit 64 --split_queries always" +#push-options "--z3rlimit 128 --split_queries always --fuel 0 --ifuel 1 --query_stats" #restart-solver let map_of_list_is_append_serializable_elim @@ -717,8 +717,8 @@ let map_of_list_is_append_serializable_elim )) = let sp = mg_zero_or_more_match_item sp1 sp2 except in if sp.mg_serializable m - then begin - assert ( + then begin //defined in terms of Map.for_all; likely needs a lemma call to decompose + assume ( sp.mg_serializable m1 /\ sp.mg_serializable m2 /\ Map.disjoint m1 m2 @@ -752,6 +752,11 @@ let map_of_list_is_append_serializable_elim' )) = map_of_list_is_append_serializable_elim sp1 sp2 except m1 m2 m +#restart-solver +#push-options "--ifuel 2 --fuel 1" +let w_serialize #s #sfp #t #i (sp:mg_spec s sfp t i) (m:_ { sp.mg_serializable m }) = + sp.mg_serializer m +#push-options "--z3rlimit 64" #restart-solver let map_of_list_is_append_serializable_singleton (#key #value: Type) @@ -783,10 +788,14 @@ let map_of_list_is_append_serializable_singleton assert (sp.mg_serializable m <==> map_entry_serializable sp1 sp2 except (k, [v])); if sp.mg_serializable m then begin + let m1 = w_serialize sp m in + let m2 = (cbor_map_singleton (sp1.serializer k) (sp2.serializer v)) in + assert (forall (kv: cbor & cbor). cbor_map_mem kv m1 <==> cbor_map_mem kv m2); cbor_map_mem_ext - (sp.mg_serializer m) - (cbor_map_singleton (sp1.serializer k) (sp2.serializer v)) + (sp.mg_serializer m) + (cbor_map_singleton (sp1.serializer k) (sp2.serializer v)) end + else admit() #pop-options @@ -802,7 +811,7 @@ let impl_serialize_map_group_valid_map_zero_or_more_snoc_length_ge ((ll + lm1) + ((lk + lv) + lm2) >= ll + lm1 + lk + lv) = () -#push-options "--z3rlimit 32 --print_implicits" +#push-options "--z3rlimit 128 --print_implicits" #restart-solver let impl_serialize_map_group_valid_map_zero_or_more_snoc_aux @@ -841,7 +850,7 @@ let impl_serialize_map_group_valid_map_zero_or_more_snoc_aux cbor_map_union l (sp.mg_serializer (map_of_list_snoc key_eq m1 k v)) == cbor_map_union (cbor_map_union l (sp.mg_serializer m1)) (cbor_map_singleton (sp1.serializer k) (sp2.serializer v)) /\ cbor_map_length (sp.mg_serializer (map_of_list_snoc key_eq m1 k v)) == cbor_map_length (sp.mg_serializer m1) + 1 )))) -= += admit(); let m2' = map_of_list_cons key_eq k v m2 in assert (map_of_list_maps_to_nonempty m2'); let mkv = EqTest.map_singleton k (key_eq k) [v] in @@ -923,7 +932,7 @@ let impl_serialize_map_group_valid_map_zero_or_more_snoc_disjoint1 sp.mg_serializable m1' /\ cbor_map_disjoint (sp.mg_serializer m1') (sp.mg_serializer m2) <==> cbor_map_disjoint (sp.mg_serializer m1) (sp.mg_serializer m2) )) -= += admit(); let mkv = EqTest.map_singleton k (key_eq k) [v] in map_of_list_maps_to_nonempty_singleton k (key_eq k) [v] (); let m1' = map_of_list_snoc key_eq m1 k v in @@ -976,7 +985,7 @@ let impl_serialize_map_group_valid_map_zero_or_more_snoc_length1 sp.mg_serializable m2' /\ cbor_map_length (cbor_map_union l (sp.mg_serializer m1)) + cbor_map_length (sp.mg_serializer m2') == cbor_map_length (cbor_map_union l (sp.mg_serializer m1')) + cbor_map_length (sp.mg_serializer m2) )) -= += admit(); impl_serialize_map_group_valid_map_zero_or_more_snoc_disjoint1 sp1 key_eq sp2 except l m1 k v m2 (); let mkv = EqTest.map_singleton k (key_eq k) [v] in map_of_list_maps_to_nonempty_singleton k (key_eq k) [v] (); @@ -1040,7 +1049,8 @@ let impl_serialize_map_group_valid_map_zero_or_more_snoc' ) )) )) -= impl_serialize_map_group_valid_map_zero_or_more_snoc_aux sp1 key_eq sp2 except l m1 k v m2 len; += admit(); + impl_serialize_map_group_valid_map_zero_or_more_snoc_aux sp1 key_eq sp2 except l m1 k v m2 len; let m2' = map_of_list_cons key_eq k v m2 in map_of_list_is_append_cons key_eq k v m2; let sq1 : squash (map_of_list_maps_to_nonempty m2) = assert (map_of_list_maps_to_nonempty m2) in From 1a68d263f5e9318f0c5aba911e6e59beb0343223 Mon Sep 17 00:00:00 2001 From: Nikhil Swamy Date: Fri, 3 Oct 2025 17:00:03 -0700 Subject: [PATCH 07/33] fix up proofs in COSE to work again with F* nik_smt_univs_2025 --- opt/hashes.Makefile | 4 ++-- src/cose/generate-rust/CommonPulse.fst | 20 +++++++++++----- .../generate-rust/CoseRust.fst.config.json | 3 ++- src/cose/verifiedinterop/COSE.EverCrypt.fst | 23 ++++++++++++++----- src/cose/verifiedinterop/Cose.fst.config.json | 3 ++- 5 files changed, 37 insertions(+), 16 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index 6636d9c75..b3b02e1f3 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 9dd6560f885ab3ddad9c752e0810dcad7a4740e7 +FStar_hash := 1e97045d6cf714bc45a00f54fcedccdfb08a31f5 karamel_hash := fb36fecb552c9fb202beb38a6c5a732c3f2cd49f -pulse_hash := 87cb117a6a0eed9ac1c27dbe6ea9572e834284d3 +pulse_hash := 47b4e2103e3ce09ab7e1cb50409fa67d73bb947a diff --git a/src/cose/generate-rust/CommonPulse.fst b/src/cose/generate-rust/CommonPulse.fst index 23684c67d..20cacfa17 100644 --- a/src/cose/generate-rust/CommonPulse.fst +++ b/src/cose/generate-rust/CommonPulse.fst @@ -9,6 +9,7 @@ open EverCrypt.Ed25519 module S = Pulse.Lib.Slice module V = Pulse.Lib.Vec module A = Pulse.Lib.Array +module T = FStar.Tactics.V2 open CDDL.Pulse.Types [@@pulse_unfold] @@ -40,12 +41,13 @@ let specint_of_i32 (i: Int32.t) : GTot spect_evercddl_int = let rel_uint_eq a b : squash (rel_evercddl_uint a b == pure (Mkevercddl_uint0?._x0 a == Mkspect_evercddl_uint0?._x0 b)) = () let rel_nint_eq a b : squash (rel_nint a b == pure (Mknint0?._x0 a == Mkspect_nint0?._x0 b)) = () +#push-options "--query_stats --fuel 0 --ifuel 0 --z3rlimit_factor 4" +#restart-solver let rel_evercddl_int_eq a b : squash (rel_evercddl_int a b == (match a, b with | Mkevercddl_int0 a, Mkspect_evercddl_int0 b -> rel_evercddl_uint a b | Mkevercddl_int1 a, Mkspect_evercddl_int1 b -> rel_nint a b - | _ -> pure False)) = - () + | _ -> pure False)) = _ by (T.compute(); T.smt()) ghost fn rw_r (#a: slprop) (#b: slprop) (h: squash (a == b)) requires a ensures b { rewrite a as b } ghost fn rw_l (#a: slprop) (#b: slprop) (h: squash (a == b)) requires b ensures a { rewrite b as a } @@ -86,8 +88,8 @@ let rel_sig_structure_eq (a: sig_structure) (b: spect_sig_structure) : | Inl (sign_protected, (aad, payload)), Inl (vsign_protected, (vaad, vpayload)) -> rel_empty_or_serialized_map sign_protected vsign_protected ** (rel_bstr aad vaad ** rel_bstr payload vpayload) - | _ -> pure False)))) = - () + | _ -> pure False)))) + = _ by (T.compute(); T.smt()) inline_for_extraction noextract let signature1: either unit unit = Inr () @@ -249,7 +251,8 @@ let dummy_map_val () : label & values = let assert_norm' (p: prop) : Pure (squash p) (requires normalize p) (ensures fun _ -> True) = () -let rel_inl_map_eq (x: slice (label & values)) y = assert_norm' (rel_inl_map x y == +let rel_inl_map_eq (x: slice (label & values)) y += assert_norm' (rel_inl_map x y == (exists* l . (exists* s . pts_to x.s #x.p s ** Pulse.Lib.SeqMatch.seq_list_match s l (rel_pair rel_label rel_values) ** pure (false == false)) ** pure (y == map_of_list_pair @@ -293,6 +296,7 @@ let rel_map_sign1_phdrs_eq (alg: Int32.t) alg' s = (((((rel_evercddl_int alg' (specint_of_i32 alg) ** emp) ** emp) ** emp) ** (emp ** emp)) ** rel_inl_map s (CDDL.Spec.Map.empty _ _))) +#pop-options inline_for_extraction fn mk_phdrs (alg: Int32.t) (rest: A.larray (label & values) 0) @@ -433,7 +437,8 @@ ghost fn trade_exists (#t: Type0) (p: t->slprop) x fn _ { () }; } - +#push-options "--fuel 0 --ifuel 0 --z3rlimit_factor 10 --query_stats" +//the proof of pure sign1_spec takes a while---should profile it inline_for_extraction // Karamel's lifetime support is massively lacking fn sign1 privkey uhdr aad payload (outbuf: S.slice UInt8.t) #pprivkey (#vprivkey: erased (Seq.seq UInt8.t) { Seq.length vprivkey == 32 }) @@ -693,6 +698,7 @@ let int_eq_of_diff_zero (a b: int) : Lemma (requires a - b == 0) (ensures a == b let nat_eq_of_diff_zero (a b: nat) : Lemma (requires a - b == 0) (ensures a == b) = int_eq_of_diff_zero a b +#push-options "--fuel 0 --ifuel 1 --z3rlimit_factor 10 --query_stats" inline_for_extraction // Karamel's lifetime support is massively lacking fn verify1 pubkey aad msg #ppubkey (#vpubkey: erased (Seq.seq UInt8.t) { Seq.length vpubkey == 32 }) @@ -784,3 +790,5 @@ fn verify1_simple pubkey msg S.to_array aadslice; res } +#pop-options +#pop-options \ No newline at end of file diff --git a/src/cose/generate-rust/CoseRust.fst.config.json b/src/cose/generate-rust/CoseRust.fst.config.json index caffee87e..30e01052c 100644 --- a/src/cose/generate-rust/CoseRust.fst.config.json +++ b/src/cose/generate-rust/CoseRust.fst.config.json @@ -2,7 +2,8 @@ "fstar_exe": "../../../fstar.sh", "options": [ "--load_cmxs", "evercddl_lib", - "--load_cmxs", "evercddl_plugin" + "--load_cmxs", "evercddl_plugin", + "--z3version", "4.15.3" ], "include_dirs": [ ".", diff --git a/src/cose/verifiedinterop/COSE.EverCrypt.fst b/src/cose/verifiedinterop/COSE.EverCrypt.fst index ed039c4dd..4abae43fa 100644 --- a/src/cose/verifiedinterop/COSE.EverCrypt.fst +++ b/src/cose/verifiedinterop/COSE.EverCrypt.fst @@ -5,6 +5,7 @@ open COSE.Format open Pulse.Lib.Trade open Pulse.Lib.Trade.Util open EverCrypt.Ed25519 +module T = FStar.Tactics.V2 module AP = Pulse.Lib.ArrayPtr module S = Pulse.Lib.Slice module V = Pulse.Lib.Vec @@ -22,11 +23,13 @@ let specnint_of_int (i: int { - pow2 64 <= i /\ i < 0 }) : GTot spect_nint = let specuint_of_int (i: int { 0 <= i /\ i < pow2 64 }) : GTot spect_evercddl_uint = Mkspect_evercddl_uint0 (UInt64.uint_to_t i) +#push-options "--fuel 0 --ifuel 0 --z3rlimit_factor 4" let specint_of_int (i: int { -pow2 64 <= i /\ i < pow2 64 }) : GTot spect_evercddl_int = if i >= 0 then Mkspect_evercddl_int0 (specuint_of_int i) else Mkspect_evercddl_int1 (specnint_of_int i) +#pop-options inline_for_extraction noextract let i32_to_u64_safe (i: Int32.t { Int32.v i >= 0 }) : j:UInt64.t { UInt64.v j == Int32.v i } = @@ -45,8 +48,7 @@ let rel_evercddl_int_eq a b : squash (rel_evercddl_int a b == (match a, b with | Mkevercddl_int0 a, Mkspect_evercddl_int0 b -> rel_evercddl_uint a b | Mkevercddl_int1 a, Mkspect_evercddl_int1 b -> rel_nint a b - | _ -> pure False)) = - () + | _ -> pure False)) = _ by (T.compute(); T.smt()) ghost fn rw_r (#a: slprop) (#b: slprop) (h: squash (a == b)) requires a ensures b { rewrite a as b } ghost fn rw_l (#a: slprop) (#b: slprop) (h: squash (a == b)) requires b ensures a { rewrite b as a } @@ -75,6 +77,7 @@ fn mk_int (i: Int32.t) } } +#push-options "--fuel 0 --ifuel 0 --query_stats --z3rlimit_factor 4" let rel_sig_structure_eq (a: sig_structure) (b: spect_sig_structure) : squash (rel_sig_structure a b == (match a, b with | Mksig_structure0 context body_protected rest, @@ -87,8 +90,8 @@ let rel_sig_structure_eq (a: sig_structure) (b: spect_sig_structure) : | Inl (sign_protected, (aad, payload)), Inl (vsign_protected, (vaad, vpayload)) -> rel_empty_or_serialized_map sign_protected vsign_protected ** (rel_bstr aad vaad ** rel_bstr payload vpayload) - | _ -> pure False)))) = - () + | _ -> pure False)))) = _ by (T.compute(); T.smt()) +#pop-options inline_for_extraction noextract let signature1: either unit unit = Inr () @@ -149,10 +152,12 @@ fn mk_sig_structure phdr aad payload let ser_to #t #st (s: CDDL.Spec.Base.spec t st true) (x: st) y = s.serializable x /\ Seq.equal y (CBOR.Spec.API.Format.cbor_det_serialize (s.serializer x)) +#push-options "--fuel 0 --ifuel 0 --z3rlimit_factor 4" let ser_to_inj #t #st s x y y' : Lemma (requires ser_to #t #st s x y /\ ser_to s x y') (ensures y == y') [SMTPat (ser_to s x y); SMTPat (ser_to s x y')] = () +#pop-options let to_be_signed_spec (phdr: spect_empty_or_serialized_map) @@ -166,7 +171,7 @@ let sz_to_u32_safe (i: SizeT.t { SizeT.v i < pow2 32 }) : j:UInt32.t { UInt32.v Math.Lemmas.small_mod (SizeT.v i) (pow2 32); SizeT.sizet_to_uint32 i -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 32 --fuel 0 --ifuel 0" fn create_sig privkey phdr aad payload (sigbuf: AP.ptr UInt8.t) (#vphdr: erased _) (#vaad: erased _) (#vpayload: erased _) (#pprivkey: erased _) (#vprivkey: erased (Seq.seq UInt8.t) { Seq.length vprivkey == 32 }) @@ -431,6 +436,8 @@ ghost fn trade_exists (#t: Type0) (p: t->slprop) x { () }; } +#push-options "--fuel 0 --ifuel 0 --z3rlimit_factor 10 --query_stats" +//the proof of pure sign1_spec takes a while---should profile it fn sign1 privkey uhdr aad payload (outbuf: S.slice UInt8.t) #pprivkey (#vprivkey: erased (Seq.seq UInt8.t) { Seq.length vprivkey == 32 }) (#vuhdr: erased _) (#vaad: erased _) (#vpayload: erased _) @@ -564,6 +571,7 @@ fn verify_sig pubkey phdr aad payload (sigbuf: AP.ptr UInt8.t) #pop-options +#push-options "--fuel 0 --ifuel 0 --z3rlimit_factor 20 --query_stats --z3cliopt 'smt.qi.eager_threshold=100'" let rel_sign1_tagged_eq (a: cose_sign1_tagged) (b: spect_cose_sign1_tagged) = assert_norm' (rel_cose_sign1_tagged a b == ((COSE.Format.rel_empty_or_serialized_map a._x0.protected b._x0.protected ** @@ -694,7 +702,8 @@ let nat_eq_of_diff_zero (a b: nat) : Lemma (requires a - b == 0) (ensures a == b int_eq_of_diff_zero a b #pop-options - +#pop-options +#push-options "--z3rlimit_factor 50 --fuel 0 --ifuel 1" fn verify1 pubkey aad msg #ppubkey (#vpubkey: erased (Seq.seq UInt8.t) { Seq.length vpubkey == 32 }) (#vaad: erased _) #pmsg (#vmsg: erased _) @@ -785,3 +794,5 @@ fn verify1_simple pubkey msg S.to_array aadslice; res } +#pop-options +#pop-options diff --git a/src/cose/verifiedinterop/Cose.fst.config.json b/src/cose/verifiedinterop/Cose.fst.config.json index 7152870b9..f47f15989 100644 --- a/src/cose/verifiedinterop/Cose.fst.config.json +++ b/src/cose/verifiedinterop/Cose.fst.config.json @@ -2,7 +2,8 @@ "fstar_exe": "../../../fstar.sh", "options": [ "--load_cmxs", "evercddl_lib", - "--load_cmxs", "evercddl_plugin" + "--load_cmxs", "evercddl_plugin", + "--z3version", "4.15.3" ], "include_dirs": [ "./_output", From ea8104cd4c6d17236d3ed93eed3576dabf2edb22 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Tue, 18 Nov 2025 01:02:03 +0000 Subject: [PATCH 08/33] Revert "Update hashes" This reverts commit f71a6a03348e823b115fa92bd22e0f78f9ecdb08. --- opt/hashes.Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index 35ab1d12b..9a2559686 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 1cff8d796deed8834926389a986d015498780041 +FStar_hash := 6cd60f09e1c6cc895b2ea82fc6a91a6af0fcdcb6 karamel_hash := fb36fecb552c9fb202beb38a6c5a732c3f2cd49f -pulse_hash := f51670f4c0117c8614e10c421025d77e1e44940e +pulse_hash := 87cb117a6a0eed9ac1c27dbe6ea9572e834284d3 From 3642275688f2a11284852a8a752149829a359f49 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Tue, 18 Nov 2025 18:38:48 +0000 Subject: [PATCH 09/33] use the right Z3 version in VSCode --- deps.Makefile | 7 ++++--- fstar.sh | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/deps.Makefile b/deps.Makefile index b31c15f23..ff6c5d95c 100644 --- a/deps.Makefile +++ b/deps.Makefile @@ -13,7 +13,7 @@ export EVERPARSE_OPT_PATH := $(shell cygpath -m $(EVERPARSE_OPT_PATH)) NO_PULSE := 1 endif -Z3_VERSION := 4.13.3 +EVERPARSE_Z3_VERSION ?= 4.15.3 ifeq (1,$(EVERPARSE_USE_MY_DEPS)) export EVERPARSE_USE_OPAMROOT:=1 @@ -51,7 +51,7 @@ NEED_FSTAR := ifneq (1,$(EVERPARSE_USE_FSTAR_EXE)) export FSTAR_EXE := $(EVERPARSE_OPT_PATH)/FStar/out/bin/fstar.exe NEED_FSTAR := $(EVERPARSE_OPT_PATH)/FStar.done -z3_exe := $(shell $(FSTAR_EXE) --locate_z3 \$(Z3_VERSION) 2>/dev/null) +z3_exe := $(shell $(FSTAR_EXE) --locate_z3 \$(EVERPARSE_Z3_VERSION) 2>/dev/null) ifneq (0,$(.SHELLSTATUS)) z3_exe := endif @@ -74,7 +74,7 @@ endif NEED_Z3 := ifeq (,$(z3_exe)) -z3_exe := $(shell which z3-$(Z3_VERSION)) +z3_exe := $(shell which z3-$(EVERPARSE_Z3_VERSION)) ifneq (0,$(.SHELLSTATUS)) z3_exe := endif @@ -170,6 +170,7 @@ ifeq ($(OS),Windows_NT) else @echo export EVERPARSE_HOME=$(CURDIR) endif + @echo export EVERPARSE_Z3_VERSION=$(EVERPARSE_Z3_VERSION) @echo export PATH=\"$(z3_dir):'$$PATH'\" .PHONY: env diff --git a/fstar.sh b/fstar.sh index 5dee9d4d6..1950a6ef2 100755 --- a/fstar.sh +++ b/fstar.sh @@ -3,4 +3,4 @@ set -e unset CDPATH EVERPARSE_HOME="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source "$EVERPARSE_HOME"/env.sh -exec "$FSTAR_EXE" --include "$KRML_HOME/krmllib" --include "$KRML_HOME/krmllib/obj" --include "$PULSE_HOME/lib/pulse" "$@" +exec "$FSTAR_EXE" --z3version $EVERPARSE_Z3_VERSION --include "$KRML_HOME/krmllib" --include "$KRML_HOME/krmllib/obj" --include "$PULSE_HOME/lib/pulse" "$@" From a2ad34be566a0a9dce5904415d86a6389033cd6e Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 20 Nov 2025 00:21:13 +0000 Subject: [PATCH 10/33] partial F*, Karamel, Pulse upgrade --- opt/hashes.Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index b3b02e1f3..011db6f7e 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 1e97045d6cf714bc45a00f54fcedccdfb08a31f5 -karamel_hash := fb36fecb552c9fb202beb38a6c5a732c3f2cd49f -pulse_hash := 47b4e2103e3ce09ab7e1cb50409fa67d73bb947a +FStar_hash := 3e3ce160b5a61c6eb036137068e64c46af38e0fd +karamel_hash := 8e7262955105599e91f3a99c9ab3d3387f7046f2 +pulse_hash := b6fe83f041203c407e29a8400bb3f801d69d1f8d From c4fbe393a7ccbdf3dff482c50dd7bb84837dafab Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 19 Nov 2025 23:01:30 +0000 Subject: [PATCH 11/33] specify some missing universes --- src/cbor/pulse/CBOR.Pulse.API.Base.fst | 2 +- src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst | 4 ++-- src/cddl/pulse/CDDL.Pulse.ArrayGroup.fst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cbor/pulse/CBOR.Pulse.API.Base.fst b/src/cbor/pulse/CBOR.Pulse.API.Base.fst index da7585559..1483fed08 100644 --- a/src/cbor/pulse/CBOR.Pulse.API.Base.fst +++ b/src/cbor/pulse/CBOR.Pulse.API.Base.fst @@ -872,7 +872,7 @@ let mk_array_from_array_t inline_for_extraction noextract [@@noextract_to "krml"] fn mk_array_from_array' - (#t: Type) + (#t: Type0) (#vmatch: perm -> t -> cbor -> slprop) (mk_array_from_array: mk_array_from_array_t vmatch) (a: A.array t) diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst index 7163f9e11..06dc046cf 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst @@ -1169,7 +1169,7 @@ fn cbor_det_array_iterator_length (_: unit) : array_iterator_length_t u#0 #_ cbo } inline_for_extraction noextract [@@noextract_to "krml"] -fn cbor_det_array_iterator_next (_: unit) : array_iterator_next_t u#0 #_ #_ cbor_det_match cbor_det_array_iterator_match +fn cbor_det_array_iterator_next (_: unit) : array_iterator_next_t u#0 u#0 #_ #_ cbor_det_match cbor_det_array_iterator_match = (x: _) (#y: _) (#py: _) @@ -1554,7 +1554,7 @@ fn cbor_det_map_iterator_is_empty (_: unit) : map_iterator_is_empty_t u#0 #_ cbo } inline_for_extraction noextract [@@noextract_to "krml"] -fn cbor_det_map_iterator_next (_: unit) : map_iterator_next_t u#0 #_ #_ cbor_det_map_entry_match cbor_det_map_iterator_match +fn cbor_det_map_iterator_next (_: unit) : map_iterator_next_t u#0 u#0 #_ #_ cbor_det_map_entry_match cbor_det_map_iterator_match = (x: _) (#y: _) (#py: _) diff --git a/src/cddl/pulse/CDDL.Pulse.ArrayGroup.fst b/src/cddl/pulse/CDDL.Pulse.ArrayGroup.fst index cead01fcb..e9048b0ab 100644 --- a/src/cddl/pulse/CDDL.Pulse.ArrayGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.ArrayGroup.fst @@ -11,7 +11,7 @@ module R = Pulse.Lib.Reference inline_for_extraction noextract [@@noextract_to "krml"] let impl_array_group - (#cbor_array_iterator_t: Type) + (#cbor_array_iterator_t: Type0) (cbor_array_iterator_match: perm -> cbor_array_iterator_t -> list cbor -> slprop) (#b: Ghost.erased (option cbor)) (g: array_group b) From f174fa296f52e37b2f253c6aa10733544e25a7d9 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 19 Nov 2025 23:13:25 +0000 Subject: [PATCH 12/33] split continuation boolean pure condition in loop invariants --- .../pulse/raw/CBOR.Pulse.API.Det.Common.fst | 12 ++-- .../pulse/raw/CBOR.Pulse.Raw.Compare.Base.fst | 3 +- .../raw/CBOR.Pulse.Raw.Compare.Iterator.fst | 3 +- src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst | 12 ++-- src/cbor/pulse/raw/CBOR.Pulse.Raw.Insert.fst | 3 +- .../CBOR.Pulse.Raw.EverParse.UTF8.fst | 3 +- .../everparse/CBOR.Pulse.Raw.Format.Parse.fst | 3 +- src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst | 6 +- .../pulse/CDDL.Pulse.Serialize.ArrayGroup.fst | 6 +- .../pulse/CDDL.Pulse.Serialize.MapGroup.fst | 3 +- .../pulse/LowParse.Pulse.Recursive.fst | 18 +++--- src/lowparse/pulse/LowParse.Pulse.VCList.fst | 58 +++++++++++++------ 12 files changed, 88 insertions(+), 42 deletions(-) diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst index 06dc046cf..af55526d1 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst @@ -1760,6 +1760,7 @@ let cbor_det_map_get_invariant_false_elim_precond ghost fn cbor_det_map_get_invariant_false_elim + (#gb: bool) (px: perm) (x: cbor_det_t) (vx: Spec.cbor) @@ -1769,12 +1770,14 @@ fn cbor_det_map_get_invariant_false_elim (i: cbor_det_map_iterator_t) (res: option cbor_det_t) requires - cbor_det_map_get_invariant false px x vx vk m p' i res ** + cbor_det_map_get_invariant gb px x vx vk m p' i res ** + pure (gb == false) ** pure (cbor_det_map_get_invariant_false_elim_precond vx m) ensures map_get_post cbor_det_match x px vx vk res ** pure (Spec.CMap? (Spec.unpack vx) /\ (Some? (Spec.cbor_map_get (Spec.CMap?.c (Spec.unpack vx)) vk) == Some? res)) { + rewrite each gb as false; match res { None -> { unfold (cbor_det_map_get_invariant false px x vx vk m p' i None); @@ -1817,13 +1820,14 @@ fn cbor_det_map_get (_: unit) fold (cbor_det_map_get_invariant cont px x vx vk m p' i None); while ( !pcont - ) invariant cont . exists* i res . + ) invariant cont . exists* i res cont' . pts_to pi i ** pts_to pcont cont ** pts_to pres res ** cbor_det_match pk k vk ** - cbor_det_map_get_invariant cont px x vx vk m p' i res ** - pure (cont ==> None? res) + cbor_det_map_get_invariant cont' px x vx vk m p' i res ** + pure (cont' == true ==> None? res) ** + pure (cont == cont') { with gb gi gres . assert (cbor_det_map_get_invariant gb px x vx vk m p' gi gres); unfold (cbor_det_map_get_invariant gb px x vx vk m p' gi None); diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Base.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Base.fst index ab0a5c164..2bb5a0bf6 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Base.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Base.fst @@ -162,7 +162,8 @@ fn impl_lex_compare SZ.v i1 <= SZ.v n1 /\ SZ.v i2 <= SZ.v n2 /\ same_sign (lex_compare compare v1 v2) (if res = 0s then lex_compare' compare v1 v2 (SZ.v i1) (SZ.v i2) else I16.v res) /\ - (res == 0s ==> (SZ.lt i1 n1 == SZ.lt i2 n2)) /\ + (res == 0s ==> (SZ.lt i1 n1 == SZ.lt i2 n2)) + ) ** pure ( cont == (res = 0s && SZ.lt i1 n1) ) ) { diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Iterator.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Iterator.fst index 02b3a7f35..044ddc7e2 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Iterator.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.Iterator.fst @@ -75,7 +75,8 @@ fn lex_compare_iterator pts_to pfin1 fin1 ** pure ( same_sign (lex_compare compare v1 v2) (if res = 0s then lex_compare compare l1 l2 else I16.v res) /\ - (res == 0s ==> (Nil? l1 == Nil? l2 /\ fin1 == Nil? l1)) /\ + (res == 0s ==> (Nil? l1 == Nil? l2 /\ fin1 == Nil? l1)) + ) ** pure ( cont == (res = 0s && Cons? l1) ) ) { diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst index c2f212a09..a264ecba8 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst @@ -238,7 +238,8 @@ ensures SM.seq_seq_match freeable_match' s s' j (SZ.v len) ** pure ( j == SZ.v i /\ - SZ.v i <= SZ.v len /\ + SZ.v i <= SZ.v len + ) ** pure ( b == (SZ.v i < SZ.v len) ) ) { @@ -272,7 +273,8 @@ ensures SM.seq_seq_match freeable_match_map_entry s s' j (SZ.v len) ** pure ( j == SZ.v i /\ - SZ.v i <= SZ.v len /\ + SZ.v i <= SZ.v len + ) ** pure ( b == (SZ.v i < SZ.v len) ) ) { @@ -431,8 +433,9 @@ ensures pure ( j == SZ.v i /\ j <= SZ.v len /\ - b == (j < SZ.v len) /\ Seq.length st == SZ.v len + ) ** pure ( + b == (j < SZ.v len) ) ) { S.pts_to_len ar; @@ -621,8 +624,9 @@ ensures pure ( j == SZ.v i /\ j <= SZ.v len /\ - b == (j < SZ.v len) /\ Seq.length st == SZ.v len + ) ** pure ( + b == (j < SZ.v len) ) ) { S.pts_to_len ar; diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Insert.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Insert.fst index 9dac54a3f..f579827e5 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Insert.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Insert.fst @@ -246,7 +246,8 @@ ensures exists* v . R.pts_to poff off ** R.pts_to pres res ** pure ( - cbor_raw_map_insert_inv m off2 key off3 value v l1 l2 off res /\ + cbor_raw_map_insert_inv m off2 key off3 value v l1 l2 off res + ) ** pure ( b == (CInProgress? res && (SZ.v off < SZ.v off2)) ) ) { diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.UTF8.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.UTF8.fst index 1ce0241d6..676babd96 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.UTF8.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.UTF8.fst @@ -130,7 +130,8 @@ ensures pts_to pi i ** pure ( SZ.v i <= Seq.length v /\ - correct v == (res && correct (Seq.slice v (SZ.v i) (Seq.length v))) /\ + correct v == (res && correct (Seq.slice v (SZ.v i) (Seq.length v))) + ) ** pure ( cont == (res && SZ.v i < Seq.length v) ) { diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst index 227a6a5c9..e786dc12c 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Parse.fst @@ -499,7 +499,8 @@ fn cbor_raw_sorted (sq: squash SZ.fits_u64) : LowParse.Pulse.Recursive.impl_pred (pts_to_serialized (LowParse.Spec.VCList.serialize_nlist (SZ.v n) (serializer_of_tot_serializer (LowParse.Spec.Recursive.serialize_recursive serialize_raw_data_item_param))) a #pm va) ** pure ( vn == U64.v vpairs + U64.v vpairs /\ - List.Tot.sorted (map_entry_order deterministically_encoded_cbor_map_key_order _) l0 == (vres && sorted2 deterministically_encoded_cbor_map_key_order (vkey :: vvalue :: fst vtail)) /\ + List.Tot.sorted (map_entry_order deterministically_encoded_cbor_map_key_order _) l0 == (vres && sorted2 deterministically_encoded_cbor_map_key_order (vkey :: vvalue :: fst vtail)) + ) ** pure ( b == (vres && Cons? (fst vtail)) ) { diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst index e3f259402..45678877c 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst @@ -976,8 +976,9 @@ fn cddl_map_iterator_is_empty (cbor_map_iterator_match i.pm i.cddl_map_iterator_contents li) ** pts_to pres res ** pure ( - b == (res && Cons? lj) /\ Nil? (parse_table_entries i.sp1.parser i.tex i.ps2 li) == (res && Nil? (parse_table_entries i.sp1.parser i.tex i.ps2 lj)) + ) ** pure ( + b == (res && Cons? lj) ) ) { let elt = map_next pj; @@ -1174,9 +1175,10 @@ fn cddl_map_iterator_next (vmatch2 pmhd hd vhd ** cbor_map_iterator_match gi.pm j lj) (rel_map_iterator vmatch vmatch2 cbor_map_iterator_match impl_elt1 impl_elt2 spec1 spec2 gi l) ** pure ( - b == not (Ghost.reveal i.t1 (fst vhd) && not (Ghost.reveal i.tex (vhd)) && Ghost.reveal i.t2 (snd vhd)) /\ List.Tot.no_repeats_p (List.Tot.map fst (vhd :: lj)) /\ parse_table_entries i.sp1.parser i.tex i.ps2 li == parse_table_entries i.sp1.parser i.tex i.ps2 (vhd :: lj) + ) ** pure ( + b == not (Ghost.reveal i.t1 (fst vhd) && not (Ghost.reveal i.tex (vhd)) && Ghost.reveal i.t2 (snd vhd)) ) { Trade.elim_hyp_l _ _ _; diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst index 5854e81da..b5d338a7e 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst @@ -709,7 +709,8 @@ fn impl_serialize_array_group_zero_or_more_slice Ghost.reveal v == List.Tot.append l1 l2 /\ ps.ag_serializable l1 /\ (impl_serialize_array_group_valid l ps v (Seq.length w) == (res && impl_serialize_array_group_valid (l `List.Tot.append` ps.ag_serializer l1) ps l2 (Seq.length w))) /\ - (res == true ==> impl_serialize_array_group_post count size l ps l1 w true) /\ + (res == true ==> impl_serialize_array_group_post count size l ps l1 w true) + ) ** pure ( b == (res && (SZ.v i < Seq.length s)) ) ) { @@ -843,7 +844,8 @@ impl_serialize_array_group_zero_or_more_iterator (res == true ==> Ghost.reveal v == List.Tot.append l1 l2) /\ ps.ag_serializable l1 /\ (impl_serialize_array_group_valid l ps v (Seq.length w) == (res && impl_serialize_array_group_valid (l `List.Tot.append` ps.ag_serializer l1) ps l2 (Seq.length w))) /\ - (res == true ==> impl_serialize_array_group_post count size l ps l1 w true) /\ + (res == true ==> impl_serialize_array_group_post count size l ps l1 w true) + ) ** pure ( b == (res && (Cons? l2)) ) ) { diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index 66652d9b8..bb3799e9a 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -1485,7 +1485,8 @@ fn impl_serialize_map_zero_or_more_iterator_gen (r (Iterator.mk_spec r1) (Iterator.mk_spec r2) c m2) (r (Iterator.mk_spec r1) (Iterator.mk_spec r2) c0 v0) ** pure ( - impl_serialize_map_zero_or_more_iterator_inv sp1 sp2 except v0 l res w m1 (Ghost.hide (Ghost.reveal m2)) m2' count size /\ + impl_serialize_map_zero_or_more_iterator_inv sp1 sp2 except v0 l res w m1 (Ghost.hide (Ghost.reveal m2)) m2' count size + ) ** pure ( b == (res && not (FStar.StrongExcludedMiddle.strong_excluded_middle (m2 == Map.empty _ _))) ) ) { diff --git a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst index 3c6198bd8..7bd9a35a5 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst @@ -151,13 +151,15 @@ fn validate_tot_nlist_recursive pts_to poffset offset ** pts_to input #pm v ** pure ( - SZ.v offset <= Seq.length v /\ - b == (res && (SZ.gt n 0sz)) /\ ( + SZ.v offset <= Seq.length v /\ ( let pr0 = parse_consume (L.tot_parse_nlist (SZ.v n0) (parse_recursive p)) (Seq.slice v (SZ.v offset0) (Seq.length v)) in let pr = parse_consume (L.tot_parse_nlist (SZ.v n) (parse_recursive p)) (Seq.slice v (SZ.v offset) (Seq.length v)) in Some? pr0 == (res && Some? pr) /\ (Some? pr0 ==> (SZ.v offset0 + Some?.v pr0 == SZ.v offset + Some?.v pr)) - )) + )) ** + pure ( + b == (res && (SZ.gt n 0sz)) + ) { let off = !poffset; let n = !pn; @@ -280,13 +282,14 @@ fn jump_tot_nlist_recursive pts_to poffset offset ** pts_to input #pm v ** pure ( - SZ.v offset <= Seq.length v /\ - b == (SZ.gt n 0sz) /\ ( + SZ.v offset <= Seq.length v /\ ( let pr0 = parse_consume (L.tot_parse_nlist (SZ.v n0) (parse_recursive p)) (Seq.slice v (SZ.v offset0) (Seq.length v)) in let pr = parse_consume (L.tot_parse_nlist (SZ.v n) (parse_recursive p)) (Seq.slice v (SZ.v offset) (Seq.length v)) in Some? pr0 /\ Some? pr /\ (SZ.v offset0 + Some?.v pr0 == SZ.v offset + Some?.v pr) - )) + )) ** pure ( + b == (SZ.gt n 0sz) + ) { with gn . assert (pts_to pn gn); with goffset . assert (pts_to poffset goffset); @@ -609,8 +612,9 @@ fn impl_nlist_forall_pred_recursive (pts_to_serialized (L.serialize_nlist (SZ.v n0) (serializer_of_tot_serializer (serialize_recursive s))) input #pm v ) ** pure ( - b == (res && (SZ.v n > 0)) /\ List.Tot.for_all pr.pred v == (res && List.Tot.for_all pr.pred vi) + ) ** pure ( + b == (res && (SZ.v n > 0)) )) { let n = !pn; with pi'. assert pts_to ppi pi'; diff --git a/src/lowparse/pulse/LowParse.Pulse.VCList.fst b/src/lowparse/pulse/LowParse.Pulse.VCList.fst index e331dd096..989008da3 100644 --- a/src/lowparse/pulse/LowParse.Pulse.VCList.fst +++ b/src/lowparse/pulse/LowParse.Pulse.VCList.fst @@ -50,6 +50,27 @@ let rec serialize_nlist_append (serialize (serialize_nlist n2 s) l2) end +let jump_nlist_inv + (#t: Type0) + (#k: Ghost.erased parser_kind) + (p: parser k t) + (n0: SZ.t) + (offset0: SZ.t) + (v: Ghost.erased bytes) + (b: bool) + (n: SZ.t) + (offset: SZ.t) +: Tot prop += + SZ.v offset0 <= Seq.length v /\ + SZ.v offset <= Seq.length v /\ ( + let pr0 = parse_consume (parse_nlist (SZ.v n0) p) (Seq.slice v (SZ.v offset0) (Seq.length v)) in + let pr = parse_consume (parse_nlist (SZ.v n) p) (Seq.slice v (SZ.v offset) (Seq.length v)) in + Some? pr0 /\ Some? pr /\ + SZ.v offset0 + Some?.v pr0 == SZ.v offset + Some?.v pr /\ + b == (SZ.v n > 0) + ) + inline_for_extraction fn jump_nlist (#t: Type0) @@ -71,13 +92,9 @@ fn jump_nlist (SZ.gt n 0sz) ) invariant b . exists* n offset . ( pts_to input #pm v ** R.pts_to pn n ** R.pts_to poffset offset ** pure ( - SZ.v offset <= Seq.length v /\ ( - let pr0 = parse_consume (parse_nlist (SZ.v n0) p) (Seq.slice v (SZ.v offset0) (Seq.length v)) in - let pr = parse_consume (parse_nlist (SZ.v n) p) (Seq.slice v (SZ.v offset) (Seq.length v)) in - Some? pr0 /\ Some? pr /\ - SZ.v offset0 + Some?.v pr0 == SZ.v offset + Some?.v pr /\ - b == (SZ.v n > 0) - ))) { + jump_nlist_inv #t #k p n0 offset0 v b n offset) ** + pure (b == (SZ.v n > 0)) + ) { let n = !pn; let offset = !poffset; parse_nlist_eq (SZ.v n) p (Seq.slice v (SZ.v offset) (Seq.length v)); @@ -522,11 +539,12 @@ ensures exists* v . pts_to_serialized (serialize_nlist n s) res #pm v ** trade (pts_to_serialized (serialize_nlist n s) res #pm v) (pts_to_serialized (serialize_nlist n0 s) input #pm v0) ** pure ( - SZ.v i <= SZ.v i0 /\ - (b == (SZ.v i < SZ.v i0)) /\ - n == n0 - SZ.v i /\ - List.Tot.index v0 (SZ.v i0) == List.Tot.index v (SZ.v i0 - SZ.v i) - )) { + nlist_nth_inv #t n0 v0 i0 i n v + ) ** + pure ( + b == (SZ.v i < SZ.v i0) + ) + ) { with 'res. assert R.pts_to pres 'res; let res = !pres; rewrite each 'res as res; @@ -614,7 +632,9 @@ ensures pts_to_serialized (serialize_nlist (SZ.v i) s) stl #pm tl) (pts_to_serialized (serialize_nlist (SZ.v n) s) a #pm v) ** pure ( - List.Tot.sorted order v == (res && List.Tot.sorted order (hd :: tl)) /\ + List.Tot.sorted order v == (res && List.Tot.sorted order (hd :: tl)) + ) ** + pure ( cont == (res && SZ.gt i 0sz) ) { @@ -821,7 +841,6 @@ fn compute_remaining_size_nlist_as_array (PM.seq_list_match c x (vmatch arr)) ** pure ( SZ.v i <= SZ.v n /\ - b == (res && (SZ.v i < SZ.v n)) /\ Seq.length c == SZ.v n /\ (res == false ==> SZ.v v < Seq.length (serialize (serialize_nlist (SZ.v n) s) x)) /\ (res == true ==> ( @@ -830,6 +849,8 @@ fn compute_remaining_size_nlist_as_array SZ.v v - Seq.length (serialize (serialize_nlist (SZ.v n) s) x) == SZ.v v1 - Seq.length (serialize (serialize_nlist (SZ.v n - SZ.v i) s) l2) )) /\ True + ) ** pure ( + b == (res && (SZ.v i < SZ.v n)) ) ) { let i = !pi; @@ -906,7 +927,6 @@ fn l2r_write_nlist_as_array (PM.seq_list_match c x (vmatch arr)) ** pure ( SZ.v i <= SZ.v n /\ - b == (SZ.v i < SZ.v n) /\ Seq.length c == SZ.v n /\ Seq.equal c2 (Seq.slice c (SZ.v i) (SZ.v n)) /\ SZ.v offset <= SZ.v res /\ @@ -917,6 +937,8 @@ fn l2r_write_nlist_as_array Seq.slice v1 (SZ.v offset) (SZ.v res) `Seq.equal` bare_serialize (serialize_nlist (SZ.v i) s) l1 /\ List.Tot.append l1 l2 == Ghost.reveal x /\ True + ) ** pure ( + b == (SZ.v i < SZ.v n) ) ) { let i = !pi; @@ -1083,7 +1105,6 @@ fn compute_remaining_size_nlist_as_slice (PM.seq_list_match c x (vmatch arr)) ** pure ( SZ.v i <= SZ.v n /\ - b == (res && (SZ.v i < SZ.v n)) /\ Seq.length c == SZ.v n /\ (res == false ==> SZ.v v < Seq.length (serialize (serialize_nlist (SZ.v n) s) x)) /\ (res == true ==> ( @@ -1092,6 +1113,8 @@ fn compute_remaining_size_nlist_as_slice SZ.v v - Seq.length (serialize (serialize_nlist (SZ.v n) s) x) == SZ.v v1 - Seq.length (serialize (serialize_nlist (SZ.v n - SZ.v i) s) l2) )) /\ True + ) ** pure ( + b == (res && (SZ.v i < SZ.v n)) ) ) { let i = !pi; @@ -1169,7 +1192,6 @@ fn l2r_write_nlist_as_slice (PM.seq_list_match c x (vmatch arr)) ** pure ( SZ.v i <= SZ.v n /\ - b == (SZ.v i < SZ.v n) /\ Seq.length c == SZ.v n /\ Seq.equal c2 (Seq.slice c (SZ.v i) (SZ.v n)) /\ SZ.v offset <= SZ.v res /\ @@ -1180,6 +1202,8 @@ fn l2r_write_nlist_as_slice Seq.slice v1 (SZ.v offset) (SZ.v res) `Seq.equal` bare_serialize (serialize_nlist (SZ.v i) s) l1 /\ List.Tot.append l1 l2 == Ghost.reveal x /\ True + ) ** pure ( + b == (SZ.v i < SZ.v n) ) ) { let i = !pi; From 744a9fad14b7f20d547f1ac9201e766c29ac0d40 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 19 Nov 2025 23:14:57 +0000 Subject: [PATCH 13/33] ADMIT: Cannot properly solve `exists* (x: unit)` --- src/cddl/pulse/CDDL.Pulse.Parse.Base.fst | 5 ++++- src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst b/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst index 297d719f1..2b04e942d 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst @@ -252,8 +252,9 @@ fn impl_copyful_unit (#p: _) (#v: _) { - let res = (); + let res: unit = (); fold (rel_unit res ()); + admit (); // HELP!!! res } @@ -279,6 +280,7 @@ fn impl_zero_copy_unit unfold (rel_unit res ()) }; Trade.intro_trade _ _ _ aux; + admit (); // HELP! res } @@ -321,6 +323,7 @@ fn impl_zero_copy_always_false let res : squash False = (); fold (rel_always_false _ _ res res); rewrite (vmatch p c v) as (Trade.trade (rel_always_false _ _ res res) (vmatch p c v)); // by contradiction + admit (); // HELP! res } diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst index 45678877c..7b3f3e9f3 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.MapGroup.fst @@ -187,6 +187,7 @@ fn impl_zero_copy_map_nop { rewrite (rel_unit () ()) as emp }; + admit (); // HELP! () } From d12f3243d3566f798cfbe4dda974b070786c0012 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 19 Nov 2025 23:16:20 +0000 Subject: [PATCH 14/33] ADMIT: Pulse OOM in impl_serialize_map_zero_or_more_iterator_gen --- src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index bb3799e9a..aba215872 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -1410,7 +1410,8 @@ let seq_slice_length_zero_left (Seq.length (Seq.slice s 0 len) == len) = () -#push-options "--z3rlimit 256 --fuel 2 --ifuel 2 --query_stats --print_implicits --split_queries always" +// #push-options "--z3rlimit 256 --fuel 2 --ifuel 2 --query_stats --print_implicits --split_queries always" +#push-options "--admit_smt_queries true" #restart-solver inline_for_extraction noextract [@@noextract_to "krml"] @@ -1450,6 +1451,8 @@ fn impl_serialize_map_zero_or_more_iterator_gen (out_size: _) (l: _) { + admit (); // Pulse OOM even without SMT +(* let sp = Ghost.hide (mg_zero_or_more_match_item sp1 sp2 except); let mut pc = c0; let pm1 = GR.alloc (Map.empty tkey (list tvalue)); @@ -1673,6 +1676,7 @@ fn impl_serialize_map_zero_or_more_iterator_gen GR.free pm2; Classical.move_requires (map_of_list_is_append_nil_r_elim m1) v0; !pres +*) } #pop-options From b9d339c3a72daf5929c996f690be05f2856cc42b Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 19 Nov 2025 23:23:34 +0000 Subject: [PATCH 15/33] WHY WHY WHY do I need to help Pulse with middle Trade.trans arguments? --- .../pulse/raw/CBOR.Pulse.API.Det.Common.fst | 21 +++++++++++-------- .../CBOR.Pulse.Raw.Format.Serialize.fst | 12 +++++------ .../pulse/CDDL.Pulse.Serialize.MapGroup.fst | 2 +- .../pulse/LowParse.Pulse.Combinators.fst | 4 ++-- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst index af55526d1..605cf0dd9 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst @@ -53,7 +53,7 @@ fn cbor_det_reset_perm (cbor_det_match p x1 x2) (Raw.cbor_match p x1 (SpecRaw.mk_det_raw_cbor x2)); let res = Raw.cbor_raw_reset_perm _ x1 _; - Trade.trans _ _ (cbor_det_match p x1 x2); + Trade.trans _ (Raw.cbor_match p x1 (SpecRaw.mk_det_raw_cbor x2)) (cbor_det_match p x1 x2); Trade.rewrite_with_trade (Raw.cbor_match 1.0R res (SpecRaw.mk_det_raw_cbor x2)) (cbor_det_match 1.0R res x2); @@ -1047,7 +1047,7 @@ fn cbor_det_get_string (_: unit) : get_string_t u#0 #_ cbor_det_match (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)); SpecRaw.mk_cbor_eq (SpecRaw.mk_det_raw_cbor v); let res = Raw.cbor_match_string_elim_payload x; - Trade.trans _ _ (cbor_det_match p x v); + Trade.trans _ (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)) (cbor_det_match p x v); // FIXME: WHY WHY WHY do I now need to help Pulse here? res } @@ -1075,7 +1075,7 @@ fn cbor_det_get_tagged_payload (_: unit) : get_tagged_payload_t u#0 #_ cbor_det_ (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)); SpecRaw.mk_cbor_eq (SpecRaw.mk_det_raw_cbor v); let res = Read.cbor_match_tagged_get_payload x; - Trade.trans _ _ (cbor_det_match p x v); + Trade.trans _ (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)) (cbor_det_match p x v); // FIXME: WHY WHY WHY do I now need to help Pulse here? with p' v' . assert (Raw.cbor_match p' res v'); SpecRaw.mk_det_raw_cbor_mk_cbor v'; Trade.rewrite_with_trade @@ -1134,7 +1134,7 @@ fn cbor_det_array_iterator_start (_: unit) : array_iterator_start_t u#0 u#0 #_ # (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)); let f64 : squash (SZ.fits_u64) = assume (SZ.fits_u64); let res = Read.cbor_array_iterator_init f64 x; - Trade.trans _ _ (cbor_det_match p x v); + Trade.trans _ (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)) (cbor_det_match p x v); // FIXME: WHY WHY WHY do I now need to help Pulse here? with p' l . assert (Read.cbor_array_iterator_match p' res l); list_map_mk_det_raw_cbor_mk_cbor l; Trade.rewrite_with_trade @@ -1180,7 +1180,7 @@ fn cbor_det_array_iterator_next (_: unit) : array_iterator_next_t u#0 u#0 #_ #_ (Read.cbor_array_iterator_match py y (List.Tot.map mk_det_raw_cbor z)); let f64 : squash (SZ.fits_u64) = assume (SZ.fits_u64); let res = Read.cbor_array_iterator_next f64 x; - Trade.trans _ _ (cbor_det_array_iterator_match py y z); + Trade.trans _ (Read.cbor_array_iterator_match py y (List.Tot.map mk_det_raw_cbor z)) (cbor_det_array_iterator_match py y z); // FIXME: WHY WHY WHY do I now need to help Pulse here? with y' z' . assert (Read.cbor_array_iterator_match py y' z'); Trade.rewrite_with_trade (Read.cbor_array_iterator_match py y' z') @@ -1217,7 +1217,8 @@ fn cbor_det_array_iterator_truncate (_: unit) : array_iterator_truncate_t u#0 #_ (cbor_det_array_iterator_match py x z) (Read.cbor_array_iterator_match py x (List.Tot.map mk_det_raw_cbor z)); let res = Read.cbor_array_iterator_truncate x len; - Trade.trans _ _ (cbor_det_array_iterator_match py x z); + Trade.trans _ (Read.cbor_array_iterator_match py x (List.Tot.Base.map mk_det_raw_cbor z) + ) (cbor_det_array_iterator_match py x z); // FIXME: WHY WHY WHY do I now need to help Pulse here? list_map_splitAt mk_det_raw_cbor z (U64.v len); Trade.rewrite_with_trade (Read.cbor_array_iterator_match 1.0R res (fst (List.Tot.splitAt (U64.v len) (List.Tot.map mk_det_raw_cbor z)))) @@ -1282,7 +1283,7 @@ fn cbor_det_get_array_item (_: unit) : get_array_item_t u#0 #_ cbor_det_match (cbor_det_match p x v) (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)); let res = Read.cbor_array_item (assume (SZ.fits_u64)) x i; - Trade.trans _ _ (cbor_det_match p x v); + Trade.trans _ (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor v)) (cbor_det_match p x v); // FIXME: WHY WHY WHY do I now need to help Pulse here? with p' v' . assert (Raw.cbor_match p' res v'); list_map_mk_cbor_mk_det_raw_cbor l; assert (pure (List.Tot.index (List.Tot.map SpecRaw.mk_cbor (List.Tot.map mk_det_raw_cbor l)) (U64.v i) == List.Tot.index l (U64.v i))); @@ -1518,7 +1519,7 @@ fn cbor_det_map_iterator_start' (_: unit) : det_map_iterator_start_t SpecRaw.mk_cbor_eq (SpecRaw.mk_det_raw_cbor y); let f64 : squash (SZ.fits_u64) = assume (SZ.fits_u64); let res = Read.cbor_map_iterator_init f64 x; - Trade.trans _ _ (cbor_det_match p x y); + Trade.trans _ (Raw.cbor_match p x (SpecRaw.mk_det_raw_cbor y)) (cbor_det_match p x y); // FIXME: WHY WHY WHY do I now need to help Pulse here? with p' l . assert (Read.cbor_map_iterator_match p' res l); list_map_mk_det_raw_cbor_map_entry_mk_cbor_map_entry l; mk_cbor_match_map_elem_elim_no_repeats_p l; @@ -1565,7 +1566,9 @@ fn cbor_det_map_iterator_next (_: unit) : map_iterator_next_t u#0 u#0 #_ #_ cbor (Read.cbor_map_iterator_match py y (List.Tot.map SpecRaw.mk_det_raw_cbor_map_entry z)); let f64 : squash (SZ.fits_u64) = assume (SZ.fits_u64); let res = Read.cbor_map_iterator_next f64 x; - Trade.trans _ _ (cbor_det_map_iterator_match py y z); + Trade.trans _ (Read.cbor_map_iterator_match py + y + (List.Tot.Base.map SpecRaw.mk_det_raw_cbor_map_entry z)) (cbor_det_map_iterator_match py y z); // FIXME: WHY WHY WHY do I now need to help Pulse here? with y' z' . assert (Read.cbor_map_iterator_match py y' z'); Trade.rewrite_with_trade (Read.cbor_map_iterator_match py y' z') diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst index c74b26982..6785e0f40 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst @@ -762,7 +762,7 @@ ensures Trade.rewrite_with_trade (cbor_match_with_perm xl xh0) (cbor_match xl.p xl.v xh0); - Trade.trans (cbor_match _ _ _) _ _; + Trade.trans (cbor_match _ _ _) (cbor_match_with_perm _ _) _; // FIXME: WHY WHY WHY do I need to help Pulse here? cbor_match_cases _; let CBOR_Case_Array a = xl.v; cbor_match_eq_array xl.p a xh0; @@ -947,7 +947,7 @@ fn ser_payload_array_not_array_lens Trade.rewrite_with_trade (cbor_match_with_perm xl xh0) (cbor_match xl.p xl.v xh0); - Trade.trans (cbor_match xl.p xl.v xh0) _ _; + Trade.trans (cbor_match xl.p xl.v xh0) (cbor_match_with_perm xl xh0) _; // FIXME: WHY WHY WHY do I need to help Pulse there? cbor_match_cases xl.v; let CBOR_Case_Serialized_Array xs = xl.v; Trade.rewrite_with_trade @@ -1220,7 +1220,7 @@ ensures Trade.rewrite_with_trade (cbor_match_with_perm xl xh0) (cbor_match xl.p xl.v xh0); - Trade.trans (cbor_match _ _ _) _ _; + Trade.trans (cbor_match _ _ _) (cbor_match_with_perm xl xh0) _; // FIXME: WHY WHY WHY do I need to help Pulse here? cbor_match_cases _; let CBOR_Case_Map a = xl.v; cbor_match_eq_map0 xl.p a xh0; @@ -1403,7 +1403,7 @@ fn ser_payload_map_not_map_lens Trade.rewrite_with_trade (cbor_match_with_perm xl xh0) (cbor_match xl.p xl.v xh0); - Trade.trans (cbor_match xl.p xl.v xh0) _ _; + Trade.trans (cbor_match xl.p xl.v xh0) (cbor_match_with_perm xl xh0) _; // FIXME: WHY WHY WHY do I need to help Pulse here? cbor_match_cases xl.v; let CBOR_Case_Serialized_Map xs = xl.v; Trade.rewrite_with_trade @@ -1550,7 +1550,7 @@ fn ser_payload_tagged_tagged_lens Trade.rewrite_with_trade (cbor_match_with_perm xl xh0) (cbor_match xl.p xl.v xh0); - Trade.trans (cbor_match xl.p xl.v xh0) _ _; + Trade.trans (cbor_match xl.p xl.v xh0) (cbor_match_with_perm xl xh0) _; // FIXME: WHY WHY WHY do I need to help Pulse here? cbor_match_cases xl.v; let CBOR_Case_Tagged tg = xl.v; cbor_match_eq_tagged xl.p tg xh0; @@ -1626,7 +1626,7 @@ fn ser_payload_tagged_not_tagged_lens Trade.rewrite_with_trade (cbor_match_with_perm xl xh0) (cbor_match xl.p xl.v xh0); - Trade.trans (cbor_match xl.p xl.v xh0) _ _; + Trade.trans (cbor_match xl.p xl.v xh0) (cbor_match_with_perm xl xh0) _; // FIXME: WHY WHY WHY do I need to help Pulse here? cbor_match_cases xl.v; let CBOR_Case_Serialized_Tagged ser = xl.v; Trade.rewrite_with_trade diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index aba215872..c0583b733 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -1872,7 +1872,7 @@ fn map_slice_iterator_next fold (rel_slice_of_table #_ #(dfst spec1) #_ #(dfst spec2) i.key_eq (dsnd spec1) (dsnd spec2) i.base m); }; Trade.trans_hyp_r _ _ _ _; - Trade.trans _ _ (rel_map_slice_iterator impl_elt1 impl_elt2 spec1 spec2 gi m); + Trade.trans _ (rel_slice_of_table #_ #(dfst spec1) #_ #(dfst spec2) i.key_eq (dsnd spec1) (dsnd spec2) i.base m) (rel_map_slice_iterator impl_elt1 impl_elt2 spec1 spec2 gi m); Trade.rewrite_with_trade (r res gv) (dsnd spec1 (fst res) (fst gv) ** dsnd spec2 (snd res) (snd gv)); diff --git a/src/lowparse/pulse/LowParse.Pulse.Combinators.fst b/src/lowparse/pulse/LowParse.Pulse.Combinators.fst index 8c351b4cc..698144b7a 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Combinators.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Combinators.fst @@ -2189,7 +2189,7 @@ fn zero_copy_parse_nondep_then Trade.rewrite_with_trade (vmatch1 res1 _ ** vmatch2 res2 _) (vmatch_pair vmatch1 vmatch2 (res1, res2) v); - Trade.trans (vmatch_pair vmatch1 vmatch2 (res1, res2) v) _ _; + Trade.trans (vmatch_pair vmatch1 vmatch2 (res1, res2) v) (vmatch1 res1 (fst v) ** vmatch2 res2 (snd v)) _; (res1, res2) } @@ -2334,7 +2334,7 @@ fn zero_copy_parse_synth Trade.rewrite_with_trade (vmatch res (f1 v)) (vmatch_synth vmatch f1 res v); - Trade.trans (vmatch_synth vmatch f1 res v) _ _; + Trade.trans (vmatch_synth vmatch f1 res v) (vmatch res (f1 v)) _; res } From 3b97d8f2c76018a61a8fd974faa701f5b9128c80 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 19 Nov 2025 23:29:55 +0000 Subject: [PATCH 16/33] various rewrites and other Pulse unification issues --- src/cbor/pulse/CBOR.Pulse.API.Base.fst | 5 + .../pulse/CBOR.Pulse.API.Det.Rust.Macros.fst | 28 ++- src/cbor/pulse/raw/CBOR.Pulse.API.Det.C.fst | 4 + .../pulse/raw/CBOR.Pulse.API.Det.Common.fst | 50 ++++- .../pulse/raw/CBOR.Pulse.API.Det.Rust.fst | 11 +- src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.fst | 9 + src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst | 102 ++++++++-- .../pulse/raw/CBOR.Pulse.Raw.Iterator.fst | 157 +++++++++++++-- .../pulse/raw/CBOR.Pulse.Raw.Match.Perm.fst | 52 ++++- src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.fst | 77 ++++++-- src/cbor/pulse/raw/CBOR.Pulse.Raw.Read.fst | 81 +++++++- .../CBOR.Pulse.Raw.EverParse.Format.fst | 181 +++++++++++++++++- .../CBOR.Pulse.Raw.EverParse.Iterator.fst | 4 +- ...OR.Pulse.Raw.EverParse.Serialized.Base.fst | 37 +++- .../CBOR.Pulse.Raw.Format.Serialize.fst | 15 +- .../CBOR.Pulse.Raw.Format.Serialized.fst | 4 +- src/cddl/pulse/CDDL.Pulse.Parse.Base.fst | 5 +- src/cddl/pulse/CDDL.Pulse.Parse.Misc.fst | 2 + .../pulse/CDDL.Pulse.Serialize.MapGroup.fst | 8 +- src/lowparse/pulse/LowParse.Pulse.Base.fst | 13 +- .../pulse/LowParse.Pulse.Combinators.fst | 21 +- .../pulse/LowParse.Pulse.Recursive.fst | 16 +- src/lowparse/pulse/LowParse.Pulse.VCList.fst | 70 +++++-- 23 files changed, 846 insertions(+), 106 deletions(-) diff --git a/src/cbor/pulse/CBOR.Pulse.API.Base.fst b/src/cbor/pulse/CBOR.Pulse.API.Base.fst index 1483fed08..4d887677d 100644 --- a/src/cbor/pulse/CBOR.Pulse.API.Base.fst +++ b/src/cbor/pulse/CBOR.Pulse.API.Base.fst @@ -1154,8 +1154,10 @@ fn mk_map_gen let bres = mk_map_gen_by_ref a dest; if bres { let res = !dest; + with res' . rewrite mk_map_gen_post vmatch1 vmatch2 a va pv vv res' as mk_map_gen_post vmatch1 vmatch2 a va pv vv (Some res); Some res } else { + with res' . rewrite mk_map_gen_post vmatch1 vmatch2 a va pv vv res' as mk_map_gen_post vmatch1 vmatch2 a va pv vv None; None #t1 } } @@ -1411,6 +1413,7 @@ fn mk_map_from_ref PM.seq_list_match_length (vmatch2 pv) va vv; let _ = mk_map_gen a dest; let res = !dest; + with res' . rewrite (mk_map_gen_post vmatch1 vmatch2 a va pv vv res') as (mk_map_gen_post vmatch1 vmatch2 a va pv vv (Some res)); unfold (mk_map_gen_post vmatch1 vmatch2 a va pv vv (Some res)); res } @@ -1514,8 +1517,10 @@ fn map_get_as_option let bres = m x k dest; if bres { let res = !dest; + with res' . rewrite map_get_post vmatch x px vx vk res' as map_get_post vmatch x px vx vk (Some res); Some res } else { + with res' . rewrite map_get_post vmatch x px vx vk res' as map_get_post vmatch x px vx vk None; None #t } } diff --git a/src/cbor/pulse/CBOR.Pulse.API.Det.Rust.Macros.fst b/src/cbor/pulse/CBOR.Pulse.API.Det.Rust.Macros.fst index 6de631890..94ade1985 100644 --- a/src/cbor/pulse/CBOR.Pulse.API.Det.Rust.Macros.fst +++ b/src/cbor/pulse/CBOR.Pulse.API.Det.Rust.Macros.fst @@ -20,7 +20,13 @@ fn cbor_det_mk_int64' (v: _) { let mty = (if ty = cbor_major_type_uint64 then UInt64 else NegInt64); - cbor_det_mk_int64 mty v + let res = cbor_det_mk_int64 mty v; + with ty' . rewrite cbor_det_match 1.0R + res + (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CInt64 ty' v)) as cbor_det_match 1.0R + res + (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CInt64 ty v)); + res } inline_for_extraction @@ -32,6 +38,11 @@ fn cbor_det_mk_simple' { let Some res = cbor_det_mk_simple_value v; unfold (cbor_det_mk_simple_value_post v (Some res)); + with res' . rewrite cbor_det_match 1.0R + res + res' as cbor_det_match 1.0R + res + (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CSimple v)); res } @@ -49,6 +60,7 @@ fn cbor_det_mk_string0 let mty = (if ty = cbor_major_type_byte_string then ByteString else TextString); let res = cbor_det_mk_string mty s; let Some c = res; + with ty' res' . rewrite (cbor_det_mk_string_post ty' s p v res') as (cbor_det_mk_string_post ty s p v (Some c)); unfold (cbor_det_mk_string_post ty s p v (Some c)); c } @@ -230,7 +242,7 @@ fn cbor_det_array_iterator_start' with p' . assert (cbor_det_view_match p' v y); let Array a = v; Trade.rewrite_with_trade - (cbor_det_view_match p' v y) + (cbor_det_view_match p' _ y) (cbor_det_array_match p' a y); Trade.trans _ _ (cbor_det_match p x y); let res = cbor_det_array_iterator_start a; @@ -252,7 +264,7 @@ fn cbor_det_get_array_item' with p' . assert (cbor_det_view_match p' v y); let Array a = v; Trade.rewrite_with_trade - (cbor_det_view_match p' v y) + (cbor_det_view_match p' _ y) (cbor_det_array_match p' a y); Trade.trans _ _ (cbor_det_match p x y); let ores = cbor_det_get_array_item a i; @@ -295,7 +307,7 @@ fn cbor_det_map_iterator_start' with p' . assert (cbor_det_view_match p' v y); let Map a = v; Trade.rewrite_with_trade - (cbor_det_view_match p' v y) + (cbor_det_view_match p' _ y) (cbor_det_map_match p' a y); Trade.trans _ _ (cbor_det_match p x y); let res = cbor_det_map_iterator_start a; @@ -326,13 +338,15 @@ ensures unfold (safe_map_get_post m p' vx vk None); Trade.elim _ _; fold (Base.map_get_post_none cbor_det_match x px vx vk); - fold (Base.map_get_post cbor_det_match x px vx vk None) + fold (Base.map_get_post cbor_det_match x px vx vk None); + rewrite (Base.map_get_post cbor_det_match x px vx vk None) as (Base.map_get_post cbor_det_match x px vx vk res) } Some x' -> { unfold (safe_map_get_post m p' vx vk (Some x')); Trade.trans _ _ (cbor_det_match px x vx); fold (Base.map_get_post_some cbor_det_match x px vx vk x'); - fold (Base.map_get_post cbor_det_match x px vx vk (Some x')) + fold (Base.map_get_post cbor_det_match x px vx vk (Some x')); + rewrite (Base.map_get_post cbor_det_match x px vx vk (Some x')) as (Base.map_get_post cbor_det_match x px vx vk res); } } } @@ -353,7 +367,7 @@ fn cbor_det_map_get' with p' . assert (cbor_det_view_match p' x' vx); let Map m = x'; Trade.rewrite_with_trade - (cbor_det_view_match p' x' vx) + (cbor_det_view_match p' _ vx) (cbor_det_map_match p' m vx); Trade.trans _ _ (cbor_det_match px x vx); let res = cbor_det_map_get m k; diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.C.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.C.fst index 096db824b..407a1ef17 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.C.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.C.fst @@ -216,6 +216,8 @@ ensures unfold (mk_map_gen_post vmatch1 vmatch2 s va pv vv None); S.to_array s; fold (mk_map_from_array_safe_post vmatch1 vmatch2 a va pv vv vdest false); + rewrite (mk_map_from_array_safe_post vmatch1 vmatch2 a va pv vv vdest false) + as (mk_map_from_array_safe_post vmatch1 vmatch2 a va pv vv vdest bres); } Some vres -> { unfold (mk_map_gen_post vmatch1 vmatch2 s va pv vv (Some vres)); @@ -233,6 +235,8 @@ ensures Trade.trans_concl_l _ _ _ _; rewrite each vres as vdest; fold (mk_map_from_array_safe_post vmatch1 vmatch2 a va pv vv vdest true); + rewrite (mk_map_from_array_safe_post vmatch1 vmatch2 a va pv vv vdest true) + as (mk_map_from_array_safe_post vmatch1 vmatch2 a va pv vv vdest bres); } } } diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst index 605cf0dd9..fe2e35d43 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Common.fst @@ -180,6 +180,7 @@ fn cbor_det_parse_valid let res = Parse.cbor_parse input len; with v1' . assert (Raw.cbor_match 1.0R res v1'); Classical.forall_intro_2 (cbor_det_parse_aux v (SZ.v len) v1'); + rewrite Raw.cbor_match 1.0R res v1' as Raw.cbor_match 1.0R res (SpecRaw.mk_det_raw_cbor (SpecRaw.mk_cbor v1')); fold (cbor_det_match 1.0R res (SpecRaw.mk_cbor v1')); rewrite each Raw.cbor_match 1.0R res v1' @@ -430,6 +431,10 @@ fn cbor_det_mk_simple_value (_: unit) : mk_simple_t u#0 #_ cbor_det_match { let res = Raw.cbor_match_simple_intro v; SpecRaw.mk_cbor_eq (SpecRaw.mk_det_raw_cbor (Spec.pack (Spec.CSimple v))); + rewrite Raw.cbor_match 1.0R res (SpecRaw.Simple v) as Raw.cbor_match 1.0R + res + (SpecRaw.mk_det_raw_cbor (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CSimple + v))); fold (cbor_det_match 1.0R res (Spec.pack (Spec.CSimple v))); res } @@ -443,6 +448,10 @@ fn cbor_det_mk_int64 (_: unit) : mk_int64_t u#0 #_ cbor_det_match { let res = Raw.cbor_match_int_intro ty (SpecRaw.mk_raw_uint64 v); SpecRaw.mk_cbor_eq (SpecRaw.mk_det_raw_cbor (Spec.pack (Spec.CInt64 ty v))); + rewrite Raw.cbor_match 1.0R res (SpecRaw.Int64 ty (SpecRaw.mk_raw_uint64 v)) as Raw.cbor_match 1.0R + res + (SpecRaw.mk_det_raw_cbor (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CInt64 + ty v))); fold (cbor_det_match 1.0R res (Spec.pack (Spec.CInt64 ty v))); res } @@ -469,11 +478,16 @@ fn cbor_det_mk_string (_: unit) : mk_string_t u#0 #_ cbor_det_match (SpecRaw.mk_det_raw_cbor (Spec.pack (Spec.CString ty v))) (SpecRaw.String ty len64 v); assert (pure (SpecRaw.mk_det_raw_cbor (Spec.pack (Spec.CString ty v)) == SpecRaw.String ty len64 v)); + rewrite Raw.cbor_match 1.0R res r as Raw.cbor_match 1.0R + res + (SpecRaw.mk_det_raw_cbor (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CString + ty v))); fold (cbor_det_match 1.0R res (Spec.pack (Spec.CString ty v))); rewrite each Raw.cbor_match 1.0R res r as cbor_det_match 1.0R res (SpecRaw.mk_cbor r); + rewrite each (SpecRaw.mk_cbor r) as (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CString ty v)); res } @@ -505,11 +519,18 @@ fn cbor_det_mk_tagged (_: unit) : mk_tagged_t #_ cbor_det_match (SpecRaw.mk_det_raw_cbor (Spec.pack (Spec.CTagged tag v'))) (SpecRaw.Tagged tag64 w'); assert (pure (SpecRaw.mk_det_raw_cbor (Spec.pack (Spec.CTagged tag v')) == SpecRaw.Tagged tag64 w')); + rewrite Raw.cbor_match 1.0R res (SpecRaw.Tagged tag64 w') as + Raw.cbor_match 1.0R + res + (SpecRaw.mk_det_raw_cbor (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CTagged + tag v'))); fold (cbor_det_match 1.0R res (Spec.pack (Spec.CTagged tag v'))); rewrite each Raw.cbor_match 1.0R res r as cbor_det_match 1.0R res (SpecRaw.mk_cbor r); + rewrite each (SpecRaw.mk_cbor (SpecRaw.Tagged tag64 w')) as + (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CTagged tag v')); res } @@ -553,6 +574,9 @@ decreases v SM.seq_list_match_cons_intro_trade (Seq.head c) (mk_det_raw_cbor (List.Tot.hd v)) (Seq.tail c) (List.Tot.map mk_det_raw_cbor (List.Tot.tl v)) (Raw.cbor_match p); Trade.trans _ _ (SM.seq_list_match c v (cbor_det_match p)); rewrite each Seq.cons (Seq.head c) (Seq.tail c) as c; + rewrite each (mk_det_raw_cbor (List.Tot.Base.hd v) :: + List.Tot.Base.map mk_det_raw_cbor (List.Tot.Base.tl v)) + as List.Tot.Base.map mk_det_raw_cbor v; (); } } @@ -594,12 +618,19 @@ fn cbor_det_mk_array (_: unit) : mk_array_t #_ cbor_det_match with r. assert Raw.cbor_match 1.0R res r; Trade.trans_concl_r _ _ _ _; Spec.unpack_pack (Spec.CArray vv); + rewrite Raw.cbor_match 1.0R res r + as + Raw.cbor_match 1.0R + res + (SpecRaw.mk_det_raw_cbor (CBOR.Spec.API.Type.pack (CBOR.Spec.API.Type.CArray + vv))); fold (cbor_det_match 1.0R res (Spec.pack (Spec.CArray vv))); rewrite each Raw.cbor_match 1.0R res r as cbor_det_match 1.0R res v'; + rewrite each Ghost.reveal v' as (Spec.pack (Spec.CArray vv)); res } @@ -698,6 +729,11 @@ decreases v SM.seq_list_match_cons_intro_trade (Seq.head c) (SpecRaw.mk_det_raw_cbor_map_entry (List.Tot.hd v)) (Seq.tail c) (List.Tot.map SpecRaw.mk_det_raw_cbor_map_entry (List.Tot.tl v)) (Raw.cbor_match_map_entry p); Trade.trans _ _ (SM.seq_list_match c v (cbor_det_map_entry_match p)); rewrite each Seq.cons (Seq.head c) (Seq.tail c) as c; + rewrite each (SpecRaw.mk_det_raw_cbor_map_entry (List.Tot.Base.hd v) :: + List.Tot.Base.map SpecRaw.mk_det_raw_cbor_map_entry + (List.Tot.Base.tl v)) as ( + List.Tot.Base.map SpecRaw.mk_det_raw_cbor_map_entry + (v)); (); } } @@ -723,7 +759,8 @@ fn cbor_det_mk_map_entry Trade.rewrite_with_trade (Raw.cbor_match_map_entry 1.0R res (SpecRaw.mk_det_raw_cbor vk, SpecRaw.mk_det_raw_cbor vv)) (cbor_det_map_entry_match 1.0R res (Ghost.reveal vk, Ghost.reveal vv)); - Trade.trans (cbor_det_map_entry_match 1.0R res (Ghost.reveal vk, Ghost.reveal vv)) _ _; + CBOR.Pulse.Raw.Iterator.trade_trans_nounify (cbor_det_map_entry_match 1.0R res (Ghost.reveal vk, Ghost.reveal vv)) _ (Raw.cbor_match_map_entry 1.0R + res _) _; Trade.trans_concl_l (cbor_det_map_entry_match 1.0R res (Ghost.reveal vk, Ghost.reveal vv)) _ _ _; Trade.trans_concl_r (cbor_det_map_entry_match 1.0R res (Ghost.reveal vk, Ghost.reveal vv)) _ _ _; res @@ -853,6 +890,9 @@ decreases v SM.seq_list_match_cons_intro_trade (Seq.head c) (mk_cbor_map_entry (List.Tot.hd v)) (Seq.tail c) (List.Tot.map mk_cbor_map_entry (List.Tot.tl v)) (cbor_det_map_entry_match p); Trade.trans _ _ (SM.seq_list_match c v (Raw.cbor_match_map_entry p)); rewrite each Seq.cons (Seq.head c) (Seq.tail c) as c; + rewrite each (mk_cbor_map_entry (List.Tot.Base.hd v) :: + List.Tot.Base.map mk_cbor_map_entry (List.Tot.Base.tl v)) as ( + List.Tot.Base.map mk_cbor_map_entry (v)); (); } } @@ -1788,6 +1828,8 @@ ensures Trade.elim _ _; fold (map_get_post_none cbor_det_match x px vx vk); fold (map_get_post cbor_det_match x px vx vk None); + rewrite (map_get_post cbor_det_match x px vx vk None) + as (map_get_post cbor_det_match x px vx vk res); (); } Some x' -> { @@ -1795,6 +1837,8 @@ ensures unfold (cbor_det_map_get_invariant_some px x vx vk m x'); fold (map_get_post_some cbor_det_match x px vx vk x'); fold (map_get_post cbor_det_match x px vx vk (Some x')); + rewrite (map_get_post cbor_det_match x px vx vk (Some x')) + as (map_get_post cbor_det_match x px vx vk res); } } } @@ -1833,6 +1877,8 @@ fn cbor_det_map_get (_: unit) pure (cont == cont') { with gb gi gres . assert (cbor_det_map_get_invariant gb px x vx vk m p' gi gres); + rewrite (cbor_det_map_get_invariant gb px x vx vk m p' gi gres) + as (cbor_det_map_get_invariant gb px x vx vk m p' gi None); unfold (cbor_det_map_get_invariant gb px x vx vk m p' gi None); unfold (cbor_det_map_get_invariant_none gb px x vx vk m p' gi); let entry = cbor_det_map_iterator_next () pi; @@ -1859,6 +1905,7 @@ fn cbor_det_map_get (_: unit) List.Tot.assoc_mem (Ghost.reveal vk) l'; pcont := false; fold (cbor_det_map_get_invariant_none false px x vx vk m p' gi'); + assert (pts_to pres None); fold (cbor_det_map_get_invariant false px x vx vk m p' gi' None); } else { Trade.elim_hyp_l _ _ (cbor_det_match px x vx); @@ -1870,6 +1917,7 @@ fn cbor_det_map_get (_: unit) let cont = not is_empty; pcont := cont; fold (cbor_det_map_get_invariant_none cont px x vx vk m p' i'); + assert (pts_to pres None); fold (cbor_det_map_get_invariant cont px x vx vk m p' i' None); } }; diff --git a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Rust.fst b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Rust.fst index bf1ad4bfe..470f62089 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Rust.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.API.Det.Rust.fst @@ -272,7 +272,7 @@ ensures exists* p' . let s = cbor_det_get_string () c; with p' v' . assert (pts_to s #p' v'); fold (cbor_det_string_match ty p' s v); - fold (cbor_det_view_match p' (String k s) v); + rewrite (cbor_det_string_match ty p' s v) as (cbor_det_view_match p' (String k s) v); intro (Trade.trade (cbor_det_view_match p' (String k s) v) @@ -282,13 +282,14 @@ ensures exists* p' . fn _ { unfold (cbor_det_view_match p' (String k s) v); - unfold (cbor_det_string_match ty p' s v); + with ty . unfold (cbor_det_string_match ty p' s v); }; Trade.trans _ _ (cbor_det_match p c v); String k s } else if (ty = cbor_major_type_array) { let res : cbor_det_array = { array = c }; + rewrite Det.cbor_det_match p c v as Det.cbor_det_match p res.array v; fold (cbor_det_array_match p res v); fold (cbor_det_view_match p (Array res) v); intro @@ -301,11 +302,13 @@ ensures exists* p' . { unfold (cbor_det_view_match p (Array res) v); unfold (cbor_det_array_match p res v); + rewrite Det.cbor_det_match p res.array v as Det.cbor_det_match p c v; }; Array res } else if (ty = cbor_major_type_map) { let res : cbor_det_map = { map = c }; + rewrite Det.cbor_det_match p c v as Det.cbor_det_match p res.map v; fold (cbor_det_map_match p res v); fold (cbor_det_view_match p (Map res) v); intro @@ -318,6 +321,7 @@ ensures exists* p' . { unfold (cbor_det_view_match p (Map res) v); unfold (cbor_det_map_match p res v); + rewrite Det.cbor_det_match p res.map v as Det.cbor_det_match p c v; }; Map res } @@ -337,6 +341,7 @@ ensures exists* p' . { unfold (cbor_det_view_match p' (Tagged tag payload) v); unfold (cbor_det_tagged_match p' tag payload v); + with v_ . rewrite Det.cbor_det_match p' payload v_ as Det.cbor_det_match p' payload v' }; Trade.trans _ _ (cbor_det_match p c v); Tagged tag payload @@ -573,12 +578,14 @@ ensures unfold (map_get_post_none cbor_det_match x.map px vx vk); Trade.elim _ _; fold (safe_map_get_post x px vx vk None); + rewrite (safe_map_get_post x px vx vk None) as (safe_map_get_post x px vx vk res) } Some res' -> { unfold (map_get_post cbor_det_match x.map px vx vk (Some res')); unfold (map_get_post_some cbor_det_match x.map px vx vk res'); Trade.trans _ _ (cbor_det_map_match px x vx); fold (safe_map_get_post x px vx vk (Some res')); + rewrite (safe_map_get_post x px vx vk (Some res')) as (safe_map_get_post x px vx vk res) } } } diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.fst index 74f311cee..1c52d96d4 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Compare.fst @@ -156,32 +156,41 @@ ensures { cbor_match_cases x; match x { + norewrite CBOR_Case_Simple _ -> { cbor_major_type_simple_value } + norewrite CBOR_Case_Int _ -> { let res = cbor_match_int_elim_type x; res } + norewrite CBOR_Case_String _ -> { let res = cbor_match_string_elim_type x; res } + norewrite CBOR_Case_Tagged _ -> { cbor_major_type_tagged } + norewrite CBOR_Case_Serialized_Tagged _ -> { cbor_major_type_tagged } + norewrite CBOR_Case_Array _ -> { cbor_major_type_array } + norewrite CBOR_Case_Serialized_Array _ -> { cbor_major_type_array } + norewrite CBOR_Case_Map _ -> { cbor_major_type_map } + norewrite CBOR_Case_Serialized_Map _ -> { cbor_major_type_map } diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst index a264ecba8..e0e37f331 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Copy.fst @@ -204,14 +204,18 @@ ensures freeable_match'_cases x ft; match x { CBOR_Copy_Unit -> { + rewrite each ft as FTUnit; unfold (freeable_match' CBOR_Copy_Unit FTUnit); + () } CBOR_Copy_Bytes v -> { + rewrite each ft as FTBytes; unfold (freeable_match' (CBOR_Copy_Bytes v) FTBytes); V.free v } CBOR_Copy_Box b -> { let ft' = Ghost.hide (FTBox?.b ft); + rewrite each ft as (FTBox ft'); unfold (freeable_match' (CBOR_Copy_Box b) (FTBox ft')); B.free b.box_cbor; let b' = ((let open Pulse.Lib.Box in ( ! )) b.box_footprint); @@ -220,6 +224,7 @@ ensures } CBOR_Copy_Array a -> { let ft' = Ghost.hide (FTArray?.a ft); + rewrite each ft as (FTArray ft'); unfold (freeable_match' (CBOR_Copy_Array a) (FTArray ft')); V.free a.array_cbor; with s . assert (pts_to a.array_footprint s ** SM.seq_list_match s ft' freeable_match'); @@ -246,6 +251,7 @@ ensures SM.seq_seq_match_dequeue_left freeable_match' s s' _ _; let i = !pi; let x' = V.op_Array_Access a.array_footprint i; + with x_ y_ . rewrite freeable_match' x_ y_ as freeable_match' x' y_; cbor_free' x' _; pi := (SZ.add i 1sz); }; @@ -254,6 +260,7 @@ ensures } CBOR_Copy_Map a -> { let ft' = Ghost.hide (FTMap?.m ft); + rewrite each ft as (FTMap ft'); unfold (freeable_match' (CBOR_Copy_Map a) (FTMap ft')); V.free a.map_cbor; with s . assert (pts_to a.map_footprint s ** SM.seq_list_match s ft' (freeable_match_map_entry' ft freeable_match')); @@ -281,6 +288,7 @@ ensures SM.seq_seq_match_dequeue_left freeable_match_map_entry s s' _ _; let i = !pi; let x' = V.op_Array_Access a.map_footprint i; + with x_ y_ . rewrite freeable_match_map_entry x_ y_ as freeable_match_map_entry x' y_; cbor_free_map_entry cbor_free' x' _; pi := (SZ.add i 1sz); }; @@ -442,10 +450,11 @@ ensures V.pts_to_len v'; V.pts_to_len vf; let i = !pi; - with s1 sf st . assert (pts_to v' s1 ** pts_to vf sf ** Trade.trade - (SM.seq_seq_match (cbor_match 1.0R) s1 sl 0 (SZ.v i)) - (SM.seq_seq_match freeable_match' sf st 0 (SZ.v i)) + with s1 j sf st . assert (pts_to v' s1 ** pts_to vf sf ** Trade.trade + (SM.seq_seq_match (cbor_match 1.0R) s1 sl 0 j) + (SM.seq_seq_match freeable_match' sf st 0 j) ); + rewrite each j as (SZ.v i); let c = ar.(i); SM.seq_list_match_index_trade (cbor_match pl) s l (SZ.v i); let c' = copy c; @@ -478,15 +487,16 @@ ensures pi := (SZ.add i 1sz); }; Trade.elim _ (cbor_match p x v); - with s1 sf st . assert (pts_to v' s1 ** pts_to vf sf ** - SM.seq_seq_match (cbor_match 1.0R) s1 sl 0 (SZ.v len) ** + with s1 j sf st . assert (pts_to v' s1 ** pts_to vf sf ** + SM.seq_seq_match (cbor_match 1.0R) s1 sl 0 j ** Trade.trade - (SM.seq_seq_match (cbor_match 1.0R) s1 sl 0 (SZ.v len)) - (SM.seq_seq_match freeable_match' sf st 0 (SZ.v len)) + (SM.seq_seq_match (cbor_match 1.0R) s1 sl 0 j) + (SM.seq_seq_match freeable_match' sf st 0 j) ); + rewrite each j as (SZ.v len); V.pts_to_len v'; SM.seq_seq_match_seq_list_match_trade (cbor_match 1.0R) s1 sl; - Trade.trans _ _ (SM.seq_seq_match freeable_match' sf st 0 (SZ.v len)); + CBOR.Pulse.Raw.Iterator.trade_trans_nounify _ _ _ (SM.seq_seq_match freeable_match' sf st 0 (SZ.v len)); V.pts_to_len vf; let lt = Ghost.hide (Seq.seq_to_list st); intro @@ -530,9 +540,13 @@ ensures rewrite (pts_to v' s1) as (pts_to fa.array_cbor s1); rewrite (pts_to vf sf) as (pts_to fa.array_footprint sf); fold (freeable_match' (CBOR_Copy_Array fa) (FTArray lt)); + rewrite freeable_match' (CBOR_Copy_Array fa) (FTArray lt) as + freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.trans _ _ (freeable res); + with r' . assert cbor_match 1.0R c' (Array len64 r'); + rewrite each cbor_match 1.0R c' (Array len64 r') as cbor_match 1.0R res.cbor v; res } @@ -633,10 +647,11 @@ ensures V.pts_to_len v'; V.pts_to_len vf; let i = !pi; - with s1 sf st . assert (pts_to v' s1 ** pts_to vf sf ** Trade.trade - (SM.seq_seq_match (cbor_match_map_entry 1.0R) s1 sl 0 (SZ.v i)) - (SM.seq_seq_match freeable_match_map_entry sf st 0 (SZ.v i)) + with s1 j sf st . assert (pts_to v' s1 ** pts_to vf sf ** Trade.trade + (SM.seq_seq_match (cbor_match_map_entry 1.0R) s1 sl 0 j) + (SM.seq_seq_match freeable_match_map_entry sf st 0 j) ); + rewrite each j as (SZ.v i); let c = S.op_Array_Access ar i; SM.seq_list_match_index_trade (cbor_match_map_entry pl) s l (SZ.v i); with v1 . assert (cbor_match_map_entry pl c v1); @@ -692,15 +707,16 @@ ensures pi := (SZ.add i 1sz); }; Trade.elim _ (cbor_match p x v); - with s1 sf st . assert (pts_to v' s1 ** pts_to vf sf ** - SM.seq_seq_match (cbor_match_map_entry 1.0R) s1 sl 0 (SZ.v len) ** + with s1 j sf st . assert (pts_to v' s1 ** pts_to vf sf ** + SM.seq_seq_match (cbor_match_map_entry 1.0R) s1 sl 0 j ** Trade.trade - (SM.seq_seq_match (cbor_match_map_entry 1.0R) s1 sl 0 (SZ.v len)) - (SM.seq_seq_match freeable_match_map_entry sf st 0 (SZ.v len)) + (SM.seq_seq_match (cbor_match_map_entry 1.0R) s1 sl 0 j) + (SM.seq_seq_match freeable_match_map_entry sf st 0 j) ); + rewrite each j as (SZ.v len); V.pts_to_len v'; SM.seq_seq_match_seq_list_match_trade (cbor_match_map_entry 1.0R) s1 sl; - Trade.trans _ _ (SM.seq_seq_match freeable_match_map_entry sf st 0 (SZ.v len)); + CBOR.Pulse.Raw.Iterator.trade_trans_nounify _ _ _ (SM.seq_seq_match freeable_match_map_entry sf st 0 (SZ.v len)); V.pts_to_len vf; let lt = Ghost.hide (Seq.seq_to_list st); intro @@ -745,9 +761,13 @@ ensures rewrite (pts_to v' s1) as (pts_to fa.map_cbor s1); rewrite (pts_to vf sf) as (pts_to fa.map_footprint sf); fold (freeable_match' (CBOR_Copy_Map fa) (FTMap lt)); + rewrite (freeable_match' (CBOR_Copy_Map fa) (FTMap lt)) as freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.trans _ _ (freeable res); + with r' . assert cbor_match 1.0R c' (Map len64 r'); + rewrite each cbor_match 1.0R c' (Map len64 r') as + cbor_match 1.0R res.cbor v; res } @@ -769,6 +789,7 @@ ensures { cbor_match_cases x; match x { + norewrite CBOR_Case_Int _ -> { let ty = cbor_match_int_elim_type x; let w = cbor_match_int_elim_value x; @@ -788,10 +809,14 @@ ensures { cbor_match_int_free c'; fold (freeable_match' CBOR_Copy_Unit FTUnit); + rewrite (freeable_match' CBOR_Copy_Unit FTUnit) as freeable_match' res.footprint res.tree; fold (freeable res) }; + rewrite each cbor_match 1.0R c' (Int64 ty w) + as cbor_match 1.0R res.cbor v; res } + norewrite CBOR_Case_Simple _ -> { let w = cbor_match_simple_elim x; let c' = cbor_match_simple_intro w; @@ -810,10 +835,13 @@ ensures { cbor_match_simple_free c'; fold (freeable_match' CBOR_Copy_Unit FTUnit); + rewrite (freeable_match' CBOR_Copy_Unit FTUnit) as freeable_match' res.footprint res.tree; fold (freeable res) }; + rewrite each cbor_match 1.0R c' (Simple w) as cbor_match 1.0R res.cbor v; res } + norewrite CBOR_Case_String _ -> { let ty = cbor_match_string_elim_type x; let len = cbor_match_string_elim_length x; @@ -844,11 +872,15 @@ ensures S.to_array s'; V.to_vec_pts_to v'; fold (freeable_match' (CBOR_Copy_Bytes v') FTBytes); + rewrite (freeable_match' (CBOR_Copy_Bytes v') FTBytes) as freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.trans _ (pts_to s' vs') _; + with r_ . assert cbor_match 1.0R c' r_; + rewrite each cbor_match 1.0R c' r_ as cbor_match 1.0R res.cbor v; res } + norewrite CBOR_Case_Tagged _ -> { let tag = cbor_match_tagged_get_tag x; let pl = cbor_match_tagged_get_payload x; @@ -882,18 +914,23 @@ ensures unfold (freeable cpl'); fold (freeable_match_box fb cpl'.tree); freeable_match_box_eq fb cpl'.tree; - rewrite (freeable_match_box fb cpl'.tree) as (freeable_match' (CBOR_Copy_Box fb) (FTBox cpl'.tree)); + rewrite (freeable_match_box fb cpl'.tree) as freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.trans _ _ (freeable res); + rewrite each cbor_match 1.0R c' (Tagged tag (Tagged?.v v)) + as cbor_match 1.0R res.cbor v; res } + norewrite CBOR_Case_Array a -> { - cbor_copy_array cbor_copy0 (CBOR_Case_Array a); + cbor_copy_array cbor_copy0 x; } + norewrite CBOR_Case_Map a -> { - cbor_copy_map cbor_copy0 (CBOR_Case_Map a); + cbor_copy_map cbor_copy0 x; } + norewrite CBOR_Case_Serialized_Array a -> { Trade.rewrite_with_trade (cbor_match p x v) @@ -913,6 +950,10 @@ ensures cbor_serialized_payload = s'; cbor_serialized_perm = 1.0R; }; + rewrite cbor_match_serialized_payload_array s' 1.0R (Array?.v v) + as cbor_match_serialized_payload_array a'.cbor_serialized_payload + (perm_mul 1.0R a'.cbor_serialized_perm) + (Array?.v v); fold (cbor_match_serialized_array a' 1.0R v); let res = { cbor = CBOR_Case_Serialized_Array a'; @@ -931,10 +972,15 @@ ensures fn _ { unfold (cbor_match_serialized_array a' 1.0R v); + rewrite cbor_match_serialized_payload_array a'.cbor_serialized_payload + (perm_mul 1.0R a'.cbor_serialized_perm) + (Array?.v v) + as cbor_match_serialized_payload_array s' 1.0R (Array?.v v); Trade.elim _ _; S.to_array s'; V.to_vec_pts_to v'; fold (freeable_match' (CBOR_Copy_Bytes v') FTBytes); + rewrite (freeable_match' (CBOR_Copy_Bytes v') FTBytes) as freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.rewrite_with_trade @@ -943,6 +989,7 @@ ensures Trade.trans (cbor_match 1.0R res.cbor v) _ _; res } + norewrite CBOR_Case_Serialized_Map a -> { Trade.rewrite_with_trade (cbor_match p x v) @@ -962,6 +1009,9 @@ ensures cbor_serialized_payload = s'; cbor_serialized_perm = 1.0R; }; + rewrite cbor_match_serialized_payload_map s' 1.0R (Map?.v v) as cbor_match_serialized_payload_map a'.cbor_serialized_payload + (perm_mul 1.0R a'.cbor_serialized_perm) + (Map?.v v); fold (cbor_match_serialized_map a' 1.0R v); let res = { cbor = CBOR_Case_Serialized_Map a'; @@ -980,10 +1030,15 @@ ensures fn _ { unfold (cbor_match_serialized_map a' 1.0R v); + rewrite cbor_match_serialized_payload_map a'.cbor_serialized_payload + (perm_mul 1.0R a'.cbor_serialized_perm) + (Map?.v v) + as cbor_match_serialized_payload_map s' 1.0R (Map?.v v); Trade.elim _ _; S.to_array s'; V.to_vec_pts_to v'; fold (freeable_match' (CBOR_Copy_Bytes v') FTBytes); + rewrite (freeable_match' (CBOR_Copy_Bytes v') FTBytes) as freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.rewrite_with_trade @@ -992,6 +1047,7 @@ ensures Trade.trans (cbor_match 1.0R res.cbor v) _ _; res } + norewrite CBOR_Case_Serialized_Tagged a -> { Trade.rewrite_with_trade (cbor_match p x v) @@ -1011,6 +1067,10 @@ ensures cbor_serialized_payload = s'; cbor_serialized_perm = 1.0R; }; + rewrite cbor_match_serialized_payload_tagged s' 1.0R (Tagged?.v v) + as cbor_match_serialized_payload_tagged a'.cbor_serialized_payload + (perm_mul 1.0R a'.cbor_serialized_perm) + (Tagged?.v v); fold (cbor_match_serialized_tagged a' 1.0R v); let res = { cbor = CBOR_Case_Serialized_Tagged a'; @@ -1029,10 +1089,14 @@ ensures fn _ { unfold (cbor_match_serialized_tagged a' 1.0R v); + rewrite cbor_match_serialized_payload_tagged a'.cbor_serialized_payload + (perm_mul 1.0R a'.cbor_serialized_perm) + (Tagged?.v v) as cbor_match_serialized_payload_tagged s' 1.0R (Tagged?.v v); Trade.elim _ _; S.to_array s'; V.to_vec_pts_to v'; fold (freeable_match' (CBOR_Copy_Bytes v') FTBytes); + rewrite (freeable_match' (CBOR_Copy_Bytes v') FTBytes) as freeable_match' res.footprint res.tree; fold (freeable res) }; Trade.rewrite_with_trade diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Iterator.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Iterator.fst index 31c56518d..5a65b748e 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Iterator.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Iterator.fst @@ -118,6 +118,49 @@ ensures } #pop-options +ghost +fn cbor_raw_slice_iterator_match_fold_nounify + (#elt_low #elt_high: Type0) + (elt_match: perm -> elt_low -> elt_high -> slprop) + (pm: perm) + (s1: S.slice elt_low) + (p1: perm) + (c: cbor_raw_slice_iterator elt_low) + (c': cbor_raw_slice_iterator elt_low { c' == { c with slice_perm = c.slice_perm /. 2.0R } }) + (l: list elt_high) + (sq: Seq.seq elt_low) +requires + S.pts_to s1 #p1 sq ** + PM.seq_list_match sq l (elt_match (pm `perm_mul` c.payload_perm)) ** + pure (s1 == c.s) ** + pure (p1 == pm `perm_mul` c.slice_perm) +ensures + cbor_raw_slice_iterator_match elt_match pm c' l ** + trade + (cbor_raw_slice_iterator_match elt_match pm c' l) + (S.pts_to s1 #p1 sq ** + PM.seq_list_match sq l (elt_match (pm `perm_mul` c.payload_perm)) + ) +{ + Trade.rewrite_with_trade + (S.pts_to s1 #p1 sq) + (pts_to c.s #(pm `perm_mul` c.slice_perm) sq); + cbor_raw_slice_iterator_match_fold elt_match pm c c' l sq; + Trade.trans_concl_l _ _ _ _; + () +} + +ghost fn trade_trans_nounify + (a1 a2 a2' a3: slprop) +requires + trade a1 a2 ** trade a2' a3 ** pure (a2 == a2') +ensures + trade a1 a3 +{ + rewrite each a2' as a2; + Trade.trans a1 a2 a3 +} + inline_for_extraction fn cbor_raw_slice_iterator_init (#elt_low #elt_high: Type0) @@ -158,7 +201,7 @@ ensures exists* p . (PM.seq_list_match sq l (elt_match pm')) ; cbor_raw_slice_iterator_match_fold elt_match pm c c' l sq; - Trade.trans (cbor_raw_slice_iterator_match elt_match pm c' l) _ _; + trade_trans_nounify (cbor_raw_slice_iterator_match elt_match pm c' l) _ _ _; c' } @@ -245,12 +288,13 @@ fn slice_split_right (#t: Type0) (s: S.slice t) (#p: perm) (#v: Ghost.erased (Se ghost fn trade_partial_trans - (a b c d e: slprop) + (a b c d c' e: slprop) requires - (trade a (b ** c) ** trade (d ** c) e) + (trade a (b ** c) ** trade (d ** c') e) ** pure (c == c') ensures (trade (d ** a) (e ** b)) { + rewrite each c' as c; Trade.reg_l d a (b ** c); slprop_equivs (); rewrite (trade (d ** a) (d ** (b ** c))) as (trade (d ** a) ((d ** c) ** b)); @@ -260,12 +304,13 @@ ensures ghost fn trade_partial_trans_2 - (a b c d: slprop) + (a b c c' d: slprop) requires - (trade a (b ** c) ** trade c d) + (trade a (b ** c) ** trade c' d) ** pure (c == c') ensures (trade a (b ** d)) { + rewrite each c' as c; Trade.reg_l b c d; Trade.trans a (b ** c) (b ** d) } @@ -307,23 +352,28 @@ ensures rewrite each s' as i1.s; let i' = { i1 with slice_perm = i.slice_perm /. 2.0R }; pi := CBOR_Raw_Iterator_Slice i'; + with sq_ l_ p_ . rewrite PM.seq_list_match sq_ l_ (elt_match p_) + as PM.seq_list_match sq_ (List.Tot.tl l) (elt_match (pm `perm_mul` i1.payload_perm)); cbor_raw_slice_iterator_match_fold elt_match pm i1 i' (List.Tot.tl l) _; // 4: cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l) @==> (pts_to s' _ ** PM.seq_list_match _ (List.Tot.tl l) _) // BEGIN FIXME: PLEASE PLEASE PLEASE automate the following steps away! trade_partial_trans // uses 2, 4 (cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l)) - (pts_to s' #(pm `perm_mul` i.slice_perm) _) - (PM.seq_list_match _ (List.Tot.tl l) (elt_match (pm `perm_mul` i.payload_perm))) + (pts_to i1.s #(pm `perm_mul` _) _) + (PM.seq_list_match _ (List.Tot.tl l) (elt_match (pm `perm_mul` _))) (elt_match (pm `perm_mul` i.payload_perm) res (List.Tot.hd l)) + _ (PM.seq_list_match _ l (elt_match (pm `perm_mul` i.payload_perm))); // 5: elt_match _ _ (List.Tot.hd l) ** cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l) @==> PM.seq_list_match _ l _ ** pts_to s' _ trade_partial_trans_2 // uses 3, 5 - (elt_match (pm `perm_mul` i.payload_perm) res (List.Tot.hd l) ** cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l)) - (PM.seq_list_match _ l (elt_match (pm `perm_mul` i.payload_perm))) - (pts_to i1.s #(pm `perm_mul` i.slice_perm) _) + (elt_match (pm `perm_mul` _) res (List.Tot.hd l) ** cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l)) + (PM.seq_list_match _ l (elt_match (pm `perm_mul` _))) + (pts_to i1.s #(pm `perm_mul` _) _) + _ (pts_to i.s #(pm `perm_mul` i.slice_perm) _); // 6: elt_match _ _ (List.Tot.hd l) ** cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l) @==> PM.seq_list_match _ l _ ** pts_to i.s _ slprop_equivs (); - Trade.trans - (elt_match (pm `perm_mul` i.payload_perm) res (List.Tot.hd l) ** cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l)) - (PM.seq_list_match _ l (elt_match (pm `perm_mul` i.payload_perm)) ** pts_to i.s #(pm `perm_mul` i.slice_perm) _) + trade_trans_nounify + (elt_match (pm `perm_mul` _) res (List.Tot.hd l) ** cbor_raw_slice_iterator_match elt_match pm i' (List.Tot.tl l)) + (PM.seq_list_match _ l (elt_match (pm `perm_mul` _)) ** pts_to i.s #(pm `perm_mul` _) _) + _ (cbor_raw_slice_iterator_match elt_match pm i l); // END FIXME rewrite (elt_match (pm `perm_mul` i.payload_perm) (Seq.head sq) (List.Tot.hd l)) as (elt_match (pm `perm_mul` i.payload_perm) res (List.Tot.hd l)); // FIXME: automate this step away; it is the only occurrence of `sq`, see the `assert` above @@ -406,6 +456,7 @@ ensures pure (res == Nil? r) { match c { + norewrite CBOR_Raw_Iterator_Slice c' -> { rewrite (cbor_raw_iterator_match elt_match ser_match pm c r) as (cbor_raw_slice_iterator_match elt_match pm c' r); @@ -414,6 +465,7 @@ ensures as (cbor_raw_iterator_match elt_match ser_match pm c r); res } + norewrite CBOR_Raw_Iterator_Serialized c' -> { rewrite (cbor_raw_iterator_match elt_match ser_match pm c r) as (ser_match pm c' r); @@ -456,6 +508,7 @@ ensures pure ((U64.v res <: nat) == List.Tot.length r) { match c { + norewrite CBOR_Raw_Iterator_Slice c' -> { rewrite (cbor_raw_iterator_match elt_match ser_match pm c r) as (cbor_raw_slice_iterator_match elt_match pm c' r); @@ -464,6 +517,7 @@ ensures as (cbor_raw_iterator_match elt_match ser_match pm c r); res } + norewrite CBOR_Raw_Iterator_Serialized c' -> { rewrite (cbor_raw_iterator_match elt_match ser_match pm c r) as (ser_match pm c' r); @@ -603,6 +657,20 @@ let cbor_raw_serialized_iterator_truncate_t (ser_match pm c r) ) +ghost +fn trade_trans_hyp_r_nounify + (p q1 q2 q2' r: slprop) + requires + trade q1 q2 ** + trade (p ** q2') r ** + pure (q2 == q2') + ensures + trade (p ** q1) r +{ + rewrite each q2' as q2; + Trade.trans_hyp_r p q1 q2 r +} + inline_for_extraction fn cbor_raw_iterator_truncate (#elt_low #elt_high: Type0) @@ -624,6 +692,7 @@ ensures (cbor_raw_iterator_match elt_match ser_match pm c r) { match c { + norewrite CBOR_Raw_Iterator_Slice c' -> { Trade.rewrite_with_trade (cbor_raw_iterator_match elt_match ser_match pm c r) (cbor_raw_slice_iterator_match elt_match pm c' r); @@ -641,12 +710,12 @@ ensures let s2 = Ghost.hide (Seq.slice s (U64.v len) (Seq.length s)); rewrite each s as (s1 `Seq.append` s2); PM.seq_list_match_append_elim_trade (elt_match (pm `perm_mul` c'.payload_perm)) s1 l1 s2 l2; - Trade.elim_hyp_r _ _ (PM.seq_list_match (s1 `Seq.append` s2) l (elt_match (pm `perm_mul` c'.payload_perm))); - Trade.trans_hyp_r _ _ _ (cbor_raw_iterator_match elt_match ser_match pm c r); + Trade.elim_hyp_r _ _ (PM.seq_list_match (s1 `Seq.append` s2) _ (elt_match (pm `perm_mul` c'.payload_perm))); + trade_trans_hyp_r_nounify _ _ _ _ (cbor_raw_iterator_match elt_match ser_match pm c r); assume (pure (SZ.fits_u64)); let sl1, sl2 = S.split_trade c'.s (SZ.uint64_to_sizet len); S.pts_to_len sl1; - Trade.elim_hyp_r _ _ (pts_to c'.s #(pm `perm_mul` c'.slice_perm) s); + Trade.elim_hyp_r _ _ (pts_to c'.s #(pm `perm_mul` c'.slice_perm) _); Trade.trans_hyp_l _ _ _ (cbor_raw_iterator_match elt_match ser_match pm c r); let c1 = { s = sl1; @@ -658,15 +727,19 @@ ensures let c' = { c1 with slice_perm = c1.slice_perm /. 2.0R; }; + rewrite each (Seq.Base.slice (Seq.Base.append s1 s2) 0 (SZ.v (SZ.uint64_to_sizet len))) + as s1; cbor_raw_slice_iterator_match_fold elt_match 1.0R c1 c' _ _; - Trade.trans _ _ (cbor_raw_iterator_match elt_match ser_match pm c r); + trade_trans_nounify _ _ _ (cbor_raw_iterator_match elt_match ser_match pm c r); let res = CBOR_Raw_Iterator_Slice c'; Trade.rewrite_with_trade (cbor_raw_slice_iterator_match elt_match 1.0R c' l1) (cbor_raw_iterator_match elt_match ser_match 1.0R res l1); Trade.trans _ _ (cbor_raw_iterator_match elt_match ser_match pm c r); + rewrite each l1 as (fst (List.Tot.Base.splitAt (U64.v len) r)); res } + norewrite CBOR_Raw_Iterator_Serialized c' -> { Trade.rewrite_with_trade (cbor_raw_iterator_match elt_match ser_match pm c r) (ser_match pm c' r); @@ -770,6 +843,7 @@ ensures cbor_raw_iterator_match elt_match ser_match (pm /. 2.0R) c r { match c { + norewrite CBOR_Raw_Iterator_Slice c' -> { rewrite (cbor_raw_iterator_match elt_match ser_match pm c r) as (cbor_raw_slice_iterator_match elt_match pm c' r); @@ -786,6 +860,7 @@ ensures rewrite (cbor_raw_slice_iterator_match elt_match (pm /. 2.0R) c' r) as (cbor_raw_iterator_match elt_match ser_match (pm /. 2.0R) c r); } + norewrite CBOR_Raw_Iterator_Serialized c' -> { rewrite (cbor_raw_iterator_match elt_match ser_match pm c r) as (ser_match pm c' r); @@ -849,6 +924,42 @@ decreases r1 } } +ghost +fn cbor_raw_gather_slice_nounify + (#elt_low #elt_high: Type0) + (elt_match: perm -> elt_low -> elt_high -> slprop) + (p1: perm) + (c1: Seq.seq elt_low) + (r1: list elt_high) + (p2: perm) + (c2: Seq.seq elt_low) + (r2: list elt_high) + (elt_gather: ( + (p1': perm) -> + (c': elt_low) -> + (r1': elt_high) -> + (p2': perm) -> + (r2': elt_high { r1' << r1 }) -> + stt_ghost unit emp_inames + (elt_match p1' c' r1' ** elt_match p2' c' r2') + (fun _ -> elt_match (p1' +. p2') c' r1' ** + pure (r1' == r2') + ) + )) + (_: unit) +requires + PM.seq_list_match c1 r1 (elt_match p1) ** + PM.seq_list_match c2 r2 (elt_match p2) ** + pure (c1 == c2) +ensures + PM.seq_list_match c1 r1 (elt_match (p1 +. p2)) ** + pure (r1 == r2) +{ + rewrite each c2 as c1; + cbor_raw_gather_slice elt_match p1 c1 r1 p2 r2 elt_gather () +} + + (* This is a hack to deal with ambiguity. *) let tag (s: slprop) = s @@ -940,22 +1051,26 @@ ensures CBOR_Raw_Iterator_Slice c' -> { unfold cbor_raw_slice_iterator_match elt_match pm1 c' r1; with gs1. assert PM.seq_list_match gs1 r1 (elt_match (perm_mul pm1 c'.payload_perm)); - rewrite PM.seq_list_match gs1 r1 (elt_match (perm_mul pm1 c'.payload_perm)) - as tag (PM.seq_list_match gs1 r1 (elt_match (perm_mul pm1 c'.payload_perm))); +// rewrite PM.seq_list_match gs1 r1 (elt_match (perm_mul pm1 c'.payload_perm)) +// as tag (PM.seq_list_match gs1 r1 (elt_match (perm_mul pm1 c'.payload_perm))); unfold cbor_raw_slice_iterator_match elt_match pm2 c' r2; S.gather c'.s; perm_mul_add_l pm1 pm2 c'.slice_perm; - cbor_raw_gather_slice_TAGGED - elt_match (pm1 *. c'.payload_perm) _ r1 (pm2 *. c'.payload_perm) r2 elt_gather (); + cbor_raw_gather_slice_nounify + elt_match (pm1 *. c'.payload_perm) _ r1 (pm2 `perm_mul` c'.payload_perm) _ r2 elt_gather (); perm_mul_add_l pm1 pm2 c'.payload_perm; fold (cbor_raw_slice_iterator_match elt_match (pm1 +. pm2) c' r1); fold (cbor_raw_iterator_match elt_match ser_match (pm1 +. pm2) (CBOR_Raw_Iterator_Slice c') r1); + rewrite (cbor_raw_iterator_match elt_match ser_match (pm1 +. pm2) (CBOR_Raw_Iterator_Slice c') r1) as cbor_raw_iterator_match elt_match ser_match (pm1 +. pm2) c r1; + () } CBOR_Raw_Iterator_Serialized c' -> { phi c' #pm1 #r1 #pm2 #r2; fold (cbor_raw_iterator_match elt_match ser_match (pm1 +. pm2) (CBOR_Raw_Iterator_Serialized c') r1); + rewrite (cbor_raw_iterator_match elt_match ser_match (pm1 +. pm2) (CBOR_Raw_Iterator_Serialized c') r1) as cbor_raw_iterator_match elt_match ser_match (pm1 +. pm2) c r1; + () } } } diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.Perm.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.Perm.fst index 6fc4cbee6..1ebe2caf9 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.Perm.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.Perm.fst @@ -33,10 +33,10 @@ decreases r } a :: q -> { PM.seq_list_match_cons_elim c r (cbor_match p); - cbor_raw_share p (Seq.head c) a; + cbor_raw_share p (Seq.head c) _; cbor_raw_share_array p (Seq.tail c) q cbor_raw_share (); - PM.seq_list_match_cons_intro (Seq.head c) a (Seq.tail c) q (cbor_match (p /. 2.0R)); - PM.seq_list_match_cons_intro (Seq.head c) a (Seq.tail c) q (cbor_match (p /. 2.0R)); + PM.seq_list_match_cons_intro (Seq.head c) _ (Seq.tail c) q (cbor_match (p /. 2.0R)); + PM.seq_list_match_cons_intro (Seq.head c) _ (Seq.tail c) q (cbor_match (p /. 2.0R)); rewrite each Seq.cons (Seq.head c) (Seq.tail c) as c; (); } @@ -75,6 +75,7 @@ decreases r } a :: q -> { PM.seq_list_match_cons_elim c r (cbor_match_map_entry0 r0 (cbor_match p)); + rewrite each (List.Tot.Base.hd r) as a; unfold (cbor_match_map_entry0 r0 (cbor_match p) (Seq.head c) a); cbor_raw_share p (Seq.head c).cbor_map_entry_key (fst a); cbor_raw_share p (Seq.head c).cbor_map_entry_value (snd a); @@ -103,6 +104,7 @@ fn rec cbor_raw_share { cbor_match_cases c; match c { + norewrite CBOR_Case_String v -> { rewrite (cbor_match p c r) as (cbor_match_string v p r); @@ -116,6 +118,7 @@ fn rec cbor_raw_share rewrite (cbor_match_string v (p /. 2.0R) r) as (cbor_match (p /. 2.0R) c r) } + norewrite CBOR_Case_Int v -> { rewrite (cbor_match p c r) as (cbor_match_int v r); @@ -127,6 +130,7 @@ fn rec cbor_raw_share rewrite (cbor_match_int v r) as (cbor_match (p /. 2.0R) c r) } + norewrite CBOR_Case_Simple v -> { rewrite (cbor_match p c r) as (cbor_match_simple v r); @@ -138,6 +142,7 @@ fn rec cbor_raw_share rewrite (cbor_match_simple v r) as (cbor_match (p /. 2.0R) c r) } + norewrite CBOR_Case_Tagged v -> { cbor_match_eq_tagged p v r; rewrite (cbor_match p c r) @@ -147,14 +152,17 @@ fn rec cbor_raw_share R.share v.cbor_tagged_ptr; half_mul_l p v.cbor_tagged_ref_perm; half_mul_l p v.cbor_tagged_payload_perm; + with c' . rewrite cbor_match (perm_mul p v.cbor_tagged_payload_perm /. 2.0R) c' (Tagged?.v r) as cbor_match (perm_mul (p /. 2.0R) v.cbor_tagged_payload_perm) c' (Tagged?.v r); fold (cbor_match_tagged v (p /. 2.0R) r cbor_match); cbor_match_eq_tagged (p /. 2.0R) v r; + with c' . rewrite cbor_match (perm_mul p v.cbor_tagged_payload_perm /. 2.0R) c' (Tagged?.v r) as cbor_match (perm_mul (p /. 2.0R) v.cbor_tagged_payload_perm) c' (Tagged?.v r); fold (cbor_match_tagged v (p /. 2.0R) r cbor_match); rewrite (cbor_match_tagged v (p /. 2.0R) r cbor_match) as (cbor_match (p /. 2.0R) c r); rewrite (cbor_match_tagged v (p /. 2.0R) r cbor_match) as (cbor_match (p /. 2.0R) c r) } + norewrite CBOR_Case_Array v -> { cbor_match_eq_array p v r; rewrite (cbor_match p c r) @@ -172,6 +180,7 @@ fn rec cbor_raw_share rewrite (cbor_match_array v (p /. 2.0R) r cbor_match) as (cbor_match (p /. 2.0R) c r) } + norewrite CBOR_Case_Map v -> { cbor_match_eq_map0 p v r; rewrite (cbor_match p c r) @@ -189,12 +198,18 @@ fn rec cbor_raw_share rewrite (cbor_match_map0 v (p /. 2.0R) r cbor_match) as (cbor_match (p /. 2.0R) c r) } + norewrite CBOR_Case_Serialized_Tagged v -> { rewrite (cbor_match p c r) as (cbor_match_serialized_tagged v p r); unfold (cbor_match_serialized_tagged v p r); cbor_match_serialized_payload_tagged_share _ _ _; half_mul_l p v.cbor_serialized_perm; + rewrite each cbor_match_serialized_payload_tagged v.cbor_serialized_payload + (perm_mul p v.cbor_serialized_perm /. 2.0R) + (Tagged?.v r) as cbor_match_serialized_payload_tagged v.cbor_serialized_payload + (perm_mul (p /. 2.0R) v.cbor_serialized_perm) + (Tagged?.v r); fold (cbor_match_serialized_tagged v (p /. 2.0R) r); rewrite (cbor_match_serialized_tagged v (p /. 2.0R) r) as (cbor_match (p /. 2.0R) c r); @@ -202,12 +217,19 @@ fn rec cbor_raw_share rewrite (cbor_match_serialized_tagged v (p /. 2.0R) r) as (cbor_match (p /. 2.0R) c r); } + norewrite CBOR_Case_Serialized_Array v -> { rewrite (cbor_match p c r) as (cbor_match_serialized_array v p r); unfold (cbor_match_serialized_array v p r); cbor_match_serialized_payload_array_share _ _ _; half_mul_l p v.cbor_serialized_perm; + rewrite each cbor_match_serialized_payload_array v.cbor_serialized_payload + (perm_mul p v.cbor_serialized_perm /. 2.0R) + (Array?.v r) + as cbor_match_serialized_payload_array v.cbor_serialized_payload + (perm_mul (p /. 2.0R) v.cbor_serialized_perm) + (Array?.v r); fold (cbor_match_serialized_array v (p /. 2.0R) r); rewrite (cbor_match_serialized_array v (p /. 2.0R) r) as (cbor_match (p /. 2.0R) c r); @@ -215,12 +237,19 @@ fn rec cbor_raw_share rewrite (cbor_match_serialized_array v (p /. 2.0R) r) as (cbor_match (p /. 2.0R) c r); } + norewrite CBOR_Case_Serialized_Map v -> { rewrite (cbor_match p c r) as (cbor_match_serialized_map v p r); unfold (cbor_match_serialized_map v p r); cbor_match_serialized_payload_map_share _ _ _; half_mul_l p v.cbor_serialized_perm; + rewrite each cbor_match_serialized_payload_map v.cbor_serialized_payload + (perm_mul p v.cbor_serialized_perm /. 2.0R) + (Map?.v r) + as cbor_match_serialized_payload_map v.cbor_serialized_payload + (perm_mul (p /. 2.0R) v.cbor_serialized_perm) + (Map?.v r); fold (cbor_match_serialized_map v (p /. 2.0R) r); rewrite (cbor_match_serialized_map v (p /. 2.0R) r) as (cbor_match (p /. 2.0R) c r); @@ -461,6 +490,8 @@ fn rec cbor_raw_gather perm_mul_add_l p1 p2 v.cbor_string_perm; fold cbor_match_string v (p1 +. p2) (String t1 l1 v1); fold cbor_match (p1 +. p2) (CBOR_Case_String v) (String t1 l1 v1); + rewrite cbor_match (p1 +. p2) (CBOR_Case_String v) (String t1 l1 v1) as cbor_match (p1 +. p2) c r1; + () } CBOR_Case_Int v -> { unfold cbor_match p1 (CBOR_Case_Int v) r1; @@ -472,6 +503,7 @@ fn rec cbor_raw_gather (* permissions do not show up in cbor_match_int *) fold cbor_match_int v (Int64 t1 v1); fold cbor_match (p1 +. p2) (CBOR_Case_Int v) (Int64 t1 v1); + rewrite cbor_match (p1 +. p2) (CBOR_Case_Int v) (Int64 t1 v1) as cbor_match (p1 +. p2) c r1; } CBOR_Case_Simple v -> { unfold cbor_match p1 (CBOR_Case_Simple v) r1; @@ -483,6 +515,7 @@ fn rec cbor_raw_gather (* permissions do not show up in cbor_match_simple *) fold cbor_match_simple v (Simple v1); fold cbor_match (p1 +. p2) (CBOR_Case_Simple v) (Simple v1); + rewrite cbor_match (p1 +. p2) (CBOR_Case_Simple v) (Simple v1) as cbor_match (p1 +. p2) c r1; } norewrite CBOR_Case_Tagged v -> { @@ -490,14 +523,19 @@ fn rec cbor_raw_gather rewrite (cbor_match p1 c r1) as (cbor_match_tagged v p1 r1 cbor_match); unfold (cbor_match_tagged v p1 r1 cbor_match); + with q1 c1 . assert (R.pts_to v.cbor_tagged_ptr #q1 c1); cbor_match_eq_tagged p2 v r2; rewrite (cbor_match p2 c r2) as (cbor_match_tagged v p2 r2 cbor_match); unfold (cbor_match_tagged v p2 r2 cbor_match); + with q2 c2 . assert (R.pts_to v.cbor_tagged_ptr #q1 c1 ** R.pts_to v.cbor_tagged_ptr #q2 c2); R.gather v.cbor_tagged_ptr; + rewrite each c2 as c1; cbor_raw_gather _ _ (Tagged?.v r1) _ _; perm_mul_add_l p1 p2 v.cbor_tagged_ref_perm; perm_mul_add_l p1 p2 v.cbor_tagged_payload_perm; + rewrite each (perm_mul p1 v.cbor_tagged_payload_perm +. + perm_mul p2 v.cbor_tagged_payload_perm) as (perm_mul (p1 +. p2) v.cbor_tagged_payload_perm); fold (cbor_match_tagged v (p1 +. p2) r1 cbor_match); cbor_match_eq_tagged (p1 +. p2) v r1; rewrite (cbor_match_tagged v (p1 +. p2) r1 cbor_match) @@ -510,6 +548,7 @@ fn rec cbor_raw_gather let Array len2 a2 = r2; cbor_raw_gather_array p1 v (Array len1 a1) p2 (Array len2 a2) cbor_raw_gather (); fold cbor_match (p1 +. p2) (CBOR_Case_Array v) (Array len1 a1); + rewrite cbor_match (p1 +. p2) (CBOR_Case_Array v) (Array len1 a1) as cbor_match (p1 +. p2) c r1 } CBOR_Case_Map v -> { unfold cbor_match p1 (CBOR_Case_Map v) r1; @@ -518,6 +557,7 @@ fn rec cbor_raw_gather let Map len2 a2 = r2; cbor_raw_gather_map p1 v (Map len1 a1) p2 (Map len2 a2) cbor_raw_gather (); fold cbor_match (p1 +. p2) (CBOR_Case_Map v) (Map len1 a1); + rewrite cbor_match (p1 +. p2) (CBOR_Case_Map v) (Map len1 a1) as cbor_match (p1 +. p2) c r1 } norewrite CBOR_Case_Serialized_Tagged v -> { @@ -529,6 +569,8 @@ fn rec cbor_raw_gather unfold (cbor_match_serialized_tagged v p2 r2); cbor_match_serialized_payload_tagged_gather _ _ (Tagged?.v r1) _ _; perm_mul_add_l p1 p2 v.cbor_serialized_perm; + rewrite each (perm_mul p1 v.cbor_serialized_perm +. + perm_mul p2 v.cbor_serialized_perm) as (perm_mul (p1 +. p2) v.cbor_serialized_perm); fold (cbor_match_serialized_tagged v (p1 +. p2) r1); rewrite (cbor_match_serialized_tagged v (p1 +. p2) r1) as (cbor_match (p1 +. p2) c r1); @@ -543,6 +585,8 @@ fn rec cbor_raw_gather unfold (cbor_match_serialized_array v p2 r2); cbor_match_serialized_payload_array_gather _ _ (Array?.v r1) _ _; perm_mul_add_l p1 p2 v.cbor_serialized_perm; + rewrite each (perm_mul p1 v.cbor_serialized_perm +. + perm_mul p2 v.cbor_serialized_perm) as (perm_mul (p1 +. p2) v.cbor_serialized_perm); fold (cbor_match_serialized_array v (p1 +. p2) r1); rewrite (cbor_match_serialized_array v (p1 +. p2) r1) as (cbor_match (p1 +. p2) c r1); @@ -557,6 +601,8 @@ fn rec cbor_raw_gather unfold (cbor_match_serialized_map v p2 r2); cbor_match_serialized_payload_map_gather _ _ (Map?.v r1) _ _; perm_mul_add_l p1 p2 v.cbor_serialized_perm; + rewrite each (perm_mul p1 v.cbor_serialized_perm +. + perm_mul p2 v.cbor_serialized_perm) as (perm_mul (p1 +. p2) v.cbor_serialized_perm); fold (cbor_match_serialized_map v (p1 +. p2) r1); rewrite (cbor_match_serialized_map v (p1 +. p2) r1) as (cbor_match (p1 +. p2) c r1); diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.fst index c7150a741..94e9e86d7 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Match.fst @@ -351,6 +351,7 @@ fn cbor_match_int_intro let resi = cbor_match_int_intro_aux typ i; let res = CBOR_Case_Int resi; fold (cbor_match 1.0R (CBOR_Case_Int resi) (Int64 typ i)); + rewrite (cbor_match 1.0R (CBOR_Case_Int resi) (Int64 typ i)) as cbor_match 1.0R res (Int64 typ i); res } @@ -383,6 +384,7 @@ ensures cbor_match p c v ** pure (Int64? v /\ res == Int64?.typ v) { cbor_match_cases c; + norewrite let CBOR_Case_Int c' = c; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_int c' v); unfold (cbor_match_int c' v); @@ -403,6 +405,7 @@ ensures cbor_match p c v ** pure (Int64? v /\ res == Int64?.v v) { cbor_match_cases c; + norewrite let CBOR_Case_Int c' = c; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_int c' v); unfold (cbor_match_int c' v); @@ -426,6 +429,7 @@ ensures emp { cbor_match_cases c; + norewrite let CBOR_Case_Int c' = c; rewrite (cbor_match p c v) as (cbor_match_int c' v); unfold (cbor_match_int c' v) @@ -463,6 +467,7 @@ fn cbor_match_simple_intro fold (cbor_match_simple i (Simple i)); let res = CBOR_Case_Simple i; fold (cbor_match 1.0R (CBOR_Case_Simple i) (Simple i)); + rewrite (cbor_match 1.0R (CBOR_Case_Simple i) (Simple i)) as cbor_match 1.0R res (Simple i); res } @@ -494,6 +499,7 @@ ensures cbor_match p c v ** pure (v == Simple res) { cbor_match_cases c; + norewrite let CBOR_Case_Simple res = c; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_simple res v); unfold (cbor_match_simple res v); @@ -513,6 +519,7 @@ ensures emp { cbor_match_cases c; + norewrite let CBOR_Case_Simple res = c; rewrite (cbor_match p c v) as (cbor_match_simple res v); unfold (cbor_match_simple res v) @@ -548,7 +555,7 @@ fn cbor_match_string_intro_aux fn _ { unfold (cbor_match_string c 1.0R r); - rewrite each c.cbor_string_ptr as input; + rewrite S.pts_to c.cbor_string_ptr #pm v as S.pts_to input #pm v; (); }; } @@ -599,6 +606,7 @@ ensures cbor_match p c v ** pure (String? v /\ res == String?.typ v) { cbor_match_cases c; + norewrite let CBOR_Case_String c' = c; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_string c' p v); unfold (cbor_match_string c' p v); @@ -619,6 +627,7 @@ ensures cbor_match p c v ** pure (String? v /\ res == String?.len v) { cbor_match_cases c; + norewrite let CBOR_Case_String c' = c; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_string c' p v); unfold (cbor_match_string c' p v); @@ -664,6 +673,7 @@ ensures exists* p' (v': Seq.seq U8.t) . pure (String? v /\ v' == String?.v v) { cbor_match_cases c; + norewrite let CBOR_Case_String c' = c; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_string c' p v); unfold (cbor_match_string c' p v); @@ -712,6 +722,7 @@ ensures { cbor_match_cases c; match c { + norewrite CBOR_Case_Tagged c' -> { cbor_match_eq_tagged p c' v; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_tagged c' p v cbor_match); @@ -720,6 +731,7 @@ ensures Trade.elim _ _; c'.cbor_tagged_tag } + norewrite CBOR_Case_Serialized_Tagged c' -> { Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_serialized_tagged c' p v); unfold (cbor_match_serialized_tagged c' p v); @@ -786,6 +798,7 @@ fn cbor_match_tagged_intro R.share pc; rewrite (R.pts_to pc #(pr /. 2.0R) c) as (R.pts_to res'.cbor_tagged_ptr #res'.cbor_tagged_ref_perm c); + rewrite cbor_match pm c r as cbor_match (perm_mul 1.0R res'.cbor_tagged_payload_perm) c (Tagged?.v (Tagged tag r)); fold (cbor_match_tagged res' 1.0R (Tagged tag r) cbor_match); intro (Trade.trade @@ -799,7 +812,12 @@ fn cbor_match_tagged_intro with c' . assert (R.pts_to res'.cbor_tagged_ptr #res'.cbor_tagged_ref_perm c'); rewrite (R.pts_to res'.cbor_tagged_ptr #res'.cbor_tagged_ref_perm c') as (R.pts_to pc #(pr /. 2.0R) c'); - R.gather pc + rewrite cbor_match (perm_mul 1.0R res'.cbor_tagged_payload_perm) + c' + (Tagged?.v (Tagged tag r)) + as cbor_match pm c' r; + R.gather pc; + rewrite each c' as c }; cbor_match_eq_tagged 1.0R res' (Tagged tag r); let res = CBOR_Case_Tagged res'; @@ -838,6 +856,7 @@ ensures { cbor_match_cases c; match c { + norewrite CBOR_Case_Array c' -> { cbor_match_eq_array p c' v; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_array c' p v cbor_match); @@ -846,6 +865,7 @@ ensures Trade.elim _ _; ({ size = c'.cbor_array_length_size; value = SZ.sizet_to_uint64 (S.len c'.cbor_array_ptr) }) } + norewrite CBOR_Case_Serialized_Array c' -> { Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_serialized_array c' p v); unfold (cbor_match_serialized_array c' p v); @@ -942,6 +962,7 @@ ensures { cbor_match_cases c; match c { + norewrite CBOR_Case_Map c' -> { cbor_match_eq_map0 p c' v; Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_map0 c' p v cbor_match); @@ -950,6 +971,7 @@ ensures Trade.elim _ _; ({ size = c'.cbor_map_length_size; value = SZ.sizet_to_uint64 (S.len c'.cbor_map_ptr) }) } + norewrite CBOR_Case_Serialized_Map c' -> { Trade.rewrite_with_trade (cbor_match p c v) (cbor_match_serialized_map c' p v); unfold (cbor_match_serialized_map c' p v); @@ -1086,6 +1108,7 @@ fn cbor_string_reset_perm_correct rewrite each c'.cbor_string_ptr as c.cbor_string_ptr; fold (cbor_match_string c p r) }; + rewrite each c' as cbor_string_reset_perm p c; } ghost @@ -1108,6 +1131,8 @@ fn cbor_tagged_reset_perm_correct with s . assert (pts_to c.cbor_tagged_ptr #(p `perm_mul` c.cbor_tagged_ref_perm) s); rewrite (pts_to c.cbor_tagged_ptr #(p `perm_mul` c.cbor_tagged_ref_perm) s) as (pts_to c'.cbor_tagged_ptr #(1.0R `perm_mul` c'.cbor_tagged_ref_perm) s); + with c_ . rewrite cbor_match (perm_mul p c.cbor_tagged_payload_perm) c_ (Tagged?.v r) + as cbor_match (perm_mul 1.0R c'.cbor_tagged_payload_perm) c_ (Tagged?.v r); fold (cbor_match_tagged c' 1.0R r cbor_match); intro (Trade.trade @@ -1121,8 +1146,12 @@ fn cbor_tagged_reset_perm_correct with s . assert (pts_to c'.cbor_tagged_ptr #(1.0R `perm_mul` c'.cbor_tagged_ref_perm) s); rewrite (pts_to c'.cbor_tagged_ptr #(1.0R `perm_mul` c'.cbor_tagged_ref_perm) s) as (pts_to c.cbor_tagged_ptr #(p `perm_mul` c.cbor_tagged_ref_perm) s); - fold (cbor_match_tagged c p r cbor_match) + with c_ . rewrite cbor_match (perm_mul 1.0R c'.cbor_tagged_payload_perm) c_ (Tagged?.v r) + as cbor_match (perm_mul p c.cbor_tagged_payload_perm) c_ (Tagged?.v r); + fold (cbor_match_tagged c p r cbor_match); + () }; + rewrite each c' as cbor_tagged_reset_perm p c; } ghost @@ -1160,6 +1189,7 @@ fn cbor_array_reset_perm_correct as (pts_to c.cbor_array_ptr #(p `perm_mul` c.cbor_array_array_perm) s); fold (cbor_match_array c p r cbor_match) }; + rewrite each c' as cbor_array_reset_perm p c; } ghost @@ -1197,6 +1227,7 @@ fn cbor_map_reset_perm_correct as (pts_to c.cbor_map_ptr #(p `perm_mul` c.cbor_map_array_perm) s); fold (cbor_match_map0 c p r cbor_match) }; + rewrite each c' as cbor_map_reset_perm p c; } ghost @@ -1215,6 +1246,7 @@ fn cbor_raw_reset_perm_correct cbor_match_cases c; let c' = cbor_raw_reset_perm_tot p c; match c { + norewrite CBOR_Case_String v -> { Trade.rewrite_with_trade (cbor_match p c r) @@ -1224,26 +1256,32 @@ fn cbor_raw_reset_perm_correct Trade.rewrite_with_trade (cbor_match_string (cbor_string_reset_perm p v) 1.0R r) (cbor_match 1.0R c' r); - Trade.trans _ _ (cbor_match p c r) + Trade.trans _ _ (cbor_match p c r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Int v -> { Trade.rewrite_with_trade (cbor_match p c r) (cbor_match_int v r); Trade.rewrite_with_trade (cbor_match_int v r) - (cbor_match 1.0R c r); - Trade.trans _ _ (cbor_match p c r) + (cbor_match 1.0R c' r); + Trade.trans _ _ (cbor_match p c r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Simple v -> { Trade.rewrite_with_trade (cbor_match p c r) (cbor_match_simple v r); Trade.rewrite_with_trade (cbor_match_simple v r) - (cbor_match 1.0R c r); - Trade.trans _ _ (cbor_match p c r) + (cbor_match 1.0R c' r); + Trade.trans _ _ (cbor_match p c r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Tagged v -> { cbor_match_eq_tagged p v r; cbor_match_eq_tagged 1.0R (cbor_tagged_reset_perm p v) r; @@ -1255,8 +1293,10 @@ fn cbor_raw_reset_perm_correct Trade.rewrite_with_trade (cbor_match_tagged (cbor_tagged_reset_perm p v) 1.0R r cbor_match) (cbor_match 1.0R c' r); - Trade.trans _ _ (cbor_match p c r) + Trade.trans _ _ (cbor_match p c r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Array v -> { cbor_match_eq_array p v r; cbor_match_eq_array 1.0R (cbor_array_reset_perm p v) r; @@ -1268,8 +1308,10 @@ fn cbor_raw_reset_perm_correct Trade.rewrite_with_trade (cbor_match_array (cbor_array_reset_perm p v) 1.0R r cbor_match) (cbor_match 1.0R c' r); - Trade.trans _ _ (cbor_match p c r) + Trade.trans _ _ (cbor_match p c r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Map v -> { cbor_match_eq_map0 p v r; cbor_match_eq_map0 1.0R (cbor_map_reset_perm p v) r; @@ -1281,22 +1323,29 @@ fn cbor_raw_reset_perm_correct Trade.rewrite_with_trade (cbor_match_map0 (cbor_map_reset_perm p v) 1.0R r cbor_match) (cbor_match 1.0R c' r); - Trade.trans _ _ (cbor_match p c r) + Trade.trans _ _ (cbor_match p c r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Serialized_Tagged _ -> { Trade.rewrite_with_trade (cbor_match p c r) - (cbor_match 1.0R c' r) + (cbor_match 1.0R c' r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Serialized_Array _ -> { Trade.rewrite_with_trade (cbor_match p c r) - (cbor_match 1.0R c' r) + (cbor_match 1.0R c' r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } + norewrite CBOR_Case_Serialized_Map _ -> { Trade.rewrite_with_trade (cbor_match p c r) - (cbor_match 1.0R c' r) + (cbor_match 1.0R c' r); + rewrite each c' as cbor_raw_reset_perm_tot p c; } } } diff --git a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Read.fst b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Read.fst index a24b0c029..18208d08d 100644 --- a/src/cbor/pulse/raw/CBOR.Pulse.Raw.Read.fst +++ b/src/cbor/pulse/raw/CBOR.Pulse.Raw.Read.fst @@ -29,6 +29,7 @@ fn cbor_match_tagged_get_payload { cbor_match_cases c; match c { + norewrite CBOR_Case_Serialized_Tagged cs -> { Trade.rewrite_with_trade (cbor_match pm c r) @@ -37,6 +38,7 @@ fn cbor_match_tagged_get_payload Trade.trans _ _ (cbor_match pm c r); res } + norewrite CBOR_Case_Tagged ct -> { cbor_match_eq_tagged pm ct r; Trade.rewrite_with_trade @@ -108,6 +110,7 @@ ensures exists* p' y . { cbor_match_cases c; match c { + norewrite CBOR_Case_Serialized_Array c' -> { Trade.rewrite_with_trade (cbor_match pm c r) @@ -116,6 +119,7 @@ ensures exists* p' y . Trade.trans _ _ (cbor_match pm c r); res } + norewrite CBOR_Case_Array c' -> { assert_norm (cbor_match pm (CBOR_Case_Array c') (Array (Array?.len r) (Array?.v r)) == cbor_match_array c' pm (Array (Array?.len r) (Array?.v r)) cbor_match @@ -131,6 +135,7 @@ ensures exists* p' y . Trade.elim_hyp_l _ _ (cbor_match pm c r); PM.seq_list_match_index_trade (cbor_match (pm `perm_mul` c'.cbor_array_payload_perm)) _ _ (U64.v i); Trade.trans _ _ (cbor_match pm c r); + rewrite each (U64.v i) as (SZ.v (SZ.uint64_to_sizet i)); res } } @@ -157,6 +162,7 @@ ensures exists* p . { cbor_match_cases c; match c { + norewrite CBOR_Case_Serialized_Array c' -> { Trade.rewrite_with_trade (cbor_match pm c r) @@ -177,6 +183,7 @@ ensures exists* p . (cbor_match pm c r); i } + norewrite CBOR_Case_Array c' -> { assert_norm (cbor_match pm (CBOR_Case_Array c') (Array (Array?.len r) (Array?.v r)) == cbor_match_array c' pm (Array (Array?.len r) (Array?.v r)) cbor_match @@ -269,10 +276,30 @@ ensures exists* a p i' q . (cbor_serialized_array_iterator_next sq) pi; with i'. assert (R.pts_to pi i'); + with l' . rewrite cbor_raw_iterator_match #cbor_raw + #raw_data_item + cbor_match + cbor_serialized_array_iterator_match + pm + i' + l' + as + cbor_raw_iterator_match #cbor_raw + #raw_data_item + cbor_match + cbor_serialized_array_iterator_match + pm + i' + (List.Tot.Base.tl l) + ; fold (cbor_array_iterator_match pm i' (List.Tot.tl l)); - with _pre _post. - rewrite trade _pre _post - as trade _pre (cbor_array_iterator_match pm i l); + with _pre1 _pre2 _post. + rewrite trade (_pre1 ** _pre2) _post + as trade (_pre1 ** cbor_array_iterator_match pm + (reveal u#0 #(cbor_raw_iterator cbor_raw) i') + (List.Tot.Base.tl u#0 + #raw_data_item + (reveal u#0 #(list u#0 raw_data_item) l))) (cbor_array_iterator_match pm i l); res } @@ -403,6 +430,7 @@ ensures exists* p . { cbor_match_cases c; match c { + norewrite CBOR_Case_Serialized_Map c' -> { Trade.rewrite_with_trade (cbor_match pm c r) @@ -423,6 +451,7 @@ ensures exists* p . (cbor_match pm c r); i } + norewrite CBOR_Case_Map c' -> { assert_norm (cbor_match pm (CBOR_Case_Map c') (Map (Map?.len r) (Map?.v r)) == cbor_match_map0 c' pm (Map (Map?.len r) (Map?.v r)) cbor_match @@ -496,7 +525,53 @@ ensures exists* a p i' q . (cbor_serialized_map_iterator_next sq) pi; with i' . assert (R.pts_to pi i'); + with l' . rewrite cbor_raw_iterator_match #cbor_map_entry + #(raw_data_item & raw_data_item) + cbor_match_map_entry + cbor_serialized_map_iterator_match + pm + (reveal u#0 #(cbor_raw_iterator cbor_map_entry) i') + l' as cbor_raw_iterator_match #cbor_map_entry + #(raw_data_item & raw_data_item) + cbor_match_map_entry + cbor_serialized_map_iterator_match + pm + (reveal u#0 #(cbor_raw_iterator cbor_map_entry) i') + (List.Tot.Base.tl u#0 + #(raw_data_item & raw_data_item) + (reveal u#0 #(list u#0 (raw_data_item & raw_data_item)) l)); fold (cbor_map_iterator_match pm i' (List.Tot.tl l)); + with p a q . rewrite + trade #emp_inames + (cbor_match_map_entry p + res + a ** + cbor_raw_iterator_match #cbor_map_entry + #(raw_data_item & raw_data_item) + cbor_match_map_entry + cbor_serialized_map_iterator_match + pm + (reveal u#0 #(cbor_raw_iterator cbor_map_entry) i') + q) + (cbor_raw_iterator_match #cbor_map_entry + #(raw_data_item & raw_data_item) + cbor_match_map_entry + cbor_serialized_map_iterator_match + pm + (reveal u#0 #(cbor_raw_iterator cbor_map_entry) i) + (reveal u#0 #(list u#0 (raw_data_item & raw_data_item)) l)) + as trade #emp_inames + (cbor_match_map_entry p + res + a ** + cbor_map_iterator_match pm + (reveal u#0 #(cbor_raw_iterator cbor_map_entry) i') + (List.Tot.Base.tl u#0 + #(raw_data_item & raw_data_item) + (reveal u#0 #(list u#0 (raw_data_item & raw_data_item)) l))) + (cbor_map_iterator_match pm + (reveal u#0 #cbor_map_iterator i) + (reveal u#0 #(list u#0 (raw_data_item & raw_data_item)) l)); res } diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst index a8f862906..be1e1cade 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst @@ -909,7 +909,7 @@ fn get_header_and_contents synth_raw_data_item synth_raw_data_item_recip input; - Trade.trans _ _ (pts_to_serialized serialize_raw_data_item input #pm v); + LowParse.Pulse.VCList.trade_trans_nounify _ _ _ (pts_to_serialized serialize_raw_data_item input #pm v); with v' . assert (pts_to_serialized (serialize_dtuple2 serialize_header serialize_content) input #pm v'); let ph, outc = split_dtuple2 serialize_header (jump_header ()) serialize_content input; unfold (split_dtuple2_post serialize_header serialize_content input pm v' (ph, outc)); @@ -918,6 +918,8 @@ fn get_header_and_contents let h = read_header () ph; Trade.elim_hyp_l _ _ _; outh := h; + rewrite each dfst (synth_raw_data_item_recip + v) as h; outc } @@ -964,7 +966,41 @@ fn get_tagged_payload pts_to_serialized_ext_trade (serialize_content h) serialize_raw_data_item - input + input; + rewrite + trade #emp_inames + (pts_to_serialized #parse_raw_data_item_kind + #(content (reveal #header h)) + #parse_raw_data_item + serialize_raw_data_item + input + #pm + (reveal #(content (reveal #header h)) c)) + (pts_to_serialized #parse_content_kind + #(content (reveal #header h)) + #(parse_content parse_raw_data_item (reveal #header h)) + (serialize_content (reveal #header h)) + input + #pm + (reveal #(content (reveal #header h)) c)) + as + trade #emp_inames + (pts_to_serialized #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item + input + #pm + (reveal #(content (reveal #header h)) c)) + (pts_to_serialized #parse_content_kind + #(content (reveal #header h)) + #(parse_content parse_raw_data_item (reveal #header h)) + (serialize_content (reveal #header h)) + input + #pm + (reveal #(content (reveal #header h)) c)) + ; + () } ghost @@ -983,7 +1019,58 @@ fn get_array_payload' pts_to_serialized_ext_trade (serialize_content h) (L.serialize_nlist (U64.v (Array?.len v).value) serialize_raw_data_item) - input + input; + rewrite + trade #emp_inames + (pts_to_serialized #(L.parse_nlist_kind (U64.v (Array?.len (reveal #raw_data_item v)) + .value) + parse_raw_data_item_kind) + #(content (reveal #header h)) + #(L.parse_nlist (U64.v (Array?.len (reveal #raw_data_item v)).value) + #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item) + (L.serialize_nlist (U64.v (Array?.len (reveal #raw_data_item v)).value) + #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item) + input + #pm + (reveal #(content (reveal #header h)) c)) + (pts_to_serialized #parse_content_kind + #(content (reveal #header h)) + #(parse_content parse_raw_data_item (reveal #header h)) + (serialize_content (reveal #header h)) + input + #pm + (reveal #(content (reveal #header h)) c)) + as + trade #emp_inames + (pts_to_serialized #(L.parse_nlist_kind (U64.v (Array?.len (reveal #raw_data_item v)) + .value) + parse_raw_data_item_kind) + #(L.nlist (U64.v (Array?.len (reveal #raw_data_item v)).value) raw_data_item) + #(L.parse_nlist (U64.v (Array?.len (reveal #raw_data_item v)).value) + #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item) + (L.serialize_nlist (U64.v (Array?.len (reveal #raw_data_item v)).value) + #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item) + input + #pm + (reveal #(content (reveal #header h)) c)) + (pts_to_serialized #parse_content_kind + #(content (reveal #header h)) + #(parse_content parse_raw_data_item (reveal #header h)) + (serialize_content (reveal #header h)) + input + #pm + (reveal #(content (reveal #header h)) c)); + () } ghost @@ -1016,7 +1103,93 @@ fn get_map_payload' pts_to_serialized_ext_trade (serialize_content h) (L.serialize_nlist (U64.v (Map?.len v).value) (serialize_nondep_then serialize_raw_data_item serialize_raw_data_item)) - input + input; + rewrite + trade #emp_inames + (pts_to_serialized #(L.parse_nlist_kind (U64.v (Map?.len (reveal #raw_data_item v)) + .value) + (and_then_kind parse_raw_data_item_kind parse_raw_data_item_kind)) + #(content (reveal #header h)) + #(L.parse_nlist (U64.v (Map?.len (reveal #raw_data_item v)).value) + #(and_then_kind parse_raw_data_item_kind parse_raw_data_item_kind) + #(raw_data_item & raw_data_item) + (nondep_then #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item + #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item)) + (L.serialize_nlist (U64.v (Map?.len (reveal #raw_data_item v)).value) + #(and_then_kind parse_raw_data_item_kind parse_raw_data_item_kind) + #(raw_data_item & raw_data_item) + #(nondep_then #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item + #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item) + (serialize_nondep_then #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item + #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item)) + input + #pm + (reveal #(content (reveal #header h)) c)) + (pts_to_serialized #parse_content_kind + #(content (reveal #header h)) + #(parse_content parse_raw_data_item (reveal #header h)) + (serialize_content (reveal #header h)) + input + #pm + (reveal #(content (reveal #header h)) c)) + as trade #emp_inames + (pts_to_serialized #(L.parse_nlist_kind (U64.v (Map?.len (reveal #raw_data_item v)) + .value) + (and_then_kind parse_raw_data_item_kind parse_raw_data_item_kind)) + #(L.nlist (U64.v (Map?.len (reveal #raw_data_item v)).value) + (raw_data_item & raw_data_item)) + #(L.parse_nlist (U64.v (Map?.len (reveal #raw_data_item v)).value) + #(and_then_kind parse_raw_data_item_kind parse_raw_data_item_kind) + #(raw_data_item & raw_data_item) + (nondep_then #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item + #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item)) + (L.serialize_nlist (U64.v (Map?.len (reveal #raw_data_item v)).value) + #(and_then_kind parse_raw_data_item_kind parse_raw_data_item_kind) + #(raw_data_item & raw_data_item) + #(nondep_then #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item + #parse_raw_data_item_kind + #raw_data_item + parse_raw_data_item) + (serialize_nondep_then #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item + #parse_raw_data_item_kind + #raw_data_item + #parse_raw_data_item + serialize_raw_data_item)) + input + #pm + (reveal #(content (reveal #header h)) c)) + (pts_to_serialized #parse_content_kind + #(content (reveal #header h)) + #(parse_content parse_raw_data_item (reveal #header h)) + (serialize_content (reveal #header h)) + input + #pm + (reveal #(content (reveal #header h)) c)) + ; + () } #pop-options diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Iterator.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Iterator.fst index 3c0211358..22a4a743f 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Iterator.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Iterator.fst @@ -260,7 +260,7 @@ fn cbor_raw_serialized_iterator_next i.s; unfold (LPC.split_nondep_then_post s s' i.s (pm *. i.p) v' (s1, s2)); unfold (LPC.split_nondep_then_post' s s' i.s (pm *. i.p) v' s1 s2); - Trade.trans _ _ (cbor_raw_serialized_iterator_match s pm i l); + trade_trans_nounify _ _ _ (cbor_raw_serialized_iterator_match s pm i l); let res = phi s1; with pm' . assert (elt_match pm' res (fst v')); Trade.rewrite_with_trade @@ -281,7 +281,7 @@ fn cbor_raw_serialized_iterator_next _ (cbor_raw_serialized_iterator_match s pm i' (List.Tot.tl l)) _; - Trade.trans _ _ (cbor_raw_serialized_iterator_match s pm i l); + trade_trans_nounify _ _ _ (cbor_raw_serialized_iterator_match s pm i l); res } diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Serialized.Base.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Serialized.Base.fst index 1e0e5c45f..f51d03f4e 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Serialized.Base.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Serialized.Base.fst @@ -38,6 +38,13 @@ fn cbor_match_serialized_tagged_intro_aux (pts_to_serialized serialize_raw_data_item pc #pm v) { fold (cbor_match_serialized_payload_tagged pc (1.0R `perm_mul` res.cbor_serialized_perm) v); + rewrite cbor_match_serialized_payload_tagged pc + (perm_mul 1.0R res.cbor_serialized_perm) + v + as + cbor_match_serialized_payload_tagged res.cbor_serialized_payload + (perm_mul 1.0R res.cbor_serialized_perm) + (Tagged?.v r); fold (cbor_match_serialized_tagged res 1.0R r); intro (Trade.trade @@ -48,7 +55,13 @@ fn cbor_match_serialized_tagged_intro_aux fn _ { unfold (cbor_match_serialized_tagged res 1.0R r); - unfold (cbor_match_serialized_payload_tagged pc pm v) + rewrite + cbor_match_serialized_payload_tagged res.cbor_serialized_payload + (perm_mul 1.0R res.cbor_serialized_perm) + (Tagged?.v r) + as (cbor_match_serialized_payload_tagged pc pm v); + unfold (cbor_match_serialized_payload_tagged pc pm v); + () }; } @@ -77,6 +90,9 @@ fn cbor_match_serialized_array_intro_aux (pts_to_serialized (LowParse.Spec.VCList.serialize_nlist n serialize_raw_data_item) pc #pm v) { fold (cbor_match_serialized_payload_array pc (1.0R `perm_mul` pm) v); + rewrite cbor_match_serialized_payload_array pc (perm_mul 1.0R pm) v as cbor_match_serialized_payload_array res.cbor_serialized_payload + (perm_mul 1.0R res.cbor_serialized_perm) + (Array?.v r); fold (cbor_match_serialized_array res 1.0R r); intro (Trade.trade @@ -87,6 +103,9 @@ fn cbor_match_serialized_array_intro_aux fn _ { unfold (cbor_match_serialized_array res 1.0R r); + rewrite cbor_match_serialized_payload_array res.cbor_serialized_payload + (perm_mul 1.0R res.cbor_serialized_perm) + (Array?.v r) as cbor_match_serialized_payload_array pc pm (Array?.v r); unfold (cbor_match_serialized_payload_array pc pm (Array?.v r)) }; } @@ -116,6 +135,9 @@ fn cbor_match_serialized_map_intro_aux (pts_to_serialized (LowParse.Spec.VCList.serialize_nlist n (serialize_nondep_then serialize_raw_data_item serialize_raw_data_item)) pc #pm v) { fold (cbor_match_serialized_payload_map pc (1.0R `perm_mul` pm) v); + rewrite cbor_match_serialized_payload_map pc (perm_mul 1.0R pm) v as cbor_match_serialized_payload_map res.cbor_serialized_payload + (perm_mul 1.0R res.cbor_serialized_perm) + (Map?.v r); fold (cbor_match_serialized_map res 1.0R r); intro (Trade.trade @@ -126,6 +148,9 @@ fn cbor_match_serialized_map_intro_aux fn _ { unfold (cbor_match_serialized_map res 1.0R r); + rewrite cbor_match_serialized_payload_map res.cbor_serialized_payload + (perm_mul 1.0R res.cbor_serialized_perm) + (Map?.v r) as cbor_match_serialized_payload_map pc pm (Map?.v r); unfold (cbor_match_serialized_payload_map pc pm (Map?.v r)) }; } @@ -149,7 +174,9 @@ fn cbor_read if (typ = cbor_major_type_uint64 || typ = cbor_major_type_neg_int64) { elim_trade _ _; let i = get_int64_value v h; - cbor_match_int_intro_trade (pts_to_serialized serialize_raw_data_item input #pm v) typ i + let res = cbor_match_int_intro_trade (pts_to_serialized serialize_raw_data_item input #pm v) typ i; + rewrite each (Int64 typ i) as v; + res } else if (typ = cbor_major_type_text_string || typ = cbor_major_type_byte_string) { let i = get_string_length v h; @@ -157,6 +184,8 @@ fn cbor_read Trade.trans _ _ (pts_to_serialized serialize_raw_data_item input #pm v); let res = cbor_match_string_intro typ i pc; Trade.trans _ _ (pts_to_serialized serialize_raw_data_item input #pm v); + with r . assert cbor_match 1.0R res r; + rewrite each r as v; res } else if (typ = cbor_major_type_tagged) { @@ -219,7 +248,9 @@ fn cbor_read assert (pure (typ == cbor_major_type_simple_value)); elim_trade _ _; let i = get_simple_value v h; - cbor_match_simple_intro_trade (pts_to_serialized serialize_raw_data_item input #pm v) i + let res = cbor_match_simple_intro_trade (pts_to_serialized serialize_raw_data_item input #pm v) i; + rewrite each (Simple i) as v; + res } } #pop-options diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst index 6785e0f40..d2beb64a1 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst @@ -367,40 +367,49 @@ ensures { cbor_match_cases xl; match xl { + norewrite CBOR_Case_Int _ -> { let ty = cbor_match_int_elim_type xl; let v = cbor_match_int_elim_value xl; raw_uint64_as_argument ty v } + norewrite CBOR_Case_String _ -> { let ty = cbor_match_string_elim_type xl; let len = cbor_match_string_elim_length xl; raw_uint64_as_argument ty len } + norewrite CBOR_Case_Tagged _ -> { let tag = cbor_match_tagged_get_tag xl; raw_uint64_as_argument cbor_major_type_tagged tag } + norewrite CBOR_Case_Serialized_Tagged _ -> { let tag = cbor_match_tagged_get_tag xl; raw_uint64_as_argument cbor_major_type_tagged tag } + norewrite CBOR_Case_Array _ -> { let len = cbor_match_array_get_length xl; raw_uint64_as_argument cbor_major_type_array len } + norewrite CBOR_Case_Serialized_Array _ -> { let len = cbor_match_array_get_length xl; raw_uint64_as_argument cbor_major_type_array len } + norewrite CBOR_Case_Map _ -> { let len = cbor_match_map_get_length xl; raw_uint64_as_argument cbor_major_type_map len } + norewrite CBOR_Case_Serialized_Map _ -> { let len = cbor_match_map_get_length xl; raw_uint64_as_argument cbor_major_type_map len } + norewrite CBOR_Case_Simple _ -> { let v = cbor_match_simple_elim xl; simple_value_as_argument v @@ -585,7 +594,7 @@ vmatch_lens #_ #_ #_ (cbor_match x1'.p x1'.v xh'); Trade.trans (cbor_match x1'.p x1'.v xh') - _ _; + (cbor_match_with_perm x1' xh') _; // FIXME: WHY WHY WHY do I now have to help Pulse here? let s = cbor_match_string_elim_payload x1'.v; Trade.trans _ (cbor_match _ x1'.v xh') _; S.pts_to_len s; @@ -601,11 +610,12 @@ vmatch_lens #_ #_ #_ s z res; - Trade.trans + LowParse.Pulse.VCList.trade_trans_nounify (LowParse.Pulse.SeqBytes.pts_to_seqbytes (U64.v (argument_as_uint64 (get_header_initial_byte xh1) (get_header_long_argument xh1))) res x') + _ _ _; Trade.rewrite_with_trade (LowParse.Pulse.SeqBytes.pts_to_seqbytes @@ -1639,6 +1649,7 @@ fn ser_payload_tagged_not_tagged_lens }; cbor_serialized_tagged_pts_to_serialized_with_perm_trade ser _ _ res; Trade.trans _ (cbor_match_serialized_tagged ser xl.p xh0) _; + rewrite each (Tagged?.v xh0) as v; res } diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialized.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialized.fst index 88dabd593..da38b26fa 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialized.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialized.fst @@ -170,7 +170,7 @@ ensures ; Trade.trans _ _ (cbor_match_serialized_array c pm r); cbor_raw_serialized_iterator_fold serialize_raw_data_item p res (Array?.v r); - Trade.trans _ _ (cbor_match_serialized_array c pm r); + LowParse.Pulse.VCList.trade_trans_nounify _ _ _ (cbor_match_serialized_array c pm r); fold (cbor_serialized_array_iterator_match p res (Array?.v r)); res } @@ -272,7 +272,7 @@ ensures ; Trade.trans _ _ (cbor_match_serialized_map c pm r); cbor_raw_serialized_iterator_fold (serialize_nondep_then serialize_raw_data_item serialize_raw_data_item) p res (Map?.v r); - Trade.trans _ _ (cbor_match_serialized_map c pm r); + LowParse.Pulse.VCList.trade_trans_nounify _ _ _ (cbor_match_serialized_map c pm r); fold (cbor_serialized_map_iterator_match p res (Map?.v r)); res } diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst b/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst index 2b04e942d..20712ee78 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.Base.fst @@ -184,7 +184,7 @@ fn validate_and_parse match q { None -> { unfold (cbor_det_parse_post vmatch s p w None); - fold (validate_and_parse_post ps r s p w None); + fold (validate_and_parse_post ps r' s p w None); None } Some rlrem -> { @@ -199,10 +199,11 @@ fn validate_and_parse let x = i rl; Trade.trans_hyp_l _ _ _ (pts_to s #p w); fold (validate_and_parse_post ps r s p w (Some (x, rem))); + rewrite (validate_and_parse_post ps r s p w (Some (x, rem))) as (validate_and_parse_post ps r' s p w (Some (x, rem))); Some (x, rem) } else { Trade.elim _ _; - fold (validate_and_parse_post ps r s p w None); + fold (validate_and_parse_post ps r' s p w None); None } } diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.Misc.fst b/src/cddl/pulse/CDDL.Pulse.Parse.Misc.fst index 87702404f..35adb69a7 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.Misc.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.Misc.fst @@ -407,6 +407,7 @@ fn impl_copyful_det_cbor Some cp_ -> { let cp = fst cp_; let rem = Ghost.hide (snd cp_); + with cp' . rewrite cbor_det_parse_post vmatch' cs ps s cp' as cbor_det_parse_post vmatch' cs ps s (Some (cp, Ghost.reveal rem)); unfold (cbor_det_parse_post vmatch' cs ps s (Some (cp, Ghost.reveal rem))); unfold (cbor_det_parse_post_some vmatch' cs ps s cp rem); Trade.trans _ _ (vmatch p c v); @@ -447,6 +448,7 @@ fn impl_zero_copy_det_cbor Some cp_ -> { let cp = fst cp_; let rem = Ghost.hide (snd cp_); + with cp' . rewrite (cbor_det_parse_post vmatch' cs ps s (Some cp')) as (cbor_det_parse_post vmatch' cs ps s (Some (cp, Ghost.reveal rem))); unfold (cbor_det_parse_post vmatch' cs ps s (Some (cp, Ghost.reveal rem))); unfold (cbor_det_parse_post_some vmatch' cs ps s cp rem); with ps vs . assert (vmatch' ps cp vs); diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index c0583b733..93c0224c1 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -1576,7 +1576,7 @@ fn impl_serialize_map_zero_or_more_iterator_gen S.pts_to_len outl2; // assert (pure (S.len outl == size2)); let Some oo1 = parse outl2; - let (o1, orem1) = oo1; + norewrite let (o1, orem1) = oo1; rewrite (cbor_det_parse_post vmatch' outl2 1.0R vl (Some oo1)) as (cbor_det_parse_post_some vmatch' outl2 1.0R vl o1 orem1); unfold (cbor_det_parse_post_some vmatch' outl2 1.0R vl o1 orem1); @@ -1585,7 +1585,7 @@ fn impl_serialize_map_zero_or_more_iterator_gen Cbor.cbor_det_serialize_inj_strong ke' (sp1.serializer ke) w1'' Seq.empty; assert (pure (Ghost.reveal ke' == sp1.serializer ke)); let Some oo2 = parse out2; - let (o2, orem2) = oo2; + norewrite let (o2, orem2) = oo2; rewrite (cbor_det_parse_post vmatch' out2 1.0R w2 (Some oo2)) as (cbor_det_parse_post_some vmatch' out2 1.0R w2 o2 orem2); unfold (cbor_det_parse_post_some vmatch' out2 1.0R w2 o2 orem2); @@ -1862,7 +1862,11 @@ fn map_slice_iterator_next unfold (rel_slice_of_list r false i'.base l'); with s' . assert (pts_to i'.base.s #i'.base.p s'); SM.seq_list_match_cons_intro res (Ghost.reveal gv) s' l' r; + with s1 s2 s . rewrite (S.is_split s1 s2 s) as S.is_split i.base.s il i'.base.s; S.join il i'.base.s i.base.s; + with s1 . assert pts_to i.base.s #i.base.p s1; + with s2 . rewrite SM.seq_list_match s2 (Ghost.reveal gv :: l') (rel_pair #_ #(dfst spec1) (dsnd spec1) #_ #(dfst spec2) (dsnd spec2)) + as SM.seq_list_match s1 (Ghost.reveal gv :: l') (rel_pair #_ #(dfst spec1) (dsnd spec1) #_ #(dfst spec2) (dsnd spec2)); fold (rel_slice_of_list (rel_pair #_ #(dfst spec1) (dsnd spec1) #_ #(dfst spec2) (dsnd spec2)) false diff --git a/src/lowparse/pulse/LowParse.Pulse.Base.fst b/src/lowparse/pulse/LowParse.Pulse.Base.fst index 5e40e5ec1..60ba16219 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Base.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Base.fst @@ -94,6 +94,15 @@ let pts_to_serialized_ext_trade_gen_precond t1 == t2 /\ (forall x . parse p1 x == parse p2 x) +let pts_to_serialized_ext_trade_gen_post + (t1 t2: Type0) + (v: t1) + (v2: t2) +: Tot prop += + t1 == t2 /\ + v == v2 + ghost fn pts_to_serialized_ext_trade_gen (#t1 #t2: Type0) @@ -111,9 +120,7 @@ fn pts_to_serialized_ext_trade_gen ) ensures exists* v2 . pts_to_serialized s2 input #pm v2 ** trade (pts_to_serialized s2 input #pm v2) (pts_to_serialized s1 input #pm v) ** - pure (t1 == t2 /\ - v == v2 - ) + pure (pts_to_serialized_ext_trade_gen_post t1 t2 v v2) { pts_to_serialized_ext s1 s2 input; intro diff --git a/src/lowparse/pulse/LowParse.Pulse.Combinators.fst b/src/lowparse/pulse/LowParse.Pulse.Combinators.fst index 698144b7a..385b98f1f 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Combinators.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Combinators.fst @@ -1059,6 +1059,18 @@ fn split_nondep_then unfold (split_dtuple2_post #t1 #(const_fun t2) s1 #k2 #(const_fun p2) (const_fun s2) input pm (dtuple2_of_pair v) (input1, input2)); unfold (split_dtuple2_post' #t1 #(const_fun t2) s1 #_ #(const_fun p2) (const_fun s2) input pm (dtuple2_of_pair v) input1 input2); Trade.trans (_ ** _) _ _; + rewrite + (trade (pts_to_serialized s1 input1 #pm (dfst (dtuple2_of_pair v)) ** + pts_to_serialized (const_fun s2 (dfst (dtuple2_of_pair v))) + input2 #pm + (dsnd (dtuple2_of_pair v))) + (pts_to_serialized (serialize_nondep_then s1 s2) input #pm v)) + as + (trade (pts_to_serialized s1 input1 #pm (fst v) ** + pts_to_serialized (const_fun s2 (fst v)) + input2 #pm + (snd v)) + (pts_to_serialized (serialize_nondep_then s1 s2) input #pm v)); fold (split_nondep_then_post' s1 s2 input pm v input1 input2); fold (split_nondep_then_post s1 s2 input pm v (input1, input2)); (input1, input2) @@ -1848,6 +1860,10 @@ fn l2r_leaf_write_dtuple2_body_lens (x: Ghost.erased (th2 xh1)) { let _ = l2r_leaf_write_dtuple2_body_lens_aux xh1 x' x; + with y . rewrite (trade (eq_as_slprop (th2 xh1) y x) + (vmatch_dep_proj2 (eq_as_slprop (dtuple2 th1 th2)) xh1 x' x) ** eq_as_slprop (th2 xh1) y x) + as (trade (eq_as_slprop (th2 xh1) (dsnd x') x) + (vmatch_dep_proj2 (eq_as_slprop (dtuple2 th1 th2)) xh1 x' x) ** eq_as_slprop (th2 xh1) (dsnd x') x); dsnd x' } @@ -1986,6 +2002,7 @@ fn read_and_zero_copy_parse_dtuple2 let v1 = w1 input1; Trade.elim_hyp_l _ _ _; let res = w2 v1 input2; + rewrite each (dfst v) as v1; Trade.trans (vmatch_dep_proj2 vmatch v1 res _) _ _; Trade.rewrite_with_trade (vmatch_dep_proj2 vmatch v1 res _) @@ -2107,7 +2124,7 @@ returns xl1: tl1 ensures vmatch1 xl1 (fst xh) ** trade (vmatch1 xl1 (fst xh)) (vmatch_pair vmatch1 vmatch2 xl xh) { - let (res, _) = xl; + norewrite let (res, _) = xl; Trade.rewrite_with_trade (vmatch_pair vmatch1 vmatch2 xl xh) (vmatch1 res (fst xh) ** vmatch2 (snd xl) (snd xh)); @@ -2128,7 +2145,7 @@ returns xl2: tl2 ensures vmatch2 xl2 (snd xh) ** trade (vmatch2 xl2 (snd xh)) (vmatch_pair vmatch1 vmatch2 xl xh) { - let (_, res) = xl; + norewrite let (_, res) = xl; Trade.rewrite_with_trade (vmatch_pair vmatch1 vmatch2 xl xh) (vmatch1 (fst xl) (fst xh) ** vmatch2 res (snd xh)); diff --git a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst index 7bd9a35a5..ef38a7199 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst @@ -579,6 +579,16 @@ let serialize_recursive_bound_correct (count <= Seq.length (L.serialize_nlist count (serializer_of_tot_serializer (serialize_recursive s)) c)) = parse_nlist_recursive_bound_correct' p count (L.serialize_nlist count (serializer_of_tot_serializer (serialize_recursive s)) c) +ghost fn trade_rewrite_l + (p p' q: slprop) +requires + trade p q ** pure (p == p') +ensures + trade p' q +{ + rewrite each p as p' +} + inline_for_extraction fn impl_nlist_forall_pred_recursive (#p: Ghost.erased parse_recursive_param) @@ -695,8 +705,12 @@ fn impl_nlist_forall_pred_recursive Trade.trans _ _ (pts_to_serialized (L.serialize_nlist (SZ.v n0) (serializer_of_tot_serializer (serialize_recursive s))) input #pm v); - pn := SZ.add (SZ.sub n 1sz) count; + let n' = SZ.add (SZ.sub n 1sz) count; + pn := n'; ppi := pc; + with vi' . assert (pts_to_serialized (L.serialize_nlist (SZ.v n') (serializer_of_tot_serializer (serialize_recursive s))) pc #pm vi'); + trade_rewrite_l _ (pts_to_serialized (L.serialize_nlist (SZ.v n') (serializer_of_tot_serializer (serialize_recursive s))) pc #pm vi') _; + () } }; elim_trade _ _; diff --git a/src/lowparse/pulse/LowParse.Pulse.VCList.fst b/src/lowparse/pulse/LowParse.Pulse.VCList.fst index 989008da3..1c79a9e49 100644 --- a/src/lowparse/pulse/LowParse.Pulse.VCList.fst +++ b/src/lowparse/pulse/LowParse.Pulse.VCList.fst @@ -185,9 +185,9 @@ ensures exists* v' . synth_inverse_2 t (n - 1); Trade.rewrite_with_trade (pts_to_serialized (serialize_nlist n s) input #pm v) - (pts_to_serialized (serialize_synth _ (synth_nlist (n - 1)) (serialize_nondep_then s (serialize_nlist' (n - 1) s)) (synth_nlist_recip (n - 1)) ()) input #pm v); + (pts_to_serialized (serialize_synth _ (synth_nlist (n - 1)) (serialize_nondep_then s (serialize_nlist (n - 1) s)) (synth_nlist_recip (n - 1)) ()) input #pm v); pts_to_serialized_synth_l2r_trade - (serialize_nondep_then s (serialize_nlist' (n - 1) s)) + (serialize_nondep_then s (serialize_nlist (n - 1) s)) (synth_nlist (n - 1)) (synth_nlist_recip (n - 1)) input; @@ -252,8 +252,11 @@ ensures unfold (split_nondep_then_post s (serialize_nlist (n - 1) s) input pm v' (s1, s2)); unfold (split_nondep_then_post' s (serialize_nlist (n - 1) s) input pm v' s1 s2); Trade.trans _ _ (pts_to_serialized (serialize_nlist n s) input #pm v); + rewrite each (fst v') as (List.Tot.hd v); + rewrite each (snd v') as (List.Tot.tl v); fold (nlist_hd_tl_post' s sq n input pm v s1 s2); - fold (nlist_hd_tl_post s sq n input pm v res); + rewrite (nlist_hd_tl_post' s sq n input pm v s1 s2) + as (nlist_hd_tl_post s sq n input pm v res); res } @@ -380,6 +383,15 @@ ensures ( hd tl ); Trade.trans _ _ (pts_to_serialized (serialize_nondep_then (serialize_nlist n s) s') input #pm v); + with vhd v' . assert ( + pts_to_serialized s hd #pm vhd ** + pts_to_serialized (serialize_nondep_then (serialize_nlist (n - 1) s) s') tl #pm v' ** + Trade.trade + (pts_to_serialized s hd #pm vhd ** + pts_to_serialized (serialize_nondep_then (serialize_nlist (n - 1) s) s') tl #pm v') + (pts_to_serialized (serialize_nondep_then (serialize_nlist n s) s') input #pm v) + ); + rewrite each vhd as (List.Tot.hd (fst v)); (hd, tl) } @@ -508,6 +520,33 @@ ensures ( tl } +ghost fn trade_trans_nounify + (a1 a2 a2' a3: slprop) +requires + trade a1 a2 ** trade a2' a3 ** pure (a2 == a2') +ensures + trade a1 a3 +{ + rewrite each a2' as a2; + Trade.trans a1 a2 a3 +} + +let nlist_nth_inv + (#t: Type0) + (n0: Ghost.erased nat) + (v0: list t) + (i0: SZ.t) + (i: SZ.t) + (n: nat) + (v: list t) +: Tot prop += SZ.v i0 < n0 /\ + SZ.v i <= SZ.v i0 /\ + n == n0 - SZ.v i /\ + List.Tot.length v0 == Ghost.reveal n0 /\ + List.Tot.length v == n /\ + List.Tot.index v0 (SZ.v i0) == List.Tot.index v (SZ.v i0 - SZ.v i) + inline_for_extraction fn nlist_nth (#t: Type0) @@ -549,20 +588,21 @@ ensures exists* v . let res = !pres; rewrite each 'res as res; let i = !pi; + with v . assert (pts_to_serialized (serialize_nlist (n0 - SZ.v i) s) res #pm v); let res2 = nlist_tl s j (n0 - SZ.v i) res; pi := (SZ.add i 1sz); pres := res2; - Trade.trans - (pts_to_serialized (serialize_nlist (n0 - SZ.v i - 1) s) res2 #pm _) - _ - _ + with v' . assert (pts_to_serialized (serialize_nlist (n0 - SZ.v i - 1) s) res2 #pm v'); +// rewrite each (n') as (n0 - SZ.v i - 1); + trade_trans_nounify _ _ _ + (pts_to_serialized (serialize_nlist n0 s) input #pm v0); }; with 'res. assert R.pts_to pres 'res; let res = !pres; rewrite each 'res as res; let res2 = nlist_hd s j (n0 - SZ.v i0) res; - Trade.trans - (pts_to_serialized s res2 #pm _) _ _; + trade_trans_nounify + _ _ _ (pts_to_serialized (serialize_nlist n0 s) input #pm v0); res2 } @@ -608,14 +648,15 @@ ensures true } else { let pl = nlist_hd_tl s sq j (SZ.v n) a; - let s1, s2 = pl; - unfold (nlist_hd_tl_post s sq (SZ.v n) a pm v pl); + norewrite let s1, s2 = pl; + rewrite (nlist_hd_tl_post s sq (SZ.v n) a pm v pl) as (nlist_hd_tl_post' s sq (SZ.v n) a pm v s1 s2); unfold (nlist_hd_tl_post' s sq (SZ.v n) a pm v s1 s2); let mut phd = s1; let mut ptl = s2; let n' : SZ.t = SZ.sub n 1sz; let mut pi = n'; let mut pres = true; + rewrite each (SZ.v n - 1) as SZ.v n'; while ( let i = !pi; let res = !pres; @@ -644,8 +685,8 @@ ensures rewrite each 'stl as stl; with tl . assert (pts_to_serialized (serialize_nlist (SZ.v gi) s) stl #pm tl); let pl = nlist_hd_tl s sq j (SZ.v gi) stl; - let s1, s2 = pl; - unfold (nlist_hd_tl_post s sq (SZ.v gi) stl pm tl pl); + norewrite let s1, s2 = pl; + rewrite (nlist_hd_tl_post s sq (SZ.v gi) stl pm tl pl) as (nlist_hd_tl_post' s sq (SZ.v gi) stl pm tl s1 s2); unfold (nlist_hd_tl_post' s sq (SZ.v gi) stl pm tl s1 s2); with 'phd. assert R.pts_to phd 'phd; let shd = !phd; @@ -659,6 +700,8 @@ ensures let i = !pi; let i' : SZ.t = SZ.sub i 1sz; pi := i'; + rewrite each (SZ.v i - 1) as SZ.v i'; + () } else { Trade.elim _ (pts_to_serialized (serialize_nlist (SZ.v gi) s) stl #pm tl); pres := false; @@ -1395,6 +1438,7 @@ fn l2r_write_nlist_as_slice0 let n' = S.len arr.v; nlist_match_slice_intro Some (fun _ -> vmatch) (SZ.v n') arr x arr c; let res = l2r_write_nlist_as_slice Some (fun _ -> vmatch) s (fun _ -> w) n' arr out offset; + rewrite each SZ.v n' as n; fold (nlist_match_slice0 vmatch (n) arr x); res } From c42bf836538717074a04b71db22a1ecd683a467b Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 20 Nov 2025 00:45:58 +0000 Subject: [PATCH 17/33] LowParse.Pulse rlimit --- src/lowparse/pulse/LowParse.Pulse.Recursive.fst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst index ef38a7199..5b96c8a01 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst @@ -59,6 +59,8 @@ let parse_nlist_recursive_bound_correct #restart-solver +#push-options "--z3rlimit_factor 4" + let validate_tot_nlist_recursive_progress (p: parse_recursive_param) (v: bytes) @@ -89,6 +91,8 @@ let validate_tot_nlist_recursive_progress )) = parse_consume_nlist_recursive_eq' p n (Seq.slice v off (Seq.length v)) +#pop-options + #restart-solver #push-options "--z3rlimit_factor 4 --split_queries always" @@ -254,7 +258,7 @@ let jump_recursive_step_count (pts_to_serialized (serializer_of_tot_serializer s.serialize_header) a #pm va ** pure (p.count va <= SZ.v bound)) (fun res -> pts_to_serialized (serializer_of_tot_serializer s.serialize_header) a #pm va ** pure (p.count va == SZ.v res)) -#push-options "--z3rlimit 32" +#push-options "--z3rlimit_factor 16 --ifuel 4" #restart-solver inline_for_extraction @@ -422,7 +426,7 @@ let tot_nondep_then_eq )) = C.nondep_then_eq #k1 p1 #k2 p2 b -#push-options "--z3rlimit 32" +#push-options "--z3rlimit_factor 8" #restart-solver From 2a1a624442b44c23ebfcbaa7a2cd9e5a772905e6 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 20 Nov 2025 00:48:43 +0000 Subject: [PATCH 18/33] Revert "partial F*, Karamel, Pulse upgrade" This reverts commit a2ad34be566a0a9dce5904415d86a6389033cd6e. --- opt/hashes.Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index 011db6f7e..b3b02e1f3 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 3e3ce160b5a61c6eb036137068e64c46af38e0fd -karamel_hash := 8e7262955105599e91f3a99c9ab3d3387f7046f2 -pulse_hash := b6fe83f041203c407e29a8400bb3f801d69d1f8d +FStar_hash := 1e97045d6cf714bc45a00f54fcedccdfb08a31f5 +karamel_hash := fb36fecb552c9fb202beb38a6c5a732c3f2cd49f +pulse_hash := 47b4e2103e3ce09ab7e1cb50409fa67d73bb947a From 679a11e6fe75186ac4b3fb1f7a7eec18cf08b242 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 20 Nov 2025 00:49:06 +0000 Subject: [PATCH 19/33] full F*, Karamel, Pulse upgrade --- opt/hashes.Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index b3b02e1f3..37307794f 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 1e97045d6cf714bc45a00f54fcedccdfb08a31f5 -karamel_hash := fb36fecb552c9fb202beb38a6c5a732c3f2cd49f -pulse_hash := 47b4e2103e3ce09ab7e1cb50409fa67d73bb947a +FStar_hash := cb10e521335aab2adc5e2951ba066fa256599d8c +karamel_hash := b76a625f12cfbbcd6db9daec6b845a4a09bf3fbe +pulse_hash := 8db0c41eba48e5b49de65dbf2e514a2c26189e22 From f771f78b471664255c317fe4bc68bba829998903 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 20 Nov 2025 00:01:49 +0000 Subject: [PATCH 20/33] WHY WHY WHY do Pulse functions with functional types no longer typecheck? This commit gives one example of cumbersome workaround, which I have by far not replicated yet. --- .../pulse/LowParse.Pulse.Combinators.fst | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/src/lowparse/pulse/LowParse.Pulse.Combinators.fst b/src/lowparse/pulse/LowParse.Pulse.Combinators.fst index 385b98f1f..d9733a37a 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Combinators.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Combinators.fst @@ -1939,8 +1939,9 @@ let leaf_compute_remaining_size_dtuple2 (leaf_compute_remaining_size_dtuple2_body w2) ) +// FIXME: WHY WHY WHY do my Pulse functions with functional types no longer typecheck? WHY WHY WHY do I need to expand the definition of the functional type in Pulse as below? In most cases this will be awfully painful! inline_for_extraction -fn zero_copy_parse_dtuple2 +fn zero_copy_parse_dtuple2' (#tl1 #tl2 #th1: Type) (#th2: th1 -> Type) (#vmatch1: tl1 -> th1 -> slprop) @@ -1955,10 +1956,17 @@ fn zero_copy_parse_dtuple2 (#p2: (x: th1) -> parser k2 (th2 x)) (#s2: (x: th1) -> serializer (p2 x)) (w2: (xh: Ghost.erased th1) -> zero_copy_parse (vmatch2 xh) (s2 xh)) -: zero_copy_parse #(tl1 `cpair` tl2) #(dtuple2 th1 th2) (vmatch_dep_prod vmatch1 vmatch2) #(and_then_kind k1 k2) #(parse_dtuple2 p1 p2) (serialize_dtuple2 s1 s2) -= (input: _) - (#pm: _) - (#v: _) + (input: slice byte) + (#pm: perm) + (#v: Ghost.erased (dtuple2 th1 th2)) +requires + pts_to_serialized (serialize_dtuple2 s1 s2) input #pm v +returns res: (tl1 `cpair` tl2) +ensures + vmatch_dep_prod vmatch1 vmatch2 res v ** + Trade.trade + (vmatch_dep_prod vmatch1 vmatch2 res v) + (pts_to_serialized (serialize_dtuple2 s1 s2) input #pm v) { let (input1, input2) = split_dtuple2 s1 j1 s2 input; unfold (split_dtuple2_post s1 s2 input pm v (input1, input2)); @@ -1976,6 +1984,25 @@ fn zero_copy_parse_dtuple2 res } +inline_for_extraction +let zero_copy_parse_dtuple2 + (#tl1 #tl2 #th1: Type) + (#th2: th1 -> Type) + (#vmatch1: tl1 -> th1 -> slprop) + (#k1: Ghost.erased parser_kind) + (#p1: parser k1 th1) + (#s1: serializer p1) + (j1: jumper p1) + (w1: zero_copy_parse vmatch1 s1) + (sq: squash (k1.parser_kind_subkind == Some ParserStrong)) + (#vmatch2: (x: th1) -> tl2 -> th2 x -> slprop) + (#k2: Ghost.erased parser_kind) + (#p2: (x: th1) -> parser k2 (th2 x)) + (#s2: (x: th1) -> serializer (p2 x)) + (w2: (xh: Ghost.erased th1) -> zero_copy_parse (vmatch2 xh) (s2 xh)) +: zero_copy_parse #(tl1 `cpair` tl2) #(dtuple2 th1 th2) (vmatch_dep_prod vmatch1 vmatch2) #(and_then_kind k1 k2) #(parse_dtuple2 p1 p2) (serialize_dtuple2 s1 s2) += zero_copy_parse_dtuple2' j1 w1 sq w2 + inline_for_extraction fn read_and_zero_copy_parse_dtuple2 (#tl #th1: Type) From a0893b0566cda617b722a097e80bfd456b4d280e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guido=20Mart=C3=ADnez?= Date: Mon, 8 Dec 2025 12:00:31 -0800 Subject: [PATCH 21/33] Bump hashes (including Pulse fix) --- opt/hashes.Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index 37307794f..b9b514282 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := cb10e521335aab2adc5e2951ba066fa256599d8c -karamel_hash := b76a625f12cfbbcd6db9daec6b845a4a09bf3fbe -pulse_hash := 8db0c41eba48e5b49de65dbf2e514a2c26189e22 +FStar_hash := 8f6fbb324fdf4051783a45cad574132dae2f41ee +karamel_hash := 1ea635e8e7b736a93cb9c9832501aa6be921b024 +pulse_hash := 085e9701b618b2a87d0710e28b501fedb4cea860 From 320a5ed4bbe5f3f596aad71e90a41ae94f929c5c Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 11 Dec 2025 00:39:00 +0000 Subject: [PATCH 22/33] revert to Z3 4.13.3 --- EverParse.fst.config.json | 3 ++- deps.Makefile | 2 +- src/cose/generate-rust/CoseRust.fst.config.json | 3 +-- src/cose/verifiedinterop/Cose.fst.config.json | 3 +-- src/fstar.Makefile | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/EverParse.fst.config.json b/EverParse.fst.config.json index 6b85b8405..47fcdb218 100644 --- a/EverParse.fst.config.json +++ b/EverParse.fst.config.json @@ -1,7 +1,8 @@ { "fstar_exe": "./fstar.sh", "options": [ - "--z3version", "4.15.3" + "--load_cmxs", "evercddl_lib", + "--load_cmxs", "evercddl_plugin" ], "include_dirs": [ "./src/lowparse", diff --git a/deps.Makefile b/deps.Makefile index ff6c5d95c..1edc5fd47 100644 --- a/deps.Makefile +++ b/deps.Makefile @@ -13,7 +13,7 @@ export EVERPARSE_OPT_PATH := $(shell cygpath -m $(EVERPARSE_OPT_PATH)) NO_PULSE := 1 endif -EVERPARSE_Z3_VERSION ?= 4.15.3 +EVERPARSE_Z3_VERSION ?= 4.13.3 ifeq (1,$(EVERPARSE_USE_MY_DEPS)) export EVERPARSE_USE_OPAMROOT:=1 diff --git a/src/cose/generate-rust/CoseRust.fst.config.json b/src/cose/generate-rust/CoseRust.fst.config.json index 30e01052c..caffee87e 100644 --- a/src/cose/generate-rust/CoseRust.fst.config.json +++ b/src/cose/generate-rust/CoseRust.fst.config.json @@ -2,8 +2,7 @@ "fstar_exe": "../../../fstar.sh", "options": [ "--load_cmxs", "evercddl_lib", - "--load_cmxs", "evercddl_plugin", - "--z3version", "4.15.3" + "--load_cmxs", "evercddl_plugin" ], "include_dirs": [ ".", diff --git a/src/cose/verifiedinterop/Cose.fst.config.json b/src/cose/verifiedinterop/Cose.fst.config.json index f47f15989..7152870b9 100644 --- a/src/cose/verifiedinterop/Cose.fst.config.json +++ b/src/cose/verifiedinterop/Cose.fst.config.json @@ -2,8 +2,7 @@ "fstar_exe": "../../../fstar.sh", "options": [ "--load_cmxs", "evercddl_lib", - "--load_cmxs", "evercddl_plugin", - "--z3version", "4.15.3" + "--load_cmxs", "evercddl_plugin" ], "include_dirs": [ "./_output", diff --git a/src/fstar.Makefile b/src/fstar.Makefile index bab9bcbeb..cb633b7e5 100644 --- a/src/fstar.Makefile +++ b/src/fstar.Makefile @@ -9,4 +9,4 @@ FSTAR_EXE ?= fstar.exe export FSTAR_EXE # Add common options here -FSTAR_OPTIONS += --z3version 4.15.3 +FSTAR_OPTIONS += --z3version 4.13.3 From e447f7504d7b57250aff5320f61ac4fc5c6c1122 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 11 Dec 2025 00:54:58 +0000 Subject: [PATCH 23/33] VS config for LowParse --- src/lowparse/EverParse.fst.config.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/lowparse/EverParse.fst.config.json diff --git a/src/lowparse/EverParse.fst.config.json b/src/lowparse/EverParse.fst.config.json new file mode 100644 index 000000000..e67094e64 --- /dev/null +++ b/src/lowparse/EverParse.fst.config.json @@ -0,0 +1,6 @@ +{ + "fstar_exe": "../../fstar.sh", + "include_dirs": [ + "pulse" + ] + } From 0e66d24814f5639ce96636168457acc3b45c6636 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 11 Dec 2025 00:55:17 +0000 Subject: [PATCH 24/33] binder -> binding --- src/lowparse/LowParse.TacLib.fst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lowparse/LowParse.TacLib.fst b/src/lowparse/LowParse.TacLib.fst index 3f2e0cc39..4995d6a83 100644 --- a/src/lowparse/LowParse.TacLib.fst +++ b/src/lowparse/LowParse.TacLib.fst @@ -60,7 +60,7 @@ let rec intros_until_eq_hyp () : Tac binder = let i = intro () in - let (sq, ar) = app_head_tail (type_of_binder i) in + let (sq, ar) = app_head_tail (type_of_binding i) in let cond = if sq `is_fvar` (`%squash) then match ar with From c741512b4287b81a3a91a25243d940aba94fcfe7 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Thu, 11 Dec 2025 00:55:24 +0000 Subject: [PATCH 25/33] rlimit --- src/lowparse/pulse/LowParse.Pulse.Recursive.fst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst index 5b96c8a01..bc70f4403 100644 --- a/src/lowparse/pulse/LowParse.Pulse.Recursive.fst +++ b/src/lowparse/pulse/LowParse.Pulse.Recursive.fst @@ -123,7 +123,6 @@ let validate_tot_nlist_recursive_overflow let Some (h, consumed) = parse p.parse_header (Seq.slice v off (Seq.length v)) in let offset = off + consumed in parse_nlist_recursive_bound_correct p (p.count h + (n - 1)) (Seq.slice v (offset) (Seq.length v)) -#pop-options #restart-solver @@ -206,6 +205,8 @@ fn validate_tot_nlist_recursive !pres } +#pop-options + inline_for_extraction fn validate_nlist_recursive (#p: Ghost.erased parse_recursive_param) From 1c3866f21aad50f5cdaa11885e59a0328157fd09 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Fri, 12 Dec 2025 21:22:43 +0000 Subject: [PATCH 26/33] fix VS config for src/cddl --- src/cddl/cddl.fst.config.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/cddl/cddl.fst.config.json diff --git a/src/cddl/cddl.fst.config.json b/src/cddl/cddl.fst.config.json new file mode 100644 index 000000000..d264f1f4f --- /dev/null +++ b/src/cddl/cddl.fst.config.json @@ -0,0 +1,11 @@ +{ + "_comment": "This allows to interactively edit the generated CDDLTest.Test.fst file. Make sure to build the plugins before.", + "fstar_exe": "../../fstar.sh", + "include_dirs": [ + "../cbor/spec", + "../cbor/pulse", + "pulse", + "spec", + "tool" + ] + } From e7c2092ded483e4ace8b27a8c1daa122e64efa6d Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Mon, 15 Dec 2025 20:00:55 +0000 Subject: [PATCH 27/33] move some CDDL.Spec.MapGroup definitions from fsti to fst --- src/cddl/spec/CDDL.Spec.MapGroup.fst | 115 +++++++++++++++++++++++++- src/cddl/spec/CDDL.Spec.MapGroup.fsti | 106 ++++++++++++++---------- 2 files changed, 176 insertions(+), 45 deletions(-) diff --git a/src/cddl/spec/CDDL.Spec.MapGroup.fst b/src/cddl/spec/CDDL.Spec.MapGroup.fst index f960fc5dc..6f63917fc 100644 --- a/src/cddl/spec/CDDL.Spec.MapGroup.fst +++ b/src/cddl/spec/CDDL.Spec.MapGroup.fst @@ -286,7 +286,96 @@ let map_group_parser_spec_concat_eq (map_group_parser_spec_concat s1 s2 target_size target_prop l <: (target1 & target2)) == ((p1 l1 <: target1), (p2 l2 <: target2)) ) -#push-options "--z3rlimit 32" +#push-options "--z3rlimit_factor 8" +let map_group_serializer_spec_concat + (#source1: det_map_group) + (#source_fp1: map_constraint) + (#target1: Type) + (#target_size1: target1 -> Tot nat) + (#target_prop1: target1 -> bool) + (#p1: map_group_parser_spec source1 source_fp1 target_size1 target_prop1) + (s1: map_group_serializer_spec p1) + (#source2: det_map_group) + (#source_fp2: map_constraint) + (#target2: Type) + (#target_size2: target2 -> Tot nat) + (#target_prop2: target2 -> bool) + (#p2: map_group_parser_spec source2 source_fp2 target_size2 target_prop2) + (s2: map_group_serializer_spec p2) + (target_size: (target1 & target2) -> Tot nat { + map_group_footprint source1 source_fp1 /\ + map_group_footprint source2 source_fp2 /\ + ( + (map_constraint_disjoint source_fp1 source_fp2 /\ + map_group_parser_spec_domain_inj p1 /\ + map_group_parser_spec_domain_inj p2 + ) \/ map_constraint_disjoint_domains source_fp1 source_fp2 + ) /\ + (forall x . target_size x == target_size1 (fst x) + target_size2 (snd x)) + }) + (target_prop: (target1 & target2) -> bool { + forall x . target_prop x <==> (target_prop1 (fst x) /\ target_prop2 (snd x) /\ + cbor_map_disjoint (s1 (fst x)) (s2 (snd x)) + ) + }) +: Tot (map_group_serializer_spec (map_group_parser_spec_concat s1 s2 target_size target_prop)) += fun x -> + map_group_footprint_concat source1 source2 source_fp1 source_fp2; + let (x1, x2) = x in + let l1 = s1 x1 in + let l2 = s2 x2 in + let res = l1 `cbor_map_union` l2 in + assert (cbor_map_disjoint l1 l2); + map_group_footprint_concat_consumes_all source1 source2 source_fp1 source_fp2 (l1) (l2); + assert (cbor_map_in_footprint (l1) (source_fp1 `map_constraint_choice` source_fp2)); + assert (cbor_map_in_footprint (l2) (source_fp1 `map_constraint_choice` source_fp2)); + assert (cbor_map_in_footprint (l1 `cbor_map_union` l2) (source_fp1 `map_constraint_choice` source_fp2)); + assert (map_group_serializer_spec_arg_prop (source1 `map_group_concat` source2) (source_fp1 `map_constraint_choice` source_fp2) res); + let f1 = source_fp1 in + let f2 = source_fp2 in + let f = (source_fp1 `map_constraint_choice` source_fp2) in + cbor_map_filter_ext (f1 `orp` f2) f res; + assert (cbor_map_equal l1 (cbor_map_filter f1 l1)); + assert (cbor_map_equal cbor_map_empty (cbor_map_filter f1 l2)); + assert (cbor_map_equal l1 (cbor_map_filter f1 res)); + assert (cbor_map_equal l2 (cbor_map_filter f2 l2)); + assert (cbor_map_equal cbor_map_empty (cbor_map_filter f2 l1)); + assert (cbor_map_equal l2 (cbor_map_filter f2 res)); + assert (map_group_parser_spec_concat s1 s2 target_size target_prop res == x); + cbor_map_length_disjoint_union l1 l2; + res +#pop-options + +let map_group_serializer_spec_concat_eq + s1 s2 target_size target_prop x += () + +#push-options "--z3rlimit_factor 8" +let mg_spec_concat_inj + (#source1: det_map_group) + (#source_fp1: map_constraint) + (#target1: Type) + (#inj1: bool) + (p1: mg_spec source1 source_fp1 target1 inj1) + (#source2: det_map_group) + (#source_fp2: map_constraint) + (#target2: Type) + (#inj2: bool) + (p2: mg_spec source2 source_fp2 target2 inj2 { + map_group_footprint source1 source_fp1 /\ + map_group_footprint source2 source_fp2 /\ + map_constraint_disjoint source_fp1 source_fp2 + }) + (m: cbor_map { map_group_serializer_spec_arg_prop (map_group_concat source1 source2) (source_fp1 `map_constraint_choice` source_fp2) m }) +: Lemma + (requires (inj1 && inj2)) + (ensures ( + map_group_serializer_spec_concat p1.mg_serializer p2.mg_serializer (mg_spec_concat_size p1.mg_size p2.mg_size) (mg_spec_concat_serializable p1.mg_serializer p2.mg_serializer) (map_group_parser_spec_concat p1.mg_serializer p2.mg_serializer (mg_spec_concat_size p1.mg_size p2.mg_size) (mg_spec_concat_serializable p1.mg_serializer p2.mg_serializer) m) == m + )) += map_group_concat_footprint_disjoint source1 source_fp1 source2 source_fp2 m +#pop-options + +#push-options "--z3rlimit 64 --ifuel 8" #restart-solver let map_group_parser_spec_choice' @@ -571,6 +660,30 @@ let rec list_fold_map_group_zero_or_more_match_item_serializer_length | a :: q -> list_fold_map_group_zero_or_more_match_item_serializer_length pkey pvalue except m (map_group_zero_or_more_match_item_serializer_op pkey pvalue except m accu a) q +#restart-solver +#push-options "--z3rlimit_factor 4 --fuel 2 --ifuel 2 --split_queries always --query_stats" +#restart-solver +let map_group_zero_or_more_match_item_serializer + (#tkey #tvalue: Type) + (#key #value: typ) + (pkey: spec key tkey true) + (#inj: bool) + (pvalue: spec value tvalue inj) + (except: map_constraint { map_constraint_value_injective key pvalue.parser except }) +: Tot (map_group_serializer_spec (map_group_zero_or_more_match_item_parser pkey pvalue except)) += fun x -> + let y = map_group_zero_or_more_match_item_serializer' pkey pvalue except x in + assert (forall x . {:pattern cbor_map_get y x} Some? (cbor_map_get y x) ==> cbor_map_mem (x, Some?.v (cbor_map_get y x)) y); + let py = map_group_zero_or_more_match_item_parser' pkey pvalue except y in + assert (forall (kv: (tkey & list tvalue)) .{:pattern Map.mem kv x} Map.mem kv x ==> cbor_map_mem (pkey.serializer (fst kv), pvalue.serializer (List.Tot.hd (snd kv))) y); + assert (Map.equal' py x); + y +#pop-options + +let map_group_zero_or_more_match_item_serializer_eq + pkey pvalue except x += () + #restart-solver let map_group_zero_or_more_match_item_parser_inj (#tkey #tvalue: Type) diff --git a/src/cddl/spec/CDDL.Spec.MapGroup.fsti b/src/cddl/spec/CDDL.Spec.MapGroup.fsti index 03084c46c..3327f133d 100644 --- a/src/cddl/spec/CDDL.Spec.MapGroup.fsti +++ b/src/cddl/spec/CDDL.Spec.MapGroup.fsti @@ -1622,8 +1622,8 @@ val map_group_parser_spec_concat_eq [SMTPat (map_group_parser_spec_concat s1 s2 target_size target_prop l)] #restart-solver -#push-options "--z3rlimit_factor 4" -let map_group_serializer_spec_concat + +val map_group_serializer_spec_concat (#source1: det_map_group) (#source_fp1: map_constraint) (#target1: Type) @@ -1655,32 +1655,50 @@ let map_group_serializer_spec_concat ) }) : Tot (map_group_serializer_spec (map_group_parser_spec_concat s1 s2 target_size target_prop)) -= fun x -> - map_group_footprint_concat source1 source2 source_fp1 source_fp2; - let (x1, x2) = x in - let l1 = s1 x1 in - let l2 = s2 x2 in - let res = l1 `cbor_map_union` l2 in - assert (cbor_map_disjoint l1 l2); - map_group_footprint_concat_consumes_all source1 source2 source_fp1 source_fp2 (l1) (l2); - assert (cbor_map_in_footprint (l1) (source_fp1 `map_constraint_choice` source_fp2)); - assert (cbor_map_in_footprint (l2) (source_fp1 `map_constraint_choice` source_fp2)); - assert (cbor_map_in_footprint (l1 `cbor_map_union` l2) (source_fp1 `map_constraint_choice` source_fp2)); - assert (map_group_serializer_spec_arg_prop (source1 `map_group_concat` source2) (source_fp1 `map_constraint_choice` source_fp2) res); - let f1 = source_fp1 in - let f2 = source_fp2 in - let f = (source_fp1 `map_constraint_choice` source_fp2) in - cbor_map_filter_ext (f1 `orp` f2) f res; - assert (cbor_map_equal l1 (cbor_map_filter f1 l1)); - assert (cbor_map_equal cbor_map_empty (cbor_map_filter f1 l2)); - assert (cbor_map_equal l1 (cbor_map_filter f1 res)); - assert (cbor_map_equal l2 (cbor_map_filter f2 l2)); - assert (cbor_map_equal cbor_map_empty (cbor_map_filter f2 l1)); - assert (cbor_map_equal l2 (cbor_map_filter f2 res)); - assert (map_group_parser_spec_concat s1 s2 target_size target_prop res == x); - cbor_map_length_disjoint_union l1 l2; - res -#pop-options + +val map_group_serializer_spec_concat_eq + (#source1: det_map_group) + (#source_fp1: map_constraint) + (#target1: Type) + (#target_size1: target1 -> Tot nat) + (#target_prop1: target1 -> bool) + (#p1: map_group_parser_spec source1 source_fp1 target_size1 target_prop1) + (s1: map_group_serializer_spec p1) + (#source2: det_map_group) + (#source_fp2: map_constraint) + (#target2: Type) + (#target_size2: target2 -> Tot nat) + (#target_prop2: target2 -> bool) + (#p2: map_group_parser_spec source2 source_fp2 target_size2 target_prop2) + (s2: map_group_serializer_spec p2) + (target_size: (target1 & target2) -> Tot nat { + map_group_footprint source1 source_fp1 /\ + map_group_footprint source2 source_fp2 /\ + ( + (map_constraint_disjoint source_fp1 source_fp2 /\ + map_group_parser_spec_domain_inj p1 /\ + map_group_parser_spec_domain_inj p2 + ) \/ map_constraint_disjoint_domains source_fp1 source_fp2 + ) /\ + (forall x . target_size x == target_size1 (fst x) + target_size2 (snd x)) + }) + (target_prop: (target1 & target2) -> bool { + forall x . target_prop x <==> (target_prop1 (fst x) /\ target_prop2 (snd x) /\ + cbor_map_disjoint (s1 (fst x)) (s2 (snd x)) + ) + }) + (x: (target1 & target2) { target_prop x }) +: Lemma + (ensures + map_group_serializer_spec_concat s1 s2 target_size target_prop x == ( + let (x1, x2) = x in + let l1 = s1 x1 in + let l2 = s2 x2 in + let res = l1 `cbor_map_union` l2 in + res + ) + ) + [SMTPat (map_group_serializer_spec_concat s1 s2 target_size target_prop x)] let mg_spec_concat_size (#target1: Type) @@ -1710,8 +1728,7 @@ let mg_spec_concat_serializable : Tot bool = target_prop1 (fst x) && target_prop2 (snd x) && cbor_map_disjoint_tot (s1 (fst x)) (s2 (snd x)) -#push-options "--z3rlimit_factor 8" -let mg_spec_concat_inj +val mg_spec_concat_inj (#source1: det_map_group) (#source_fp1: map_constraint) (#target1: Type) @@ -1732,8 +1749,6 @@ let mg_spec_concat_inj (ensures ( map_group_serializer_spec_concat p1.mg_serializer p2.mg_serializer (mg_spec_concat_size p1.mg_size p2.mg_size) (mg_spec_concat_serializable p1.mg_serializer p2.mg_serializer) (map_group_parser_spec_concat p1.mg_serializer p2.mg_serializer (mg_spec_concat_size p1.mg_size p2.mg_size) (mg_spec_concat_serializable p1.mg_serializer p2.mg_serializer) m) == m )) -= map_group_concat_footprint_disjoint source1 source_fp1 source2 source_fp2 m -#pop-options #push-options "--z3rlimit_factor 4 --split_queries always" let mg_spec_concat_domain_inj' @@ -2737,10 +2752,7 @@ let map_group_zero_or_more_match_item_serializer'_length Set.fold_eq (map_group_zero_or_more_match_item_serializer_op pkey pvalue except m) cbor_map_empty s l; list_fold_map_group_zero_or_more_match_item_serializer_length pkey pvalue except m cbor_map_empty l -#restart-solver -#push-options "--z3rlimit_factor 4 --fuel 2 --ifuel 2 --split_queries always --query_stats" -#restart-solver -let map_group_zero_or_more_match_item_serializer +val map_group_zero_or_more_match_item_serializer (#tkey #tvalue: Type) (#key #value: typ) (pkey: spec key tkey true) @@ -2748,14 +2760,20 @@ let map_group_zero_or_more_match_item_serializer (pvalue: spec value tvalue inj) (except: map_constraint { map_constraint_value_injective key pvalue.parser except }) : Tot (map_group_serializer_spec (map_group_zero_or_more_match_item_parser pkey pvalue except)) -= fun x -> - let y = map_group_zero_or_more_match_item_serializer' pkey pvalue except x in - assert (forall x . {:pattern cbor_map_get y x} Some? (cbor_map_get y x) ==> cbor_map_mem (x, Some?.v (cbor_map_get y x)) y); - let py = map_group_zero_or_more_match_item_parser' pkey pvalue except y in - assert (forall (kv: (tkey & list tvalue)) .{:pattern Map.mem kv x} Map.mem kv x ==> cbor_map_mem (pkey.serializer (fst kv), pvalue.serializer (List.Tot.hd (snd kv))) y); - assert (Map.equal' py x); - y -#pop-options + +val map_group_zero_or_more_match_item_serializer_eq + (#tkey #tvalue: Type) + (#key #value: typ) + (pkey: spec key tkey true) + (#inj: bool) + (pvalue: spec value tvalue inj) + (except: map_constraint { map_constraint_value_injective key pvalue.parser except }) + (x: Map.t tkey (list tvalue) { map_group_zero_or_more_match_item_serializable pkey pvalue except x }) +: Lemma + (ensures map_group_zero_or_more_match_item_serializer pkey pvalue except x == + map_group_zero_or_more_match_item_serializer' pkey pvalue except x + ) + [SMTPat (map_group_zero_or_more_match_item_serializer pkey pvalue except x)] val map_group_zero_or_more_match_item_parser_inj (#tkey #tvalue: Type) From 035d10264a0f4616a7530091ee3cb3d23800b991 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Mon, 15 Dec 2025 20:03:01 +0000 Subject: [PATCH 28/33] add a few admits in Serialize.ArrayGroup/MapGroup, to be replaced with parser-generic implementations --- src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst | 8 ++++---- src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst index b5d338a7e..d970ebcb5 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst @@ -589,9 +589,9 @@ let impl_serialize_array_group_valid_zero_or_more_true_intro ag_serializable_zero_or_more_append ps1 l1 [x]; assert (ps.ag_serializable (List.Tot.append l1 [x])); ag_spec_zero_or_more_serializer_append ps1 l1 [x]; - assert (let ps = ag_spec_zero_or_more ps1 in + assume (let ps = ag_spec_zero_or_more ps1 in (ps.ag_serializer [x] <: list cbor) == List.Tot.append (ps1.ag_serializer x) []) - by (FStar.Tactics.trefl ()); // FIXME: WHY WHY WHY? + ; // by (FStar.Tactics.trefl ()); // FIXME: WHY WHY WHY? List.Tot.append_l_nil (ps1.ag_serializer x); assert ((ps.ag_serializer [x] <: list cbor) == ps1.ag_serializer x); assert ((ps.ag_size [x] <: nat) == ps1.ag_size x); @@ -605,11 +605,11 @@ let impl_serialize_array_group_valid_zero_or_more_true_intro assert (ps.ag_serializable (x :: l2) == ps.ag_serializable l2); if ps.ag_serializable l2 then begin - assert ( + assume ( let ps = ag_spec_zero_or_more ps1 in (ps.ag_serializer (x :: l2) <: list cbor) == List.Tot.append (ps1.ag_serializer x) (ps.ag_serializer l2) ) - by (FStar.Tactics.trefl ()); // FIXME: WHY WHY WHY? + ; // by (FStar.Tactics.trefl ()); // FIXME: WHY WHY WHY? List.Tot.append_length (ps1.ag_serializer x) (ps.ag_serializer l2); let a = (List.Tot.length l + List.Tot.length (ps.ag_serializer l1)) + (List.Tot.length (ps1.ag_serializer x) + List.Tot.length (ps.ag_serializer l2)) in assert ( diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index 93c0224c1..a021ef88a 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -781,7 +781,9 @@ let map_of_list_is_append_serializable_singleton (sp.mg_serializable m ==> ( sp.mg_serializer m == cbor_map_singleton (sp1.serializer k) (sp2.serializer v) )))) -= let sp = mg_zero_or_more_match_item sp1 sp2 except in += admit () +(* + let sp = mg_zero_or_more_match_item sp1 sp2 except in let m = EqTest.map_singleton k k_eq [v] in assert (forall kv . Map.mem kv m <==> (fst kv == k /\ snd kv == [v])); assert (sp.mg_serializable m <==> (forall kv . Map.mem kv m ==> map_entry_serializable sp1 sp2 except kv)); @@ -796,6 +798,7 @@ let map_of_list_is_append_serializable_singleton (cbor_map_singleton (sp1.serializer k) (sp2.serializer v)) end else admit() +*) #pop-options From d11e604ca2f65e7a77ff34570ffbd3232fbcafd5 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Mon, 15 Dec 2025 20:03:36 +0000 Subject: [PATCH 29/33] rlimit --- .../CBOR.Pulse.Raw.EverParse.Format.fst | 8 +++ .../CBOR.Pulse.Raw.Format.Serialize.fst | 26 ++++++++-- .../raw/everparse/CBOR.Spec.Raw.EverParse.fst | 51 ++++++++++++++----- .../raw/everparse/CBOR.Spec.Raw.Format.fst | 14 +++-- src/cddl/pulse/CDDL.Pulse.MapGroup.fst | 8 +++ .../pulse/CDDL.Pulse.Parse.ArrayGroup.fst | 6 ++- .../pulse/CDDL.Pulse.Serialize.ArrayGroup.fst | 3 +- .../pulse/CDDL.Pulse.Serialize.MapGroup.fst | 2 +- src/cddl/pulse/CDDL.Pulse.Serialize.Misc.fst | 4 ++ src/cddl/pulse/CDDL.Pulse.Types.fst | 4 ++ src/cddl/spec/CDDL.Spec.AST.Elab.Base.fst | 2 +- src/cddl/spec/CDDL.Spec.MapGroup.Base.fst | 20 +++++--- src/cddl/spec/CDDL.Spec.MapGroup.fst | 6 +-- 13 files changed, 114 insertions(+), 40 deletions(-) diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst index be1e1cade..3d05f39a9 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.EverParse.Format.fst @@ -808,6 +808,8 @@ fn validate_recursive_step_count_leaf (_: squash SZ.fits_u64) : } } +#push-options "--z3rlimit 20" + fn jump_recursive_step_count_leaf (_: squash SZ.fits_u64) : jump_recursive_step_count #parse_raw_data_item_param serialize_raw_data_item_param = @@ -846,6 +848,8 @@ fn jump_recursive_step_count_leaf (_: squash SZ.fits_u64) : } } +#pop-options + inline_for_extraction noextract [@@noextract_to "krml"] let validate_raw_data_item' (_: squash SZ.fits_u64) : validator #raw_data_item #parse_raw_data_item_kind parse_raw_data_item = @@ -923,6 +927,8 @@ fn get_header_and_contents outc } +#push-options "--z3rlimit 20" + ghost fn get_string_payload (input: S.slice byte) @@ -1073,6 +1079,8 @@ fn get_array_payload' () } +#pop-options + ghost fn get_array_payload (input: S.slice byte) diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst index d2beb64a1..77ba97d67 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst @@ -352,7 +352,7 @@ fn cbor_match_with_perm_lens res } -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 64" fn cbor_raw_get_header (p: perm) @@ -848,6 +848,8 @@ vmatch_lens #_ #_ #_ x1' } +#push-options "--z3rlimit 32" + inline_for_extraction let ser_payload_array_array (f64: squash SZ.fits_u64) @@ -888,6 +890,8 @@ let size_payload_array_array ) (serialize_content xh1) +#pop-options + ghost fn cbor_serialized_array_pts_to_serialized_with_perm_trade (xs: cbor_serialized) @@ -1012,8 +1016,6 @@ fn ser_payload_array_not_array_lens res } -#pop-options - inline_for_extraction let ser_payload_array_not_array (xh1: header) @@ -1046,6 +1048,8 @@ compute_remaining_size (vmatch_with_cond (match_cbor_payload xh1) (pnot cbor_wit ) _ +#pop-options + inline_for_extraction let ser_payload_array (f64: squash SZ.fits_u64) @@ -1304,6 +1308,8 @@ vmatch_lens #_ #_ #_ x1' } +#push-options "--z3rlimit 32" + inline_for_extraction let ser_payload_map_map (f64: squash SZ.fits_u64) @@ -1344,6 +1350,8 @@ let size_payload_map_map ) (serialize_content xh1) +#pop-options + ghost fn cbor_serialized_map_pts_to_serialized_with_perm_trade (xs: cbor_serialized) @@ -1473,8 +1481,6 @@ fn ser_payload_map_not_map_lens res } -#pop-options - inline_for_extraction let ser_payload_map_not_map (xh1: header) @@ -1507,6 +1513,8 @@ compute_remaining_size (vmatch_with_cond (match_cbor_payload xh1) (pnot cbor_wit ) _ +#pop-options + inline_for_extraction let ser_payload_map (f64: squash SZ.fits_u64) @@ -1653,6 +1661,8 @@ fn ser_payload_tagged_not_tagged_lens res } +#push-options "--z3rlimit 32" + inline_for_extraction let ser_payload_tagged (f: l2r_writer (cbor_match_with_perm) serialize_raw_data_item) @@ -1695,6 +1705,8 @@ let size_payload_tagged ) _ +#pop-options + inline_for_extraction let ser_payload_scalar (xh1: header) @@ -2396,6 +2408,10 @@ let cbor_serialize_map_t = ) (fun res -> cbor_serialize_map_post len out l off res) +#pop-options + +#push-options "--z3rlimit 128" + #restart-solver fn cbor_serialize_map' diff --git a/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst b/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst index d9456e352..68e1e9493 100644 --- a/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst +++ b/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst @@ -765,7 +765,7 @@ let synth_raw_data_item'_from_alt then (| h, LeafContentSeq?.v lc |) else (| h, () |) -#push-options "--ifuel 3" +#push-options "--ifuel 3 --z3rlimit_factor 2" #restart-solver let synth_raw_data_item'_from_alt_injective : squash (synth_injective synth_raw_data_item'_from_alt) = @@ -833,8 +833,7 @@ let tot_parse_nlist_parse_nlist' (ensures (tot_parse_nlist n p b == parse_nlist n #k p b)) = tot_parse_nlist_parse_nlist n p b -// #push-options "--z3rlimit 128 --ifuel 8" -#push-options "--z3rlimit 64" +#push-options "--z3rlimit 1024 --ifuel 8 --split_queries always" #restart-solver let parse_raw_data_item_eq @@ -1020,6 +1019,8 @@ let tot_serialize_header : tot_serializer tot_parse_header = let serialize_header : serializer parse_header = serialize_ext (parser_of_tot_parser tot_parse_header) (serializer_of_tot_serializer tot_serialize_header) parse_header +#push-options "--z3rlimit 16" + let synth_raw_data_item_recip (x: raw_data_item) : Tot raw_data_item' @@ -1037,8 +1038,6 @@ let synth_raw_data_item_recip | Tagged tag v -> (| raw_uint64_as_argument cbor_major_type_tagged tag, v |) -#push-options "--z3rlimit 16" - #restart-solver let synth_raw_data_item_recip_inverse : squash (synth_inverse synth_raw_data_item synth_raw_data_item_recip) = () @@ -1185,6 +1184,9 @@ let serialize_raw_data_item : serializer parse_raw_data_item = (* Serialization equations to prove the functional correctness of implementations *) +#push-options "--z3rlimit 32" +#restart-solver + let serialize_content (h: header) : Tot (serializer (parse_content parse_raw_data_item h)) @@ -1200,6 +1202,8 @@ let serialize_content then serialize_weaken _ serialize_raw_data_item else serialize_weaken _ serialize_empty +#pop-options + let serialize_raw_data_item_aux : serializer (parse_raw_data_item_aux parse_raw_data_item) = serialize_synth _ @@ -1287,6 +1291,9 @@ let get_uint64_as_initial_byte x (fun h -> match h with (| b, _ |) -> mk_synth_initial_byte (synth_initial_byte_recip b)) +#push-options "--z3rlimit 32" +#restart-solver + let get_initial_byte_header_correct (h: header) : Lemma @@ -1307,6 +1314,8 @@ let get_initial_byte_header_correct (synth_initial_byte_recip b); serialize_u8_spec (synth_bitsum'_recip initial_byte_desc (synth_initial_byte_recip b)) +#pop-options + #push-options "--z3rlimit 16" #restart-solver @@ -1331,8 +1340,6 @@ let get_initial_byte_header_inj assert (synth_bitsum' initial_byte_desc b1' == synth_initial_byte_recip b1); assert (synth_bitsum' initial_byte_desc b2' == synth_initial_byte_recip b2) -#pop-options - let get_uint64_as_initial_byte_header_correct (ty: major_type_t { ty `U8.lt` cbor_major_type_simple_value }) (x: raw_uint64) @@ -1349,9 +1356,6 @@ let get_major_type_synth_raw_data_item_recip (get_major_type x == get_header_major_type (dfst (synth_raw_data_item_recip x))) = () - -#push-options "--z3rlimit 16" - inline_for_extraction noextract [@@noextract_to "krml"] let get_int64_value @@ -1908,6 +1912,10 @@ let bytes_lex_compare_refl = Seq.append_empty_r x; bytes_lex_compare_prefix x Seq.empty Seq.empty +#pop-options + +#push-options "--z3rlimit 256 --split_queries always" + let serialized_lex_compare_simple_value (x1 x2: simple_value) : Lemma @@ -1991,6 +1999,7 @@ let serialized_lex_compare_simple_value seq_to_list_length_one (bare_serialize (serialize_long_argument b2) l2); bytes_lex_compare_serialize_strong_prefix serialize_header h1 h2 (bare_serialize (serialize_content h1) c1) (bare_serialize (serialize_content h2) c2) end +#pop-options let deterministically_encoded_cbor_map_key_order_simple_value_correct (x1 x2: simple_value) @@ -1998,8 +2007,6 @@ let deterministically_encoded_cbor_map_key_order_simple_value_correct (ensures (deterministically_encoded_cbor_map_key_order (Simple x1) (Simple x2) == x1 `U8.lt` x2)) = serialized_lex_compare_simple_value x1 x2 -#pop-options - #restart-solver let lex_compare_with_header_long_argument (ty1: major_type_t { ty1 `U8.lt` cbor_major_type_simple_value }) @@ -2071,6 +2078,9 @@ let big_endian_lex_compare' end else () +#pop-options + +#push-options "--z3rlimit 64" #restart-solver let lex_compare_with_header_uint (ty1: major_type_t { ty1 `U8.lt` cbor_major_type_simple_value }) @@ -2196,7 +2206,7 @@ let raw_uint64_compare then int_compare (U64.v x1.value) (U64.v x2.value) else c -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 64" #restart-solver let lex_compare_header_intro @@ -2267,6 +2277,11 @@ let lex_order_int64_correct (ensures (bytes_lex_order (bare_serialize serialize_raw_data_item (Int64 ty x1)) (bare_serialize serialize_raw_data_item (Int64 ty x2)) == x1 `raw_uint64_lt` x2)) = serialized_lex_compare_int64 ty x1 x2 +#pop-options + +#push-options "--z3rlimit 128" +#restart-solver + let serialized_lex_compare_string (ty: major_type_byte_string_or_text_string) (len1: raw_uint64) @@ -2430,7 +2445,7 @@ let rec lex_compare_ext #pop-options -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 64 --split_queries always" let serialized_lex_compare_array_aux (len1: raw_uint64) @@ -2473,6 +2488,10 @@ let serialized_lex_compare_array_aux lex_compare_header_intro cbor_major_type_array len1 len2; bytes_lex_compare_serialize_strong_prefix serialize_header h1 h2 (bare_serialize (serialize_content h1) c1) (bare_serialize (serialize_content h2) c2) +#pop-options + +#push-options "--z3rlimit 32" + let serialized_lex_compare_array (len1: raw_uint64) (x1: list raw_data_item {List.Tot.length x1 == U64.v len1.value}) @@ -2521,6 +2540,10 @@ let tot_nondep_then_eq_gen = nondep_then_eq (parser_of_tot_parser pt1) (parser_of_tot_parser pt2) x; nondep_then_eq pg1 pg2 x +#pop-options + +#push-options "--z3rlimit 64 --split_queries always" + let serialized_lex_compare_map_aux (len1: raw_uint64) (x1: list (raw_data_item & raw_data_item) {List.Tot.length x1 == U64.v len1.value}) diff --git a/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.Format.fst b/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.Format.fst index 75d1f5853..2f7146633 100644 --- a/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.Format.fst +++ b/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.Format.fst @@ -150,6 +150,8 @@ let serialize_cbor_tag tag = let serialize_cbor_tag_length tag = LP.serialize_length F.serialize_header (F.raw_uint64_as_argument cbor_major_type_tagged tag) +#push-options "--z3rlimit 32" + let serialize_cbor_tag_correct tag payload = let v1 = Tagged tag payload in F.serialize_raw_data_item_aux_correct v1; @@ -163,6 +165,8 @@ let serialize_cbor_tag_correct tag payload = let v1' = F.synth_raw_data_item_recip v1 in LP.serialize_dtuple2_eq F.serialize_header F.serialize_content v1' +#pop-options + module LPL = LowParse.Spec.VCList let serialize_cbor_list l = @@ -173,6 +177,8 @@ let serialize_cbor_list_nil () = () let serialize_cbor_list_cons a q = LPL.tot_serialize_nlist_cons (List.Tot.length q) F.tot_serialize_raw_data_item a q +#push-options "--z3rlimit 32" + let serialize_array_eq (len1: raw_uint64) (x1: list raw_data_item {List.Tot.length x1 == U64.v len1.value}) @@ -224,18 +230,20 @@ let serialize_cbor_string_length_gt ty len l = serialize_string_eq ty len l; LP.serialize_length F.serialize_header (F.raw_uint64_as_argument ty len) +#pop-options + let serialize_cbor_map l = LPL.tot_serialize_nlist (List.Tot.length l) (LP.tot_serialize_nondep_then F.tot_serialize_raw_data_item F.tot_serialize_raw_data_item) l let serialize_cbor_map_nil () = () +#push-options "--z3rlimit 32" + let serialize_cbor_map_cons key value q = LPL.tot_serialize_nlist_cons (List.Tot.length q) (LP.tot_serialize_nondep_then F.tot_serialize_raw_data_item F.tot_serialize_raw_data_item) (key, value) q; LPL.tot_serialize_nondep_then_eq F.tot_serialize_raw_data_item F.tot_serialize_raw_data_item (key, value); () -#push-options "--z3rlimit 32" - #restart-solver let rec serialize_cbor_map_insert_length' @@ -288,7 +296,7 @@ let parse_nlist_ext' (ensures (LP.parse (LowParse.Spec.VCList.parse_nlist n p) b == LP.parse (LowParse.Spec.VCList.parse_nlist n p') b)) = LowParse.Spec.VCList.parse_nlist_ext n p p' b (fun x -> ()) -#push-options "--z3rlimit 32 --split_queries always" +#push-options "--z3rlimit 64 --split_queries always" #restart-solver diff --git a/src/cddl/pulse/CDDL.Pulse.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.MapGroup.fst index 6aca8d35a..eebff0a19 100644 --- a/src/cddl/pulse/CDDL.Pulse.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.MapGroup.fst @@ -342,6 +342,8 @@ let impl_map_group_match_item_for_body_post pts_to pi i' ** pure (impl_map_group_post (map_group_match_item_for cut k dest) (map_group_match_item_for_footprint cut k dest) v v1 v2 count i i' res) +#push-options "--z3rlimit 32" + inline_for_extraction fn impl_map_group_match_item_for_body (#t: Type0) @@ -407,6 +409,8 @@ fn impl_map_group_match_item_for_body } } +#pop-options + inline_for_extraction fn impl_map_group_match_item_for (#t: Type0) @@ -675,6 +679,10 @@ ensures } } +#pop-options + +#push-options "--z3rlimit 64 --split_queries always --fuel 8 --ifuel 6" + #restart-solver inline_for_extraction fn impl_map_group_filter diff --git a/src/cddl/pulse/CDDL.Pulse.Parse.ArrayGroup.fst b/src/cddl/pulse/CDDL.Pulse.Parse.ArrayGroup.fst index 598357bef..64e74e6d9 100644 --- a/src/cddl/pulse/CDDL.Pulse.Parse.ArrayGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Parse.ArrayGroup.fst @@ -481,8 +481,6 @@ let array_group_parser_spec_zero_or_more0_mk_array_iterator_eq' )) = _ by (FStar.Tactics.trefl ()) // FIXME: WHY WHY WHY tactics? assert_norm does not work -#push-options "--print_implicits" - let array_group_parser_spec_zero_or_more0_mk_array_iterator_eq (#cbor_array_iterator_t: Type0) (#cbor_array_iterator_match: perm -> cbor_array_iterator_t -> list cbor -> slprop) (#impl_elt: Type0) (#src_elt: Type0) @@ -647,6 +645,8 @@ let cddl_array_iterator_next_t pure (Ghost.reveal l == a :: q) ) +#push-options "--z3rlimit 32" + inline_for_extraction fn cddl_array_iterator_next (#cbor_array_iterator_t: Type0) (#cbor_array_iterator_match: perm -> cbor_array_iterator_t -> list cbor -> slprop) @@ -745,6 +745,8 @@ fn cddl_array_iterator_next res; } +#pop-options + #restart-solver inline_for_extraction noextract [@@noextract_to "krml"] diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst index d970ebcb5..a544e4fa4 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.ArrayGroup.fst @@ -556,6 +556,8 @@ let impl_serialize_array_group_valid_zero_or_more_true_intro_length ((x1 + x2) + (x3 + x4) == (x1 + (x2 + x3)) + x4) = () +#push-options "--z3rlimit 32" + let impl_serialize_array_group_valid_zero_or_more_true_intro (l: list Cbor.cbor) (#t: array_group None) @@ -639,7 +641,6 @@ let impl_serialize_array_group_valid_zero_or_more_true_intro end else () -#push-options "--z3rlimit 32" #restart-solver inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_array_group_zero_or_more_slice diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst index a021ef88a..7ee369ac9 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.MapGroup.fst @@ -357,7 +357,7 @@ let cbor_map_length_disjoint_union_pat (m1 m2: cbor_map) : Lemma #push-options "--z3rlimit 32" #restart-solver -#push-options "--z3rlimit_factor 4 --split_queries always --query_stats" +#push-options "--z3rlimit_factor 8 --split_queries always --query_stats" inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_map_group_concat (#[@@@erasable]t1: Ghost.erased det_map_group) diff --git a/src/cddl/pulse/CDDL.Pulse.Serialize.Misc.fst b/src/cddl/pulse/CDDL.Pulse.Serialize.Misc.fst index 1a8ffa1e1..b13497574 100644 --- a/src/cddl/pulse/CDDL.Pulse.Serialize.Misc.fst +++ b/src/cddl/pulse/CDDL.Pulse.Serialize.Misc.fst @@ -473,6 +473,8 @@ fn impl_serialize_tagged_some res } +#push-options "--z3rlimit 32" + inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_bstr_cbor_det (cbor_det_serialize_string: cbor_det_serialize_string_t) @@ -498,6 +500,8 @@ fn impl_serialize_bstr_cbor_det } } +#pop-options + inline_for_extraction noextract [@@noextract_to "krml"] fn impl_serialize_any (#ty: Type u#0) diff --git a/src/cddl/pulse/CDDL.Pulse.Types.fst b/src/cddl/pulse/CDDL.Pulse.Types.fst index b2f6357e0..635b445fe 100644 --- a/src/cddl/pulse/CDDL.Pulse.Types.fst +++ b/src/cddl/pulse/CDDL.Pulse.Types.fst @@ -564,6 +564,8 @@ let map_of_list_is_append_nil_r_elim (ensures (m1 == m2)) = assert (Map.equal m1 m2) +#push-options "--z3rlimit 32" + let map_of_list_is_append_cons_snoc_equiv (#key #value: Type) (key_eq: EqTest.eq_test key) @@ -578,6 +580,8 @@ let map_of_list_is_append_cons_snoc_equiv | Some l1, Some l2 -> List.Tot.append_assoc l1 [v] l2 | _ -> () +#pop-options + let map_of_list_maps_to_nonempty (#key #value: Type0) (m: Map.t key (list value)) diff --git a/src/cddl/spec/CDDL.Spec.AST.Elab.Base.fst b/src/cddl/spec/CDDL.Spec.AST.Elab.Base.fst index 2e8296ffa..8d441b11a 100644 --- a/src/cddl/spec/CDDL.Spec.AST.Elab.Base.fst +++ b/src/cddl/spec/CDDL.Spec.AST.Elab.Base.fst @@ -422,7 +422,7 @@ let rewrite_group_correct_postcond end end -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 128 --ifuel 8 --split_queries always" #restart-solver let rec rewrite_typ_correct diff --git a/src/cddl/spec/CDDL.Spec.MapGroup.Base.fst b/src/cddl/spec/CDDL.Spec.MapGroup.Base.fst index 29a996b87..95b3a3601 100644 --- a/src/cddl/spec/CDDL.Spec.MapGroup.Base.fst +++ b/src/cddl/spec/CDDL.Spec.MapGroup.Base.fst @@ -414,7 +414,7 @@ let cbor_map_disjoint_union_intro (ensures cbor_map_disjoint m (m1 `cbor_map_union` m2)) = () -#push-options "--z3rlimit 16" +#push-options "--z3rlimit 32" #restart-solver let map_group_concat_witness_pred_correct @@ -997,7 +997,7 @@ let map_group_is_productive_choice )) = () -#push-options "--z3rlimit 16" +#push-options "--z3rlimit 32" #restart-solver let map_group_is_productive_concat @@ -1081,6 +1081,8 @@ let map_group_match_item_for_eq_none | MapGroupCutFailure -> assert False | MapGroupResult s -> assert (s `MPS.equal` MPS.empty) +#push-options "--z3rlimit 32" + #restart-solver let map_group_match_item_for_eq (k: cbor) @@ -1153,6 +1155,8 @@ let map_group_match_item_for_eq_gen assert (map_group_match_item_for true k ty l == MapGroupCutFailure) end +#pop-options + let mps_equal_intro (s1 s2: MPS.t) (prf12: (x: MPS.elt) -> Lemma @@ -1400,8 +1404,6 @@ let apply_map_group_det_concat (m1 m2: map_group) (l: cbor_map) = end | _ -> () -#pop-options - #restart-solver let apply_map_group_det_match_item_for (cut: bool) @@ -1424,6 +1426,8 @@ let apply_map_group_det_match_item_for else () | _ -> () +#pop-options + #push-options "--z3rlimit 512" #restart-solver @@ -1544,6 +1548,8 @@ let apply_map_group_det_filter f l = () +#push-options "--z3rlimit 32" + #restart-solver let map_group_filter_filter p1 p2 @@ -1583,8 +1589,6 @@ let map_group_zero_or_one_match_item_filter_matched cbor_map_disjoint_union_filter p s l'; cbor_map_equiv cbor_map_empty (cbor_map_filter p s) -#push-options "--z3rlimit 16" - #restart-solver let map_group_zero_or_one_match_item_filter key value p @@ -1811,7 +1815,7 @@ let map_group_fail_shorten_intro (map_group_fail_shorten g) = Classical.forall_intro_2 (fun m1 -> Classical.move_requires (prf m1)) -#push-options "--z3rlimit 16" +#push-options "--z3rlimit 32" #restart-solver @@ -1983,7 +1987,7 @@ let map_group_concat_match_item_cut_eq (map_group_match_item_for b k v) (map_group_concat (map_group_match_item_for b k v) (map_group_cut (t_literal k))) -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 64" #restart-solver let map_group_concat_zero_or_one_match_item_cut_eq diff --git a/src/cddl/spec/CDDL.Spec.MapGroup.fst b/src/cddl/spec/CDDL.Spec.MapGroup.fst index 6f63917fc..f52ce0ebc 100644 --- a/src/cddl/spec/CDDL.Spec.MapGroup.fst +++ b/src/cddl/spec/CDDL.Spec.MapGroup.fst @@ -1,7 +1,7 @@ module CDDL.Spec.MapGroup module U = CBOR.Spec.Util -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 64" (* #restart-solver @@ -58,10 +58,6 @@ let map_group_choice_compatible_match_item_for map_group_footprint_elim right fp (cbor_map_filter phi x) (cbor_map_filter (U.notp phi) x) ) -#pop-options - -#push-options "--z3rlimit 64" - #restart-solver let map_group_footprint_concat_consumes_all_recip g1 g2 f1 f2 m From d5df53ea3d52d473e5d9c67e38f7066f006f2ed3 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Mon, 15 Dec 2025 21:02:40 +0000 Subject: [PATCH 30/33] advance F*, Karamel, Pulse --- opt/hashes.Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opt/hashes.Makefile b/opt/hashes.Makefile index b9b514282..55ca47631 100644 --- a/opt/hashes.Makefile +++ b/opt/hashes.Makefile @@ -1,3 +1,3 @@ -FStar_hash := 8f6fbb324fdf4051783a45cad574132dae2f41ee -karamel_hash := 1ea635e8e7b736a93cb9c9832501aa6be921b024 -pulse_hash := 085e9701b618b2a87d0710e28b501fedb4cea860 +FStar_hash := f1a55bbbe7dcac6c99033bd22fd73b74a3bea237 +karamel_hash := 9c4744acf0d663c6fc079fb318820f4188971652 +pulse_hash := afc380e13aeacc0e4f18d605735056ef9789062e From 7c9ad2a7f0b259ea61096ac52fccd15bd67c92dd Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Mon, 15 Dec 2025 23:07:41 +0000 Subject: [PATCH 31/33] move LowParse.Spec.VCList.bare_serialize_vclist_correct from the .fsti to the .fst --- src/lowparse/LowParse.Spec.VCList.fst | 27 ++++++++++++++++++++++++++ src/lowparse/LowParse.Spec.VCList.fsti | 16 +-------------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/lowparse/LowParse.Spec.VCList.fst b/src/lowparse/LowParse.Spec.VCList.fst index 1f6d620da..497984ed6 100644 --- a/src/lowparse/LowParse.Spec.VCList.fst +++ b/src/lowparse/LowParse.Spec.VCList.fst @@ -224,4 +224,31 @@ let rec tot_serialize_nlist_refine_eq ) end +let bare_serialize_vclist_correct + (min: nat) + (max: nat { min <= max /\ max < 4294967296 } ) + (#lk: parser_kind) + (#lp: parser lk U32.t) + (ls: serializer lp { lk.parser_kind_subkind == Some ParserStrong } ) + (#k: parser_kind) + (#t: Type) + (#p: parser k t) + (s: serializer p { k.parser_kind_subkind == Some ParserStrong } ) +: Lemma + (serializer_correct (parse_vclist min max lp p) (bare_serialize_vclist min max ls s)) += let prf (x: vlarray t min max) + : Lemma + (let fx = bare_serialize_vclist min max ls s x in + parse (parse_vclist min max lp p) fx == Some (x, Seq.length fx)) + = let fx = bare_serialize_vclist min max ls s x in + parse_vclist_eq min max lp p fx; + let n = L.length x in + let un = U32.uint_to_t n in + let fn = serialize ls un in + parse_strong_prefix lp fn fx; + let fl = serialize (serialize_nlist n s) x in + assert (fl `Seq.equal` Seq.slice fx (Seq.length fn) (Seq.length fx)) + in + Classical.forall_intro prf + #pop-options diff --git a/src/lowparse/LowParse.Spec.VCList.fsti b/src/lowparse/LowParse.Spec.VCList.fsti index 3c5214c7a..56efa032e 100644 --- a/src/lowparse/LowParse.Spec.VCList.fsti +++ b/src/lowparse/LowParse.Spec.VCList.fsti @@ -971,7 +971,7 @@ let bare_serialize_vclist let un = U32.uint_to_t n in serialize ls un `Seq.append` serialize (serialize_nlist n s) l -let bare_serialize_vclist_correct +val bare_serialize_vclist_correct (min: nat) (max: nat { min <= max /\ max < 4294967296 } ) (#lk: parser_kind) @@ -983,20 +983,6 @@ let bare_serialize_vclist_correct (s: serializer p { k.parser_kind_subkind == Some ParserStrong } ) : Lemma (serializer_correct (parse_vclist min max lp p) (bare_serialize_vclist min max ls s)) -= let prf (x: vlarray t min max) - : Lemma - (let fx = bare_serialize_vclist min max ls s x in - parse (parse_vclist min max lp p) fx == Some (x, Seq.length fx)) - = let fx = bare_serialize_vclist min max ls s x in - parse_vclist_eq min max lp p fx; - let n = L.length x in - let un = U32.uint_to_t n in - let fn = serialize ls un in - parse_strong_prefix lp fn fx; - let fl = serialize (serialize_nlist n s) x in - assert (fl `Seq.equal` Seq.slice fx (Seq.length fn) (Seq.length fx)) - in - Classical.forall_intro prf let serialize_vclist (min: nat) From 3f8f7d6178cba9006f2675a8049398db344c6a76 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Mon, 15 Dec 2025 23:08:22 +0000 Subject: [PATCH 32/33] rlimit --- .../pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst | 2 +- src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst | 2 +- src/lowparse/LowParse.Spec.Sum.fst | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst index 77ba97d67..cd6c88009 100644 --- a/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst +++ b/src/cbor/pulse/raw/everparse/CBOR.Pulse.Raw.Format.Serialize.fst @@ -2410,7 +2410,7 @@ let cbor_serialize_map_t = #pop-options -#push-options "--z3rlimit 128" +#push-options "--z3rlimit 256" #restart-solver diff --git a/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst b/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst index 68e1e9493..54bbd10a5 100644 --- a/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst +++ b/src/cbor/spec/raw/everparse/CBOR.Spec.Raw.EverParse.fst @@ -1436,7 +1436,7 @@ let rec list_for_all_holds_on_pair_list_of_pair_list | [] -> () | _ :: q -> list_for_all_holds_on_pair_list_of_pair_list pred q -#push-options "--z3rlimit 32" +#push-options "--z3rlimit 64" #restart-solver let holds_on_raw_data_item_eq_recursive diff --git a/src/lowparse/LowParse.Spec.Sum.fst b/src/lowparse/LowParse.Spec.Sum.fst index edd3a0f96..0bcc542cc 100644 --- a/src/lowparse/LowParse.Spec.Sum.fst +++ b/src/lowparse/LowParse.Spec.Sum.fst @@ -326,6 +326,8 @@ let serialize_sum = // FIXME: WHY WHY WHY is implicit argument inference failing here? (i.e. introducing an eta-expansion) serialize_sum' t s #_ #(parse_sum_cases t pc) (serialize_sum_cases t pc sc) +#push-options "--z3rlimit 16" + let serialize_sum_eq (#kt: parser_kind) (t: sum) @@ -347,6 +349,8 @@ let serialize_sum_eq synth_sum_case_inverse t tg; serialize_synth_eq (dsnd (pc tg)) (synth_sum_case t tg) (sc tg) (synth_sum_case_recip t tg) () x +#pop-options + inline_for_extraction let make_sum (#key #repr: eqtype) From 3ecbcecb5b6c2a4a70b4591527941d7b1bde7802 Mon Sep 17 00:00:00 2001 From: Tahina Ramananandro Date: Wed, 17 Dec 2025 01:46:46 +0000 Subject: [PATCH 33/33] (TEMP) EverCDDL: add an option to disable NBE during extraction --- src/cddl/tool/CDDL.Tool.Gen.fst | 85 +++++++++++++----------- src/cddl/tool/ocaml/evercddl-gen/Main.ml | 5 +- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/cddl/tool/CDDL.Tool.Gen.fst b/src/cddl/tool/CDDL.Tool.Gen.fst index cf6f284c3..41ea903fc 100644 --- a/src/cddl/tool/CDDL.Tool.Gen.fst +++ b/src/cddl/tool/CDDL.Tool.Gen.fst @@ -148,9 +148,12 @@ let rec compute_wf_typ RSuccess (fuel, (wt, (f, wf_ast_env_extend_typ_with_weak env name t wt))) else RFailure (name ^ " is already defined") -let produce_validator env wf validator = " +let if_nbe nbe = + if nbe then "nbe :: " else "" + +let produce_validator nbe env wf validator = " let _ : unit = _ by (FStar.Tactics.print (\"validator\"); FStar.Tactics.exact (`())) -[@@normalize_for_extraction (nbe :: T.steps)] +[@@normalize_for_extraction (" ^ if_nbe nbe ^ "T.steps)] let "^validator^" = Impl.validate_typ' Det.cbor_det_impl "^env^".be_v true _ "^wf let uglify (s: string) = s ^ "_ugly" @@ -160,7 +163,7 @@ let produce_splice typename attrs = " "^attrs^" noeq %splice["^typename^"; "^typename^"_left; "^typename^"_right; "^typename^"_left_right; "^typename^"_right_left] (FStar.Tactics.PrettifyType.entry \""^typename^"\" (`%"^uglify typename^"))" -let produce_parser0 env env_anc' validator parser serializer typename bundle = " +let produce_parser0 nbe env env_anc' validator parser serializer typename bundle = " [@@bundle_attr; bundle_get_impl_type_attr] let g"^bundle^"' : Ghost.erased (bundle Det.cbor_det_match) = Ghost.hide "^bundle^"' let _ : unit = _ by (FStar.Tactics.print (\"type\"); FStar.Tactics.exact (`())) @@ -203,10 +206,10 @@ let gteq"^bundle^"'' () : squash (g"^bundle^"''.b_impl_type == "^typename^") = c let peq"^bundle^" () = Parse.impl_zero_copy_parse_t_eq Det.cbor_det_match "^bundle^"''.b_spec.parser "^bundle^"''.b_rel "^typename^" (teq"^bundle^"'' ()) let seq"^bundle^" () = CDDL.Pulse.Serialize.Base.impl_serialize_t_eq "^bundle^"''.b_spec "^bundle^"''.b_rel "^typename^" (teq"^bundle^"'' ()) let _ : unit = _ by (FStar.Tactics.print (\"parser\"); FStar.Tactics.exact (`())) -[@@normalize_for_extraction (nbe :: T.bundle_steps); +[@@normalize_for_extraction ("^if_nbe nbe^"T.bundle_steps); Comment \"Parser for "^typename^"\"] let "^parser^" = T.inline_coerce_eq (peq"^bundle^" ()) "^bundle^"''.b_parser -[@@normalize_for_extraction (nbe :: T.bundle_steps); +[@@normalize_for_extraction ("^if_nbe nbe^"T.bundle_steps); Comment \"Serializer for "^typename^"\"] let "^serializer^" = T.inline_coerce_eq (seq"^bundle^" ()) "^bundle^"''.b_serializer let _ : unit = _ by (FStar.Tactics.print (\"bundle'\"); FStar.Tactics.exact (`())) @@ -216,39 +219,39 @@ let validate_and_"^parser^" = validate_and_parse Det.cbor_det_impl.cbor_det_pars inline_for_extraction noextract [@@noextract_to "^krml^"] let "^serializer^"' = CDDL.Pulse.Serialize.Base.impl_serialize_cast_rel "^bundle^".b_serializer rel_"^typename^" () () ()" -let produce_parser env env_anc' wf validator parser serializer typename bundle = -produce_validator env (wf^"'") validator^" +let produce_parser nbe env env_anc' wf validator parser serializer typename bundle = +produce_validator nbe env (wf^"'") validator^" let _ : unit = _ by (FStar.Tactics.print (\"bundle\"); FStar.Tactics.exact (`())) noextract [@@noextract_to "^krml^"; bundle_attr; bundle_get_impl_type_attr; "^opaque_to_smt^"] let "^bundle^"' = impl_bundle_wf_type' Det.cbor_det_impl "^env^" "^compute_ancillary_env0 env_anc'^" "^wf^" "^wf^"' ("^wf^"_eq ()) (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ()))"^ -produce_parser0 env env_anc' validator parser serializer typename bundle +produce_parser0 nbe env env_anc' validator parser serializer typename bundle -let produce_ask_for_validator env wf validator = +let produce_ask_for_validator nbe env wf validator = "let _ : unit = _ by (FStar.Tactics.print (\"validator\"); FStar.Tactics.exact (`())) let is_type_"^wf^" () : squash (Parse.option_ask_for_is_type "^wf^") = (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ())) -[@@normalize_for_extraction (nbe :: T.steps)] +[@@normalize_for_extraction ("^if_nbe nbe^"T.steps)] let "^validator^" = Parse.validate_ask_for_type Det.cbor_det_impl "^env^".be_v "^wf^" (is_type_"^wf^" ())" -let produce_ask_for_map_constraint env wf map_constraint = +let produce_ask_for_map_constraint nbe env wf map_constraint = "let _ : unit = _ by (FStar.Tactics.print (\"map_constraint\"); FStar.Tactics.exact (`())) let is_map_constraint_"^wf^" () : squash (Parse.option_ask_for_is_map_constraint "^wf^") = (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ())) -[@@normalize_for_extraction (nbe :: T.steps)] +[@@normalize_for_extraction ("^if_nbe nbe^"T.steps)] let "^map_constraint^" = Parse.validate_ask_for_map_constraint Det.cbor_det_impl "^env^".be_v "^wf^" (is_map_constraint_"^wf^" ())" -let produce_ask_for_parser env env_anc' wf validator parser serializer typename bundle = -produce_ask_for_validator env wf validator^" +let produce_ask_for_parser nbe env env_anc' wf validator parser serializer typename bundle = +produce_ask_for_validator nbe env wf validator^" let _ : unit = _ by (FStar.Tactics.print (\"bundle\"); FStar.Tactics.exact (`())) noextract [@@noextract_to "^krml^"; bundle_attr; bundle_get_impl_type_attr; "^opaque_to_smt^"] let "^bundle^"' = impl_bundle_wf_ask_for_guarded_type Det.cbor_det_impl "^env^" "^compute_ancillary_env0 env_anc'^" "^wf^" (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ())) (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ()))"^ -produce_parser0 env env_anc' validator parser serializer typename bundle +produce_parser0 nbe env env_anc' validator parser serializer typename bundle -let produce_ask_for_array_validator env wf validator = " +let produce_ask_for_array_validator nbe env wf validator = " let _ : unit = _ by (FStar.Tactics.print (\"validator\"); FStar.Tactics.exact (`())) -[@@normalize_for_extraction (nbe :: T.steps)] +[@@normalize_for_extraction ("^if_nbe nbe^"T.steps)] let "^validator^" = Parse.validate_ask_for_array_group Det.cbor_det_impl "^env^".be_v "^wf^" (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ()))" -let produce_ask_for_array_parser env env_anc' wf validator parser serializer typename bundle = -produce_ask_for_array_validator env wf validator^" +let produce_ask_for_array_parser nbe env env_anc' wf validator parser serializer typename bundle = +produce_ask_for_array_validator nbe env wf validator^" let _ : unit = _ by (FStar.Tactics.print (\"bundle\"); FStar.Tactics.exact (`())) noextract [@@noextract_to "^krml^"; bundle_attr; bundle_get_impl_type_attr; "^opaque_to_smt^"] let "^bundle^"' = impl_bundle_wf_ask_for_array_group Det.cbor_det_impl "^env^" "^compute_ancillary_env0 env_anc'^" "^wf^" (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ())) (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ())) @@ -293,10 +296,10 @@ let gteq"^bundle^"'' () : squash (g"^bundle^"''.ab_impl_type == "^typename^") = let peq"^bundle^" () = CDDL.Pulse.Parse.ArrayGroup.impl_zero_copy_array_group_t_eq Det.cbor_det_array_iterator_match "^bundle^"''.ab_spec.ag_parser "^bundle^"''.ab_rel "^typename^" (teq"^bundle^"'' ()) let seq"^bundle^" () = CDDL.Pulse.Serialize.ArrayGroup.impl_serialize_array_group_t_eq "^bundle^"''.ab_spec "^bundle^"''.ab_rel "^typename^" (teq"^bundle^"'' ()) let _ : unit = _ by (FStar.Tactics.print (\"parser\"); FStar.Tactics.exact (`())) -[@@normalize_for_extraction (nbe :: T.bundle_steps); +[@@normalize_for_extraction ("^if_nbe nbe^"T.bundle_steps); Comment \"Parser for "^typename^"\"] let "^parser^" = T.inline_coerce_eq (peq"^bundle^" ()) "^bundle^"''.ab_parser -[@@normalize_for_extraction (nbe :: T.bundle_steps); +[@@normalize_for_extraction ("^if_nbe nbe^"T.bundle_steps); Comment \"Serializer for "^typename^"\"] let "^serializer^" = T.inline_coerce_eq (seq"^bundle^" ()) "^bundle^"''.ab_serializer let _ : unit = _ by (FStar.Tactics.print (\"bundle'\"); FStar.Tactics.exact (`())) @@ -305,6 +308,7 @@ let "^bundle^" = array_bundle_set_parser_and_serializer g"^bundle^"'' "^typename let rec compute_ancillaries_aux (#se: sem_env) + (nbe: bool) (anc: ancillaries_aux_t se) (ask: P.option_ask_for se) (env: string) @@ -326,7 +330,7 @@ let rec compute_ancillaries_aux begin match ask with | None -> anc | Some (P.AskForMapConstraint t _) -> - let msg = produce_ask_for_map_constraint env wf map_constraint ^ " + let msg = produce_ask_for_map_constraint nbe env wf map_constraint ^ " let _ : unit = _ by (FStar.Tactics.print (\"ancillary env'\"); FStar.Tactics.exact (`())) [@@bundle_attr; noextract_to "^krml^"; "^opaque_to_smt^"] noextract let a"^anc_env'^" = a" ^ anc_env ^ " @@ -346,7 +350,7 @@ let aa"^anc_env'^" = aa" ^ anc_env output = anc.output ^ msg; } | Some (P.AskForType t _ false) -> - let msg = produce_ask_for_validator env wf validator ^ " + let msg = produce_ask_for_validator nbe env wf validator ^ " let _ : unit = _ by (FStar.Tactics.print (\"ancillary env'\"); FStar.Tactics.exact (`())) [@@bundle_attr; sem_attr; noextract_to "^krml^"; "^opaque_to_smt^"] noextract let av"^anc_env'^" = Parse.ancillary_validate_env_set_ask_for av"^anc_env^" "^wf^" (_ by (FStar.Tactics.norm (nbe :: T.bundle_steps); T.trefl_or_trivial ())) "^validator^" @@ -366,7 +370,7 @@ let aa"^anc_env'^" = aa" ^ anc_env output = anc.output ^ msg; } | Some (P.AskForType t t_wf true) -> - let msg = produce_ask_for_parser env anc_env wf validator parser serializer typename bundle ^ " + let msg = produce_ask_for_parser nbe env anc_env wf validator parser serializer typename bundle ^ " let _ : unit = _ by (FStar.Tactics.print (\"ancillary env'\"); FStar.Tactics.exact (`())) [@@bundle_attr; sem_attr; noextract_to "^krml^"; "^opaque_to_smt^"] noextract let av"^anc_env'^" = av"^anc_env^" @@ -388,7 +392,7 @@ let aa"^anc_env'^" = aa" ^ anc_env } | Some (P.AskForArrayGroup t t_wf) -> let _ = FStar.IO.print_string ("ancillary for group:" ^ CDDL.Spec.AST.Print.group_to_string t ^ ", typename: " ^ typename ^ "\n") in - let msg = produce_ask_for_array_parser env anc_env wf validator parser serializer typename bundle ^ " + let msg = produce_ask_for_array_parser nbe env anc_env wf validator parser serializer typename bundle ^ " let _ : unit = _ by (FStar.Tactics.print (\"ancillary env'\"); FStar.Tactics.exact (`())) [@@bundle_attr; sem_attr; noextract_to "^krml^"; "^opaque_to_smt^"] noextract let av"^anc_env'^" = av"^anc_env^" @@ -414,11 +418,12 @@ let aa"^anc_env'^" = ancillary_array_bundle_env_set_ask_for aa"^anc_env^" "^wf^" [@@noextract_to "^krml^"; bundle_attr; "^opaque_to_smt^"] noextract let "^wf'^"' = Parse.ask_zero_copy_ask_for_option (Parse.ancillary_validate_env_is_some av"^anc_env^") (ancillary_bundle_env_is_some a"^anc_env^") (ancillary_array_bundle_env_is_some aa"^anc_env^") (Parse.ancillary_map_constraint_env_is_some amc"^anc_env^") "^wf in - let anc2 = init_compute_ancillaries_aux anc ask' env msg in - compute_ancillaries_aux anc2 ask env wf validator bundle parser serializer map_constraint typename + let anc2 = init_compute_ancillaries_aux nbe anc ask' env msg in + compute_ancillaries_aux nbe anc2 ask env wf validator bundle parser serializer map_constraint typename and init_compute_ancillaries_aux (#se: sem_env) + (nbe: bool) (anc: ancillaries_aux_t se) (ask': P.option_ask_for se) (env: string) @@ -448,10 +453,11 @@ let "^wf'^" = "^wf'^"' output = anc.output ^ msg'; } in - compute_ancillaries_aux anc1 ask' env wf' validator' bundle' parser' serializer' map_constraint' typename' + compute_ancillaries_aux nbe anc1 ask' env wf' validator' bundle' parser' serializer' map_constraint' typename' let rec compute_ancillaries (#se: sem_env) + (nbe: bool) (init: ancillaries_t se -> P.option_ask_for se) (anc: ancillaries_aux_t se) (env: string) @@ -468,8 +474,8 @@ let rec compute_ancillaries [@@noextract_to "^krml^"; bundle_attr; "^opaque_to_smt^"] noextract let "^wf'^"' = Parse.ask_zero_copy_wf_type (Parse.ancillary_validate_env_is_some av"^anc_env^") (ancillary_bundle_env_is_some a"^anc_env^") (ancillary_array_bundle_env_is_some aa"^anc_env^") (Parse.ancillary_map_constraint_env_is_some amc"^anc_env^") "^wf in - let anc2 = init_compute_ancillaries_aux anc ask env msg in - compute_ancillaries init anc2 env wf + let anc2 = init_compute_ancillaries_aux nbe anc ask env msg in + compute_ancillaries nbe init anc2 env wf let extend_ancillaries_t (#se: sem_env) @@ -678,6 +684,7 @@ let next_" ^ map_iterator ^ " = CDDL.Pulse.Parse.MapGroup.cddl_map_iterator_next | _ -> (anc, accu) let produce_typ_defs + (nbe: bool) (index: nat) (wenv: wf_ast_env) (anc: ancillaries_t wenv.e_sem_env) @@ -702,7 +709,7 @@ let produce_typ_defs let source' = "sorted_source" ^ j in let bundle = mk_bundle_name name in let fuel = string_of_int fuel in - let anc1 = compute_ancillaries f { + let anc1 = compute_ancillaries nbe f { anc = anc; env_index = 0; next_candidate_index = 1; @@ -730,7 +737,7 @@ let _ : unit = _ by (FStar.Tactics.print (\"wf\"); FStar.Tactics.exact (`())) [@@FStar.Tactics.postprocess_with (fun _ -> FStar.Tactics.norm [delta; zeta; iota; primops]; FStar.Tactics.trefl ()); noextract_to "^krml^"; base_attr; "^opaque_to_smt^"] noextract let "^wf^"' = "^wf^" let "^wf^"_eq () : Lemma ("^wf^"' == "^wf^") = assert ("^wf^"' == "^wf^") by (FStar.Tactics.norm [delta; zeta; iota; primops]; FStar.Tactics.trefl ())"^ -anc1.output^produce_parser env env_anc' wf validator parser serializer parsertype bundle ^" +anc1.output^produce_parser nbe env env_anc' wf validator parser serializer parsertype bundle ^" let _ : unit = _ by (FStar.Tactics.print (\"env'\"); FStar.Tactics.exact (`())) [@@noextract_to "^krml^"; sem_attr; bundle_attr; "^opaque_to_smt^"] noextract let "^env'^" = @@ -774,6 +781,7 @@ let "^env'^" = RSuccess (msg, (| wenv', extend_ancillaries_t anc _ |)) let rec produce_defs' + (nbe: bool) (index: nat) (accu: string) (env: wf_ast_env) @@ -791,16 +799,16 @@ let _ : unit = _ by (FStar.Tactics.print (\"" ^ string_of_int (List.Tot.length l in begin match def with | DType t -> - begin match produce_typ_defs index env anc name t with + begin match produce_typ_defs nbe index env anc name t with | RSuccess (msg, (| env', anc' |)) -> - produce_defs' (index + 1) (accu ^ msg) env' anc' q + produce_defs' nbe (index + 1) (accu ^ msg) env' anc' q | RFailure s -> RFailure s end | DGroup g -> begin match produce_group_defs env anc name g index with | RFailure s -> RFailure s | RSuccess (msg, (| env', anc' |)) -> - produce_defs' (index + 1) (accu ^ msg) env' anc' q + produce_defs' nbe (index + 1) (accu ^ msg) env' anc' q end end @@ -815,8 +823,8 @@ let empty_ancillaries : ancillaries_t empty_sem_env = { array_iterators = []; } -let produce_defs0 accu l = - produce_defs' 0 accu empty_wf_ast_env empty_ancillaries l +let produce_defs0 nbe accu l = + produce_defs' nbe 0 accu empty_wf_ast_env empty_ancillaries l let prelude_fst mname lang filenames = " module "^mname^" @@ -858,6 +866,7 @@ let _ : squash (SZ.fits_u64) = assume (SZ.fits_u64) " let produce_defs_fst + nbe mname lang filenames (l: list (string & decl)) : FStar.All.ML // Dv string @@ -865,6 +874,6 @@ let produce_defs_fst | RFailure fail -> "Error: topological sort failed: "^ fail | RSuccess l -> let accu = prelude_fst mname lang filenames in - match produce_defs0 accu l with + match produce_defs0 nbe accu l with | RSuccess s -> s | RFailure msg -> "Error: " ^ msg diff --git a/src/cddl/tool/ocaml/evercddl-gen/Main.ml b/src/cddl/tool/ocaml/evercddl-gen/Main.ml index 5acd57ffb..3fbd7e9b8 100644 --- a/src/cddl/tool/ocaml/evercddl-gen/Main.ml +++ b/src/cddl/tool/ocaml/evercddl-gen/Main.ml @@ -31,13 +31,15 @@ let mkdir dir = then () else try Sys.mkdir dir 0o755 with _ -> () +let nbe = ref true + let produce_fst_file (dir: string) : string = let filenames = List.rev !rev_filenames in match ParseFromFile.parse_from_files filenames with | None -> failwith "Parsing failed" | Some l -> let filenames_str = List.fold_left (fun accu fn -> accu ^ "\"" ^ fn ^ "\";") "" filenames in - let str = CDDL_Tool_Gen.produce_defs_fst !mname !lang filenames_str l in + let str = CDDL_Tool_Gen.produce_defs_fst !nbe !mname !lang filenames_str l in if String.starts_with ~prefix:"Error: " str then begin print_endline str; @@ -259,6 +261,7 @@ let _ = ("--fstar_only", Arg.Unit (fun _ -> fstar_only := true), "Only generate F*"); ("--skip_compilation", Arg.Unit (fun _ -> skip_compilation := true), "Do not compile produced C files"); ("--tmpdir", Arg.String (fun d -> tmpdir := d), "Set the temporary directory (default automatically generated)"); + ("--__tmp_no_nbe", Arg.Unit (fun _ -> nbe := false), "(TEMP) Disable NBE for extraction"); ] in let usagemsg = "EverCDDL: Produces a F* file to generate formally verified parsers and serializers from CDDL specifications.\nUsage: "^Sys.argv.(0) ^" [options] file1 [file2 ...]" in