Skip to content
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

Add add option for running why3 though cargo creusot CLI #925

Merged
merged 16 commits into from
Jan 24, 2024

Conversation

dewert99
Copy link
Collaborator

@dewert99 dewert99 commented Jan 9, 2024

I added an experimental --why3 <CMD> flag to to cargo creusot which cause Creusot to run Why3 on the generated mlcfg (automatically including the mlcfg file).
Example usages:
cargo creusot --why3 "prove" TODO, should give a nice error requiring a prover/driver but currently gives a parse error
cargo creusot --why3 "prove -P z3 -a split-vc": Runs Creusot and Why3 prove and reports verifications failures as Rust errors usually pointing to appropriate spans, (TODO issue with spans from inside macros)
cargo creusot --why3 "prove -P z3-ce -a split-vc": Like above but also prints counter examples in a pseudo-Rust syntax (TODO this could be improved by mapping why3 paths to Rust paths).
TODO I'm currently using a hack in printer.rs to get some spans for assignments but this should also be improved
cargo creusot --why3 "ide": Runs creusot and then opens the Why3 ide, (TODO spans don't work because of how I'm using them for "prove" and I need to handle them differently).

@xldenis
Copy link
Collaborator

xldenis commented Jan 9, 2024

I like this, we've also discussed a project a while ago to have an engineer link why3 directly into cargo creusot, but this gets us 80% there.

@dewert99
Copy link
Collaborator Author

I improved the spans reported by making sure each mlcfg assignment has an associated span, and each mlcfg abort terminator comes directly after asserting false with an appropriate span. I also fixed the issue with spans in macros (but this required adding an extra field to the translation context. I think I was wrong before about the spans when using --why3 "ide", and the problem actually has to do with how Creusot handles relative spans when not using the --ouput-path option (Although I may be able to fix this here or in another PR). Mapping Why3 paths to Rust paths will probably have to wait until the CloneMap conversion process done.

The couterexamples are also somewhat buggy but I think has more to do with Why3 than my changes. Why3 doesn't seem to include values of polymorphic types in its counter examples. It also seems to have z3 run (check-sat) twice (the first time before adding all of the relevant asserions) and then combines counterexamples causing some values to get multiple assignments where some are incorrect.

Do you think this is still useful enough to merge into Creusot in this state? Should I try to fix the issue with relative spans when not using --output-path first?

@@ -54,7 +54,7 @@ pub enum Statement<'tcx> {
#[derive(Clone, Debug)]
pub enum RValue<'tcx> {
Ghost(Term<'tcx>),
Borrow(Place<'tcx>),
Borrow(Place<'tcx>, Span),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you explain the purpose of these specific spans? I can be sold on special casing these, but if possible it would be nice to recover the span from a surrounding Expr, Statement or Terminator.

@xldenis
Copy link
Collaborator

xldenis commented Jan 13, 2024

I also fixed the issue with spans in macros (but this required adding an extra field to the translation context

Oh, with invariant? That's fantastic!

I improved the spans reported by making sure each mlcfg assignment has an associated span, and each mlcfg abort terminator comes directly after asserting false with an appropriate span

I noticed. I'm fine with starting with this, but I'd like to push the spans into proper fields in a follow up, copying the structure of MIR (more generally fMIR needs some cleanup / love).

Mapping Why3 paths to Rust paths will probably have to wait until the CloneMap conversion process done.

I'm getting close, all tests compile to MLCFG, and ~30% are still failing during Why3 typechecking. I'm co-chairing at POPL this week but I expect it to be merged sometime the week after.

Should I try to fix the issue with relative spans when not using --output-path first?

I'm not sure what these issues are and how crippling they are. I'm generally a fan of smaller PRs anyways, so I'd lean to merge and fix afterwards.

creusot/src/ctx.rs Outdated Show resolved Hide resolved
creusot/src/ctx.rs Outdated Show resolved Hide resolved
@xldenis
Copy link
Collaborator

xldenis commented Jan 13, 2024

Overall, I'm positive about this work, but ideally, I'd like the spans in fMIR to be handled in a more principled manner.

@dewert99
Copy link
Collaborator Author

dewert99 commented Jan 15, 2024

Overall, I'm positive about this work, but ideally, I'd like the spans in fMIR to be handled in a more principled manner.

It seems like in MIR spans are attached to Statements and Terminators, but not to RValues Operands or Places, since an fMIR Expr seems to correspond to a MIR RValue or Operand, I would think that maybe it shouldn't get a span. Instead I would think that fMIR Statement::Assign could have a span since it seems like it is the only fMIR Statement to come from a MIR Statement. Does this seem like a reasonable approach?

@xldenis
Copy link
Collaborator

xldenis commented Jan 16, 2024

Yes this is reasonable. In general our expressions can correspond to multiple rust statements (due to simplifications or optimizations) so it will probably still make sense to have spans on them.

# Conflicts:
#	creusot/src/backend.rs
#	creusot/tests/should_fail/bug/01_resolve_unsoundness.mlcfg
#	creusot/tests/should_fail/bug/222.mlcfg
#	creusot/tests/should_fail/bug/492.mlcfg
#	creusot/tests/should_fail/bug/692.mlcfg
#	creusot/tests/should_fail/bug/695.mlcfg
#	creusot/tests/should_fail/bug/specialize.mlcfg
#	creusot/tests/should_fail/opaque_unproveable.mlcfg
#	creusot/tests/should_succeed/100doors.mlcfg
#	creusot/tests/should_succeed/all_zero.mlcfg
#	creusot/tests/should_succeed/bdd.mlcfg
#	creusot/tests/should_succeed/binary_search.mlcfg
#	creusot/tests/should_succeed/bug/387.mlcfg
#	creusot/tests/should_succeed/bug/463.mlcfg
#	creusot/tests/should_succeed/bug/552.mlcfg
#	creusot/tests/should_succeed/bug/594.mlcfg
#	creusot/tests/should_succeed/bug/682.mlcfg
#	creusot/tests/should_succeed/bug/691.mlcfg
#	creusot/tests/should_succeed/bug/693.mlcfg
#	creusot/tests/should_succeed/bug/766.mlcfg
#	creusot/tests/should_succeed/bug/874.mlcfg
#	creusot/tests/should_succeed/bug/box_borrow_resolve.mlcfg
#	creusot/tests/should_succeed/bug/eq_panic.mlcfg
#	creusot/tests/should_succeed/bug/two_phase.mlcfg
#	creusot/tests/should_succeed/cell/01.mlcfg
#	creusot/tests/should_succeed/cell/02.mlcfg
#	creusot/tests/should_succeed/checked_ops.mlcfg
#	creusot/tests/should_succeed/clones/01.mlcfg
#	creusot/tests/should_succeed/clones/03.mlcfg
#	creusot/tests/should_succeed/closures/01_basic.mlcfg
#	creusot/tests/should_succeed/closures/02_nested.mlcfg
#	creusot/tests/should_succeed/closures/03_generic_bound.mlcfg
#	creusot/tests/should_succeed/closures/04_generic_closure.mlcfg
#	creusot/tests/should_succeed/closures/05_map.mlcfg
#	creusot/tests/should_succeed/closures/06_fn_specs.mlcfg
#	creusot/tests/should_succeed/closures/07_mutable_capture.mlcfg
#	creusot/tests/should_succeed/closures/08_multiple_calls.mlcfg
#	creusot/tests/should_succeed/constrained_types.mlcfg
#	creusot/tests/should_succeed/drop_pair.mlcfg
#	creusot/tests/should_succeed/duration.mlcfg
#	creusot/tests/should_succeed/filter_positive.mlcfg
#	creusot/tests/should_succeed/hashmap.mlcfg
#	creusot/tests/should_succeed/heapsort_generic.mlcfg
#	creusot/tests/should_succeed/hillel.mlcfg
#	creusot/tests/should_succeed/immut.mlcfg
#	creusot/tests/should_succeed/index_range.mlcfg
#	creusot/tests/should_succeed/inplace_list_reversal.mlcfg
#	creusot/tests/should_succeed/instant.mlcfg
#	creusot/tests/should_succeed/invariant_moves.mlcfg
#	creusot/tests/should_succeed/ite_normalize.mlcfg
#	creusot/tests/should_succeed/iterators/01_range.mlcfg
#	creusot/tests/should_succeed/iterators/02_iter_mut.mlcfg
#	creusot/tests/should_succeed/iterators/03_std_iterators.mlcfg
#	creusot/tests/should_succeed/iterators/04_skip.mlcfg
#	creusot/tests/should_succeed/iterators/05_map.mlcfg
#	creusot/tests/should_succeed/iterators/06_map_precond.mlcfg
#	creusot/tests/should_succeed/iterators/07_fuse.mlcfg
#	creusot/tests/should_succeed/iterators/08_collect_extend.mlcfg
#	creusot/tests/should_succeed/iterators/09_empty.mlcfg
#	creusot/tests/should_succeed/iterators/10_once.mlcfg
#	creusot/tests/should_succeed/iterators/11_repeat.mlcfg
#	creusot/tests/should_succeed/iterators/12_zip.mlcfg
#	creusot/tests/should_succeed/iterators/13_cloned.mlcfg
#	creusot/tests/should_succeed/iterators/14_copied.mlcfg
#	creusot/tests/should_succeed/iterators/15_enumerate.mlcfg
#	creusot/tests/should_succeed/iterators/16_take.mlcfg
#	creusot/tests/should_succeed/knapsack.mlcfg
#	creusot/tests/should_succeed/knapsack_full.mlcfg
#	creusot/tests/should_succeed/lang/assoc_type.mlcfg
#	creusot/tests/should_succeed/lang/branch_borrow_2.mlcfg
#	creusot/tests/should_succeed/lang/modules.mlcfg
#	creusot/tests/should_succeed/lang/move_path.mlcfg
#	creusot/tests/should_succeed/lang/while_let.mlcfg
#	creusot/tests/should_succeed/list_index_mut.mlcfg
#	creusot/tests/should_succeed/list_reversal_lasso.mlcfg
#	creusot/tests/should_succeed/loop.mlcfg
#	creusot/tests/should_succeed/mapping_test.mlcfg
#	creusot/tests/should_succeed/mutex.mlcfg
#	creusot/tests/should_succeed/one_side_update.mlcfg
#	creusot/tests/should_succeed/option.mlcfg
#	creusot/tests/should_succeed/ord_trait.mlcfg
#	creusot/tests/should_succeed/projection_toggle.mlcfg
#	creusot/tests/should_succeed/projections.mlcfg
#	creusot/tests/should_succeed/prophecy.mlcfg
#	creusot/tests/should_succeed/red_black_tree.mlcfg
#	creusot/tests/should_succeed/resolve_uninit.mlcfg
#	creusot/tests/should_succeed/result/own.mlcfg
#	creusot/tests/should_succeed/result/result.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max_3.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max_many.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max_repeat.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_2_list.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_2_tree.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_list.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_tree.mlcfg
#	creusot/tests/should_succeed/selection_sort_generic.mlcfg
#	creusot/tests/should_succeed/slices/01.mlcfg
#	creusot/tests/should_succeed/slices/02_std.mlcfg
#	creusot/tests/should_succeed/sparse_array.mlcfg
#	creusot/tests/should_succeed/specification/opaque.mlcfg
#	creusot/tests/should_succeed/specification/trusted.mlcfg
#	creusot/tests/should_succeed/split_borrow.mlcfg
#	creusot/tests/should_succeed/sum.mlcfg
#	creusot/tests/should_succeed/sum_of_odds.mlcfg
#	creusot/tests/should_succeed/swap_borrows.mlcfg
#	creusot/tests/should_succeed/switch.mlcfg
#	creusot/tests/should_succeed/syntax/04_assoc_prec.mlcfg
#	creusot/tests/should_succeed/syntax/05_pearlite.mlcfg
#	creusot/tests/should_succeed/syntax/09_maintains.mlcfg
#	creusot/tests/should_succeed/syntax/10_mutual_rec_types.mlcfg
#	creusot/tests/should_succeed/syntax/11_array_types.mlcfg
#	creusot/tests/should_succeed/syntax/12_ghost_code.mlcfg
#	creusot/tests/should_succeed/syntax/13_vec_macro.mlcfg
#	creusot/tests/should_succeed/syntax/derive_macros.mlcfg
#	creusot/tests/should_succeed/take_first_mut.mlcfg
#	creusot/tests/should_succeed/trait.mlcfg
#	creusot/tests/should_succeed/trait_impl.mlcfg
#	creusot/tests/should_succeed/traits/01.mlcfg
#	creusot/tests/should_succeed/traits/02.mlcfg
#	creusot/tests/should_succeed/traits/03.mlcfg
#	creusot/tests/should_succeed/traits/04.mlcfg
#	creusot/tests/should_succeed/traits/06.mlcfg
#	creusot/tests/should_succeed/traits/07.mlcfg
#	creusot/tests/should_succeed/traits/08.mlcfg
#	creusot/tests/should_succeed/traits/09.mlcfg
#	creusot/tests/should_succeed/traits/11.mlcfg
#	creusot/tests/should_succeed/traits/12_default_method.mlcfg
#	creusot/tests/should_succeed/traits/13_assoc_types.mlcfg
#	creusot/tests/should_succeed/traits/16_impl_cloning.mlcfg
#	creusot/tests/should_succeed/two_modules.mlcfg
#	creusot/tests/should_succeed/type_invariants/borrows.mlcfg
#	creusot/tests/should_succeed/type_invariants/generated.mlcfg
#	creusot/tests/should_succeed/unnest.mlcfg
#	creusot/tests/should_succeed/vecdeque.mlcfg
#	creusot/tests/should_succeed/vector/01.mlcfg
#	creusot/tests/should_succeed/vector/02_gnome.mlcfg
#	creusot/tests/should_succeed/vector/03_knuth_shuffle.mlcfg
#	creusot/tests/should_succeed/vector/04_binary_search.mlcfg
#	creusot/tests/should_succeed/vector/05_binary_search_generic.mlcfg
#	creusot/tests/should_succeed/vector/06_knights_tour.mlcfg
#	creusot/tests/should_succeed/vector/07_read_write.mlcfg
#	creusot/tests/should_succeed/vector/08_haystack.mlcfg
#	creusot/tests/should_succeed/vector/09_capacity.mlcfg
@dewert99 dewert99 marked this pull request as ready for review January 19, 2024 19:31
@dewert99
Copy link
Collaborator Author

I modified span_attr to return None when converting DUMMY_SPAN since I think an mlcfg span is still better that span that was being produced before since it gives more information. Does this seem okay?

@xldenis
Copy link
Collaborator

xldenis commented Jan 20, 2024

Yes, st the very least this gives us indication of where we can improve things.

@@ -345,6 +351,60 @@ impl<'tcx> Why3Generator<'tcx> {
_ => false,
}
}

pub(crate) fn span_attr(&mut self, span: Span) -> Option<why3::declaration::Attribute> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks

Comment on lines 212 to 215
if false {
// This is necessary for type checking since ThinVec is not nameable
return exp(ExprKind::Call(P(name_to_path(f)), v));
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

? I don't understand this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If I didn't add this, Rust wasn't able to infer the type for

    let mut v = args.into_iter().map(|x| P(x)).collect();

The type is supposed to be ThinVec but it isn't pub used in rustc so I couldn't just do let mut v: ThinVec<_> = ...

@xldenis
Copy link
Collaborator

xldenis commented Jan 20, 2024

cargo creusot --why3 "prove"

Can we upgrade the cargo creusot argument parser here to improve the experience? Something like

cargo creusot why3 prove ?

@dewert99
Copy link
Collaborator Author

Can we upgrade the cargo creusot argument parser here to improve the experience? Something like
cargo creusot why3 prove ?

Maybe somewhat, but I think it is good to be able to send arbitrary options to Why3.
We could potentially have for example cargo creusot why3-prove "-P z3 -a split-vc" if you think that would be better.

@xldenis
Copy link
Collaborator

xldenis commented Jan 21, 2024

I do, but we can also do that in a follow up.

@jhjourdan
Copy link
Collaborator

Many thanks, David, for all the hard work! All in all, I am quite happy with these changes.

There is one thing with which I am not very comfortable in this PR. "why3 prove" is usually not the recommended work flow for using Why3 : the generated VCs often require a few transformations (a series of split_vc / use_th are quite common). While I think it is fine to offer a cargo command for "why3 prove", I think that we should also offer one for "why3 ide" (which you already did), and "why3 replay", the two commands mainly used in the session-based work flow.

@dewert99
Copy link
Collaborator Author

I think that we should also offer one for "why3 ide" (which you already did), and "why3 replay", the two commands mainly used in the session-based work flow.

Would you like me to add "why3 replay" to this PR, or wait for the follow up where I'll switch --why3 "prove .." to --why3-prove "" and then I can add --why3-replay?

@xldenis
Copy link
Collaborator

xldenis commented Jan 23, 2024

I think we can wait for the follow up, and in case you aren't aware, there is a plan to add why3 play which would be a version of prove with support for sessions and strategies.

@dewert99
Copy link
Collaborator Author

Is there anything I should still do before you merge this PR? (aside from merging and blessing)

@xldenis
Copy link
Collaborator

xldenis commented Jan 24, 2024

I think we can do other work in follow ups

# Conflicts:
#	creusot/tests/should_fail/bug/222.mlcfg
#	creusot/tests/should_fail/bug/492.mlcfg
#	creusot/tests/should_fail/bug/692.mlcfg
#	creusot/tests/should_fail/bug/695.mlcfg
#	creusot/tests/should_succeed/100doors.mlcfg
#	creusot/tests/should_succeed/all_zero.mlcfg
#	creusot/tests/should_succeed/bdd.mlcfg
#	creusot/tests/should_succeed/bug/463.mlcfg
#	creusot/tests/should_succeed/bug/486.mlcfg
#	creusot/tests/should_succeed/bug/570.mlcfg
#	creusot/tests/should_succeed/bug/594.mlcfg
#	creusot/tests/should_succeed/bug/682.mlcfg
#	creusot/tests/should_succeed/bug/766.mlcfg
#	creusot/tests/should_succeed/bug/box_borrow_resolve.mlcfg
#	creusot/tests/should_succeed/bug/two_phase.mlcfg
#	creusot/tests/should_succeed/closures/01_basic.mlcfg
#	creusot/tests/should_succeed/closures/03_generic_bound.mlcfg
#	creusot/tests/should_succeed/closures/05_map.mlcfg
#	creusot/tests/should_succeed/closures/06_fn_specs.mlcfg
#	creusot/tests/should_succeed/closures/07_mutable_capture.mlcfg
#	creusot/tests/should_succeed/drop_pair.mlcfg
#	creusot/tests/should_succeed/hashmap.mlcfg
#	creusot/tests/should_succeed/heapsort_generic.mlcfg
#	creusot/tests/should_succeed/hillel.mlcfg
#	creusot/tests/should_succeed/index_range.mlcfg
#	creusot/tests/should_succeed/inplace_list_reversal.mlcfg
#	creusot/tests/should_succeed/invariant_moves.mlcfg
#	creusot/tests/should_succeed/ite_normalize.mlcfg
#	creusot/tests/should_succeed/iterators/01_range.mlcfg
#	creusot/tests/should_succeed/iterators/02_iter_mut.mlcfg
#	creusot/tests/should_succeed/iterators/03_std_iterators.mlcfg
#	creusot/tests/should_succeed/iterators/04_skip.mlcfg
#	creusot/tests/should_succeed/iterators/05_map.mlcfg
#	creusot/tests/should_succeed/iterators/06_map_precond.mlcfg
#	creusot/tests/should_succeed/iterators/07_fuse.mlcfg
#	creusot/tests/should_succeed/iterators/08_collect_extend.mlcfg
#	creusot/tests/should_succeed/iterators/10_once.mlcfg
#	creusot/tests/should_succeed/iterators/12_zip.mlcfg
#	creusot/tests/should_succeed/iterators/13_cloned.mlcfg
#	creusot/tests/should_succeed/iterators/14_copied.mlcfg
#	creusot/tests/should_succeed/iterators/15_enumerate.mlcfg
#	creusot/tests/should_succeed/iterators/16_take.mlcfg
#	creusot/tests/should_succeed/knapsack.mlcfg
#	creusot/tests/should_succeed/knapsack_full.mlcfg
#	creusot/tests/should_succeed/lang/branch_borrow_2.mlcfg
#	creusot/tests/should_succeed/lang/promoted_constants.mlcfg
#	creusot/tests/should_succeed/list_index_mut.mlcfg
#	creusot/tests/should_succeed/list_reversal_lasso.mlcfg
#	creusot/tests/should_succeed/mapping_test.mlcfg
#	creusot/tests/should_succeed/projection_toggle.mlcfg
#	creusot/tests/should_succeed/projections.mlcfg
#	creusot/tests/should_succeed/red_black_tree.mlcfg
#	creusot/tests/should_succeed/resolve_uninit.mlcfg
#	creusot/tests/should_succeed/result/own.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max_3.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max_many.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_max_repeat.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_2_list.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_2_tree.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_list.mlcfg
#	creusot/tests/should_succeed/rusthorn/inc_some_tree.mlcfg
#	creusot/tests/should_succeed/selection_sort_generic.mlcfg
#	creusot/tests/should_succeed/sparse_array.mlcfg
#	creusot/tests/should_succeed/split_borrow.mlcfg
#	creusot/tests/should_succeed/sum.mlcfg
#	creusot/tests/should_succeed/sum_of_odds.mlcfg
#	creusot/tests/should_succeed/swap_borrows.mlcfg
#	creusot/tests/should_succeed/syntax/11_array_types.mlcfg
#	creusot/tests/should_succeed/syntax/12_ghost_code.mlcfg
#	creusot/tests/should_succeed/take_first_mut.mlcfg
#	creusot/tests/should_succeed/type_invariants/borrows.mlcfg
#	creusot/tests/should_succeed/type_invariants/generated.mlcfg
#	creusot/tests/should_succeed/type_invariants/non_zero.mlcfg
#	creusot/tests/should_succeed/type_invariants/quant.mlcfg
#	creusot/tests/should_succeed/type_invariants/type_invariants.mlcfg
#	creusot/tests/should_succeed/type_invariants/vec_inv.mlcfg
#	creusot/tests/should_succeed/unnest.mlcfg
#	creusot/tests/should_succeed/vector/01.mlcfg
#	creusot/tests/should_succeed/vector/02_gnome.mlcfg
#	creusot/tests/should_succeed/vector/03_knuth_shuffle.mlcfg
#	creusot/tests/should_succeed/vector/06_knights_tour.mlcfg
#	creusot/tests/should_succeed/vector/07_read_write.mlcfg
#	creusot/tests/should_succeed/vector/08_haystack.mlcfg
#	creusot/tests/should_succeed/vector/09_capacity.mlcfg
@dewert99
Copy link
Collaborator Author

I merged and blessed the latest changes. Would you be ok to fix the Why3 sessions and merge this?

@xldenis
Copy link
Collaborator

xldenis commented Jan 24, 2024

sure, but note that 99% of these can be fixed via cargo test --test why3 -- --replay=obsolete the remaining 1% should as well but sometimes why3 refuses it.

@xldenis
Copy link
Collaborator

xldenis commented Jan 24, 2024

I'm going to merge this.

In a follow up PR it would be good to see why3_cmd exploded into a subcommand using Clap, so that we can get proper parsing and validation of the commands. At the same time we can offer a command that recognizes strategies using play / replay as appropriate.

Once we've figured out the correct workflow and options, I'd like to eventually just have cargo creusot prove (or even cargo creusot if we're being crazy) which 'does the thing'.

@xldenis xldenis merged commit 4c2ff1a into creusot-rs:master Jan 24, 2024
4 checks passed
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