-
Notifications
You must be signed in to change notification settings - Fork 184
feat(PFunctor): Add API of basic constructions #803
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dtumad
wants to merge
5
commits into
leanprover:main
Choose a base branch
from
dtumad:dtumad/pfunctor-basic-api
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
d0bd317
feat: Add API of basic constructions
dtumad e02f912
Merge branch 'main' into dtumad/pfunctor-basic-api
dtumad 5011c5b
give explicit names to instances to avoid linter errors
dtumad 7ba8471
address PR feedback
dtumad 342a94d
wording correction
dtumad File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| /- | ||
| Copyright (c) 2026 PolyFun Contributors. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Devon Tuma, Quang Dao | ||
| -/ | ||
| module | ||
|
|
||
| public import Cslib.Init | ||
| public import Mathlib.Data.PFunctor.Univariate.Basic | ||
|
|
||
| /-! | ||
| # Polynomial Functors | ||
|
|
||
| Definitions of common `PFunctor` constructions: | ||
| - `monomial A B`: constant direction `B` for any shape `a : A` | ||
| - `P + Q`: shapes are a disjoint sum, directions are define by sum elimination on `a : P.A ⊕ Q.A` | ||
| - `P * Q`: shapes are pairs of underlying shapes, directions are a disjoint sum over both shapes. | ||
|
|
||
| Special cases `const`, `linear`, `selfMonomial`, `purePower`, the indeterminate `X`, | ||
| and canonical choices of `0` and `1` are defined as `abbrev` or instances over `monomial`. | ||
| -/ | ||
|
|
||
| @[expose] public section | ||
|
|
||
| universe uA uB uA₁ uA₂ uB₁ uB₂ | ||
|
|
||
| namespace PFunctor | ||
|
|
||
| /-- Two polynomial functors are equal if their head types are equal and their child types | ||
| agree over that equality. -/ | ||
| @[ext (iff := false)] | ||
| theorem ext {P Q : PFunctor.{uA, uB}} (h : P.A = Q.A) (h' : ∀ a, P.B a = Q.B (h ▸ a)) : | ||
| P = Q := by | ||
| cases P; cases Q; simp only [mk.injEq] at h h' ⊢; subst h | ||
| simp_all only [heq_eq_eq, true_and]; funext; exact h' _ | ||
|
|
||
| section monomial | ||
|
|
||
| /-- The monomial `PFunctor` with head type `A` and constant `B` for any `a : A`. -/ | ||
| abbrev monomial (A : Type uA) (B : Type uB) : PFunctor := ⟨A, fun _ => B⟩ | ||
|
|
||
| lemma monomial_A (A : Type uA) (B : Type uB) : (monomial A B).A = A := rfl | ||
|
|
||
| lemma monomial_B (A : Type uA) (B : Type uB) (a : (monomial A B).A) : | ||
| (monomial A B).B a = B := rfl | ||
|
|
||
| end monomial | ||
|
|
||
| section zero | ||
|
|
||
| /-- The zero polynomial functor, defined as `A = PEmpty` and `B _ = PEmpty`, is the identity with | ||
| respect to sum (up to equivalence) -/ | ||
| @[simps] instance instZeroPFunctor : Zero PFunctor where zero := monomial PEmpty PEmpty | ||
|
|
||
| instance instIsEmptyZeroPFunctor : IsEmpty (0 : PFunctor.{uA, uB}).A := | ||
| inferInstanceAs (IsEmpty PEmpty) | ||
|
|
||
| end zero | ||
|
|
||
| section one | ||
|
|
||
| /-- The unit polynomial functor, defined as `A = PUnit` and `B _ = PEmpty`, is the identity with | ||
| respect to product (up to equivalence) -/ | ||
| @[simps] instance instOnePFunctor : One PFunctor where one := monomial PUnit PEmpty | ||
|
|
||
| instance instUniqueOneA : Unique (1 : PFunctor.{uA, uB}).A := inferInstanceAs (Unique PUnit) | ||
|
|
||
| instance instIsEmptyOneB (a : (1 : PFunctor.{uA, uB}).A) : IsEmpty ((1 : PFunctor.{uA, uB}).B a) := | ||
| inferInstanceAs (IsEmpty PEmpty) | ||
|
|
||
| end one | ||
|
|
||
| /-- The constant polynomial functor `P(X) = A X^ PEmpty = A` -/ | ||
| abbrev const (A : Type uA) : PFunctor := monomial A PEmpty | ||
|
|
||
| /-- The linear polynomial functor `P(X) = A X` -/ | ||
| abbrev linear (A : Type uA) : PFunctor := monomial A PUnit | ||
|
|
||
| /-- The self monomial polynomial functor `P(X) = S X^ S` -/ | ||
| abbrev selfMonomial (S : Type uA) : PFunctor.{uA, uA} := monomial S S | ||
|
|
||
| /-- The pure power polynomial functor `P(X) = X^ B` -/ | ||
| abbrev purePower (B : Type uB) : PFunctor := monomial PUnit B | ||
|
|
||
| /-- The indeterminate polynomial functor `P(X) = X`, the identity with respect to | ||
| composition and tensor product (up to equivalence). -/ | ||
| abbrev X : PFunctor := monomial PUnit PUnit | ||
|
|
||
| /- Note: no explicit `IsEmpty`/`Unique` instances are needed for the positions and directions | ||
| of the abbreviations above: being reducible, they unfold to `PEmpty`/`PUnit` during instance | ||
| search. Only `0` and `1` need the explicit instances above, since the `Zero`/`One` instance | ||
| projections are not reducible. -/ | ||
|
|
||
| @[simp] lemma const_pempty : const PEmpty = 0 := rfl | ||
|
|
||
| @[simp] lemma const_punit : const PUnit = 1 := rfl | ||
|
|
||
| @[simp] lemma linear_punit : linear PUnit = X := rfl | ||
|
|
||
| @[simp] lemma selfMonomial_punit : selfMonomial PUnit = X := rfl | ||
|
|
||
| @[simp] lemma purePower_punit : purePower PUnit = X := rfl | ||
|
|
||
| section add | ||
|
|
||
| /-- The sum of two polynomial functors `P` and `Q`, written as `P + Q`, | ||
| defined as the sum of the head types and the sum case analysis for the child types. | ||
|
|
||
| This is kept as a `def` alongside the `HAdd` instance below, even though that instance is | ||
| exactly as universe-general as `add` itself: the `binop%` elaborator behind `+` eagerly | ||
| unifies the types of both operands with the expected type, so when the expected type carries | ||
| universe metavariables (e.g. inside `PFunctor.W (P.add (.const α))` with `α : Type v`), | ||
| `P + Q` can fail to elaborate where `P.add Q` succeeds; see `CslibTests/PFunctor.lean`. -/ | ||
| @[simps] def add (P : PFunctor.{uA₁, uB}) (Q : PFunctor.{uA₂, uB}) : | ||
| PFunctor.{max uA₁ uA₂, uB} := ⟨P.A ⊕ Q.A, Sum.elim P.B Q.B⟩ | ||
|
|
||
| /-- Addition of polynomial functors, defined as the sum construction. -/ | ||
| instance instHAddPFunctor : | ||
| HAdd PFunctor.{uA₁, uB} PFunctor.{uA₂, uB} PFunctor.{max uA₁ uA₂, uB} where | ||
| hAdd := add | ||
|
|
||
| /-- Normalize addition of `PFunctor`s to avoid `simp` mismatches between the notations. -/ | ||
| @[simp] lemma add_def (P : PFunctor.{uA₁, uB}) (Q : PFunctor.{uA₂, uB}) : | ||
| P + Q = P.add Q := rfl | ||
|
dtumad marked this conversation as resolved.
|
||
|
|
||
| end add | ||
|
|
||
| section prod | ||
|
|
||
| /-- The product of two polynomial functors `P` and `Q`, written as `P * Q`, | ||
| defined as the product of the head types and the sum of the child types. | ||
| Unlike `add`, the child types of `P` and `Q` may live in different universes, | ||
| since they are combined with `⊕` rather than `Sum.elim`. -/ | ||
| @[simps] def prod (P : PFunctor.{uA₁, uB₁}) (Q : PFunctor.{uA₂, uB₂}) : | ||
| PFunctor.{max uA₁ uA₂, max uB₁ uB₂} := ⟨P.A × Q.A, fun ab => P.B ab.1 ⊕ Q.B ab.2⟩ | ||
|
|
||
| /-- Multiplication of polynomial functors, defined as the product construction. | ||
| As with addition, we deliberately do not add a homogeneous `Mul` instance. -/ | ||
| instance instHMulPFunctor : | ||
| HMul PFunctor.{uA₁, uB₁} PFunctor.{uA₂, uB₂} PFunctor.{max uA₁ uA₂, max uB₁ uB₂} where | ||
| hMul := prod | ||
|
|
||
| /-- Normalize multiplication of `PFunctor`s to avoid `simp` mismatches between the notations. -/ | ||
| @[simp] lemma mul_def (P : PFunctor.{uA₁, uB₁}) (Q : PFunctor.{uA₂, uB₂}) : | ||
| P * Q = P.prod Q := rfl | ||
|
|
||
| end prod | ||
|
|
||
| end PFunctor | ||
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| /- | ||
| Copyright (c) 2026 Devon Tuma. All rights reserved. | ||
| Released under Apache 2.0 license as described in the file LICENSE. | ||
| Authors: Devon Tuma | ||
| -/ | ||
|
|
||
| import Cslib.Foundations.Data.PFunctor.Basic | ||
|
|
||
| /-! | ||
| # Polynomial Functor Tests | ||
|
|
||
| These tests exercise the universe-polymorphic polynomial sum and product, the simp API for | ||
| the basic constructions, and the extensionality lemma. | ||
| -/ | ||
|
|
||
| universe uA uB uA₁ uA₂ uB₁ uB₂ v | ||
|
|
||
| namespace CslibTests | ||
|
|
||
| open PFunctor | ||
|
|
||
| /-- Addition notation is available when its result universe is fixed by the expected type. -/ | ||
| example (P : PFunctor.{uA₁, uB}) (Q : PFunctor.{uA₂, uB}) : | ||
| PFunctor.{max uA₁ uA₂, uB} := P + Q | ||
|
|
||
| /-- Multiplication notation is likewise available, including for child types in | ||
| different universes. -/ | ||
| example (P : PFunctor.{uA₁, uB₁}) (Q : PFunctor.{uA₂, uB₂}) : | ||
| PFunctor.{max uA₁ uA₂, max uB₁ uB₂} := P * Q | ||
|
|
||
| /-- The `def` spelling `P.add (.const α)` elaborates under `PFunctor.W` even when the | ||
| expected type only determines the universe levels up to a `max`. This is the motivating | ||
| use case for keeping `PFunctor.add` as a `def` alongside the `HAdd` instance. -/ | ||
| example (P : PFunctor.{uA₁, uB}) (α : Type v) : Type (max uA₁ uB v) := | ||
| PFunctor.W (P.add (.const α)) | ||
|
|
||
| /- The `+` spelling of the same type fails: the `binop%` elaborator behind `+` commits the | ||
| universe metavariables in the expected type to the first operand's universes before it | ||
| considers the heterogeneous `HAdd` instance. -/ | ||
| /-- | ||
| error: Type mismatch | ||
| P + const α | ||
| has type | ||
| PFunctor.{max uA₁ v, uB} | ||
| of sort | ||
| Type (max (max (uA₁ + 1) (uB + 1)) (v + 1)) | ||
| but is expected to have type | ||
| PFunctor.{uA₁, uB} | ||
| of sort `Type (max (uA₁ + 1) (uB + 1))` | ||
| --- | ||
| error: failed to solve universe constraint | ||
| max (max uA₁ uB) v =?= max uB uA₁ | ||
| while trying to unify | ||
| Type (max uA₁ uB v) : Type ((max uA₁ uB v) + 1) | ||
| with | ||
| Type (max uA₁ uB) : Type ((max uA₁ uB) + 1) | ||
| -/ | ||
| #guard_msgs in | ||
| example (P : PFunctor.{uA₁, uB}) (α : Type v) : Type (max uA₁ uB v) := | ||
| PFunctor.W (P + PFunctor.const α) | ||
|
|
||
| /-- The simp set rewrites the head type of a sum through the `+` notation. -/ | ||
| example (P : PFunctor.{uA₁, uB}) (Q : PFunctor.{uA₂, uB}) : | ||
| (P + Q).A = (P.A ⊕ Q.A) := by simp | ||
|
|
||
| /-- The simp set computes child types of a sum on both shapes. -/ | ||
| example (P : PFunctor.{uA₁, uB}) (Q : PFunctor.{uA₂, uB}) (a : P.A) : | ||
| (P.add Q).B (.inl a) = P.B a := by simp | ||
|
|
||
| example (P : PFunctor.{uA₁, uB}) (Q : PFunctor.{uA₂, uB}) (a : Q.A) : | ||
| (P.add Q).B (.inr a) = Q.B a := by simp | ||
|
|
||
| /-- The simp set computes head and child types of a product. -/ | ||
| example (P : PFunctor.{uA₁, uB₁}) (Q : PFunctor.{uA₂, uB₂}) (a : P.A) (b : Q.A) : | ||
| (P * Q).B (a, b) = (P.B a ⊕ Q.B b) := by simp | ||
|
|
||
| /-- The named monomials reduce to the canonical `0`, `1`, and `X`. -/ | ||
| example : (const PUnit : PFunctor.{uA, uB}) = 1 := by simp | ||
| example : (linear PUnit : PFunctor.{uA, uB}) = X := by simp | ||
|
|
||
| /-- The `ext` tactic picks up the registered extensionality lemma. -/ | ||
| example (P Q : PFunctor.{uA, uB}) (h : P.A = Q.A) (h' : ∀ a, P.B a = Q.B (h ▸ a)) : | ||
| P = Q := by | ||
| ext | ||
| · exact h | ||
| · exact h' _ | ||
|
|
||
| end CslibTests |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great to raise this issue on Zulip and link the post from the PR description.