Skip to content

Defining IsHomogenization as linear equivalence - #102

Open
ooovi wants to merge 12 commits into
mainfrom
homogenization_linequiv
Open

ooovi wants to merge 12 commits into
mainfrom
homogenization_linequiv

Conversation

@ooovi

@ooovi ooovi commented Sep 17, 2026 •

Copy link
Copy Markdown
Owner

as suggested on zulip, redefines IsHomogenization as something thats linearly equivalent to the canonical homogenization. this is maybe nicer than the axiomatic definition because transferring API from canonical homogenization is smoother. also provides the axiomatic constructor

closes #59

Comment thread Polyhedral/Mathlib/LinearAlgebra/AffineSpace/Homogenization/Canonical.lean Outdated
@ooovi

ooovi commented Sep 29, 2026

Copy link
Copy Markdown
Owner Author

There's a draft PR to mathlib now, and I have adjusted the code here to match its current state.
leanprover-community/mathlib4#44160

@ooovi ooovi changed the title Trying another def for homogenization Defining IsHomogenization as linear equivalence Sep 29, 2026
Comment thread Polyhedral/Mathlib/Geometry/Convex/ConvexSpace/Set/Homogenization.lean Outdated
variable (R P) in
/-- The canonical homogenization is a homogenization. -/
@[expose]
def ofHomogenization : IsHomogenization R P (Homogenization R P) := ofRepr <| LinearEquiv.refl ..

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Can we call this canonical?

Comment thread Polyhedral/Mathlib/Geometry/Convex/ConvexSpace/Polytope/Face.lean Outdated
space `W` and a weight map that is the constant 1-map on the embedded `P`. This follows the
axiomatization in Definition 4.2 of [Gallier2011GeometricMethods]
https://www.cis.upenn.edu/~jean/gma-v2-root.pdf -/
def ofEmbed {embed : P →ᵃ[R] W} (embed_inj : Injective embed) {weight : W →ₗ[R] R}

@martinwintermath martinwintermath Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Does it not suffice to only pass weight and weight \ne 0?

And a second def which takes embed, Injective embed and 0 \not\in embed.range or so? Or do we even need this, because maybe this is better:

A version that takes an affine subspace E and 0 \not\in E.

Update. After some thought my current idea is:

  • have the weight version
  • don't have the emed version
  • but have a def that turns an affine subspace E, a proof of 0 \not\in E and a proof of E.codim = 1 into a linear form weight. (the last hypothesis was missing above). So to say a reverse of AffineSubspace.comap for hyperplanes.
  • maybe add an affine subspace version, that just uses this def

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

i'd kind of like to keep this def, since it mirrors the axiomatic definition. i added a constructor for weight \ne 0 over DivisionRing and created #110 for the AffineSubspace constructor.

Comment thread Polyhedral/Mathlib/LinearAlgebra/AffineSpace/Homogenization/IsHomogenization.lean Outdated
provided that hyperplane is nonempty. -/
def ofWeightOne (g : W →ₗ[R] R) [Nonempty ((affineSpan R {1}).comap g.toAffineMap)] :
IsHomogenization R ((affineSpan R {1}).comap g.toAffineMap) W :=
def ofWeightOne (g : W →ₗ[R] R) [Nonempty (comap g.toAffineMap {1})] :

@martinwintermath martinwintermath Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is it helpful to have the nonempty statement as a typeclass argument? Can we not just ask for g \neq 0? This feels more canonical.

Update

  • my suggestion does not suffice as it does not imply what we need over general rings
  • there should nevertheless be a second def which uses g \neq 0 under sufficiently strong assumptions about R
  • Nonempty should not be a typeclass parameters since it cannot be inferred here ... I think. Unless, we make suitable instances, but not sure we should.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I'm not sure about the typeclass question. IsHomogenization needs an affine space as second arg, so the Nonempty instance actually needs to be available to state the type of this def. So I could

  • make it be (h : Nonempty ...) which I probably should not since Nonempty is a class
  • make it be something like
    def ofWeightOne (g : W →ₗ[R] R) (h : (comap g.toAffineMap {1} : Set W).Nonempty) :
        letI := nonempty_subtype.mpr h
        IsHomogenization R (comap g.toAffineMap {1}) W := ...
    
    which probably isn't a good idea
    Mathlib has a couple of places where Nonempty instances are passed by the caller. None of them is about a specific set like this case tho. Lets leave it like this and see what review says about it?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I see. Another way out is to have parameters linear form g, AffineSubspace E, [Nonempty E], E = comap g {1}. Then the typeclass argument makes more sense and has a chance of firing automatically. The drawback is that we are redundant. But one could call it like ofWeightOne g (comap g {1}) rfl.

@YaelDillies Can you help out? What is the right design here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Also, I am not sure there is anything morally wrong with (h : Nonempty ...) just because it is a class. In my understanding, being a class allows you to be inferred automatically, but it does not take anything away that was permissable before.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this not equivalent to 1 \in range g which is itself equivalent to g \ne 0? Why this weird Nonempty assumption?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

i need to pass an AffineSpace to IsHomogenization, so i need to have Nonempty for it. no?

also i think if you don't have multiplicative inverses in your ring there are linear maps that are neither 0 nor does their range contain 1.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You could prove it inline like this:

Suggested change
def ofWeightOne (g : W →ₗ[R] R) [Nonempty (comap g.toAffineMap {1})] :
def ofWeightOne (g : W →ₗ[R] R) (hg : g \ne 0) :
have : Nonempty (comap g.toAffineMap {1}) ;= sorry

Comment thread Polyhedral/Mathlib/Geometry/Convex/ConvexSpace/Polytope/Face.lean Outdated
@ooovi ooovi linked an issue Sep 30, 2026 that may be closed by this pull request
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.

Write an instance of Homogenization for hyperplanes

3 participants