Support Rust syntax in thrust::predicate bodies#114
Draft
coord-e wants to merge 1 commit into
Draft
Conversation
Predicate bodies can be written as ordinary Rust boolean expressions instead of raw SMT-LIB2 string literals, reusing the formula_fn translation pipeline. A predicate whose body is a Rust expression is emitted with an additional #[thrust::formula_fn] attribute; that attribute is the discriminator. When present, the body is translated through the formula_fns cache and the resulting chc::Formula is emitted as the predicate's SMT define-fun. Raw SMT2 string bodies still work unchanged. Rendering of a translated predicate formula goes through a new TermSortEnv trait (implemented for Clause and IndexVec<TermVarIdx, Sort>) instead of a fabricated Clause, so the smtlib2 Display wrappers hold &dyn TermSortEnv. Trait/struct predicates use named field access (self.x), relying on the named-field resolution already in main (#118). https://claude.ai/code/session_01WdLyxyy4ieAxrexj83X5MX
9c96cde to
fe79724
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
#[thrust::predicate]bodies can now be written as ordinary Rust boolean expressions instead of raw SMT-LIB2 string literals, reusing the existingformula_fntranslation pipeline (AnnotFnTranslator).Raw SMT2 string bodies still work unchanged (backward compatible).
How it works
A predicate written with
#[thrust_macros::predicate]whose body is a Rust expression is expanded with an additional#[thrust::formula_fn]attribute, which is the single discriminator:AnnotFnTranslatorthrough the existingformula_fnscache (formula_fn_with_args), exactly likerequires/ensures/invariant. The resultingchc::Formulais emitted as the predicate's SMTdefine-fun.The macro picks which by inspecting the body (string-literal statement ⇒ raw; otherwise Rust). Borrow-check skipping is free, since
mir_borrowck_skip_formula_fnalready keys on theformula_fnattribute. Predicate call sites are still resolved as namedUserDefinedPredatoms.Changes
chc.rs—UserDefinedPredDefbody becomes aUserDefinedPredBody { Raw, Formula }enum; addpush_pred_define_formula. NewTermSortEnvtrait (var_sort/term_sort), implemented forClauseandIndexVec<TermVarIdx, Sort>.chc/smtlib2.rs— theTerm/Atom/Formula/BodyDisplay wrappers now hold&dyn TermSortEnvinstead of&Clause. AFormulapredicate body is rendered by passing the sig's sorts as anIndexVec— no synthetic/fakeClauseis fabricated.chc/format_context.rs— uses theTermSortEnvtrait (movedClause::term_sortonto it).chc/unbox.rs— unboxFormulapredicate bodies.analyze/crate_.rs— register predicate items also markedformula_fn.analyze/local_def.rs—define_as_predicatebranches on theformula_fnattribute; pulls the formula fromformula_fn_with_args, naming paramsv{i}.thrust-macros/src/spec.rs—expand_predicate: detect raw-vs-Rust body; for Rust bodies add#[thrust::formula_fn], rewriteself→self_, add allow-attrs.annot_preds), trait (annot_preds_trait), and multi-field (annot_preds_trait_multi) predicate tests (pass + fail) converted to Rust syntax.Dependency
Named struct-field access (
self.x) in the trait/multi-field predicates relies on #118 (merged), which taught the formula translator to resolve named ADT fields.Notes
main(single feature commit).iterators/fixed_filter_loop_none.rs, which returns solverunknownon z3 4.13.0. That failure is pre-existing and unrelated — it reproduces identically onmainat the rebase base with the same z3, andmainpins z3 to 4.15.4 (ci: pin Z3 to 4.15.4, the latest version without mut_recursive timeout #149) precisely to avoid such solver-version issues. CI runs 4.15.4.self.x * 2 == doubled.xlowers to exactly(= (* (tuple_proj<Int>.0 v0) 2) (tuple_proj<Int>.0 v1))— identical to the previous raw form.https://claude.ai/code/session_01WdLyxyy4ieAxrexj83X5MX