Skip to content

Conversation

@tahina-pro
Copy link
Member

FStarLang/FStar#3699 makes many EverParse proofs fail. This PR, authored by @nikswamy, fixes such proofs. Thanks a lot Nik!

Some remaining admits in this PR are slated to be overwritten once EverCDDL serialization is generalized beyond deterministically encoded CBOR.

@tahina-pro
Copy link
Member Author

tahina-pro commented Nov 20, 2025

Hi @nikswamy , @gebner and @mtzguido !
I am now catching up on F*, Karamel and Pulse.

Blocking issues

Can anyone please help me there? Thanks in advance!
(If you want to get started, run ADMIT=1 make -j$(nproc) -k from this branch)

Other lessons learned

  • Pulse now sometimes needs the user to specify the middle argument of Pulse.Lib.Trade.Util.trans, which I find annoying in the cases where there are exactly two trades and exactly one of them unifies with the first (or third) argument specified by the user. See b9d339c
  • I am still using "old-style" while loops; now it seems that the pure invariant for the Boolean termination argument has to be separated from other pure invariants, otherwise Pulse cannot compute a witness at the end of the loop iteration, see f174fa2
  • I had to add many rewrites, and a few trade transitivity lemmas where the middle argument does not unify. More generally, it seems that Pulse no longer unifies with SMT even if the choice of slprops from the context is unambiguous, see 3b97d8f. From what Nik told me, the meaning of mkey has been inverted and maybe I should annotate PulseParse and EverCBOR slprops with it.

Current status

Apart from the blocking issues above:

  • Pulse runs out of memory in CDDL.Pulse.Serialize.MapGroup.impl_serialize_map_zero_or_more_iterator_gen, but this function is slated to be rewritten soon, since I intend to generalize CDDL serialization to support non-deterministic CBOR, so there is no need to fix that function
  • I have not fixed SMT failures yet, but there seems to be a significant amount of them in ASN1* (among others)

Comment on lines +20 to +22
# TODO: remove this once map serializers are implemented
RUN := $(filter-out Basic1 BenchMap,$(RUN))

Copy link
Member Author

@tahina-pro tahina-pro Feb 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is to be reverted once generic CDDL map serializers are implemented.
Those two tests, Basic1 and BenchMap, serialize nonempty tables, which https://github.com/project-everest/everparse/pull/244/changes#r2760178949 currently disables.

Comment on lines 550 to 614
@@ -548,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)
@@ -581,9 +591,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);
@@ -597,11 +607,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?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assumes are to be removed and replaced with a generic implementation of array group serializers - where the signature of the serializer implementation uses a generic CBOR parser specification instead of the deterministic serializer specification.

Comment on lines +5 to +12
inline_for_extraction noextract [@@noextract_to "krml"]
fn admit_as_abort_true
(_: unit)
returns res: bool
ensures pure (res == true)
{
admit () // Karamel should extract as KRML_ABORT
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function extracts to KRML_EABORT. Indeed, if admit () is used with unit return type, then it is erased at extraction. That's why we use an informative return type, here bool.

This function is to be removed once this file is replaced with generic map group serializers.

Comment on lines 730 to 761
@@ -687,6 +761,11 @@ let map_of_list_is_append_serializable_elim'
))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assume is to be removed once this file is replaced with generic map group serializers.

Comment on lines 770 to 794
@@ -711,17 +790,24 @@ 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 ()
(*
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This admit is to be removed once this file is replaced with generic map group serializers.

Comment on lines 829 to 865
@@ -776,7 +862,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();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This admit is to be removed once this file is replaced with generic map group serializers.

Comment on lines 917 to 947
@@ -858,7 +944,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();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This admit is to be removed once this file is replaced with generic map group serializers.

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();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(for impl_serialize_map_group_valid_map_zero_or_more_snoc_length1)
This admit is to be removed once this file is replaced with generic map group serializers.

))
))
= impl_serialize_map_group_valid_map_zero_or_more_snoc_aux sp1 key_eq sp2 except l m1 k v m2 len;
= admit();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(for impl_serialize_map_group_valid_map_zero_or_more_snoc')
This admit is to be removed once this file is replaced with generic map group serializers.

b == (res && not (FStar.StrongExcludedMiddle.strong_excluded_middle (m2 == Map.empty _ _)))
)
) {
let ignore = admit_as_abort_true (); (); (* Pulse OOM
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(for impl_serialize_map_group_valid_map_zero_or_more_iterator_gen)
This is an admit that extracts to KRML_EABORT. Without it, Pulse seems to go out of memory when typechecking the loop body. Instead of putting the admit on the whole combinator, it is enough to put it into the loop body, so that empty tables can still be serialized properly, which is necessary for EverCOSE.

This is to be removed once this file is replaced with generic map group serializers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants