1use super::prelude::*;
2
3verus! {
4
5#[verifier::external_type_specification]
6#[verifier::external_body]
7#[verifier::reject_recursive_types(Options)]
8#[verifier::reject_recursive_types(ArgModes)]
9#[verifier::reject_recursive_types(OutMode)]
10#[verifier::reject_recursive_types(Args)]
11#[verifier::accept_recursive_types(Output)]
12pub struct ExFnProof<'a, Options, ArgModes, OutMode, Args, Output>(
13 FnProof<'a, Options, ArgModes, OutMode, Args, Output>,
14);
15
16#[doc(hidden)]
17#[verifier::external_type_specification]
18#[verifier::external_body]
19#[verifier::reject_recursive_types(USAGE)]
20#[verifier::reject_recursive_types(ReqEns)]
21#[verifier::reject_recursive_types(COPY)]
22#[verifier::reject_recursive_types(SEND)]
23#[verifier::reject_recursive_types(SYNC)]
24#[verifier::reject_recursive_types(OPENS)]
25pub struct ExFnProofOptions<
26 const USAGE: u8,
27 ReqEns,
28 const COPY: u8,
29 const SEND: u8,
30 const SYNC: u8,
31 const OPENS: u8,
32>(FOpts<USAGE, ReqEns, COPY, SEND, SYNC, OPENS>);
33
34#[verifier::external_trait_specification]
35pub trait ExProofFnSpecification<Args, Output> {
36 type ExternalTraitSpecificationFor: ProofFnReqEnsDef<Args, Output>;
37
38 spec fn req(_args: Args) -> bool;
39
40 spec fn ens(_args: Args, _output: Output) -> bool;
41}
42
43#[doc(hidden)]
44#[verifier::external_type_specification]
45#[verifier::external_body]
46#[verifier::reject_recursive_types(R)]
47pub struct ExFnProofOptionReqEns<R>(RqEn<R>);
48
49#[doc(hidden)]
50#[verifier::external_type_specification]
51#[verifier::external_body]
52pub struct ExFnProofOptionTracked(Trk);
53
54#[verifier::external_trait_specification]
55pub trait ExProofFnNoOpens {
56 type ExternalTraitSpecificationFor: ProofFnNoOpens;
57}
58
59#[verifier::external_trait_specification]
60pub trait ExProofFnOnceOpens {
61 type ExternalTraitSpecificationFor: ProofFnOnceOpens;
62}
63
64#[verifier::external_trait_specification]
65pub trait ExProofFnMutOpens: ProofFnOnceOpens {
66 type ExternalTraitSpecificationFor: ProofFnMutOpens;
67}
68
69#[verifier::external_trait_specification]
70pub trait ExProofFnOpens: ProofFnMutOpens {
71 type ExternalTraitSpecificationFor: ProofFnOpens;
72}
73
74#[verifier::external_trait_specification]
75pub trait ExProofFnOnce: ProofFnOnceOpens + ProofFnNoOpens {
76 type ExternalTraitSpecificationFor: ProofFnOnce;
77}
78
79#[verifier::external_trait_specification]
80pub trait ExProofFnMut: ProofFnOnce + ProofFnMutOpens + ProofFnNoOpens {
81 type ExternalTraitSpecificationFor: ProofFnMut;
82}
83
84#[verifier::external_trait_specification]
85pub trait ExProofFn: ProofFnMut + ProofFnOpens + ProofFnNoOpens {
86 type ExternalTraitSpecificationFor: ProofFn;
87}
88
89#[verifier::external_trait_specification]
90pub trait ExProofFnReqEnsAssoc {
91 type ExternalTraitSpecificationFor: ProofFnReqEnsAssoc;
92
93 type ReqEns;
94}
95
96#[verifier::external_trait_specification]
97pub trait ExProofFnReqEns<R>: ProofFnReqEnsAssoc<ReqEns = R> {
98 type ExternalTraitSpecificationFor: ProofFnReqEns<R>;
99}
100
101#[doc(hidden)]
102pub broadcast axiom fn axiom_proof_fn_requires<
103 F,
104 ArgModes,
105 OutMode,
106 Args: core::marker::Tuple,
107 Output,
108>(f: FnProof<F, ArgModes, OutMode, Args, Output>, args: Args) where
109 F: ProofFnOnceOpens,
110 F: ProofFnReqEnsAssoc,
111 <F as ProofFnReqEnsAssoc>::ReqEns: ProofFnReqEnsDef<Args, Output>,
112
113 ensures
114 #[trigger] f.requires(args) <==> <F as ProofFnReqEnsAssoc>::ReqEns::req(args),
115;
116
117#[doc(hidden)]
118pub broadcast axiom fn axiom_proof_fn_ensures<
119 F,
120 ArgModes,
121 OutMode,
122 Args: core::marker::Tuple,
123 Output,
124>(f: FnProof<F, ArgModes, OutMode, Args, Output>, args: Args, output: Output) where
125 F: ProofFnOnceOpens,
126 F: ProofFnReqEnsAssoc,
127 <F as ProofFnReqEnsAssoc>::ReqEns: ProofFnReqEnsDef<Args, Output>,
128
129 ensures
130 #[trigger] f.ensures(args, output) <==> <F as ProofFnReqEnsAssoc>::ReqEns::ens(
131 args,
132 output,
133 ),
134;
135
136#[doc(hidden)]
137pub broadcast axiom fn axiom_proof_fn_no_opens_invariants<
138 F,
139 ArgModes,
140 OutMode,
141 Args: core::marker::Tuple,
142 Output,
143>(f: FnProof<F, ArgModes, OutMode, Args, Output>, args: Args) where
144 F: ProofFnOnceOpens,
145 F: ProofFnNoOpens,
146
147 ensures
148 #[trigger] call_opens_invariants::<_, _, ISet<int>>(f, args) == ISet::empty(),
149;
150
151pub axiom fn proof_fn_as_req_ens<
153 R: ProofFnReqEnsDef<Args, Output>,
154 const USAGE: u8,
155 ReqEns,
156 const COPY: u8,
157 const SEND: u8,
158 const SYNC: u8,
159 const OPENS: u8,
160 ArgModes,
161 OutMode,
162 Args: core::marker::Tuple,
163 Output,
164>(
165 tracked f: FnProof<
166 FOpts<USAGE, ReqEns, COPY, SEND, SYNC, OPENS>,
167 ArgModes,
168 OutMode,
169 Args,
170 Output,
171 >,
172) -> tracked FnProof<
173 FOpts<USAGE, RqEn<R>, COPY, SEND, SYNC, OPENS>,
174 ArgModes,
175 OutMode,
176 Args,
177 Output,
178>
179 requires
180 forall|args: Args| #[trigger] R::req(args) ==> f.requires(args),
181 forall|args: Args, output: Output|
182 f.ensures(args, output) ==> #[trigger] R::ens(args, output),
183;
184
185pub broadcast axiom fn axiom_fn_mut_call_requires<Args: core::marker::Tuple, F: FnMut<Args>>(
186 f: &mut F,
187 args: Args,
188)
189 requires
190 call_requires::<Args, F>(mut_ref_current(f), args),
191 ensures
192 #[trigger] call_requires::<Args, &mut F>(f, args),
193;
194
195pub broadcast axiom fn axiom_fn_mut_call_ensures<Args: core::marker::Tuple, F: FnMut<Args>>(
198 f: &mut F,
199 args: Args,
200 output: F::Output,
201)
202 requires
203 #[trigger] call_ensures::<Args, &mut F>(f, args, output),
204 ensures
205 call_ensures::<Args, F>(mut_ref_current(f), args, output),
206;
207
208pub broadcast axiom fn axiom_fn_mut_call_opens_invariants<
209 Args: core::marker::Tuple,
210 F: FnMut<Args>,
211 I,
212>(f: &mut F, args: Args)
213 ensures
214 #[trigger] call_opens_invariants::<Args, &mut F, I>(f, args) == call_opens_invariants::<
215 Args,
216 F,
217 I,
218 >(mut_ref_current(f), args),
219;
220
221pub broadcast group group_function_axioms {
222 axiom_proof_fn_requires,
223 axiom_proof_fn_ensures,
224 axiom_proof_fn_no_opens_invariants,
225 axiom_fn_mut_call_requires,
226 axiom_fn_mut_call_ensures,
227 axiom_fn_mut_call_opens_invariants,
228}
229
230}