Skip to content

Add Flux tool description and CI workflow #403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

nilehmann
Copy link

This PR introduces Flux to the list of tools used in the book and adds a corresponding CI workflow.

The CI workflow runs Flux on a subset of core (specifically, files under src/ascii) to verify the absence of array out-of-bounds errors. It demonstrates how to annotate the code with refinement types to specify the pre- and post-conditions necessary to prove safety on the subset that Flux is enabled.

The Flux tool and necessary dependencies are built from source on CI (pinning specific commits).

Resolves #362

@nilehmann nilehmann requested a review from a team as a code owner June 30, 2025 03:28
@@ -109,7 +111,7 @@ impl_from!(u8 => u16, #[stable(feature = "lossless_int_conv", since = "1.5.0")])
impl_from!(u8 => u32, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
impl_from!(u8 => u64, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
impl_from!(u8 => u128, #[stable(feature = "i128", since = "1.26.0")]);
impl_from!(u8 => usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")]);
impl_from!(u8 => usize, #[stable(feature = "lossless_int_conv", since = "1.5.0")], #[cfg_attr(flux, flux::spec(fn(x:u8) -> usize[x]))]);
Copy link
Member

Choose a reason for hiding this comment

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

Can you outline a path on how this might eventually get integrated upstream?

Copy link
Author

Choose a reason for hiding this comment

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

Could you clarify whether you're referring to specs in general or just the spec in this macro?

Copy link
Member

Choose a reason for hiding this comment

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

Actually just this one: to me (and I could be wrong!) it looks like a change that, if we were to try to do more proofs using Flux, would require changes in lots of places. For other specs/contracts there is a path in that Rust upstream has experimental contracts support. But tool-specific annotations seem a lot less likely to be merged upstream.

Copy link
Author

Choose a reason for hiding this comment

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

You are not wrong in that more proofs will require more annotations. We've thought about this, and one option is to provide signatures in a separate file (à la ocaml .mli files), but this is something we have not implemented yet (we have something similar for extern specs).

Copy link
Member

Choose a reason for hiding this comment

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

With this specific case: wouldn't it be possible to move the spec into the macro_rules so that all generated implementations feature a flux_spec?

Copy link
Author

@nilehmann nilehmann Jul 7, 2025

Choose a reason for hiding this comment

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

Sadly, no, we try that first, but the macro is also used to convert from bool to integers, and we can't use the same signature for that, i.e., the following is ill-formed when $Small is bool.

#[cfg_attr(flux, flux::spec(fn(x: $Small) -> $Large[x]))]

Choose a reason for hiding this comment

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

Yes, the catch here is that we want to branch on the $Small and $Large and only put different specs depending on their values.

There is perhaps some way to do this with the macros but we couldn't quite work it out, unfortunately.

Would be great if you have any suggestions.

Comment on lines +9 to +10
- arithmetic overflows
- division by zero
Copy link
Member

Choose a reason for hiding this comment

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

For these, does Flux distinguish between ones causing a panic vs ones deemed undefined behaviour?

Copy link
Author

Choose a reason for hiding this comment

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

No, we currently don't distinguish between those.

Copy link
Member

Choose a reason for hiding this comment

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

Would you mind including some documentation to this effect?

Copy link
Author

Choose a reason for hiding this comment

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

I added a sentence at the end of the section explaining this.

- name: Install Z3
uses: cda-tum/setup-z3@v1.6.1
with:
version: 4.12.1
Copy link
Member

Choose a reason for hiding this comment

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

Do we have to stick with this particular version of Z3? Would it be conceivable to just install Ubuntu's version of Z3?

Copy link
Author

Choose a reason for hiding this comment

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

This is the version we use in our CI. I had problems in the past with Ubuntu's version being too old, and that's why I pinned it. That being said, I see that now they are in 4.13, so we should be fine with that. We may need to update in the future, though.

Copy link
Member

Choose a reason for hiding this comment

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

Could you please add a comment denoting the minimum version of Z3 required? I am worried about being stuck with a particular version of Z3 when soundness issue in that version of the solver may eventually be found.

Copy link
Author

Choose a reason for hiding this comment

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

@tautschnig, I'm unsure about what to do here. There's nothing special about this version; it's just the one we actively use in CI, so we have a bit more confidence with it. We (mostly) use standard smtlib, so newer and some older versions should also work.

Copy link
Author

Choose a reason for hiding this comment

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

Should I add a comment explaining exactly that?

Copy link
Member

@tautschnig tautschnig left a comment

Choose a reason for hiding this comment

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

I believe this is ready to go except for some remaining documentation gaps, see comments.

@@ -0,0 +1,239 @@
# Flux

[Flux](https://flux-rs.github.io/flux) is a refinement type checker
Copy link
Member

Choose a reason for hiding this comment

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

Can you please include a section on (current) limitations or caveats?

Copy link
Author

Choose a reason for hiding this comment

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

I added a section at the end of the document.

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.

Add Tool: Flux
5 participants