Skip to content

[Merged by Bors] - feat(Tactic/ComputeAsymptotics/Multiseries): non-primitive corecursion for Seq#34311

Closed
vasnesterov wants to merge 9 commits intoleanprover-community:masterfrom
vasnesterov:compute_asymptotics_corecursion
Closed

[Merged by Bors] - feat(Tactic/ComputeAsymptotics/Multiseries): non-primitive corecursion for Seq#34311
vasnesterov wants to merge 9 commits intoleanprover-community:masterfrom
vasnesterov:compute_asymptotics_corecursion

Conversation

@vasnesterov
Copy link
Copy Markdown
Collaborator

@vasnesterov vasnesterov commented Jan 23, 2026

This PR develops a theory that justifies corecursive definitions of the form

def foo (x : X) := hd x :: f (foo (tlArg x))

where f : Seq α → Seq α is a friendly operation.


This is a part of the compute_asymptotics tactic (#28291).

Open in Gitpod

@vasnesterov vasnesterov added the t-data Data (lists, quotients, numbers, etc) label Jan 23, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Jan 23, 2026

PR summary b87448799e

Import changes for modified files

Dependency changes

File Base Count Head Count Change
Mathlib.Tactic 2909 2922 +13 (+0.45%)
Import changes for all files
Files Import difference
Mathlib.Tactic 13
Mathlib.Tactic.ComputeAsymptotics.Multiseries.Corecursion (new file) 1652

Declarations diff

+ FriendlyOperation
+ FriendlyOperation.comp
+ FriendlyOperation.const
+ FriendlyOperation.dist_le
+ FriendlyOperation.exists_fixed_point
+ FriendlyOperation.id
+ FriendlyOperation.ite
+ FriendlyOperationClass
+ FriendlyOperationClass.comp
+ Stream'.dist_le_one
+ boundedSpace
+ dist_cons_cons
+ dist_cons_cons_eq_one
+ dist_cons_nil
+ dist_eq_half_of_head
+ dist_eq_one_of_head
+ dist_eq_two_inv_pow
+ dist_nil_cons
+ exists_fixed_point_of_contractible
+ gcorec
+ gcorec_nil
+ gcorec_some
++ dist_le_one
+++ foo

You can run this locally as follows
## summary with just the declaration names:
./scripts/declarations_diff.sh <optional_commit>

## more verbose report:
./scripts/declarations_diff.sh long <optional_commit>

The doc-module for script/declarations_diff.sh contains some details about this script.


No changes to technical debt.

You can run this locally as

./scripts/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

Comment thread Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean
Comment thread Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean
@grunweg grunweg changed the title feat(Tactic/ComputeAsymptotics/Multiseries): Non-primitive corecursion for Seq feat(Tactic/ComputeAsymptotics/Multiseries): non-primitive corecursion for Seq Jan 27, 2026
@ocfnash
Copy link
Copy Markdown
Contributor

ocfnash commented Jan 29, 2026

Thanks, this is very nice work! Just to check my own understanding, is the reason corecursion is useful here because:

  1. We need to regard the RHS of expansions like $1 / (1 - x) = 1 + x + x^2 + \cdots$ as a formal multiseries with an infinite basis (that is $1$, $x$, $x^2$, ...). We want these bases to be ordered lists (thus necessarily possibly infinite) whose head is the leading term, which we use to compute the limit.
  2. We want to compute lazily with these lists, partly for performance reasons, and partly because we might not know how far down an expansion we need to remember if we were to truncate (e.g., if we multiply by a large power of $x$ later on in the calculation).

Have I got that about right? If so this does indeed seem to be a strong case for your design.

@joneugster joneugster added the awaiting-author A reviewer has asked the author a question or requested changes. label Jan 30, 2026
@vasnesterov
Copy link
Copy Markdown
Collaborator Author

vasnesterov commented Feb 2, 2026

@ocfnash Thanks! Yes, we want to work with series as lazy possibly infinite lists, because we can’t know in advance how many terms we’ll need. It’s also easier to work with infinite series mathematically than with their truncations, I guess.

But "basis" in the context of this tactic means something different (and it is always finite). A basis is just a list of real functions ordered by their growth rate. The main object we work with is a so-called multiseries -- a multivariate formal series with monomials of the form b₁^e₁ * ... * bₙ^eₙ, where [b₁, ..., bₙ] is our basis and e₁, ..., eₙ are real numbers.

We need corecursion to define the operations on multiseries: addition, multiplication, etc. Some operations (multiplication and powser) cannot be expressed directly using Seq.corec. That’s why we need to develop some theory of non-primitive corecursion.

I’ve written a short description of how the tactic works to give reviewers more context: https://vasnesterov.github.io/compute_asymptotics. Feel free to ask/suggest anything.

@vasnesterov vasnesterov removed the awaiting-author A reviewer has asked the author a question or requested changes. label Feb 2, 2026
Comment on lines +68 to +70
/-- Metric space structure on `Stream' α` considering `α` as a discrete metric space. -/
noncomputable local instance : MetricSpace (Stream' α) :=
@PiNat.metricSpace (fun _ ↦ α) (fun _ ↦ ⊥) (fun _ ↦ discreteTopology_bot _)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be a global instance on Stream, but with a [DiscreteTopology α] assumption?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I don't think anything here should be global. I see this file as an ad hoc implementation of a very limited construction - just enough for the tactic.

It's possible to generalize this to arbitrary coinductive type and support a more powerful form of corecursion, but I think we need to wait until QPF is done and ready to use before doing that.

Do you think this metric space structure is useful for other applications?

Comment thread Mathlib/Tactic/ComputeAsymptotics/Multiseries/Corecursion.lean Outdated
```
(where hd and tlArg are arbitrary functions) can be encoded via the corecursor `Seq.corec`.

It is not enough, however, to define multiplication and powser operation for multiseries.
Copy link
Copy Markdown
Member

@eric-wieser eric-wieser Feb 6, 2026

Choose a reason for hiding this comment

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

Suggested change
It is not enough, however, to define multiplication and powser operation for multiseries.
It is not enough, however, to define multiplication and power operations for multiseries.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It's the powser operation (https://vasnesterov.github.io/compute_asymptotics#lazyseries-and-powser-operation) -- the substitution of a multiseries into a power series. This is what Eberl calls it in his tactic. But I'm happy to rename it if you have a better suggestion!

Copy link
Copy Markdown
Member

@jcommelin jcommelin left a comment

Choose a reason for hiding this comment

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

Thanks 🎉

bors merge

mathlib-bors bot pushed a commit that referenced this pull request Feb 10, 2026
…n for `Seq` (#34311)

This PR develops a theory that justifies corecursive definitions of the form
```lean
def foo (x : X) := hd x :: f (foo (tlArg x))
```
where `f : Seq α → Seq α` is a friendly operation.
@mathlib-triage mathlib-triage bot added the ready-to-merge This PR has been sent to bors. label Feb 10, 2026
@mathlib-bors
Copy link
Copy Markdown
Contributor

mathlib-bors bot commented Feb 10, 2026

Pull request successfully merged into master.

Build succeeded:

@mathlib-bors mathlib-bors bot changed the title feat(Tactic/ComputeAsymptotics/Multiseries): non-primitive corecursion for Seq [Merged by Bors] - feat(Tactic/ComputeAsymptotics/Multiseries): non-primitive corecursion for Seq Feb 10, 2026
@mathlib-bors mathlib-bors bot closed this Feb 10, 2026
justus-springer pushed a commit to justus-springer/mathlib4 that referenced this pull request Feb 10, 2026
…n for `Seq` (leanprover-community#34311)

This PR develops a theory that justifies corecursive definitions of the form
```lean
def foo (x : X) := hd x :: f (foo (tlArg x))
```
where `f : Seq α → Seq α` is a friendly operation.
michaellee94 pushed a commit to michaellee94/mathlib4 that referenced this pull request Feb 15, 2026
…n for `Seq` (leanprover-community#34311)

This PR develops a theory that justifies corecursive definitions of the form
```lean
def foo (x : X) := hd x :: f (foo (tlArg x))
```
where `f : Seq α → Seq α` is a friendly operation.
rao107 pushed a commit to rao107/mathlib4 that referenced this pull request Feb 18, 2026
…n for `Seq` (leanprover-community#34311)

This PR develops a theory that justifies corecursive definitions of the form
```lean
def foo (x : X) := hd x :: f (foo (tlArg x))
```
where `f : Seq α → Seq α` is a friendly operation.
Maldooor pushed a commit to Maldooor/mathlib4 that referenced this pull request Feb 25, 2026
…n for `Seq` (leanprover-community#34311)

This PR develops a theory that justifies corecursive definitions of the form
```lean
def foo (x : X) := hd x :: f (foo (tlArg x))
```
where `f : Seq α → Seq α` is a friendly operation.
pfaffelh pushed a commit to pfaffelh/mathlib4 that referenced this pull request Mar 2, 2026
…n for `Seq` (leanprover-community#34311)

This PR develops a theory that justifies corecursive definitions of the form
```lean
def foo (x : X) := hd x :: f (foo (tlArg x))
```
where `f : Seq α → Seq α` is a friendly operation.
mathlib-bors bot pushed a commit that referenced this pull request Apr 2, 2026
…n for `Seq`: `FriendlyOperation` API (#35072)

This is a continuation of #34311.

This PR adds more API about friendly operations:
* Basic friendly operations constructions
* `FriendlyOperation.destruct`: a "coinductive destructor" for `FriendlyOperation`
xroblot pushed a commit to xroblot/mathlib4 that referenced this pull request Apr 3, 2026
…n for `Seq`: `FriendlyOperation` API (leanprover-community#35072)

This is a continuation of leanprover-community#34311.

This PR adds more API about friendly operations:
* Basic friendly operations constructions
* `FriendlyOperation.destruct`: a "coinductive destructor" for `FriendlyOperation`
riccardobrasca pushed a commit to riccardobrasca/mathlib4 that referenced this pull request Apr 6, 2026
…n for `Seq`: `FriendlyOperation` API (leanprover-community#35072)

This is a continuation of leanprover-community#34311.

This PR adds more API about friendly operations:
* Basic friendly operations constructions
* `FriendlyOperation.destruct`: a "coinductive destructor" for `FriendlyOperation`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge This PR has been sent to bors. t-data Data (lists, quotients, numbers, etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants