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

Interpret ** on both sides of @==> to allow inferring implicit arguments to stick lemmas #111

Open
tahina-pro opened this issue Nov 7, 2023 · 1 comment
Labels
pulse Issues related to the Pulse separation logic DSL

Comments

@tahina-pro
Copy link
Member

I am trying to use the "stick" (or magic wand-like view shift), with lemmas such as:

assume
val stick_consume_l
(_: unit)
(#p #q #r: vprop)
: stt_ghost unit emp_inames
(p ** ((p ** q) @==> r))
(fun _ -> q @==> r)
assume
val stick_consume_r
(_: unit)
(#q #p #r: vprop)
: stt_ghost unit emp_inames
(p ** ((q ** p) @==> r))
(fun _ -> q @==> r)
assume
val stick_trans
(_: unit)
(#p #q #r: vprop)
: stt_ghost unit emp_inames
((p @==> q) ** (q @==> r))
(fun _ -> p @==> r)

While I can use stick_trans with Pulse successfully inferring implicit arguments, this is not the case for stick_consume_l or stick_consume_r, where I need to specify the two parts of the left-hand-side. From what I understood of @nikswamy 's interpretation, this may be because ** becomes an ordinary F* term as opposed to a Pulse Tm_star AST construct.

Making it easier to use such lemmas would be a first step towards further automation of reasoning about @==> (e.g. an automatic tautology checker)

@tahina-pro tahina-pro added the pulse Issues related to the Pulse separation logic DSL label Nov 7, 2023
nikswamy added a commit that referenced this issue Dec 16, 2023
nikswamy added a commit that referenced this issue Dec 16, 2023
@nikswamy
Copy link
Collaborator

I have a fix to at least the main symptom reported in this issue. However, keep in mind that the Pulse unifier is, by design, very simple, e.g., it does not backtrack.

So, see 80a3d28 for a test case which shows what you can expect to work and not.

That said, there is one aspect of it that I had been trying to get to work, which I think ought to work eventually, but is hard to do in the current way the prover is structured. Consider this example:

ghost
fn test_elim_3 (p q r:vprop)
requires ((p ** q) @==> r) ** p ** q
ensures r
{
    elim _ _;
}

Say the invocation of elim is really elim ?1 ?2, to give names to those uvars.
The prover is called with the following goals : ?1 @==> ?2 and ?1.
The unifier correctly solves the first goal, setting ?1 := p ** q and ?2 := r.
Now it recurses trying to check that the second goal ?1 := p ** q is properly solved.
But this goal is not an atomic vprop and the matcher is currently designed to solve things one atomic vprop at a time, trying to match it against atomic vprops from the context. So, this fails.
@aseemr : would be nice to talk through this; seems to require some non-trivial restructuring of the matcher and its invariants ... but perhaps you know of an easier way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pulse Issues related to the Pulse separation logic DSL
Projects
None yet
Development

No branches or pull requests

2 participants