tla-rs 0.1.0

Rust implementation of the IronFleet verified distributed systems framework
use builtin::*;
use builtin_macros::*;
use vstd::prelude::*;
use vstd::seq_lib::*;

use crate::common::framework::args_t::*;
use crate::common::native::io_s::*;

verus! {
    pub open spec fn parse_arg_as_end_point(arg: AbstractArg) -> AbstractEndPoint
    {
        AbstractEndPoint{id: arg}
    }

    pub open spec fn unchecked_parse_args(args: AbstractArgs) -> Seq<AbstractEndPoint>
    {
        args.map(|idx, arg: AbstractArg| parse_arg_as_end_point(arg))
    }

    pub open spec(checked) fn parse_args(args: AbstractArgs) -> Option<Seq<AbstractEndPoint>>
    {
        let end_points = unchecked_parse_args(args);
        if forall |i| #![auto] 0 <= i < end_points.len() ==> end_points[i].valid_physical_address() {
            Some(end_points)
        } else {
            None
        }
    }


    pub fn parse_end_point(arg: &Arg) -> (out: EndPoint)
    ensures
        out@ == parse_arg_as_end_point(arg@),
    {
        EndPoint{id: clone_arg(arg)}
    }


    pub fn parse_end_points(args: &Args) -> (out: Option<Vec<EndPoint>>)
    ensures
        match out {
            None => parse_args(abstractify_args(*args)) is None,
            Some(vec) => {
                &&& parse_args(abstractify_args(*args)) is Some
                &&& abstractify_end_points(vec) == parse_args(abstractify_args(*args)).unwrap()
                &&& forall |i: int| #![auto] 0 <= i < vec.len() ==> vec[i]@.valid_physical_address()
            },
        }
    {
        let mut end_points: Vec<EndPoint> = Vec::new();
        let mut i: usize = 0;

        while i<args.len()
        invariant
            i <= args.len(),
            end_points.len() == i,
            forall |j| #![auto] 0 <= j < i ==> parse_arg_as_end_point(abstractify_args(*args)[j]) == end_points@[j]@,
            forall |j| #![auto] 0 <= j < i ==> end_points@[j]@.valid_physical_address(),
        {
            let end_point = parse_end_point(&(*args)[i]);
            if !end_point.valid_physical_address() {
                assert(!unchecked_parse_args(abstractify_args(*args))[i as int].valid_physical_address()); // witness to !forall
                return None;
            }
            end_points.push(end_point);
            i = i + 1;
        }

        proof {
            assert_seqs_equal!(abstractify_end_points(end_points), unchecked_parse_args(abstractify_args(*args)));
        }
        Some(end_points)
    }
}