Skip to content

Conversation

@cxzhong
Copy link
Contributor

@cxzhong cxzhong commented Nov 19, 2025

Solutions

This fixes #40780
Add an explicit check in _element_constructor_ to handle vectors directly using from_vector() before attempting to use self._assoc(x):

def _element_constructor_(self, x):
    if isinstance(x, list) and len(x) == 2:
        return self(x[0])._bracket_(self(x[1]))
    
    # Check if x is a vector from the module to avoid infinite recursion
    try:
        if hasattr(x, 'parent') and x.parent() == self.module():
            return self.from_vector(x)
    except (AttributeError, NotImplementedError):
        pass
    
    return self.element_class(self, self._assoc(x))

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

The Infinite Loop Cycle

The infinite recursion occurs in the following cycle:

1. gl(vector) 
   ↓
2. LieAlgebraFromAssociative._element_constructor_(vector)
   ↓
3. self._assoc(vector)  # _assoc is a MatrixSpace
   ↓
4. MatrixSpace.__call__(vector)
   ↓
5. Uses coercion: VectorSpace → LieAlgebra → MatrixSpace
   ↓
6. Back to step 1: gl(vector)

Detailed Breakdown

  1. Morphism Construction Context:

    • When creating a morphism via gl.morphism({e:e for e in gl.gens()}), the morphism code (in morphism.py) computes brackets to extend the spanning set
    • It calls domain.bracket(spanning_set[i], spanning_set[j]) where spanning_set contains vectors
  2. Bracket Computation:

    • The bracket method in lie_algebras.py line 290:
      return self(lhs)._bracket_(self(rhs))
    • This attempts to convert vectors (lhs, rhs) to Lie algebra elements by calling self(vector)
  3. Element Constructor Issue:

    • LieAlgebraFromAssociative._element_constructor_ (line 1246) was:
      return self.element_class(self, self._assoc(x))
    • When x is a vector, it calls self._assoc(vector)
  4. Coercion Map Problem:

    • self._assoc is a MatrixSpace
    • There exists a composite coercion map:
      VectorSpace → LieAlgebra → MatrixSpace
      
    • This map was registered when LiftMorphismToAssociative was set up as a coercion
  5. The Loop Closes:

    • MatrixSpace(vector) uses the coercion map
    • First step: VectorSpace → LieAlgebra calls gl(vector)
    • This triggers _element_constructor_ again with the same vector
    • The cycle repeats infinitely

⌛ Dependencies

@cxzhong cxzhong requested a review from mantepse November 19, 2025 09:18
@cxzhong cxzhong added the t: bug label Nov 19, 2025
@cxzhong cxzhong requested a review from orlitzky November 19, 2025 14:36
True
Test that morphisms can be constructed (this used to fail with
RecursionError)::
Copy link
Contributor

Choose a reason for hiding this comment

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

Could use :exc:`RecursionError` here to create a link in the docs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But it seems this part about this function not appear in the document

Updated test documentation for morphism construction to clarify error handling.
@cxzhong cxzhong requested a review from orlitzky November 20, 2025 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

creating a morphism of the lie algebra gl_n enters (probably infinite) recursion

2 participants