Git Product home page Git Product logo

Comments (4)

Aurel300 avatar Aurel300 commented on June 11, 2024

(I can't test this atm, but) does it make a difference if you remove these two postconditions from the extern spec?

    #[ensures(!result <==> self.is_none())]
    #[ensures(!result <==> self.is_some())]

from prusti-dev.

nokunish avatar nokunish commented on June 11, 2024

It does not seem to make any difference... I've commented both/either one of them out, and they crash.
I've also tried changing to
#[ensures(!result == self.is_none())],#[ensures(result != self.is_none())], as well as annotating is_none(..) as trusted, but none of these seem to work either

If I comment out both post-conditions for None

#[pure]
    pub fn is_none(&self) -> bool;

then, Prusti does not crash, but then it wouldn't be very helpful since we can't verify

#[pure]
    #[ensures(u <= 10 ==> result.is_none())]                   // this fails 
    pub fn filter(&self, u: u32) -> Option<u32> {
        if u > 10 {
            return Some(u)
    }  
        return None
    }

from prusti-dev.

jscissr avatar jscissr commented on June 11, 2024

This bug happens for the same reason as #1391. The problem is that for enums which are only used in specifications (pre- and postconditions, assertions) of a function but not in its body, some functions and axioms are not generated in the viper domain of the snapshot type. In particular, some constructors and the discriminant axioms are missing. In this case, the injectivity axiom is still present and refers to a missing constructor:

domain Snap$m_std$$option$$Option$_beg_$u32$_end_  {
  
  function discriminant$__$TY$__Snap$m_std$$option$$Option$_beg_$u32$_end_$Snap$m_std$$option$$Option$_beg_$u32$_end_$$int$(self: Snap$m_std$$option$$Option$_beg_$u32$_end_): Int 
  
  function cons$0$__$TY$__Snap$m_std$$option$$Option$_beg_$u32$_end_$Snap$m_std$$option$$Option$_beg_$u32$_end_(): Snap$m_std$$option$$Option$_beg_$u32$_end_ 
  
  axiom Snap$m_std$$option$$Option$_beg_$u32$_end_$1$injectivity {
    (forall _l_0: Int, _r_0: Int ::
      { cons$1$__$TY$__Snap$m_std$$option$$Option$_beg_$u32$_end_$$int$$Snap$m_std$$option$$Option$_beg_$u32$_end_(_l_0),
      cons$1$__$TY$__Snap$m_std$$option$$Option$_beg_$u32$_end_$$int$$Snap$m_std$$option$$Option$_beg_$u32$_end_(_r_0) }
      cons$1$__$TY$__Snap$m_std$$option$$Option$_beg_$u32$_end_$$int$$Snap$m_std$$option$$Option$_beg_$u32$_end_(_l_0) ==
      cons$1$__$TY$__Snap$m_std$$option$$Option$_beg_$u32$_end_$$int$$Snap$m_std$$option$$Option$_beg_$u32$_end_(_r_0) ==>
      _l_0 == _r_0)
  }
}

We can work around this bug by explicitly mentioning the type in the function body, which causes everything in the snapshot domain to be generated:

#[pure]
fn test(u: u32) -> Option<u32> {
     return None
}

#[requires(test(10).is_none())]
fn main() {
    let _: Option<u32> = None;
}

from prusti-dev.

nokunish avatar nokunish commented on June 11, 2024

Hi,

There seems to be a similar bug with Option::Some(..) as well.
For instance, if we have a function that always returns Some(usize),

    #[pure]
    pub fn some_obj(&self) -> Option<usize> {
        Some(10)
    }

    #[pure]                                                     // does not affect results
    #[ensures(result <==> self.some_obj().is_some())]      
    pub fn is_true(&self) -> bool {
        let _: Option<usize> = None;                           
        true
    }

Prusti crashes if the post-condition for is_true(..) is imposed, even if we mention the type explicitly and remove the pure annotation. On the other hand when a similar tactic is used for some_obj(..), i.e.,

    #[pure]
    pub fn some_obj(&self) -> Option<usize> {
        let obj: Option<usize> = Some(10);
        obj
    }

the explicit mentioning of the type makes Prusti crash, only if the fuction is marked as pure.

from prusti-dev.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.