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

Trigger inference infers invalid triggers #687

Open
vakaras opened this issue May 5, 2023 · 4 comments
Open

Trigger inference infers invalid triggers #687

vakaras opened this issue May 5, 2023 · 4 comments
Labels
bug Something isn't working triggers

Comments

@vakaras
Copy link
Contributor

vakaras commented May 5, 2023

If one tries to verify the following Viper program:

function offset(start: Ref, index: Int): Ref

method test(start: Ref, l: Int)
    ensures forall ii: Int :: 0 <= ii && ii < l ==> offset(start, 0 + ii) == old(offset(start, 1 + ii))
{
}

they will get the following error message:

Silicon found 1 error in 5,26s:
  [0] Postcondition of test might not hold. Assertion (forall __rw_ii1: Int, __rw_ii2: Int :: { offset(start, __rw_ii1) } { offset(start, __rw_ii2) } true && __rw_ii1 - 0 == __rw_ii2 - 1 ==> 0 <= __rw_ii1 - 0 && __rw_ii1 - 0 < l ==> offset(start, __rw_ii1) == old(offset(start, __rw_ii2))) might not hold. ([email protected])

Potential incompleteness: Some((:reason-unknown "(incomplete quantifiers)"))

which shows that Viper inferred invalid triggers for the quantifier.

Z3 rejects this trigger, as witnessed by the following message in the log:

13:50:45.129 [ForkJoinPool-1-worker-3] WARN viper.silicon.decider.Z3ProverStdIO - Prover warning: WARNING: (642,21): pattern does not contain all quantified variables.

cc @marcoeilers

The credit for noticing this goes to Olivia.

@vakaras vakaras added bug Something isn't working triggers labels May 5, 2023
@fpoli
Copy link
Member

fpoli commented May 5, 2023

Why is a forall with a single quantified variable rewritten to a forall with two quantified variables? Does Silicon do it frequently?

@marcoeilers
Copy link
Contributor

The trigger generation code (I think only in Silicon?) does it when all possible trigger expressions it finds in the quantifier body contain arithmetic, like in this example. offset(start, 0 + ii) would be the natural trigger expression, but that is invalid, because it contains an addition. So Silicon rewrites the quantifier to an equivalent one where it replaces the addition expression 0 + ii with a new quantified variable and constrains it accordingly. So it can trigger on offset(start, newVar) and rewrites the body s.t. newVar must be 0 + ii.

@fpoli
Copy link
Member

fpoli commented May 5, 2023

I see, thanks! Just to be sure, the extra quantified variable can only be introduced when the user does not specify the triggers, right? Otherwise it'd be really hard to reason about the maximum number of QI of domain axioms.

@marcoeilers
Copy link
Contributor

As far as I know that's correct, yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triggers
Projects
None yet
Development

No branches or pull requests

3 participants