# featurebench-modal / sympy__sympy.c1097516.test_puiseux.cd575f09.lv2

- taskset: [featurebench-modal](https://harnessreport.com/tasks/featurebench-modal.md)
- difficulty: hard
- category: feature
- language: 
- runnable from the site: no
- agent timeout: 3600s

## Results by harness

_none yet_

## Instruction

```
# Task

## Task
**Task Statement: Implement Rational Number and Puiseux Polynomial Arithmetic Systems**

**Core Functionalities:**
- Develop a pure Python rational number class (PythonMPQ) as a fallback for gmpy2's mpq type
- Create a Puiseux polynomial ring system supporting fractional and negative exponents for truncated series representation

**Main Features & Requirements:**
- **PythonMPQ**: Implement complete arithmetic operations (+, -, *, /, **), comparison operators, hashing, and type conversions while maintaining compatibility with gmpy2's mpq interface
- **Puiseux System**: Build polynomial rings that handle rational exponents, negative powers, and proper algebraic operations (differentiation, conversion, normalization)
- Support seamless interoperability between rational numbers, integers, and domain elements
- Maintain mathematical correctness for GCD computations, fraction reduction, and monomial manipulations

**Key Challenges:**
- Ensure numerical stability and efficiency in rational arithmetic without external dependencies
- Handle complex exponent representations (fractional denominators, negative powers) in polynomial operations
- Maintain proper algebraic structure while supporting non-standard polynomial features
- Implement robust type coercion and domain compatibility across different mathematical objects
- Balance performance with mathematical rigor in series truncation and normalization operations

**NOTE**: 
- This test is derived from the `sympy` library, but you are NOT allowed to view this codebase or call any of its interfaces. It is **VERY IMPORTANT** to note that if we detect any viewing or calling of this codebase, you will receive a ZERO for this review.
- **CRITICAL**: This task is derived from `sympy`, but you **MUST** implement the task description independently. It is **ABSOLUTELY FORBIDDEN** to use `pip install sympy` or some similar commands to access the original implementation—doing so will be considered cheating and will result in an immediate score of ZERO! You must keep this firmly in mind throughout your implementation.
- You are now in `/testbed/`, and originally there was a specific implementation of `sympy` under `/testbed/` that had been installed via `pip install -e .`. However, to prevent you from cheating, we've removed the code under `/testbed/`. While you can see traces of the installation via the pip show, it's an artifact, and `sympy` doesn't exist. So you can't and don't need to use `pip install sympy`, just focus on writing your `agent_code` and accomplishing our task.
- Also, don't try to `pip uninstall sympy` even if the actual `sympy` has already been deleted by us, as this will affect our evaluation of you, and uninstalling the residual `sympy` will result in you getting a ZERO because our tests won't run.
- We've already installed all the environments and dependencies you need, you don't need to install any dependencies, just focus on writing the code!
- **CRITICAL REQUIREMENT**: After completing the task, pytest will be used to test your implementation. **YOU MUST** match the exact interface shown in the **Interface Description** (I will give you this later)

You are forbidden to access the following URLs:
black_links:
- https://github.com/sympy/sympy

Your final deliverable should be code in the `/testbed/agent_code` directory.
The final structure is like below, note that all dirs and files under agent_code/ are just examples, you will need to organize your own reasonable project structure to complete our tasks.
```
/testbed
├── agent_code/           # all your code should be put into this dir and match the specific dir structure
│   ├── __init__.py       # `agent_code/` folder must contain `__init__.py`, and it should import all the classes or functions described in the **Interface Descriptions**
│   ├── dir1/
│   │   ├── __init__.py
│   │   ├── code1.py
│   │   ├── ...
├── setup.py              # after finishing your work, you MUST generate this file
```
After you have done all your work, you need to complete three CRITICAL things: 
1. You need to generate `__init__.py` under the `agent_code/` folder and import all the classes or functions described in the **Interface Descriptions** in it. The purpose of this is that we will be able to access the interface code you wrote directly through `agent_code.ExampleClass()` in this way.
2. You need to generate `/testbed/setup.py` under `/testbed/` and place the following content exactly:
```python
from setuptools import setup, find_packages
setup(
    name="agent_code",
    version="0.1",
    packages=find_packages(),
)
```
3. After you have done above two things, you need to use `cd /testbed && pip install .` command to install your code.
Remember, these things are **VERY IMPORTANT**, as they will directly affect whether you can pass our tests.

## Interface Descriptions

### Clarification
The **Interface Description**  describes what the functions we are testing do and the input and output formats.

for example, you will get things like this:

```python
class PuiseuxPoly:
    """
    Puiseux polynomial. Represents a truncated Puiseux series.
    
        See the :class:`PuiseuxRing` class for more information.
    
        >>> from sympy import QQ
        >>> from sympy.polys.puiseux import puiseux_ring
        >>> R, x, y = puiseux_ring('x, y', QQ)
        >>> p = 5*x**2 + 7*y**3
        >>> p
        7*y**3 + 5*x**2
    
        The internal representation of a Puiseux polynomial wraps a normal
        polynomial. To support negative powers the polynomial is considered to be
        divided by a monomial.
    
        >>> p2 = 1/x + 1/y**2
        >>> p2.monom # x*y**2
        (1, 2)
        >>> p2.poly
        x + y**2
        >>> (y**2 + x) / (x*y**2) == p2
        True
    
        To support fractional powers the polynomial is considered to be a function
        of ``x**(1/nx), y**(1/ny), ...``. The representation keeps track of a
        monomial and a list of exponent denominators so that the polynomial can be
        used to represent both negative and fractional powers.
    
        >>> p3 = x**QQ(1,2) + y**QQ(2,3)
        >>> p3.ns
        (2, 3)
        >>> p3.poly
        x + y**2
    
        See Also
        ========
    
        sympy.polys.puiseux.PuiseuxRing
        sympy.polys.rings.PolyElement
        
    """
    ring = {'_type': 'annotation_only', '_annotation': 'PuiseuxRing[Er]'}
    poly = {'_type': 'annotation_only', '_annotation': 'PolyElement[Er]'}
    monom = {'_type': 'annotation_only', '_annotation': 'MonI | None'}
    ns = {'_type': 'annotation_only', '_annotation': 'MonI | None'}

    def __add__(self, other: PuiseuxPoly[Er] | Er | int) -> PuiseuxPoly[Er]:
        """
        Add another Puiseux polynomial or ground element to this polynomial.
        
        This method implements addition between Puiseux polynomials and supports adding
        ground elements (domain elements) or integers to a Puiseux polynomial.
        
        Parameters
        ----------
        other : PuiseuxPoly[Er] | Er | int
            The element to add to this polynomial. Can be:
            - Another PuiseuxPoly from the same ring
            - A ground element from the polynomial's domain
            - An integer (automatically converted to domain element)
        
        Returns
        -------
        PuiseuxPoly[Er]
            A new Puiseux polynomial representing the sum of this polynomial and other.
        
        Raises
        ------
        ValueError
            If attempting to add PuiseuxPoly objects from different rings.
        
        Notes
        -----
        When adding two Puiseux polynomials, they are first unified to have compatible
        internal representations (same monom and ns attributes) before the underlying
        polynomial addition is performed. Ground elements and integers are converted
        to constant Puiseux polynomials before addition.
        
        The addition operation preserves the fractional and negative exponent capabilities
        of Puiseux polynomials, automatically handling the normalization of the result.
        
        Examples
        --------
        >>> from sympy.polys.domains import QQ
        >>> from sympy.polys.puiseux import puiseux_ring
        >>> R, x, y = puiseux_ring('x y', QQ)
        >>> p1 = 3*x**2 + 2*y
        >>> p2 = x**2 + 5*y
        >>> p1 + p2
        4*x**2 + 7*y
        >>> p1 + 5
        3*x**2 + 2*y + 5
        >>> p1 + QQ(1,2)
        3*x**2 + 2*y + 1/2
        """
        # <your code>
...
```

The above code describes the necessary interfaces to implement this class/function, in addition to these interfaces you may need to implement some other helper functions to assist you in accomplishing these interfaces. Also remember that all classes/functions that appear in **Interface Description n** should be imported by your `agent_code/__init__.py`.

What's more, in order to implement this functionality, some additional libraries etc. are often required, I don't restrict you to any libraries, you need to think about what dependencies you might need and fetch and install and call them yourself. The only thing is that you **MUST** fulfill the input/output format described by this interface, otherwise the test will not pass and you will get zero points for this feature.

And note that there may be not only one **Interface Description**, you should match all **Interface Description {n}**

### Interface Description 1
Below is **Interface Description 1**

```python
class PuiseuxPoly:
    """
    Puiseux polynomial. Represents a truncated Puiseux series.
    
        See the :class:`PuiseuxRing` class for more information.
    
        >>> from sympy import QQ
        >>> from sympy.polys.puiseux import puiseux_ring
        >>> R, x, y = puiseux_ring('x, y', QQ)
        >>> p = 5*x**2 + 7*y**3
        >>> p
        7*y**3 + 5*x**2
    
        The internal representation of a Puiseux polynomial wraps a normal
        polynomial. To support negative powers the polynomial is considered to be
        divided by a monomial.
    
        >>> p2 = 1/x + 1/y**2
        >>> p2.monom # x*y**2
        (1, 2)
        >>> p2.poly
        x + y**2
        >>> (y**2 + x) / (x*y**2) == p2
        True
    
        To support fractional powers the polynomial is considered to be a function
        of ``x**(1/nx), y**(1/ny), ...``. The representation keeps track of a
        monomial and a list of exponent denominators so that the polynomial can be
        used to represent both negative and fractional powers.
    
        >>> p3 = x**QQ(1,2) + y**QQ(2,3)
        >>> p3.ns
        (2, 3)
        >>> p3.poly
        x + y**2
    
        See Also
        ========
    
        sympy.polys.puiseux.PuiseuxRing
        sympy.polys.rings.PolyElement
        
    """
    ring = {'_type': 'annotation_only', '_annotation': 'PuiseuxRing[Er]'}
    poly = {'_type': 'annotation_only', '_annotation': 'PolyElement[Er]'}
    monom = {'_type': 'annotation_only', '_annotation': 'MonI | None'}
    ns = {'_type': 'annotation_only', '_annotation': 'MonI | None'}

    def __add__(self, other: PuiseuxPoly[Er] | Er | int) -> PuiseuxPoly[Er]:
        """
        Add another Puiseux polynomial or ground element to this polynomial.
        
        This method implements addition between Puiseux polynomials and supports adding
        ground elements (domain elements) or integers to a Puiseux polynomial.
        
        Parameters
        ----------
        other : PuiseuxPoly[Er] | Er | int
            The element to add to this polynomial. Can be:
            - Another PuiseuxPoly from the same ring
            - A ground element from the polynomial's domain
            - An integer (automatically converted to domain element)
        
        Returns
        -------
        PuiseuxPoly[Er]
            A new Puiseux polynomial representing the sum of this polynomial and other.
        
        Raises
        ------
        ValueError
            If attempting to add PuiseuxPoly objects from different rings.
        
        Notes
        -----
        When adding two Puiseux polynomials, they are first unified to have compatible
        internal representations (same monom and ns attributes) before the underlying
        polynomial addition is performed. Ground elements and integers are converted
        to constant Puiseux polynomials before addition.
        
        The addition operation preserves the fractional and negative exponent capabilities
        of Puiseux polynomials, automatically handling the normalization of the result.
        
        Examples
        --------
        >>> from sympy.polys.domains import QQ
        >>> from sympy.polys.puiseux import puiseux_ring
        >>> R, x, y = puiseux_ring('x y', QQ)
        >>> p1 = 3*x**2 + 2*y
        >>> p2 = x**2 + 5*y
        >>> p1 + p2
        4*x**2 + 7*y
        >>> p1 + 5
        3*x**2 + 2*y + 5
        >>> p1 + QQ(1,2)
        3*x**2 + 2*y + 1/2
        """
        # <your code>

    def __eq__(self, other: object) -> bool:
        """
        Check equality between two PuiseuxPoly objects or with other types.
        
        This method compares two PuiseuxPoly instances by checking if their internal
        polynomial representation (poly), monomial divisor (monom), and exponent
        denominators (ns) are all equal. For non-PuiseuxPoly objects, it delegates
        to the underlying polynomial's __eq__ method if the current instance has
        no fractional or negative exponents.
        
        Parameters
        ----------
        other : object
            The object to compare with. Can be a PuiseuxPoly instance or any other
            type that the underlying polynomial can compare with.
        
        Returns
        -------
        bool or NotImplemented
            True if the objects are equal, False if they are not equal, or
            NotImplemented if the comparison cannot be performed (e.g., when
            comparing with incompatible types and the current instance has
            fractional or negative exponents).
        
        Notes
        -----
        Two PuiseuxPoly objects are considered equal if and only if:
        1. They have the same polynomial representation (poly)
        2. They have the same monomial divisor (monom) 
        3. They have the same exponent denominators (ns)
        
        For non-PuiseuxPoly objects, equality is only checked if the current
        instance represents a simple polynomial (monom is None and ns is None).
        Otherwise, NotImplemented is returned to indicate the comparison cannot
        be performed.
        
        Examples
        --------
        >>> from sympy.polys.domains import QQ
        >>> from sympy.polys.puiseux import puiseux_ring
        >>> R, x = puiseux_ring('x', QQ)
        >>> p1 = x**2 + 1
        >>> p2 = x**2 + 1
        >>> p1 == p2
        True
        >>> p3 = x**QQ(1,2)
        >>> p3 == p1
        False
        """
        # <your code>

    def __mul__(self, other: PuiseuxPoly[Er] | Er | int) -> PuiseuxPoly[Er]:
        """
        Multiply this Puiseux polynomial by another Puiseux polynomial or ground element.
        
        This method implements multiplication between Puiseux polynomials and supports
        multiplication by ground domain elements (coefficients) and integers.
        
        Parameters
        ----------
        other : PuiseuxPoly[Er] | Er | int
            The multiplicand. Can be:
            - Another PuiseuxPoly from the same ring
            - An element from the ground domain (Er)
            - An integer
        
        Returns
        -------
        PuiseuxPoly[Er]
            The product of this polynomial and the other operand.
        
        Raises
        ------
        ValueError
            If attempting to multiply PuiseuxPoly objects from different rings.
        
        Notes
        -----
        Whe
```
_instruction cut at 16k characters_
---
Harness Report runs agent harnesses from their GitHub repos on Harbor tasks and records every model call. Every page is also `.md` and `.json`; index: https://harnessreport.com/llms.txt · MCP: https://harnessreport.com/mcp
