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

make WeakestPrecondition.cmd complete wrt Semantics.exec #361

Merged
merged 15 commits into from
Aug 11, 2023

Conversation

samuelgruetter
Copy link
Contributor

At first I tried to delete the Fixpoint-based wp gen and base all of the program logic on wp rules. Conceptually that could have worked, but adapting all the examples in bedrock2Examples turned out too cumbersome because they rely on cbn, autogenerated hypothesis names, and hnf implicitly happening before eexists, letexists, split, and others. I stashed that experiment on this branch.

Now, I tried something simpler, just focusing on making WeakestPrecondition.cmd complete wrt Semantics.exec: The only two cases where completeness can't be proven are:

  1. cmd.while because the shape of the proof tree in exec lives in Prop and can't be extracted into a well_founded measure, at least not easily
  2. cmd.call if the function list contains the same name multiple times and a duplicate function makes a recursive call (this shouldn't happen, but carrying around NoDup premises seems much more cumbersome than simply switching to an env, ie map from string to function implementation, instead of using a list).

And it turns out that these two disagreeing cases are also exactly the two cases where a wp gen cannot be defined by structural recursion.
So I simply defined these two cases to be exec (or, more precisely, a thoroughly opaque definition called WP.wp_cmd that's defined to be exec but without being visible to tactics such as repeat split).

There's probably room for more improvements/cleanup/refactoring/simplification, but this one already gets us completeness, in a quite "minimally" invasive way.
What do you think @andres-erbsen?

and rules for cmd' whose premises are copied from WP.cmd.
This one is "fs everywhere" (ie list of functions everywhere).
The wp_call rule requires a NoDup, which would be cumbersome to
carry around.
In an "env everywhere" setting, where program_logic_goal_for!
adds a (map.get fs fname = Some fimpl) hypothesis.
Surprise #1: There's no case in straightline that handles if-then-else
Surprise #2: unfold1_... tactics are not the only place that depend
on conversion: There also exists a letexists in SPI that turns a
(WP (cmd.cond e _ _) ...) into an (exists v, eval e v /\ ...), and
probably more elsewhere.
by leaving the structurally recursive cases of cmd_body unchanged,
and defining the two non-structurally recursive cases (loop and call)
directly in terms of exec.
This seems to be the only approach that does not break proofs in
bedrock2Examples too badly.
and update compiler, LiveVerif, end2end
@andres-erbsen
Copy link
Contributor

I did try this at #294 and ended up thinking we should just delete wp and port the examples... but what you're doing here might be better than what I tried there.

@andres-erbsen andres-erbsen mentioned this pull request Aug 1, 2023

Definition refinement(c1 c2: cmd) := forall functions t m l post,
Semantics.exec.exec functions c1 t m l post ->
Semantics.exec.exec functions c2 t m l post.
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps let's flip the arguments to match c1 <= c2 and "refines" pronounciation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point, done in 535eec4

@@ -78,205 +75,142 @@ Section binops.
end.
End binops.

#[export] Instance env: map.map String.string Syntax.func := SortedListString.map _.
#[export] Instance env_ok: map.ok env := SortedListString.ok _.
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these instances required, and where? What mode do the classes have?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just pushed this commit that makes env a Definition, which requires almost no changes. Haven't tried env_ok yet.
This makes me wonder why we declared map.map a Class at all and not just a Record?

The Hint Mode of map.map is + (input), as it should be, but for map.ok, it seems no Hint Mode is registered, is this correct/intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Making env_ok a Lemma instead of an Instance would require mentioning it explicitly whenever we do pose proof (map.some_lemma ...), eapply map.some_lemma etc. Might be doable, but then it would be more consistent to make map.ok not a typeclass any more, and to make the map.ok argument an explicit one instead of an implicit one.
Or, if we keep declaring map.ok as a typeclass, then we could/should still see if it should get a Hint Mode + + + (key, value, and map implementation all are inputs to typeclass search).
But in either case, I'd say that should be separate from this PR.

(* this is the expr evaluator that is used to verify execution time, the just-correctness-oriented version is below *)
Section WithMemAndLocals.
Context (m : mem) (l : locals).

Local Notation "' x <- a | y ; f" := (match a with x => f | _ => y end)
(right associativity, at level 70, x pattern).
Local Notation "x <- a ; f" := (match a with Some x => f | None => None end)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

| cmd.call binds fname arges =>
exists args, dexprs m l arges args /\
call fname t m args (fun t m rets =>
Semantics.call e fname t m args (fun t m rets =>
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Fixpoint call functions := call_body call functions.

Definition program funcs main t m l post : Prop := cmd (call funcs) main t m l post.
Definition program := cmd.
Copy link
Contributor

Choose a reason for hiding this comment

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

🤔 hopefully this one is almost dead and can be removed soon

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes, I think only rupicola has some occurrences of this

End WeakestPrecondition.
Notation call := Semantics.call (only parsing).
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@@ -50,6 +50,32 @@ Definition uart0_rxdata := 0x10013004. Definition uart0_txdata := 0x10013000.
False
end%list%bool.

Ltac u :=
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we care to keep this file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have no strong attachment to this file 😉

@samuelgruetter samuelgruetter merged commit 4be89c9 into master Aug 11, 2023
2 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.

2 participants