Skip to content

Add recursive functions to Strata Core#499

Open
joscoh wants to merge 25 commits intomainfrom
josh/rec-fun
Open

Add recursive functions to Strata Core#499
joscoh wants to merge 25 commits intomainfrom
josh/rec-fun

Conversation

@joscoh
Copy link
Contributor

@joscoh joscoh commented Feb 28, 2026

Issue #, if available:

Description of changes: This PR adds support for recursive functions in Strata Core, including their definition in concrete syntax, partial evaluation, and an axiom-based SMT encoding.

Main changes:

  1. This PR adds an additional attribute to the DDM @[scopeSelf] that acts like @[scope] but also adds the function's name to its body's scope. This is structured and handled very similarly to @[declareDatatype], which involves a similar recursive structure. Main changes are in AST.lean, Format.lean, Core.lean.
  2. Adds fields to Func indicating whether a function is recursive and giving an optional decreases clause. This information is used in Env.lean to calculate the index of the decreasing argument. Here we also rule out recursive functions that are not yet supported: polymorphic functions, functions with more sophisticated termination measures, and functions without an explicit decreasing clause.
  3. RecursiveAxioms.lean contains the generation of axioms as LExpr for a recursive function. Generating the axiom is fairly simple, since we just create term e.g. forall h t, length (List.cons h t) = length (List.cons h t) and then partially evaluate the right-hand side. Since recursive functions are marked as inlineIfConstr on their decreasing parameter, this produces the simplified form.

Other changes

  1. Adds support in SMT/DDMTransform/Translate for trigger patterns complex enough to handle constructors applied to arguments (e.g. List.cons h t).
  2. Changes the evaluation of if-then-else to always reduce within the then and else branches and changes the small-step semantics to match.

Tests

  1. RecursiveAxiomTests.lean tests the generation of recursive axioms as Lambda terms.
  2. This PR adds a test to SMTEncoderDatatypeTests.lean that demonstrates the SMT encoding of the recursive function axioms.
  3. RecursiveFunctionDDMTest.lean tests the DDM parsing for recursive function.
  4. RecursiveFunctionErrorTest.lean demonstrates not-yet-supported recursive functions.
  5. RecursiveFunctionTests.lean contain a variety of programs with recursive functions, some of which contain VCs which can be solved purely by partial evaluation and others which require SMT-based reasoning.
  6. BinaryTreeSize.lean gives a more complex example that demonstrates inductive reasoning over types and functions.

What is not supported (yet): polymorphic and mutually recursive functions, termination checking.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@joscoh joscoh marked this pull request as ready for review March 2, 2026 15:46
@joscoh joscoh requested a review from a team March 2, 2026 15:46
Copy link
Contributor

@MikaelMayer MikaelMayer left a comment

Choose a reason for hiding this comment

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

This PR adds comprehensive support for recursive functions in Strata Core with a well-designed implementation. The changes are structured logically across the DDM layer (adding @[scopeSelf] metadata), the Lambda dialect (axiom generation), and the Core language (grammar, translation, SMT encoding). The test coverage is excellent, including positive tests, error cases, and a complex example (BinaryTreeSize). The documentation clearly explains the new @[scopeSelf] attribute and its purpose.

The implementation correctly handles the key challenges: bringing the function name into scope for recursive calls, generating per-constructor axioms for SMT reasoning, and properly rejecting unsupported cases (polymorphic recursion, missing decreases clauses). The ITE evaluation change to always reduce both branches is a sensible improvement that enables better partial evaluation.

I have a few minor suggestions for clarity and potential improvements, but overall this is high-quality work that's ready to merge after addressing the comments.

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