Skip to content

Sometimes prusti_assert needed that exactly repeats the branch condition #1285

Open
@Stef-Gijsberts

Description

@Stef-Gijsberts

I noticed that to prove some statements, it is necessary to add a prusti_assert that exactly repeats a known fact.

In particular, this seems to happen if:

  • The statement to prove has an existential quantifier, and
  • tuples are involved.

I encountered this problem in a bigger function. For the purpose of demonstration, I reduced it to a minimal example.

First example

This fails:

#[requires(pairs.len() > 0)]
#[ensures(result ==> exists(|i: usize| pairs[i].0 == key))]
pub fn head_match_first(pairs: &[(i32, char)], key: i32) -> bool {
    if pairs[0].0 == key {
        true
    } else {
        false
    }
}

But to my surprise the following does not fail, although only the prusti_assert was added which exactly matches the branch condition:

#[requires(pairs.len() > 0)]
#[ensures(result ==> exists(|i: usize| pairs[i].0 == key))]
pub fn head_match_first(pairs: &[(i32, char)], key: i32) -> bool {
    if pairs[0].0 == key {
        prusti_assert!(pairs[0].0 == key);
        true
    } else {
        false
    }
}

Second example

This second example is the same function written differently, without the if-statement. Again, this fails:

#[requires(pairs.len() > 0)]
#[ensures(result ==> exists(|i: usize| pairs[i].0 == key))]
pub fn head_match_first(pairs: &[(i32, char)], key: i32) -> bool {
    pairs[0].0 == key
}

But this does not fail:

#[requires(pairs.len() > 0)]
#[ensures(result ==> exists(|i: usize| pairs[i].0 == key))]
pub fn head_match_first(pairs: &[(i32, char)], key: i32) -> bool {
    let result = pairs[0].0 == key;
    prusti_assert!(result == (pairs[0].0 == key));
    result
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions