Exemple #1
0
    def completion(self, p, prec=20, extras=None):
        """
        EXAMPLES::

            sage: P.<x>=LaurentPolynomialRing(QQ)
            sage: P
            Univariate Laurent Polynomial Ring in x over Rational Field
            sage: PP=P.completion(x)
            sage: PP
            Laurent Series Ring in x over Rational Field
            sage: f=1-1/x
            sage: PP(f)
            -x^-1 + 1
            sage: 1/PP(f)
            -x - x^2 - x^3 - x^4 - x^5 - x^6 - x^7 - x^8 - x^9 - x^10 - x^11 - x^12 - x^13 - x^14 - x^15 - x^16 - x^17 - x^18 - x^19 - x^20 + O(x^21)

        TESTS:

        Check that the precision is taken into account (:trac:`24431`)::

            sage: L = LaurentPolynomialRing(QQ, 'x')
            sage: L.completion('x', 100).default_prec()
            100
            sage: L.completion('x', 20).default_prec()
            20
        """
        if str(p) == self._names[0] and self._n == 1:
            from sage.rings.laurent_series_ring import LaurentSeriesRing
            R = self.polynomial_ring().completion(self._names[0], prec)
            return LaurentSeriesRing(R)
        else:
            raise TypeError("Cannot complete %s with respect to %s" %
                            (self, p))
Exemple #2
0
def compute_wp_pari(E, prec):
    r"""
    Computes the Weierstrass `\wp`-function via calling the corresponding function in pari.

    EXAMPLES::
        
        sage: E = EllipticCurve([0,1])
        sage: E.weierstrass_p(algorithm='pari')
        z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + O(z^20)
        
        sage: E = EllipticCurve(GF(101),[5,4])
        sage: E.weierstrass_p(prec=30, algorithm='pari')
        z^-2 + 100*z^2 + 86*z^4 + 34*z^6 + 50*z^8 + 82*z^10 + 45*z^12 + 70*z^14 + 33*z^16 + 87*z^18 + 33*z^20 + 36*z^22 + 45*z^24 + 40*z^26 + 12*z^28 + O(z^30)

        sage: from sage.schemes.elliptic_curves.ell_wp import compute_wp_pari
        sage: compute_wp_pari(E, prec= 20)
        z^-2 + 100*z^2 + 86*z^4 + 34*z^6 + 50*z^8 + 82*z^10 + 45*z^12 + 70*z^14 + 33*z^16 + 87*z^18 + O(z^20)

    """
    ep = E._pari_()
    wpp = ep.ellwp(n=prec)
    k = E.base_ring()
    R = LaurentSeriesRing(k, 'z')
    z = R.gen()
    wp = z**(-2)
    for i in xrange(prec):
        wp += k(wpp[i]) * z**i
    wp = wp.add_bigoh(prec)
    return wp
Exemple #3
0
    def __classcall__(cls, *args, **kwds):
        r"""
        TESTS::

            sage: L = PuiseuxSeriesRing(QQ, 'q')
            sage: L is PuiseuxSeriesRing(QQ, name='q')
            True
            sage: Lp.<q> = PuiseuxSeriesRing(QQ)
            sage: L is Lp
            True
            sage: loads(dumps(L)) is L
            True

            sage: L.variable_names()
            ('q',)
            sage: L.variable_name()
            'q'
        """
        if not kwds and len(args) == 1 and isinstance(args[0],
                                                      LaurentSeriesRing):
            laurent_series = args[0]
        else:
            laurent_series = LaurentSeriesRing(*args, **kwds)

        return super(PuiseuxSeriesRing, cls).__classcall__(cls, laurent_series)
Exemple #4
0
def compute_wp_quadratic(k, A, B, prec):
    r"""
    Computes the truncated Weierstrass function of an elliptic curve
    defined by short Weierstrass model: `y^2 = x^3 + Ax + B`. Uses an
    algorithm that is of complexity `O(prec^2)`.

    Let p be the characteristic of the underlying field. Then we must
    have either p = 0, or p > prec + 2.

    INPUT:

     - ``k`` - the field of definition of the curve
     - ``A`` - and
     - ``B`` - the coefficients of the elliptic curve
     - ``prec`` - the precision to which we compute the series.

    OUTPUT:
    A Laurent series aproximating the Weierstrass `\wp`-function to precision ``prec``.

    ALGORITHM:
    This function uses the algorithm described in section 3.2 of [BMSS].

    REFERENCES:
    [BMSS] Boston, Morain, Salvy, Schost, "Fast Algorithms for Isogenies."

    EXAMPLES::

        sage: E = EllipticCurve([7,0])
        sage: E.weierstrass_p(prec=10, algorithm='quadratic')
        z^-2 - 7/5*z^2 + 49/75*z^6 + O(z^10)

        sage: E = EllipticCurve(GF(103),[1,2])
        sage: E.weierstrass_p(algorithm='quadratic')
        z^-2 + 41*z^2 + 88*z^4 + 11*z^6 + 57*z^8 + 55*z^10 + 73*z^12 + 11*z^14 + 17*z^16 + 50*z^18 + O(z^20)

        sage: from sage.schemes.elliptic_curves.ell_wp import compute_wp_quadratic
        sage: compute_wp_quadratic(E.base_ring(), E.a4(), E.a6(), prec=10)
        z^-2 + 41*z^2 + 88*z^4 + 11*z^6 + 57*z^8 + O(z^10)

    """
    m = (prec + 1) // 2
    c = [0 for j in range(m)]
    c[0] = -A / 5
    c[1] = -B / 7

    # first Z represent z^2
    R = LaurentSeriesRing(k, 'z')
    Z = R.gen()
    pe = Z**-1 + c[0] * Z + c[1] * Z**2

    for i in range(3, m):
        t = 0
        for j in range(1, i - 1):
            t += c[j - 1] * c[i - 2 - j]
        ci = (3 * t) / ((i - 2) * (2 * i + 3))
        pe += ci * Z**i
        c[i - 1] = ci

    return pe(Z**2).add_bigoh(prec)
Exemple #5
0
    def __init__(self, f, x0, singular_data, order=None):
        r"""Initialize a PuiseuxTSeries using a set of :math:`\pi = \{\tau\}`
        data.

        Parameters
        ----------
        f, x, y : polynomial
            A plane algebraic curve.
        x0 : complex
            The x-center of the Puiseux series expansion.
        singular_data : list
            The output of :func:`singular`.
        t : variable
            The variable in which the Puiseux t series is represented.

        """
        R = f.parent()
        x, y = R.gens()
        extension_polynomial, xpart, ypart = singular_data
        L = LaurentSeriesRing(ypart.base_ring(), 't')
        t = L.gen()

        self.f = f
        self.t = t
        self._xpart = xpart
        self._ypart = ypart

        # store x-part attributes. handle the centered at infinity case
        self.x0 = x0
        if x0 == infinity:
            x0 = QQ(0)
        self.center = x0

        # extract and store information about the x-part of the puiseux series
        xpart = xpart(t, 0)
        xpartshift = xpart - x0
        ramification_index, xcoefficient = xpartshift.laurent_polynomial(
        ).dict().popitem()
        self.xcoefficient = xcoefficient
        self.ramification_index = QQ(ramification_index).numerator()
        self.xpart = xpart

        # extract and store information about the y-part of the puiseux series
        self.ypart = L(ypart(t, 0))
        self._initialize_extension(extension_polynomial)

        # determine the initial order. See the order property
        val = L(ypart(t, O(t))).prec()
        self._singular_order = 0 if val == infinity else val
        self._regular_order = self._p.degree(x)

        # extend to have at least two elements
        self.extend(nterms=1)

        # the curve, x-part, and terms output by puiseux make the puiseux
        # series unique. any mutability only adds terms
        self.__parent = self.ypart.parent()
        self._hash = hash((self.f, self.xpart, self.ypart))
Exemple #6
0
    def local_coordinates_at_infinity(self, prec=20, name='t'):
        """
        For the genus `g` hyperelliptic curve `y^2 = f(x)`, return
        `(x(t), y(t))` such that `(y(t))^2 = f(x(t))`, where `t = x^g/y` is
        the local parameter at infinity

        INPUT:

        - ``prec`` -- desired precision of the local coordinates
        - ``name`` -- generator of the power series ring (default: ``t``)

        OUTPUT:

        `(x(t),y(t))` such that `y(t)^2 = f(x(t))` and `t = x^g/y`
        is the local parameter at infinity

        EXAMPLES::

            sage: R.<x> = QQ['x']
            sage: H = HyperellipticCurve(x^5-5*x^2+1)
            sage: x,y = H.local_coordinates_at_infinity(10)
            sage: x
            t^-2 + 5*t^4 - t^8 - 50*t^10 + O(t^12)
            sage: y
            t^-5 + 10*t - 2*t^5 - 75*t^7 + 50*t^11 + O(t^12)

        ::

            sage: R.<x> = QQ['x']
            sage: H = HyperellipticCurve(x^3-x+1)
            sage: x,y = H.local_coordinates_at_infinity(10)
            sage: x
            t^-2 + t^2 - t^4 - t^6 + 3*t^8 + O(t^12)
            sage: y
            t^-3 + t - t^3 - t^5 + 3*t^7 - 10*t^11 + O(t^12)

        AUTHOR:

        - Jennifer Balakrishnan (2007-12)
        """
        g = self.genus()
        pol = self.hyperelliptic_polynomials()[0]
        K = LaurentSeriesRing(self.base_ring(), name, default_prec=prec + 2)
        t = K.gen()
        L = PolynomialRing(K, 'x')
        x = L.gen()
        i = 0
        w = (x**g / t)**2 - pol
        wprime = w.derivative(x)
        if pol.degree() == 2 * g + 1:
            x = t**-2
        else:
            x = t**-1
        for i in range((RR(log(prec + 2) / log(2))).ceil()):
            x = x - w(x) / wprime(x)
        y = x**g / t
        return x + O(t**(prec + 2)), y + O(t**(prec + 2))
def _sa_coefficients_lambda_(K, beta=0):
    r"""
    Return the coefficients `\lambda_{k, \ell}(\beta)` used in singularity analysis.

    INPUT:

    - ``K`` -- an integer.

    - ``beta`` -- (default: `0`) the order of the logarithmic
      singularity.

    OUTPUT:

    A dictionary mapping pairs of indices to rationals.

    .. SEEALSO::

        :meth:`~AsymptoticExpansionGenerators.SingularityAnalysis`

    TESTS::

        sage: from sage.rings.asymptotic.asymptotic_expansion_generators \
        ....:     import _sa_coefficients_lambda_
        sage: _sa_coefficients_lambda_(3)
        {(0, 0): 1,
         (1, 1): -1,
         (1, 2): 1/2,
         (2, 2): 1,
         (2, 3): -5/6,
         (2, 4): 1/8,
         (3, 3): -1,
         (3, 4): 13/12,
         (4, 4): 1}
        sage: _sa_coefficients_lambda_(3, beta=1)
        {(0, 0): 1,
         (1, 1): -2,
         (1, 2): 1/2,
         (2, 2): 3,
         (2, 3): -4/3,
         (2, 4): 1/8,
         (3, 3): -4,
         (3, 4): 29/12,
         (4, 4): 5}
    """
    from sage.rings.laurent_series_ring import LaurentSeriesRing
    from sage.rings.power_series_ring import PowerSeriesRing
    from sage.rings.rational_field import QQ

    V = LaurentSeriesRing(QQ, names='v', default_prec=K)
    v = V.gen()
    T = PowerSeriesRing(V, names='t', default_prec=2 * K - 1)
    t = T.gen()

    S = (t - (1 + 1 / v + beta) * (1 + v * t).log()).exp()
    return dict(((k + L.valuation(), ell), c) for ell, L in enumerate(S.list())
                for k, c in enumerate(L.list()))
    def __init__(self, base_ring, name=None, default_prec=None, sparse=False,
                 category=None):
        CommutativeRing.__init__(
            self, base_ring, names=name,
            category=getattr(self, '_default_category', Fields()))

        # If self is R(( x^(1/e) )) then the corresponding Laurent series
        # ring will be R(( x ))
        self._laurent_series_ring = LaurentSeriesRing(
            base_ring, name=name, default_prec=default_prec, sparse=sparse)
Exemple #9
0
 def linear_relation(self, List, Psi, verbose=True, prec=None):
     for Phi in List:
         assert Phi.valuation() >= 0, "Symbols must be integral"
     assert Psi.valuation() >= 0
     R = self.base()
     Rbase = R.base()
     w = R.gen()
     d = len(List)
     if d == 0:
         if Psi.is_zero():
             return [None, R(1)]
         else:
             return [None, 0]
     if prec is None:
         M, var_prec = Psi.precision_absolute()
     else:
         M, var_prec = prec
     p = self.prime()
     V = R**d
     RSR = LaurentSeriesRing(Rbase, R.variable_name())
     VSR = RSR**self.source().ngens()
     List_TMs = [VSR(Phi.list_of_total_measures()) for Phi in List]
     Psi_TMs = VSR(Psi.list_of_total_measures())
     A = Matrix(RSR, List_TMs).transpose()
     try:
         sol = V([vv.power_series() for vv in A.solve_right(Psi_TMs)])
     except ValueError:
         #try "least squares"
         if verbose:
             print "Trying least squares."
         sol = (A.transpose() * A).solve_right(A.transpose() * Psi_TMs)
         #check precision (could make this better, checking each power of w)
         p_prec = M
         diff = Psi_TMs - sum([sol[i] * List_TMs[i] for i in range(len(List_TMs))])
         for i in diff:
             for j in i.list():
                 if p_prec > j.valuation():
                     p_prec = j.valuation()
         if verbose:
             print "p-adic precision is now", p_prec
         #Is this right?
         sol = V([R([j.add_bigoh(p_prec) for j in i.list()]) for i in sol])
     return [sol, R(-1)]
Exemple #10
0
    def test_LaurentSeries_V(self):
        L = LaurentSeriesRing(QQ, 't')
        t = L.gen()

        l = 1 * t**(-3) + 2 + 3 * t**1 + 4 * t**2 + 5 * t**9
        m = LaurentSeries_V(l, 1)
        self.assertEqual(l, m)

        m = LaurentSeries_V(l, 2)
        self.assertEqual(m.exponents(), [-6, 0, 2, 4, 18])
        self.assertEqual(m.coefficients(), [1, 2, 3, 4, 5])

        m = LaurentSeries_V(l, -1)
        self.assertEqual(m.exponents(), [-9, -2, -1, 0, 3])
        self.assertEqual(m.coefficients(), [5, 4, 3, 2, 1])

        m = LaurentSeries_V(l, -3)
        self.assertEqual(m.exponents(), [-27, -6, -3, 0, 9])
        self.assertEqual(m.coefficients(), [5, 4, 3, 2, 1])
Exemple #11
0
    def series(self, n):
        """
        Return the Laurent power series associated with the
        CFiniteSequence, with precision `n`.

        INPUT:

        - `n` -- a nonnegative integer

        EXAMPLES::

            sage: C.<x> = CFiniteSequences(QQ)
            sage: r = C.from_recurrence([-1,2],[0,1])
            sage: s = r.series(4); s
            x + 2*x^2 + 3*x^3 + 4*x^4 + O(x^5)
            sage: type(s)
            <class 'sage.rings.laurent_series_ring_element.LaurentSeries'>
        """
        R = LaurentSeriesRing(QQ, 'x', default_prec=n)
        return R(self.ogf())
    def completion(self, p, prec=20, extras=None):
        """
        EXAMPLES::

            sage: P.<x>=LaurentPolynomialRing(QQ)
            sage: P
            Univariate Laurent Polynomial Ring in x over Rational Field
            sage: PP=P.completion(x)
            sage: PP
            Laurent Series Ring in x over Rational Field
            sage: f=1-1/x
            sage: PP(f)
            -x^-1 + 1
            sage: 1/PP(f)
            -x - x^2 - x^3 - x^4 - x^5 - x^6 - x^7 - x^8 - x^9 - x^10 - x^11 - x^12 - x^13 - x^14 - x^15 - x^16 - x^17 - x^18 - x^19 - x^20 + O(x^21)
        """
        if str(p) == self._names[0] and self._n == 1:
            from sage.rings.laurent_series_ring import LaurentSeriesRing
            return LaurentSeriesRing(self.base_ring(), name=self._names[0])
        else:
            raise TypeError("Cannot complete %s with respect to %s" %
                            (self, p))
Exemple #13
0
def compute_wp_pari(E, prec):
    r"""
    Computes the Weierstrass `\wp`-function with the ``ellwp`` function
    from PARI.

    EXAMPLES::

        sage: E = EllipticCurve([0,1])
        sage: from sage.schemes.elliptic_curves.ell_wp import compute_wp_pari
        sage: compute_wp_pari(E, prec=20)
        z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + O(z^20)
        sage: compute_wp_pari(E, prec=30)
        z^-2 - 1/7*z^4 + 1/637*z^10 - 1/84721*z^16 + 3/38548055*z^22 - 4/8364927935*z^28 + O(z^30)
    """
    ep = E.__pari__()
    wpp = ep.ellwp(n=prec)
    k = E.base_ring()
    R = LaurentSeriesRing(k, 'z')
    z = R.gen()
    wp = z**(-2)
    for i in range(prec):
        wp += k(wpp[i]) * z**i
    wp = wp.add_bigoh(prec)
    return wp
def epsinv(F, target, prec=53, target_tol=0.001, z=None, emb=None):
    """
    Compute a bound on the hyperbolic distance.

    The true minimum will be within the computed bound.
    It is computed as the inverse of epsilon_F from [HS2018]_.
    
    INPUT:

    - ``F`` -- binary form of degree at least 3 with no multiple roots

    - ``target`` --  positive real number. The value we want to attain, i.e.,
      the value we are taking the inverse of

    - ``prec``-- positive integer. precision to use in CC

    - ``target_tol`` -- positive real number. The tolerance with which we
      attain the target value.

    - ``z`` -- complex number. ``z_0`` covariant for F.

    - ``emb`` -- embedding into CC

    OUTPUT: a real number delta satisfying  target + target_tol > eps_F(delta) > target.

    EXAMPLES::

        sage: from sage.rings.polynomial.binary_form_reduce import epsinv
        sage: R.<x,y> = QQ[]
        sage: epsinv(-2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3, 31.5022020249597) # tol 1e-12
        4.02520895942207       
    """
    def coshdelta(z):
        #The cosh of the hyperbolic distance from z = t+uj to j
        return (z.norm() + 1) / (2 * z.imag())

    def RQ(delta):
        # this is the quotient R(F_0,z)/R(F_0,z(F)) for a generic z
        # at distance delta from j. See Lemma 4.2 in [HS2018].
        cd = cosh(delta).n(prec=prec)
        sd = sinh(delta).n(prec=prec)
        return prod(
            [cd + (cost * phi[0] + sint * phi[1]) * sd for phi in phis])

    def epsF(delta):
        pol = RQ(delta)  #get R quotient in terms of z
        S = PolynomialRing(C, 'v')
        g = S([(i - d) * pol[i - d]
               for i in range(2 * d + 1)])  # take derivative
        drts = [
            e for e in g.roots(ring=C, multiplicities=False)
            if (e.norm() - 1).abs() < 0.1
        ]
        # find min
        return min([pol(r / r.abs()).real() for r in drts])

    C = ComplexField(prec=prec)
    R = F.parent()
    d = F.degree()
    if z is None:
        z, th = covariant_z0(F, prec=prec, emb=emb)
    else:  #need to do our own input checking
        if R.ngens() != 2 or any(sum(t) != d for t in F.exponents()):
            raise TypeError('must be a binary form')
        if d < 3:
            raise ValueError('must be at least degree 3')

    f = F.subs({R.gen(1): 1}).univariate_polynomial()
    #now we have a single variable polynomial
    if (max([ex for p,ex in f.roots(ring=C)]) >= QQ(d)/2)\
      or (f.degree() < QQ(d)/2):
        raise ValueError('cannot have root with multiplicity >= deg(F)/2')

    R = RealField(prec=prec)
    PR = PolynomialRing(R, 't')
    t = PR.gen(0)
    # compute phi_1, ..., phi_k
    # first find F_0 and its roots
    # this change of variables on f moves z(f) to j, i.e. produces F_0
    rts = f(z.imag() * t + z.real()).roots(ring=C)
    phis = []  # stereographic projection of roots
    for r, e in rts:
        phis.extend(
            [[2 * r.real() / (r.norm() + 1), (r.norm() - 1) / (r.norm() + 1)]])
    if d != f.degree():  # include roots at infinity
        phis.extend([(d - f.degree()) * [0, 1]])

    # for writing RQ in terms of generic z to minimize
    LC = LaurentSeriesRing(C, 'u', default_prec=2 * d + 2)
    u = LC.gen(0)
    cost = (u + u**(-1)) / 2
    sint = (u - u**(-1)) / (2 * C.gen(0))

    # first find an interval containing the desired value
    # then use regula falsi on log eps_F
    # d -> delta value in interval [0,1]
    # v in value in interval [1,epsF(1)]
    dl = R(0.0)
    vl = R(1.0)
    du = R(1.0)
    vu = epsF(du)
    while vu < target:
        # compute the next value of epsF for delta = 2*delta
        dl = du
        vl = vu
        du *= 2
        vu = epsF(du)
    # now dl < delta <= du
    logt = target.log()
    l2 = (vu.log() - logt).n(prec=prec)
    l1 = (vl.log() - logt).n(prec=prec)
    dn = (dl * l2 - du * l1) / (l2 - l1)
    vn = epsF(dn)
    dl = du
    vl = vu
    du = dn
    vu = vn
    while (du - dl).abs() >= target_tol or max(vl, vu) < target:
        l2 = (vu.log() - logt).n(prec=prec)
        l1 = (vl.log() - logt).n(prec=prec)
        dn = (dl * l2 - du * l1) / (l2 - l1)
        vn = epsF(dn)
        dl = du
        vl = vu
        du = dn
        vu = vn
    return max(dl, du)
Exemple #15
0
    def __init__(self, parent, ogf):
        r"""
        Initialize the C-Finite sequence.

        The ``__init__`` method can only be called by the :class:`CFiniteSequences`
        class. By Default, a class call reaches the ``__classcall_private__``
        which first creates a proper parent and then call the ``__init__``.

        INPUT:

        - ``ogf`` -- the ordinary generating function, a fraction of polynomials over the rationals
        - ``parent`` --  the parent of the C-Finite sequence, an occurrence of :class:`CFiniteSequences`

        OUTPUT:

        - A CFiniteSequence object

        TESTS::

            sage: C.<x> = CFiniteSequences(QQ)
            sage: C((2-x)/(1-x-x^2))            # indirect doctest
            C-finite sequence, generated by (x - 2)/(x^2 + x - 1)
        """

        br = parent.base_ring()
        ogf = parent.fraction_field()(ogf)
        P = parent.polynomial_ring()
        num = ogf.numerator()
        den = ogf.denominator()

        FieldElement.__init__(self, parent)

        if den == 1:
            self._c = []
            self._off = num.valuation()
            self._deg = 0
            if ogf == 0:
                self._a = [0]
            else:
                self._a = num.shift(-self._off).list()
        else:
            # Transform the ogf numerator and denominator to canonical form
            # to get the correct offset, degree, and recurrence coeffs and
            # start values.
            self._off = 0
            self._deg = 0
            if num.constant_coefficient() == 0:
                self._off = num.valuation()
                num = num.shift(-self._off)
            elif den.constant_coefficient() == 0:
                self._off = -den.valuation()
                den = den.shift(self._off)
            f = den.constant_coefficient()
            num = P(num / f)
            den = P(den / f)
            f = num.gcd(den)
            num = P(num / f)
            den = P(den / f)
            self._deg = den.degree()
            self._c = [-den[i] for i in range(1, self._deg + 1)]
            if self._off >= 0:
                num = num.shift(self._off)
            else:
                den = den.shift(-self._off)

            # determine start values (may be different from _get_item_ values)
            alen = max(self._deg, num.degree() + 1)
            R = LaurentSeriesRing(br,
                                  parent.variable_name(),
                                  default_prec=alen)
            rem = num % den
            if den != 1:
                self._a = R(num / den).list()
                self._aa = R(rem /
                             den).list()[:self._deg]  # needed for _get_item_
            else:
                self._a = num.list()
            if len(self._a) < alen:
                self._a.extend([0] * (alen - len(self._a)))

            ogf = num / den

        self._ogf = ogf
Exemple #16
0
def S(P, m):
    PP = P.parent()
    from sage.rings.laurent_series_ring import LaurentSeriesRing
    LS = LaurentSeriesRing(PP.base_ring(), name='z', default_prec=m)
    irP = 1 / LS(P.reverse())
    return PP(irP.list())