vstd_extra/state_machine/
action.rs1#![allow(unused_imports)]
4use super::super::temporal_logic::*;
5use vstd::prelude::*;
6
7verus! {
8
9#[verifier(reject_recursive_types(State))]
10#[verifier(reject_recursive_types(Input))]
11#[verifier(reject_recursive_types(Output))]
12pub struct Action<State, Input, Output> {
13 pub precondition: spec_fn(Input, State) -> bool,
15 pub transition: spec_fn(Input, State) -> (State, Output),
17}
18
19impl<State, Input, Output> Action<State, Input, Output> {
20 pub open spec fn pre(self, input: Input) -> StatePred<State> {
21 StatePred::new(|s: State| (self.precondition)(input, s))
22 }
23
24 pub open spec fn forward(self, input: Input) -> ActionPred<State> {
25 ActionPred::new(
26 |s: State, s_prime: State|
27 {
28 &&& (self.precondition)(input, s)
29 &&& s_prime == (self.transition)(input, s).0
30 },
31 )
32 }
33
34 pub open spec fn weak_fairness(self, input: Input) -> TempPred<State> {
37 always(lift_state(self.pre(input))).leads_to(lift_action(self.forward(input)))
38 }
39
40 pub proof fn wf1(
42 self,
43 input: Input,
44 spec: TempPred<State>,
45 next: ActionPred<State>,
46 pre: StatePred<State>,
47 post: StatePred<State>,
48 )
49 requires
50 forall|s, s_prime: State|
51 pre.apply(s) && #[trigger] next.apply(s, s_prime) ==> pre.apply(s_prime)
52 || post.apply(s_prime),
53 forall|s, s_prime: State|
54 pre.apply(s) && #[trigger] next.apply(s, s_prime) && self.forward(input).apply(
55 s,
56 s_prime,
57 ) ==> post.apply(s_prime),
58 spec.entails(always(lift_action(next))),
59 spec.entails(always(lift_state(pre).implies(lift_state(self.pre(input))))),
60 spec.entails(self.weak_fairness(input)),
61 ensures
62 spec.entails(lift_state(pre).leads_to(lift_state(post))),
63 {
64 always_implies_preserved_by_always::<State>(
65 spec,
66 lift_state(pre),
67 lift_state(self.pre(input)),
68 );
69 leads_to_weaken::<State>(
70 spec,
71 always(lift_state(self.pre(input))),
72 lift_action(self.forward(input)),
73 always(lift_state(pre)),
74 lift_action(self.forward(input)),
75 );
76 wf1_variant_temp::<State>(
77 spec,
78 lift_action(next),
79 lift_action(self.forward(input)),
80 lift_state(pre),
81 lift_state(post),
82 );
83 }
84
85 pub proof fn lemma_statisfy_pre_implies_enabled(self, input: Input, state: State)
86 requires
87 self.pre(input).apply(state),
88 ensures
89 enabled(self.forward(input)).apply(state),
90 {
91 let (new_state, _output) = (self.transition)(input, state);
92 assert(self.forward(input).apply(state, new_state));
93 }
94}
95
96pub enum ActionResult<State, Output> {
97 Disabled,
98 Enabled(State, Output),
99}
100
101}