use crate::common::collections::vecs::*;
use crate::implementation::common::generic_refinement::*;
use crate::implementation::RSL::appinterface::*;
use crate::implementation::RSL::types_i::*;
use crate::protocol::RSL::state_machine::*;
use crate::protocol::RSL::types::*;
use crate::services::RSL::app_state_machine::*;
use builtin::*;
use builtin_macros::*;
use std::collections::HashMap;
use vstd::{prelude::*, seq::*, seq_lib::*};
verus! {
pub fn CHandleRequest(state:&CAppState, request:&CRequest) -> ( result:(CAppState, CReply))
requires
CAppStateIsValid(state),
request.valid()
ensures
AbstractifyCAppStateToAppState(&result.0) == HandleRequest(AbstractifyCAppStateToAppState(state), request.view()).0,
result.1.view() == HandleRequest(AbstractifyCAppStateToAppState(state), request.view()).1
{
let (new_state, reply) = HandleAppRequest(&state, &request.request);
(new_state, CReply { client: request.client.clone_up_to_view(), seqno: request.seqno, reply })
}
pub fn CHandleRequestBatchHidden(state:&CAppState, batch:&CRequestBatch) -> (result:(Vec<CAppState>, Vec<CReply>))
requires
CAppStateIsValid(state),
crequestbatch_is_valid(batch)
ensures
result.0.len() == batch.len()+1,
(result.0@.map(|i,x:CAppState| x@),result.1@.map(|i,y:CReply| y@)) == HandleRequestBatchHidden(state@, abstractify_crequestbatch(batch)),
{
if batch.len() == 0 {
let states = vec![state.clone()];
let replies = vec![];
let ghost s = AbstractifyCAppStateToAppState(state);
let ghost b = abstractify_crequestbatch(batch);
let ghost (ss, rs) = HandleRequestBatchHidden(s,b);
assert(states@.map(|i, x: CAppState| x@)==ss);
assert(replies@.map(|i, x: CReply| x@)==rs);
(states, replies)
} else {
let t_vec = &truncate_vec(batch, 0, batch.len() - 1);
assert(t_vec@.len()==batch@.len()-1);
let (rest_states, rest_replies) = CHandleRequestBatchHidden(state, t_vec);
assert(rest_states@.len() > 0); let (new_state, reply) = HandleAppRequest(&rest_states[rest_states.len()-1], &batch[batch.len()-1].clone_up_to_view().request);
let mut states = rest_states;
states.push(new_state);
let mut replies = rest_replies;
replies.push(CReply{client: batch[batch.len()-1].client.clone(), seqno: batch[batch.len()-1].seqno, reply: reply});
let ghost s = AbstractifyCAppStateToAppState(&state);
let ghost b = abstractify_crequestbatch(&batch);
let ghost b_clone = b;
assert(b_clone.len()>0);
let ghost (rs, rp) = HandleRequestBatchHidden(s, b_clone.drop_last());
assert(rs.len()>0);
let ghost (s1, r) = AppHandleRequest(rs.last(), b.last().request);
assert(new_state@==s1);
assert(reply@==r);
let ghost (ss_prime, rs_prime) = HandleRequestBatchHidden(s, b);
assert(states@.len()==ss_prime.len());
assert(replies@.len()==rs_prime.len());
assert(states@.last()@ == ss_prime.last());
let ghost expected_reply = Reply {
client: batch[batch.len()-1].client@,
seqno: batch[batch.len()-1].seqno as int,
reply: reply@,
};
let ghost expected = rest_replies@.map(|i, x:CReply| x@) + seq![expected_reply];
assert(rs_prime == expected);
assume(replies@[replies.len()-1]@.client == rs_prime.last().client);
assert(replies@[replies.len()-1]@.seqno == rs_prime.last().seqno);
assume(replies@[replies.len()-1]@.reply == rs_prime.last().reply);
assert(replies@[replies@.len()-1]@ == expected_reply);
assert(rs_prime[rs_prime.len()-1] == expected_reply);
assert(replies@.last()@ == rs_prime.last());
assert(states@.map(|i, x: CAppState| x@) == ss_prime);
assert(replies@.map(|i, x: CReply| x@) == rs_prime);
assert(
HandleRequestBatchHidden(AbstractifyCAppStateToAppState(state), abstractify_crequestbatch(batch)) ==
(states@.map(|i, x: CAppState| x@), replies@.map(|i, x: CReply| x@))
);
(states, replies)
}
}
pub fn CHandleRequestBatch(state:&CAppState, batch:&CRequestBatch) -> (rc:(Vec<CAppState>, Vec<CReply>))
requires
CAppStateIsValid(state),
crequestbatch_is_valid(batch)
ensures
(rc.0@.map(|i, x: CAppState| x@), rc.1@.map(|i, x: CReply| x@)) == HandleRequestBatch(state@, batch@.map(|i, x:CRequest| x@))
{
let (states, replies) = CHandleRequestBatchHidden(state, batch);
(states, replies)
}
}