Skip to content

Conversation

@coeff-aij
Copy link

@coeff-aij coeff-aij commented Jan 12, 2026

This extention allows users to call arbitrary user-defined predicates (e.g., is_double(x, result)) within annotations.
Currently, a dedicated syntax for defining user-defined predicates is not yet supported. Therefore, users must define them using the #![thrust::raw_define()] (introduced in #21 ) attribute for now.

  • Usage
    The predicate is_double() defined using #![thrust::raw_define()] can be called in the annotations such as #[thrust::ensures()]:
#![feature(custom_inner_attributes)]
#![thrust::raw_define("(define-fun is_double ((x Int) (doubled_x Int)) Bool
    (=
        (* x 2)
        doubled_x
    )
)")]

#[thrust::requires(true)]
#[thrust::ensures(is_double(x, result))]
fn double(x: i64) -> i64 {
    x + x
}

coord-e added 30 commits August 17, 2025 12:17
Support logical connectives in annotations
Define rty::Formula and replace UnboundAssumption and Refinement with it
Introduce PlaceTypeBuilder to simplify PlaceType construction
Add documentation to annot, chc, and pretty modules
Add documentation to rty and some other modules
Add GitHub Actions workflow to host docs in GitHub pages
Handle parens in annotations properly
Ignore lifetime parameters properly when numbering type params
@coeff-aij coeff-aij marked this pull request as ready for review January 12, 2026 11:10
@coord-e coord-e self-requested a review January 13, 2026 14:13
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UserDefinedPred {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This struct seems to be unused. I think it's more natural to rename UserDefinedPredSymbol to UserDefinedPred and remove this one.

}
}

// TODO: This struct is almost copy of `DatatypeSymbol`. Two traits maight be unified with aliases.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually better to have different structs for different purposes; that makes them more resilient to change, since each might be updated for different reasons and in different ways in the future.

Pred::Known(p) => p.name().into(),
Pred::Var(p) => p.to_string().into(),
Pred::Matcher(p) => p.name().into(),
Pred::UserDefined(p) => p.inner.clone().into(),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(nit) using p.to_string().into() would be better because we don't have to access the implementation details (like .inner).

cursor: args.trees(),
formula_existentials: self.formula_existentials.clone(),
};
let args = parser.parse_datatype_ctor_args()?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rename parse_datatype_ctor_args to parse_arg_terms or something similar, because it's no longer used solely for datatype constructor arguments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants