use crate::verification::Contract;
pub struct CreusotStringNonEmpty;
impl Contract for CreusotStringNonEmpty {
type Input = String;
type Output = String;
fn requires(input: &String) -> bool {
!input.is_empty()
}
fn ensures(_input: &String, output: &String) -> bool {
!output.is_empty()
}
fn invariant(&self) -> bool {
true
}
}
pub struct CreusotI32Positive;
impl Contract for CreusotI32Positive {
type Input = i32;
type Output = i32;
fn requires(input: &i32) -> bool {
*input > 0
}
fn ensures(_input: &i32, output: &i32) -> bool {
*output > 0
}
fn invariant(&self) -> bool {
true
}
}
pub struct CreusotBoolValid;
impl Contract for CreusotBoolValid {
type Input = bool;
type Output = bool;
fn requires(_input: &bool) -> bool {
true
}
fn ensures(_input: &bool, _output: &bool) -> bool {
true
}
fn invariant(&self) -> bool {
true
}
}
pub struct CreusotU32NonZero;
impl Contract for CreusotU32NonZero {
type Input = u32;
type Output = u32;
fn requires(input: &u32) -> bool {
*input > 0
}
fn ensures(_input: &u32, output: &u32) -> bool {
*output > 0
}
}
pub struct CreusotU64NonZero;
impl Contract for CreusotU64NonZero {
type Input = u64;
type Output = u64;
fn requires(input: &u64) -> bool {
*input > 0
}
fn ensures(_input: &u64, output: &u64) -> bool {
*output > 0
}
}
pub struct CreusotU128NonZero;
impl Contract for CreusotU128NonZero {
type Input = u128;
type Output = u128;
fn requires(input: &u128) -> bool {
*input > 0
}
fn ensures(_input: &u128, output: &u128) -> bool {
*output > 0
}
}
pub struct CreusotUsizeNonZero;
impl Contract for CreusotUsizeNonZero {
type Input = usize;
type Output = usize;
fn requires(input: &usize) -> bool {
*input > 0
}
fn ensures(_input: &usize, output: &usize) -> bool {
*output > 0
}
}
pub struct CreusotI64Positive;
impl Contract for CreusotI64Positive {
type Input = i64;
type Output = i64;
fn requires(input: &i64) -> bool {
*input > 0
}
fn ensures(_input: &i64, output: &i64) -> bool {
*output > 0
}
}
pub struct CreusotI128Positive;
impl Contract for CreusotI128Positive {
type Input = i128;
type Output = i128;
fn requires(input: &i128) -> bool {
*input > 0
}
fn ensures(_input: &i128, output: &i128) -> bool {
*output > 0
}
}
pub struct CreusotIsizePositive;
impl Contract for CreusotIsizePositive {
type Input = isize;
type Output = isize;
fn requires(input: &isize) -> bool {
*input > 0
}
fn ensures(_input: &isize, output: &isize) -> bool {
*output > 0
}
}
pub struct CreusotF32Finite;
impl Contract for CreusotF32Finite {
type Input = f32;
type Output = f32;
fn requires(input: &f32) -> bool {
input.is_finite()
}
fn ensures(_input: &f32, output: &f32) -> bool {
output.is_finite()
}
}
pub struct CreusotF64Finite;
impl Contract for CreusotF64Finite {
type Input = f64;
type Output = f64;
fn requires(input: &f64) -> bool {
input.is_finite()
}
fn ensures(_input: &f64, output: &f64) -> bool {
output.is_finite()
}
}
pub struct CreusotOptionIsSome<T> {
_phantom: std::marker::PhantomData<T>,
}
impl<T> Default for CreusotOptionIsSome<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> CreusotOptionIsSome<T> {
pub const fn new() -> Self {
Self {
_phantom: std::marker::PhantomData,
}
}
}
impl<T> Contract for CreusotOptionIsSome<T>
where
T: crate::traits::Elicitation + Clone + std::fmt::Debug + Send,
{
type Input = Option<T>;
type Output = Option<T>;
fn requires(input: &Option<T>) -> bool {
input.is_some()
}
fn ensures(_input: &Option<T>, output: &Option<T>) -> bool {
output.is_some()
}
}
pub struct CreusotResultIsOk<T, E> {
_phantom: std::marker::PhantomData<(T, E)>,
}
impl<T, E> Default for CreusotResultIsOk<T, E> {
fn default() -> Self {
Self::new()
}
}
impl<T, E> CreusotResultIsOk<T, E> {
pub const fn new() -> Self {
Self {
_phantom: std::marker::PhantomData,
}
}
}
impl<T, E> Contract for CreusotResultIsOk<T, E>
where
T: crate::traits::Elicitation + Clone + std::fmt::Debug + Send,
E: crate::traits::Elicitation + Clone + std::fmt::Debug + Send,
{
type Input = Result<T, E>;
type Output = Result<T, E>;
fn requires(input: &Result<T, E>) -> bool {
input.is_ok()
}
fn ensures(_input: &Result<T, E>, output: &Result<T, E>) -> bool {
output.is_ok()
}
}
pub struct CreusotVecNonEmpty<T> {
_phantom: std::marker::PhantomData<T>,
}
impl<T> Default for CreusotVecNonEmpty<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> CreusotVecNonEmpty<T> {
pub const fn new() -> Self {
Self {
_phantom: std::marker::PhantomData,
}
}
}
impl<T> Contract for CreusotVecNonEmpty<T>
where
T: crate::traits::Elicitation + Clone + std::fmt::Debug + Send,
{
type Input = Vec<T>;
type Output = Vec<T>;
fn requires(input: &Vec<T>) -> bool {
!input.is_empty()
}
fn ensures(_input: &Vec<T>, output: &Vec<T>) -> bool {
!output.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_creusot_string_non_empty() {
let input = String::from("hello");
assert!(CreusotStringNonEmpty::requires(&input));
assert!(CreusotStringNonEmpty::ensures(&input, &input));
}
#[test]
fn test_creusot_i32_positive() {
let input = 42i32;
assert!(CreusotI32Positive::requires(&input));
assert!(CreusotI32Positive::ensures(&input, &input));
}
#[test]
fn test_creusot_bool_valid() {
assert!(CreusotBoolValid::requires(&true));
assert!(CreusotBoolValid::requires(&false));
assert!(CreusotBoolValid::ensures(&true, &false));
}
#[test]
fn test_creusot_u32_non_zero() {
assert!(CreusotU32NonZero::requires(&42u32));
assert!(!CreusotU32NonZero::requires(&0u32));
}
#[test]
fn test_creusot_u64_non_zero() {
assert!(CreusotU64NonZero::requires(&42u64));
assert!(!CreusotU64NonZero::requires(&0u64));
}
#[test]
fn test_creusot_u128_non_zero() {
assert!(CreusotU128NonZero::requires(&42u128));
assert!(!CreusotU128NonZero::requires(&0u128));
}
#[test]
fn test_creusot_usize_non_zero() {
assert!(CreusotUsizeNonZero::requires(&42usize));
assert!(!CreusotUsizeNonZero::requires(&0usize));
}
#[test]
fn test_creusot_i64_positive() {
assert!(CreusotI64Positive::requires(&42i64));
assert!(!CreusotI64Positive::requires(&0i64));
}
#[test]
fn test_creusot_i128_positive() {
assert!(CreusotI128Positive::requires(&42i128));
assert!(!CreusotI128Positive::requires(&0i128));
}
#[test]
fn test_creusot_isize_positive() {
assert!(CreusotIsizePositive::requires(&42isize));
assert!(!CreusotIsizePositive::requires(&0isize));
}
#[test]
fn test_creusot_f32_finite() {
assert!(CreusotF32Finite::requires(&42.0f32));
assert!(!CreusotF32Finite::requires(&f32::NAN));
}
#[test]
fn test_creusot_f64_finite() {
assert!(CreusotF64Finite::requires(&42.0f64));
assert!(!CreusotF64Finite::requires(&f64::NAN));
}
#[test]
fn test_creusot_option_is_some() {
let some_val: Option<i32> = Some(42);
let none_val: Option<i32> = None;
assert!(CreusotOptionIsSome::<i32>::requires(&some_val));
assert!(!CreusotOptionIsSome::<i32>::requires(&none_val));
}
#[test]
fn test_creusot_result_is_ok() {
let ok_val: Result<i32, String> = Ok(42);
let err_val: Result<i32, String> = Err("error".to_string());
assert!(CreusotResultIsOk::<i32, String>::requires(&ok_val));
assert!(!CreusotResultIsOk::<i32, String>::requires(&err_val));
}
#[test]
fn test_creusot_vec_non_empty() {
let non_empty: Vec<i32> = vec![1, 2, 3];
let empty: Vec<i32> = vec![];
assert!(CreusotVecNonEmpty::<i32>::requires(&non_empty));
assert!(!CreusotVecNonEmpty::<i32>::requires(&empty));
}
}