ravencheck 0.3.0

Decidable verification of Rust code using relational abstraction.
Documentation
#[crate::check_module(crate)]
#[declare_types(u32)]
#[allow(dead_code)]
mod my_mod {
    use std::collections::HashSet;

    #[declare]
    type MySet = HashSet<u32>;

    #[declare]
    fn member(e: u32, s: MySet) -> bool {
        s.contains(&e)
    }

    #[assume]
    fn equal_or_distinguisher() -> bool {
        forall(|a:MySet,b:MySet| {
            a == b || exists(|e:u32| member(e,a) !=  member(e,b))
        })
    }

    #[declare]
    fn filter(f: fn(u32) -> bool, s: MySet) -> MySet {
        let mut out = HashSet::new();
        for e in s.into_iter() {
            if f(e) {
                out.insert(e);
            }
        }
        out
    }

    #[assume(filter(f, s1) => s2)]
    fn filter_def() -> bool {
        forall(|e: u32| {
            member(e,s2) == (member(e,s1) && f(e))
        })
    }

    #[verify]
    fn filter_prop() -> bool {
        forall(|e: u32, s: MySet| {
            implies(
                !member(e,s),
                s == filter(|x: u32| x != e, s),
            )
        })
    }

    #[cfg(test)]
    #[test]
    fn filter_test() {
        let a = HashSet::from([1,2]);
        let f = |x| x >= 2;
        let b = filter(f, a.clone());
        let c = filter(|_| false, a);
        let d = filter(f, b.clone());
        assert!(b == HashSet::from([2]));
        assert!(c == HashSet::new());
        assert!(b == d);
    }
}