use super::prelude::*; verus! { #[verifier::external_type_specification] #[verifier::external_body] #[verifier::reject_recursive_types(Options)] #[verifier::reject_recursive_types(ArgModes)] #[verifier::reject_recursive_types(OutMode)] #[verifier::reject_recursive_types(Args)] #[verifier::accept_recursive_types(Output)] pub struct ExFnProof<'a, Options, ArgModes, OutMode, Args, Output>( FnProof<'a, Options, ArgModes, OutMode, Args, Output>, ); #[doc(hidden)] #[verifier::external_type_specification] #[verifier::external_body] #[verifier::reject_recursive_types(USAGE)] #[verifier::reject_recursive_types(ReqEns)] #[verifier::reject_recursive_types(COPY)] #[verifier::reject_recursive_types(SEND)] #[verifier::reject_recursive_types(SYNC)] #[verifier::reject_recursive_types(OPENS)] pub struct ExFnProofOptions< const USAGE: u8, ReqEns, const COPY: u8, const SEND: u8, const SYNC: u8, const OPENS: u8, >(FOpts); #[verifier::external_trait_specification] pub trait ExProofFnSpecification { type ExternalTraitSpecificationFor: ProofFnReqEnsDef; spec fn req(_args: Args) -> bool; spec fn ens(_args: Args, _output: Output) -> bool; } #[doc(hidden)] #[verifier::external_type_specification] #[verifier::external_body] #[verifier::reject_recursive_types(R)] pub struct ExFnProofOptionReqEns(RqEn); #[doc(hidden)] #[verifier::external_type_specification] #[verifier::external_body] pub struct ExFnProofOptionTracked(Trk); #[verifier::external_trait_specification] pub trait ExProofFnNoOpens { type ExternalTraitSpecificationFor: ProofFnNoOpens; } #[verifier::external_trait_specification] pub trait ExProofFnOnceOpens { type ExternalTraitSpecificationFor: ProofFnOnceOpens; } #[verifier::external_trait_specification] pub trait ExProofFnMutOpens: ProofFnOnceOpens { type ExternalTraitSpecificationFor: ProofFnMutOpens; } #[verifier::external_trait_specification] pub trait ExProofFnOpens: ProofFnMutOpens { type ExternalTraitSpecificationFor: ProofFnOpens; } #[verifier::external_trait_specification] pub trait ExProofFnOnce: ProofFnOnceOpens + ProofFnNoOpens { type ExternalTraitSpecificationFor: ProofFnOnce; } #[verifier::external_trait_specification] pub trait ExProofFnMut: ProofFnOnce + ProofFnMutOpens + ProofFnNoOpens { type ExternalTraitSpecificationFor: ProofFnMut; } #[verifier::external_trait_specification] pub trait ExProofFn: ProofFnMut + ProofFnOpens + ProofFnNoOpens { type ExternalTraitSpecificationFor: ProofFn; } #[verifier::external_trait_specification] pub trait ExProofFnReqEnsAssoc { type ExternalTraitSpecificationFor: ProofFnReqEnsAssoc; type ReqEns; } #[verifier::external_trait_specification] pub trait ExProofFnReqEns: ProofFnReqEnsAssoc { type ExternalTraitSpecificationFor: ProofFnReqEns; } #[doc(hidden)] pub broadcast axiom fn axiom_proof_fn_requires< F, ArgModes, OutMode, Args: core::marker::Tuple, Output, >(f: FnProof, args: Args) where F: ProofFnOnceOpens, F: ProofFnReqEnsAssoc, ::ReqEns: ProofFnReqEnsDef, ensures #[trigger] f.requires(args) <==> ::ReqEns::req(args), ; #[doc(hidden)] pub broadcast axiom fn axiom_proof_fn_ensures< F, ArgModes, OutMode, Args: core::marker::Tuple, Output, >(f: FnProof, args: Args, output: Output) where F: ProofFnOnceOpens, F: ProofFnReqEnsAssoc, ::ReqEns: ProofFnReqEnsDef, ensures #[trigger] f.ensures(args, output) <==> ::ReqEns::ens( args, output, ), ; #[doc(hidden)] pub broadcast axiom fn axiom_proof_fn_no_opens_invariants< F, ArgModes, OutMode, Args: core::marker::Tuple, Output, >(f: FnProof, args: Args) where F: ProofFnOnceOpens, F: ProofFnNoOpens, ensures #[trigger] call_opens_invariants::<_, _, ISet>(f, args) == ISet::empty(), ; /// Retype a proof_fn, introducing `ReqEns` pub axiom fn proof_fn_as_req_ens< R: ProofFnReqEnsDef, const USAGE: u8, ReqEns, const COPY: u8, const SEND: u8, const SYNC: u8, const OPENS: u8, ArgModes, OutMode, Args: core::marker::Tuple, Output, >( tracked f: FnProof< FOpts, ArgModes, OutMode, Args, Output, >, ) -> tracked FnProof< FOpts, COPY, SEND, SYNC, OPENS>, ArgModes, OutMode, Args, Output, > requires forall|args: Args| #[trigger] R::req(args) ==> f.requires(args), forall|args: Args, output: Output| f.ensures(args, output) ==> #[trigger] R::ens(args, output), ; pub broadcast axiom fn axiom_fn_mut_call_requires>( f: &mut F, args: Args, ) requires call_requires::(mut_ref_current(f), args), ensures #[trigger] call_requires::(f, args), ; // The output contract concerns the callable's current value. The reference may // outlive the call and be used to replace the callable, so its future is unconstrained. pub broadcast axiom fn axiom_fn_mut_call_ensures>( f: &mut F, args: Args, output: F::Output, ) requires #[trigger] call_ensures::(f, args, output), ensures call_ensures::(mut_ref_current(f), args, output), ; pub broadcast axiom fn axiom_fn_mut_call_opens_invariants< Args: core::marker::Tuple, F: FnMut, I, >(f: &mut F, args: Args) ensures #[trigger] call_opens_invariants::(f, args) == call_opens_invariants::< Args, F, I, >(mut_ref_current(f), args), ; pub broadcast group group_function_axioms { axiom_proof_fn_requires, axiom_proof_fn_ensures, axiom_proof_fn_no_opens_invariants, axiom_fn_mut_call_requires, axiom_fn_mut_call_ensures, axiom_fn_mut_call_opens_invariants, } } // verus!