Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - modules - genus2red.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.8.0 lcov report (development 19199-979caa2) Lines: 1278 1407 90.8 %
Date: 2016-07-24 07:10:30 Functions: 53 53 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2000  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation. It is distributed in the hope that it will be useful, but WITHOUT
       8             : ANY WARRANTY WHATSOEVER.
       9             : 
      10             : Check the License for details. You should have received a copy of it, along
      11             : with the package; see the file 'COPYING'. If not, write to the Free Software
      12             : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
      13             : #include "pari.h"
      14             : #include "paripriv.h"
      15             : 
      16             : /********************************************************************/
      17             : /**                                                                **/
      18             : /**                       IGUSA INVARIANTS                         **/
      19             : /**                       (GP2C-generated)                         **/
      20             : /**                                                                **/
      21             : /********************************************************************/
      22             : /*
      23             : j2(a0,a1,a2,a3,a4,a5,a6) = (-120*a0*a6+20*a1*a5-8*a2*a4+3*a3^2) / 4;
      24             : */
      25             : static GEN
      26        1344 : igusaj2(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5, GEN a6)
      27             : {
      28        1344 :   pari_sp av = avma;
      29        1344 :   return gerepileupto(av, gmul2n(gadd(gsub(gadd(gmul(gmulsg(-120, a0), a6), gmul(gmulsg(20, a1), a5)), gmul(gmulsg(8, a2), a4)), gmulsg(3, gsqr(a3))), -2));
      30             : }
      31             : 
      32             : /*
      33             : j4(a0,a1,a2,a3,a4,a5,a6) = (240*(a0*a3*a4*a5+a1*a2*a3*a6)-400*(a0*a2*a5^2+a1^2*a4*a6)-64*(a0*a4^3+a2^3*a6)+16*(a1*a3*a4^2+a2^2*a3*a5)-672*a0*a3^2*a6+240*a1^2*a5^2-112*a1*a2*a4*a5-8*a1*a3^2*a5+16*a2^2*a4^2-16*a2*a3^2*a4+3*a3^4+2640*a0^2*a6^2-880*a0*a1*a5*a6+1312*a0*a2*a4*a6) / 2^7
      34             : */
      35             : static GEN
      36        1344 : igusaj4(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5, GEN a6)
      37             : {
      38        1344 :   pari_sp av = avma;
      39        1344 :   return gerepileupto(av,
      40             : gmul2n(gadd(gsub(gadd(gadd(gsub(gadd(gsub(gsub(gadd(gsub(gadd(gsub(gsub(gmulsg(240,
      41             : gadd(gmul(gmul(gmul(a0, a3), a4), a5), gmul(gmul(gmul(a1, a2), a3), a6))),
      42             : gmulsg(400, gadd(gmul(gmul(a0, a2), gsqr(a5)), gmul(gmul(gsqr(a1), a4), a6)))),
      43             : gmulsg(64, gadd(gmul(a0, gpowgs(a4, 3)), gmul(gpowgs(a2, 3), a6)))), gmulsg(16,
      44             : gadd(gmul(gmul(a1, a3), gsqr(a4)), gmul(gmul(gsqr(a2), a3), a5)))),
      45             : gmul(gmul(gmulsg(672, a0), gsqr(a3)), a6)), gmul(gmulsg(240, gsqr(a1)),
      46             : gsqr(a5))), gmul(gmul(gmul(gmulsg(112, a1), a2), a4), a5)), gmul(gmul(gmulsg(8,
      47             : a1), gsqr(a3)), a5)), gmul(gmulsg(16, gsqr(a2)), gsqr(a4))),
      48             : gmul(gmul(gmulsg(16, a2), gsqr(a3)), a4)), gmulsg(3, gpowgs(a3, 4))),
      49             : gmul(gmulsg(2640, gsqr(a0)), gsqr(a6))), gmul(gmul(gmul(gmulsg(880, a0), a1),
      50             : a5), a6)), gmul(gmul(gmul(gmulsg(1312, a0), a2), a4), a6)), -7));
      51             : }
      52             : 
      53             : /*
      54             : j6(a0,a1,a2,a3,a4,a5,a6) = (1600*(a0^2*a4^2*a5^2+a1^2*a2^2*a6^2)+1600*(a0*a1*a2*a5^3+a1^3*a4*a5*a6)+640*(a0*a1*a3*a4*a5^2+a1^2*a2*a3*a5*a6)-4000*(a0^2*a3*a5^3+a1^3*a3*a6^2)-384*(a0*a1*a4^3*a5+a1*a2^3*a5*a6)-640*(a0*a2^2*a4*a5^2+a1^2*a2*a4^2*a6)+80*(a0*a2*a3^2*a5^2+a1^2*a3^2*a4*a6)+192*(a0*a2*a3*a4^2*a5+a1*a2^2*a3*a4*a6)-48*(a0*a3^3*a4*a5+a1*a2*a3^3*a6)-224*(a1^2*a3*a4^2*a5+a1*a2^2*a3*a5^2)+64*(a1^2*a4^4+a2^4*a5^2)-64*(a1*a2*a3*a4^3+a2^3*a3*a4*a5)+16*(a1*a3^3*a4^2+a2^2*a3^3*a5)-4096*(a0^2*a4^3*a6+a0*a2^3*a6^2)+6400*(a0^2*a2*a5^2*a6+a0*a1^2*a4*a6^2)+10560*(a0^2*a3*a4*a5*a6+a0*a1*a2*a3*a6^2)+2624*(a0*a1*a3*a4^2*a6+a0*a2^2*a3*a5*a6)-4432*a0*a1*a3^2*a5*a6-8*a2*a3^4*a4+a3^6-320*a1^3*a5^3+64*a1^2*a2*a4*a5^2+176*a1^2*a3^2*a5^2+128*a1*a2^2*a4^2*a5+112*a1*a2*a3^2*a4*a5-28*a1*a3^4*a5+16*a2^2*a3^2*a4^2+5120*a0^3*a6^3-2544*a0^2*a3^2*a6^2+312*a0*a3^4*a6-14336*a0^2*a2*a4*a6^2+1024*a0*a2^2*a4^2*a6-2560*a0^2*a1*a5*a6^2-2240*a0*a1^2*a5^2*a6-6528*a0*a1*a2*a4*a5*a6-1568*a0*a2*a3^2*a4*a6) / 2^10
      55             : */
      56             : static GEN
      57        1344 : igusaj6(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5, GEN a6)
      58             : {
      59        1344 :   pari_sp av = avma;
      60        1344 :   return gerepileupto(av,
      61             : gmul2n(gsub(gsub(gsub(gsub(gadd(gsub(gadd(gsub(gadd(gadd(gsub(gadd(gadd(gadd(gadd(gsub(gadd(gsub(gsub(gadd(gadd(gadd(gsub(gadd(gsub(gadd(gsub(gsub(gadd(gadd(gsub(gsub(gsub(gadd(gadd(gmulsg(1600,
      62             : gadd(gmul(gmul(gsqr(a0), gsqr(a4)), gsqr(a5)), gmul(gmul(gsqr(a1), gsqr(a2)),
      63             : gsqr(a6)))), gmulsg(1600, gadd(gmul(gmul(gmul(a0, a1), a2), gpowgs(a5, 3)),
      64             : gmul(gmul(gmul(gpowgs(a1, 3), a4), a5), a6)))), gmulsg(640,
      65             : gadd(gmul(gmul(gmul(gmul(a0, a1), a3), a4), gsqr(a5)),
      66             : gmul(gmul(gmul(gmul(gsqr(a1), a2), a3), a5), a6)))), gmulsg(4000,
      67             : gadd(gmul(gmul(gsqr(a0), a3), gpowgs(a5, 3)), gmul(gmul(gpowgs(a1, 3), a3),
      68             : gsqr(a6))))), gmulsg(384, gadd(gmul(gmul(gmul(a0, a1), gpowgs(a4, 3)), a5),
      69             : gmul(gmul(gmul(a1, gpowgs(a2, 3)), a5), a6)))), gmulsg(640,
      70             : gadd(gmul(gmul(gmul(a0, gsqr(a2)), a4), gsqr(a5)), gmul(gmul(gmul(gsqr(a1),
      71             : a2), gsqr(a4)), a6)))), gmulsg(80, gadd(gmul(gmul(gmul(a0, a2), gsqr(a3)),
      72             : gsqr(a5)), gmul(gmul(gmul(gsqr(a1), gsqr(a3)), a4), a6)))), gmulsg(192,
      73             : gadd(gmul(gmul(gmul(gmul(a0, a2), a3), gsqr(a4)), a5), gmul(gmul(gmul(gmul(a1,
      74             : gsqr(a2)), a3), a4), a6)))), gmulsg(48, gadd(gmul(gmul(gmul(a0, gpowgs(a3, 3)),
      75             : a4), a5), gmul(gmul(gmul(a1, a2), gpowgs(a3, 3)), a6)))), gmulsg(224,
      76             : gadd(gmul(gmul(gmul(gsqr(a1), a3), gsqr(a4)), a5), gmul(gmul(gmul(a1,
      77             : gsqr(a2)), a3), gsqr(a5))))), gmulsg(64, gadd(gmul(gsqr(a1), gpowgs(a4, 4)),
      78             : gmul(gpowgs(a2, 4), gsqr(a5))))), gmulsg(64, gadd(gmul(gmul(gmul(a1, a2), a3),
      79             : gpowgs(a4, 3)), gmul(gmul(gmul(gpowgs(a2, 3), a3), a4), a5)))), gmulsg(16,
      80             : gadd(gmul(gmul(a1, gpowgs(a3, 3)), gsqr(a4)), gmul(gmul(gsqr(a2), gpowgs(a3,
      81             : 3)), a5)))), gmulsg(4096, gadd(gmul(gmul(gsqr(a0), gpowgs(a4, 3)), a6),
      82             : gmul(gmul(a0, gpowgs(a2, 3)), gsqr(a6))))), gmulsg(6400,
      83             : gadd(gmul(gmul(gmul(gsqr(a0), a2), gsqr(a5)), a6), gmul(gmul(gmul(a0,
      84             : gsqr(a1)), a4), gsqr(a6))))), gmulsg(10560, gadd(gmul(gmul(gmul(gmul(gsqr(a0),
      85             : a3), a4), a5), a6), gmul(gmul(gmul(gmul(a0, a1), a2), a3), gsqr(a6))))),
      86             : gmulsg(2624, gadd(gmul(gmul(gmul(gmul(a0, a1), a3), gsqr(a4)), a6),
      87             : gmul(gmul(gmul(gmul(a0, gsqr(a2)), a3), a5), a6)))),
      88             : gmul(gmul(gmul(gmul(gmulsg(4432, a0), a1), gsqr(a3)), a5), a6)),
      89             : gmul(gmul(gmulsg(8, a2), gpowgs(a3, 4)), a4)), gpowgs(a3, 6)), gmul(gmulsg(320,
      90             : gpowgs(a1, 3)), gpowgs(a5, 3))), gmul(gmul(gmul(gmulsg(64, gsqr(a1)), a2), a4),
      91             : gsqr(a5))), gmul(gmul(gmulsg(176, gsqr(a1)), gsqr(a3)), gsqr(a5))),
      92             : gmul(gmul(gmul(gmulsg(128, a1), gsqr(a2)), gsqr(a4)), a5)),
      93             : gmul(gmul(gmul(gmul(gmulsg(112, a1), a2), gsqr(a3)), a4), a5)),
      94             : gmul(gmul(gmulsg(28, a1), gpowgs(a3, 4)), a5)), gmul(gmul(gmulsg(16, gsqr(a2)),
      95             : gsqr(a3)), gsqr(a4))), gmul(gmulsg(5120, gpowgs(a0, 3)), gpowgs(a6, 3))),
      96             : gmul(gmul(gmulsg(2544, gsqr(a0)), gsqr(a3)), gsqr(a6))), gmul(gmul(gmulsg(312,
      97             : a0), gpowgs(a3, 4)), a6)), gmul(gmul(gmul(gmulsg(14336, gsqr(a0)), a2), a4),
      98             : gsqr(a6))), gmul(gmul(gmul(gmulsg(1024, a0), gsqr(a2)), gsqr(a4)), a6)),
      99             : gmul(gmul(gmul(gmulsg(2560, gsqr(a0)), a1), a5), gsqr(a6))),
     100             : gmul(gmul(gmul(gmulsg(2240, a0), gsqr(a1)), gsqr(a5)), a6)),
     101             : gmul(gmul(gmul(gmul(gmul(gmulsg(6528, a0), a1), a2), a4), a5), a6)),
     102             : gmul(gmul(gmul(gmul(gmulsg(1568, a0), a2), gsqr(a3)), a4), a6)), -10));
     103             : }
     104             : 
     105             : /********************************************************************/
     106             : /**                                                                **/
     107             : /**   A REDUCTION ALGORITHM "A LA TATE" FOR CURVES OF GENUS 2      **/
     108             : /**                                                                **/
     109             : /********************************************************************/
     110             : /* Based on genus2reduction-0.3, http://www.math.u-bordeaux.fr/~liu/G2R/
     111             :  * by Qing Liu <liu@math.u-bordeaux.fr>
     112             :  * and Henri Cohen <cohen@math.u-bordeaux.fr>
     113             : 
     114             :  * Qing Liu: Modeles minimaux des courbes de genre deux
     115             :  * J. fuer die Reine und Angew. Math., 453 (1994), 137-164.
     116             :  * http://www.math.u-bordeaux.fr/~liu/articles/modregE.ps */
     117             : 
     118             : /* some auxiliary polynomials, gp2c-generated */
     119             : 
     120             : /*
     121             : apol2(a0,a1,a2) = -5*a1^2+12*a0*a2;
     122             : */
     123             : static GEN
     124        1344 : apol2(GEN a0, GEN a1, GEN a2)
     125             : {
     126        1344 :   return gadd(gmulsg(-5, gsqr(a1)), gmul(gmulsg(12, a0), a2));
     127             : }
     128             : 
     129             : /*
     130             : apol3(a0,a1,a2,a3) = 5*a1^3+9*a0*(-2*a1*a2+3*a0*a3);
     131             : */
     132             : static GEN
     133        1344 : apol3(GEN a0, GEN a1, GEN a2, GEN a3)
     134             : {
     135        1344 :   return gadd(gmulsg(5, gpowgs(a1, 3)), gmul(gmulsg(9, a0), gadd(gmul(gmulsg(-2, a1), a2), gmul(gmulsg(3, a0), a3))));
     136             : }
     137             : 
     138             : /*
     139             : apol5(a0,a1,a2,a3,a4,a5) = a1^5+3*a0*(-2*a1^3*a2+9*a0*a1^2*a3-36*a0^2*a1*a4+108*a0^3*a5);
     140             : */
     141             : static GEN
     142        1344 : apol5(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5)
     143             : {
     144        1344 :   return gadd(gpowgs(a1, 5), gmul(gmulsg(3, a0), gadd(gsub(gadd(gmul(gmulsg(-2, gpowgs(a1, 3)), a2), gmul(gmul(gmulsg(9, a0), gsqr(a1)), a3)), gmul(gmul(gmulsg(36, gsqr(a0)), a1), a4)), gmul(gmulsg(108, gpowgs(a0, 3)), a5))));
     145             : }
     146             : 
     147             : /*
     148             : bpol2(a0,a1,a2,a3,a4) = 2*a2^2-5*a1*a3+10*a0*a4;
     149             : */
     150             : static GEN
     151        1344 : bpol2(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4)
     152             : {
     153        1344 :   return gadd(gsub(gmulsg(2, gsqr(a2)), gmul(gmulsg(5, a1), a3)), gmul(gmulsg(10, a0), a4));
     154             : }
     155             : 
     156             : static const long VERYBIG = (1L<<20);
     157             : static long
     158       49777 : myval(GEN x, GEN p) { return signe(x)? Z_pval(x,p): VERYBIG; }
     159             : static long
     160        2674 : my3val(GEN x) { return signe(x)? Z_lval(x,3): VERYBIG; }
     161             : /* largest power of p dividing pol */
     162             : static long
     163        3080 : polval(GEN pol, GEN p)
     164             : {
     165        3080 :   long v, i, lx = lg(pol);
     166        3080 :   if (!signe(pol)) return VERYBIG;
     167        3080 :   v = myval(gel(pol,2),p);
     168        3080 :   for(i = 3;i<lx;i++) v = minss(v, myval(gel(pol,i),p));
     169        3080 :   return v;
     170             : }
     171             : /* b in Z[i], return v_3(b) */
     172             : static long
     173        1337 : myval_zi(GEN b) { return minss(my3val(real_i(b)), my3val(imag_i(b))); }
     174             : /* b in Z[i, Y]/(Y^2-3), return v_Y(b) */
     175             : static long
     176         595 : myval_zi2(GEN b)
     177             : {
     178             :   long v0, v1;
     179         595 :   b = lift(b);
     180         595 :   v0 = myval_zi(RgX_coeff(b,0));
     181         595 :   v1 = myval_zi(RgX_coeff(b,1));
     182         595 :   return minss(2*v0, 2*v1+1);
     183             : }
     184             : 
     185             : /* min(a,b,c) */
     186             : static long
     187        1561 : min3(long a, long b, long c)
     188             : {
     189        1561 :   long m = a;
     190        1561 :   if (b < m) m = b;
     191        1561 :   if (c < m) m = c;
     192        1561 :   return m;
     193             : }
     194             : /* min(a,b,c) */
     195             : static GEN
     196         574 : gmin3(GEN a, GEN b, GEN c)
     197             : {
     198         574 :   GEN m = a;
     199         574 :   if (gcmp(b, m) < 0) m = b;
     200         574 :   if (gcmp(c, m) < 0) m = c;
     201         574 :   return m;
     202             : }
     203             : 
     204             : /* a/b */
     205             : static GEN
     206       17941 : frac2s(long a, long b) { return b == 1? stoi(a): gdivgs(stoi(a), b); }
     207             : 
     208             : /* Vector of p-adic factors (over Q_p) to accuracy r of pol. */
     209             : static GEN
     210         119 : padicfactors(GEN pol, GEN p, long r) { return gel(factorpadic(pol,p,r),1); }
     211             : 
     212             : /* x(1/t)*t^6, deg x <= 6 */
     213             : static GEN
     214         294 : RgX_recip6(GEN x)
     215             : {
     216         294 :   long lx = lg(x), i, j;
     217         294 :   GEN y = cgetg(9, t_POL);
     218         294 :   y[1] = x[1];
     219         294 :   for (i=8,j=2; j < lx; i--,j++) gel(y,i) = gel(x,j);
     220         294 :   for (       ; j <  9; i--,j++) gel(y,i) = gen_0;
     221         294 :   return normalizepol_lg(y, 9);
     222             : }
     223             : /* extract coefficients of a polynomial a0 X^6 + ... + a6, of degree <= 6 */
     224             : static void
     225        6405 : RgX_to_6(GEN q, GEN *a0, GEN *a1, GEN *a2, GEN *a3, GEN *a4, GEN *a5, GEN *a6)
     226             : {
     227        6405 :   *a0 = gen_0;
     228        6405 :   *a1 = gen_0;
     229        6405 :   *a2 = gen_0;
     230        6405 :   *a3 = gen_0;
     231        6405 :   *a4 = gen_0;
     232        6405 :   *a5 = gen_0;
     233        6405 :   *a6 = gen_0;
     234        6405 :   switch(degpol(q))
     235             :   {
     236        4424 :     case 6: *a0 = gel(q,8); /*fall through*/
     237        6405 :     case 5: *a1 = gel(q,7); /*fall through*/
     238        6405 :     case 4: *a2 = gel(q,6); /*fall through*/
     239        6405 :     case 3: *a3 = gel(q,5); /*fall through*/
     240        6405 :     case 2: *a4 = gel(q,4); /*fall through*/
     241        6405 :     case 1: *a5 = gel(q,3); /*fall through*/
     242        6405 :     case 0: *a6 = gel(q,2); /*fall through*/
     243             :   }
     244        6405 : }
     245             : 
     246             : /* return a factor of maximal multiplicity (maxord) of the FpX Q, deg Q < 7.
     247             :  * In the special case maxord = 3 or maxord = 2 and p <= 5, make sure
     248             :  * the factor is irreducible */
     249             : static GEN
     250         707 : factmz(GEN Q, GEN p, long *maxord)
     251             : {
     252         707 :   GEN D, z = Q;
     253         707 :   long m = 0;
     254         707 :   if (cmpiu(p,5) <= 0)
     255             :   {
     256         511 :     if (FpX_is_squarefree(Q, p)) m = 1;
     257             :     else
     258             :     {
     259         371 :       GEN F = FpX_factor(Q,p), P = gel(F,1), E = gel(F,2);
     260         371 :       long i, l = 1;
     261        1015 :       for(i = 1;i<lg(E);i++)
     262             :       {
     263         644 :         long e = E[i];
     264         644 :         if (e >= m) { m = e; l = i; }
     265             :       }
     266         371 :       z = gel(P,l);
     267             :     }
     268         511 :     *maxord = m; return z;
     269             :   }
     270         196 :   D = Q;
     271             :   for(;;)
     272             :   {
     273             :     GEN T;
     274         364 :     m++;
     275         364 :     D = FpX_deriv(D, p);
     276         364 :     T = FpX_gcd(z, D, p);
     277         364 :     if (degpol(T) == 0) break;
     278         168 :     z = T;
     279         168 :   }
     280         196 :   if (m >= 3 && degpol(z) == 2)
     281             :   {
     282           7 :     GEN F = FpX_factor(z,p);
     283           7 :     z = gcoeff(F,1,1);
     284             :   }
     285         196 :   *maxord = m; return z;
     286             : }
     287             : 
     288             : /* deg(H mod p) = 3, return v_p( disc(correspondig p-adic factor) ) */
     289             : static long
     290          14 : discpart(GEN H, GEN p, long prec)
     291             : {
     292             :   GEN list, prod, dis;
     293             :   long i, j;
     294             : 
     295          14 :   if (degpol(FpX_red(H,p)) != 3)
     296           0 :     pari_err_BUG("discpart [must not reach]");
     297          14 :   list = padicfactors(H,p,prec);
     298          14 :   prod = pol_1(varn(H));
     299          56 :   for(i = 1; i < lg(list); i++)
     300             :   {
     301          42 :     GEN t = gel(list,i);
     302          84 :     for(j = 3; j < lg(t); j++) /* include if non-constant mod p */
     303          70 :       if (!valp(gel(t,j))) { prod = RgX_mul(prod,t); break; }
     304             :   }
     305          14 :   if (degpol(prod) != 3) pari_err_BUG("discpart [prod degree]");
     306          14 :   dis = RgX_disc(prod);
     307          14 :   return gequal0(dis)? prec+1: valp(dis);
     308             : }
     309             : 
     310             : 
     311             : /* B = b0 X^6 + ... + b6 a ZX, 0 <= j <= 3.
     312             :  * Return theta_j(H) := min { v_p(b_i) / (i - j), lambda < i <= 6 } >= 0.
     313             :  * N.B. 60 theta \in Z */
     314             : static GEN
     315        1806 : theta_j(GEN B, GEN p, long j)
     316             : {
     317        1806 :   GEN theta, b0, b1, b2, b3, b4, b5, b6, v = new_chunk(7);
     318             :   long i;
     319             : 
     320        1806 :   RgX_to_6(B, &b0,&b1,&b2,&b3,&b4,&b5,&b6);
     321        1806 :   v[0] = myval(b0,p);
     322        1806 :   v[1] = myval(b1,p);
     323        1806 :   v[2] = myval(b2,p);
     324        1806 :   v[3] = myval(b3,p);
     325        1806 :   v[4] = myval(b4,p);
     326        1806 :   v[5] = myval(b5,p);
     327        1806 :   v[6] = myval(b6,p);
     328        1806 :   theta = stoi(v[1+j]);
     329        1806 :   for(i = 2+j; i <= 6; i++) theta = gmin(theta, frac2s(v[i], i-j));
     330        1806 :   return theta;
     331             : }
     332             : /* compute theta_3 for B in Z[i][X], p = 3 */
     333             : static GEN
     334          28 : theta_3_zi(GEN B)
     335             : {
     336          28 :   long v2 = myval_zi(RgX_coeff(B,2));
     337          28 :   long v1 = myval_zi(RgX_coeff(B,1));
     338          28 :   long v0 = myval_zi(RgX_coeff(B,0));
     339          28 :   return frac2s(min3(6*v2, 3*v1, 2*v0), 6);
     340             : }
     341             : /* compute theta_3 for B in (Z[i,Y]/(Y^2-3))[X], p = 3 */
     342             : static GEN
     343          77 : theta_3_zi2(GEN B)
     344             : {
     345          77 :   long v2 = myval_zi2(RgX_coeff(B,2));
     346          77 :   long v1 = myval_zi2(RgX_coeff(B,1));
     347          77 :   long v0 = myval_zi2(RgX_coeff(B,0));
     348          77 :   return frac2s(min3(6*v2, 3*v1, 2*v0), 6);
     349             : }
     350             : 
     351             : /* T an FpX of degree 1, return its root */
     352             : static GEN
     353         182 : deg1root(GEN T, GEN p)
     354             : {
     355         182 :   GEN a = gel(T,2), b = gel(T,3);
     356         182 :   return Fp_neg(Fp_div(a, b, p), p);
     357             : }
     358             : /* H = minimal minimal over Z_p, p > 2.
     359             :  * alpha = 0,1
     360             :  * quad = 1 if root of order 3 in F_p^2 \ F_p, 0 otherwise
     361             :  * 0 <= lambda <= 3, t_INT
     362             :  * theta = theta(H, p), rational
     363             :  * beta >= 0, t_INT */
     364             : static GEN
     365        1631 : polymini(GEN pol, GEN p)
     366             : {
     367             :   GEN a0, a1, a2, a3, a4, a5, a6;
     368             :   GEN H, Hp, rac, theta, polf, pro, quad;
     369             :   long alpha, lambda, maxord, beta;
     370             : 
     371        1631 :   alpha = polval(pol,p);
     372        1631 :   H = RgX_Rg_div(pol, powiu(p,alpha));
     373        1631 :   RgX_to_6(H, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
     374        1631 :   if (dvdii(a0,p) && dvdii(a1,p) && dvdii(a2,p) && dvdii(a3,p))
     375             :   {
     376          63 :     H = RgX_recip6(H);
     377          63 :     RgX_to_6(H, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
     378             :   }
     379        1631 :   alpha = alpha&1;
     380        1631 :   beta = 0;
     381        1631 :   lambda = 0;
     382        1631 :   if (!dvdii(a1,p)) lambda = 1;
     383        1631 :   if (!dvdii(a2,p)) lambda = 2;
     384        1631 :   if (!dvdii(a3,p)) lambda = 3;
     385        1631 :   quad = gen_0;
     386             : 
     387             :   for(;;)
     388             :   {
     389        1806 :     theta = theta_j(H,p,lambda);
     390        1806 :     if (gcmp(theta,gen_1)>= 0)
     391             :     {
     392         938 :       long ent = itos(gfloor(theta));
     393         938 :       GEN pent = powiu(p,ent);
     394         938 :       H = RgX_Rg_div(RgX_unscale(H,pent), powiu(pent,6-lambda));
     395         938 :       alpha = (alpha+lambda*ent)&1;
     396         938 :       beta += ent;
     397         938 :       theta = gsubgs(theta,ent);
     398             :     }
     399        1806 :     Hp = FpX_red(H, p);
     400        1806 :     if (!gequal0(theta)) break;
     401             : 
     402         700 :     rac = factmz(Hp,p, &maxord);
     403         700 :     if (maxord <= 2)
     404             :     {
     405         504 :       if (degpol(Hp) <= 3) break;
     406          77 :       goto end;
     407             :     }
     408             :     else
     409             :     { /* maxord >= 3 */
     410         196 :       if (degpol(rac) == 2) { quad = gen_1; goto end; }
     411         175 :       rac = deg1root(rac, p);
     412         175 :       H = RgX_translate(H, rac);
     413         175 :       lambda = 6-maxord;
     414             :     }
     415         175 :   }
     416             : 
     417        1533 :   if (lambda <= 2)
     418             :   {
     419        1218 :     if (myval(RgX_coeff(H,2),p) > 1-alpha &&
     420        1015 :         myval(RgX_coeff(H,1),p) > 2-alpha &&
     421         455 :         myval(RgX_coeff(H,0),p) > 3-alpha)
     422             :     {
     423          49 :       pol = RgX_unscale(H, p);
     424          49 :       if (alpha) pol = RgX_Rg_mul(pol, p);
     425          49 :       return polymini(pol, p);
     426             :     }
     427             :   }
     428         875 :   else if (lambda == 3 && alpha == 1)
     429             :   {
     430         357 :     if (degpol(Hp) == 3)
     431             :     {
     432         637 :       if (myval(RgX_coeff(H,6),p) >= 3 &&
     433         315 :           myval(RgX_coeff(H,5),p) >= 2)
     434             :       {
     435         315 :         H = RgX_rescale(H, p); /* H(x/p)p^(deg H) */
     436         315 :         H = RgX_Rg_div(H, powiu(p, degpol(H)-3)); /* H(x/p)p^3 */
     437         315 :         theta = gadd(theta,gen_1);
     438         315 :         alpha = 0;
     439         315 :         beta--;
     440             :       }
     441             :     }
     442          35 :     else if (degpol(Hp) == 6 && !gequal0(theta))
     443             :     {
     444           7 :       rac = factmz(RgX_mulXn(Hp, -3), p, &maxord);
     445           7 :       if (maxord == 3)
     446             :       {
     447           7 :         rac = deg1root(rac, p);
     448           7 :         pro = RgX_translate(RgX_unscale(H,p), rac); /* H(rac + px) */
     449           7 :         if (polval(pro,p)>= 3)
     450             :         {
     451           0 :           H = RgX_Rg_div(pro, powiu(p,3));
     452           0 :           alpha = 0;
     453           0 :           beta--;
     454           0 :           theta = theta_j(H,p,3);
     455             :         }
     456             :       }
     457             :     }
     458             :   }
     459             : end:
     460        1582 :   polf = cgetg(7, t_VEC);
     461        1582 :   gel(polf,1) = H;
     462        1582 :   gel(polf,2) = stoi(lambda);
     463        1582 :   gel(polf,3) = theta;
     464        1582 :   gel(polf,4) = stoi(alpha);
     465        1582 :   gel(polf,5) = quad;
     466        1582 :   gel(polf,6) = stoi(beta);
     467        1582 :   return polf;
     468             : }
     469             : 
     470             : /* a in Q[i], return a^3 mod 3 */
     471             : static GEN
     472          14 : zi_pow3mod(GEN a)
     473             : {
     474             :   GEN x, y;
     475          14 :   if (typ(a) != t_COMPLEX) return gmodgs(a,3);
     476           7 :   x = gmodgs(gel(a,1), 3);
     477           7 :   y = gmodgs(gel(a,2), 3);
     478           7 :   return mkcomplex(x, negi(y));
     479             : }
     480             : static GEN
     481          21 : polymini_zi(GEN pol) /* polynome minimal dans Z[i] */
     482             : {
     483             :   GEN p, polh, rac, theta;
     484             :   GEN a0, a1, a2, a3, a4, a5, a6;
     485             :   long alpha,beta;
     486             : 
     487          21 :   p = stoi(3);
     488          21 :   alpha = polval(pol,p) & 1;
     489          21 :   polh = alpha? RgX_Rg_div(pol, p): pol;
     490          21 :   beta = 0;
     491          21 :   rac = mkcomplex(Fp_div(RgX_coeff(polh,3), RgX_coeff(polh,6), p), gen_1);
     492             :   for(;;)
     493             :   {
     494          28 :     polh = RgX_translate(polh, rac);
     495          28 :     theta = theta_3_zi(polh);
     496          28 :     if (gcmp(theta,gen_1) >= 0)
     497             :     {
     498          14 :       long ent = itos(gfloor(theta));
     499          14 :       GEN pent = powiu(p,ent);
     500          14 :       polh = RgX_Rg_div(RgX_unscale(polh,pent), powiu(pent,3));
     501          14 :       alpha = (alpha+ent)&1;
     502          14 :       beta += ent;
     503          14 :       theta = gsubgs(theta,ent);
     504             :     }
     505          28 :     RgX_to_6(polh, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
     506          28 :     if (!gequal0(theta) || !myval_zi(a4) || !myval_zi(a5)) break;
     507           7 :     rac = zi_pow3mod(gdiv(a6, gneg(a3)));
     508           7 :   }
     509          21 :   if (alpha && myval_zi(a0) >= 3 && myval_zi(a1) >= 2 && myval_zi(a2) >= 1)
     510             :   {
     511          14 :     theta = gadd(theta, gen_1);
     512          14 :     beta--;
     513          14 :     alpha = 0;
     514             :   }
     515          21 :   return mkvec3(theta, stoi(alpha), stoi(beta));
     516             : }
     517             : 
     518             : /* pol is a ZX, minimal polynomial over Z_3[i,Y]/(Y^2-3) */
     519             : static GEN
     520          77 : polymini_zi2(GEN pol)
     521             : {
     522             :   long alpha, beta;
     523             :   GEN a0, a1, a2, a3, a4, a5, a6;
     524          77 :   GEN p, polh, rac, theta, y = pol_x(fetch_var());
     525             : 
     526          77 :   p = stoi(3);
     527          77 :   if (polval(pol,p)) pari_err_BUG("polymini_zi2 [polynomial not minimal]");
     528          77 :   y = mkpolmod(y, gsubgs(gsqr(y), 3)); /* mod(y,y^2-3) */
     529          77 :   polh = pol;
     530          77 :   polh = gdivgs(RgX_unscale(polh, y),27); /* H(y*x) / 27 */
     531         147 :   if (myval_zi2(RgX_coeff(polh,4)) <= 0 ||
     532          70 :       myval_zi2(RgX_coeff(polh,2)) <= 0)
     533             :   {
     534           7 :     (void)delete_var();
     535           7 :     return mkcol2(gen_0, gen_0);
     536             :   }
     537             : 
     538          70 :   if (myval_zi2(gsub(RgX_coeff(polh,6), RgX_coeff(polh,0))) > 0)
     539           0 :     rac = gen_I();
     540             :   else
     541          70 :     rac = gen_1;
     542          70 :   alpha = 0;
     543          70 :   beta  = 0;
     544             :   for(;;)
     545             :   {
     546          77 :     polh = RgX_translate(polh, rac);
     547          77 :     theta = theta_3_zi2(polh);
     548          77 :     if (gcmp(theta,gen_1) >= 0)
     549             :     {
     550          70 :       long ent = itos(gfloor(theta));
     551          70 :       GEN pent = gpowgs(y, ent);
     552          70 :       polh = RgX_Rg_div(RgX_unscale(polh, pent), gpowgs(pent,3));
     553          70 :       alpha = (alpha+ent)&1;
     554          70 :       beta += ent;
     555          70 :       theta = gsubgs(theta,ent);
     556             :     }
     557          77 :     RgX_to_6(polh, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
     558          77 :     if (!gequal0(theta) || !myval_zi2(a4) || !myval_zi2(a5)) break;
     559           7 :     a3 = liftpol_shallow(a3); if (typ(a3)==t_POL) a3 = RgX_coeff(a3,0);
     560           7 :     a6 = liftpol_shallow(a6); if (typ(a6)==t_POL) a6 = RgX_coeff(a6,0);
     561           7 :     rac = zi_pow3mod(gdiv(a6,gneg(a3)));
     562           7 :   }
     563          70 :   if (alpha)
     564             :   {
     565          35 :     if (myval_zi2(a0) >= 3 && myval_zi2(a1) >= 2 && myval_zi2(a2) >= 1)
     566             :     {
     567          35 :       theta = gadd(theta,gen_1);
     568          35 :       beta--;
     569          35 :       alpha = 0;
     570             :     }
     571           0 :     else pari_err_BUG("polymini_zi2 [alpha]");
     572             :   }
     573          70 :   (void)delete_var();
     574          70 :   return mkcol2(theta, stoi(beta));
     575             : }
     576             : 
     577             : 
     578             : struct igusa {
     579             :   GEN j2, i4, j4, j6, j8, j10, i12;
     580             :   GEN a0, A2, A3, A5, B2;
     581             : };
     582             : struct igusa_p {
     583             :   long eps, eps2, tt, r1, r2, R, tame;
     584             :   GEN p, stable, val, neron;
     585             :   const char *type;
     586             : };
     587             : 
     588             : static void
     589        1365 : stable_reduction(struct igusa *I, struct igusa_p *Ip)
     590             : {
     591             :   static const long deg[9] = { 0,2,4,4,6,8,10,12 };
     592        1365 :   GEN j2 = I->j2, i4 = I->i4, j6 = I->j6, j8 = I->j8, j10 = I->j10;
     593        1365 :   GEN i12 = I->i12, p = Ip->p, val = Ip->val;
     594             :   GEN J, v, s, Ieps;
     595             :   long r1, r2, r3, r4, i, eps, eps2;
     596             : 
     597        1365 :   v = cgetg(8,t_COL);
     598        1365 :   for(i = 1; i <= 7; i++) gel(v,i) = frac2s(val[i], deg[i]);
     599        1365 :   s = gel(v,1);
     600        9555 :   for(i = 2; i <= 7; i++)
     601        8190 :     if (gcmp(gel(v,i),s) < 0) s = gel(v,i);
     602        1365 :   switch(itos_or_0(p))
     603             :   {
     604          14 :     case 2:  eps = 4; eps2 = 5; Ieps = j8; break;
     605         427 :     case 3:  eps = 3; eps2 = 4; Ieps = j6; break;
     606         924 :     default: eps = 1; eps2 = 1; Ieps = gdivgs(j2,12); break;
     607             :   }
     608        1365 :   Ip->eps  = eps;
     609        1365 :   Ip->eps2 = eps2;
     610             : 
     611        1365 :   r1 = 3*eps*val[3];
     612        1365 :   r3 = eps*val[6] + val[eps2];
     613        1365 :   r2 = eps*val[7];
     614        1365 :   r4 = min3(r1, r2, r3);
     615             : 
     616             :   /* s = max(v_p(X) / deg(X)) */
     617        1365 :   J = cgetg(1, t_VEC);
     618        1365 :   if (gequal(s,gel(v,6)))
     619         133 :     Ip->tt = 1;
     620        1232 :   else if (gequal(s,gel(v,7)))
     621             :   {
     622         105 :     J = mkvec( Fp_to_mod(gmod(gdiv(gpowgs(i4,3),i12), p), p) );
     623         105 :     Ip->tt = 2;
     624             :   }
     625        1127 :   else if (gequal(s,gel(v,3)))
     626         210 :     Ip->tt = (val[2] == val[3] || 2*val[4] == 3*val[3])? 3: 4;
     627         917 :   else if (r3 == r4)
     628             :   {
     629         532 :     GEN a,b, P, sj, pj, t = gmul(gpowgs(j10,eps),Ieps);
     630         532 :     sj = gaddsg(1728, gdiv(gpowgs(i12,eps), t));
     631         532 :     pj = gdiv(gpowgs(i4,3*eps), t);
     632         532 :     a = gmod(sj, p);
     633         532 :     b = gmod(pj, p);
     634         532 :     P = mkpoln(3, gen_1, Fp_neg(a,p), b, 0); /* X^2 - SX + P: roots j1,j2 */
     635         532 :     J = FpX_roots(P, p);
     636         532 :     switch(lg(J)-1)
     637             :     {
     638             :       case 0:
     639           0 :         P = FpX_to_mod(P, p);
     640           0 :         a = FpX_to_mod(pol_x(0), p);
     641           0 :         b = FpX_to_mod(deg1pol_shallow(b, gen_m1,0), p);
     642           0 :         J = mkvec2(mkpolmod(a,P), mkpolmod(b,P)); break;
     643             :       case 1:
     644         350 :         a = Fp_to_mod(gel(J,1), p);
     645         350 :         J = mkvec2(a, a); break;
     646             :       case 2:
     647         182 :         settyp(J, t_VEC);
     648         182 :         J = FpV_to_mod(J, p); break;
     649             :     }
     650         532 :     Ip->tt = 5;
     651             :   }
     652         385 :   else if (r2 == r4)
     653             :   {
     654         273 :     J = mkvec( Fp_to_mod(gmod(gdiv(gpowgs(i4,3),i12), p), p) );
     655         273 :     Ip->tt = 6;
     656             :   }
     657             :   else
     658         112 :     Ip->tt = 7; /* r1 == r4 */
     659        1365 :   Ip->stable = mkvec2(stoi(Ip->tt), J);
     660        1365 : }
     661             : 
     662             : struct red {
     663             :   const char *t, *pages;
     664             :   GEN g;
     665             : };
     666             : 
     667             : /* destroy v */
     668             : static GEN
     669        1351 : zv_snf(GEN v)
     670             : {
     671        1351 :   long i, l = lg(v);
     672        2968 :   for (i = 1; i < l; i++)
     673             :   {
     674        1617 :     long j, a = v[i];
     675        2310 :     for (j = i+1; j < l; j++)
     676             :     {
     677         693 :       long b = v[j], d = ugcd(a,b);
     678         693 :       v[i] = a = a*(b/d);
     679         693 :       v[j] = d;
     680             :     }
     681             :   }
     682        1428 :   for (i = l-1; i > 0; i--)
     683        1141 :     if (v[i] != 1) { setlg(v, i+1); break; }
     684        1351 :   return zv_to_ZV(v);
     685             : }
     686             : 
     687             : static GEN
     688        1260 : cyclic(long n)
     689        1260 : { return (n <= 1)? cgetg(1, t_VECSMALL): mkvecsmall(n); }
     690             : static GEN
     691         329 : dicyclic(long a, long b)
     692             : {
     693             :   long d;
     694         329 :   if (!a) a = 1;
     695         329 :   if (!b) b = 1;
     696         329 :   if (a < b) lswap(a,b);
     697         329 :   d = ugcd(a,b);
     698         329 :   if (d == 1) return cyclic(a*b);
     699         273 :   return mkvecsmall2(a*b/d, d);
     700             : }
     701             : /* Z/2xZ/2, resp Z/4 for n even, resp. odd */
     702             : static GEN
     703         280 : groupH(long n) { return odd(n)? cyclic(4): dicyclic(2,2); }
     704             : 
     705             : static long
     706         196 : get_red(struct red *S, struct igusa_p *Ip, GEN polh, GEN p, long alpha, long r)
     707             : {
     708         196 :   GEN val = Ip->val;
     709             :   long indice;
     710         196 :   switch(r)
     711             :   {
     712             :     case 0:
     713          70 :       indice = FpX_is_squarefree(FpX_red(polh,p), p)
     714             :                ? 0
     715          35 :                : val[6] - val[7] + val[Ip->eps2]/Ip->eps;
     716          35 :       S->t = stack_sprintf("I{%ld}", indice);
     717          35 :       S->pages = "159-177";
     718          35 :       S->g = cyclic(indice);
     719          35 :       return indice ? indice: 1;
     720             :     case 6:
     721          35 :       if (alpha == 0) /* H(px) /p^3 */
     722          28 :         polh = RgX_Rg_div(RgX_unscale(polh,p), powiu(p,3));
     723          70 :       indice = FpX_is_squarefree(FpX_red(polh,p), p)
     724             :                ? 0
     725          35 :                : val[6] - val[7] + val[Ip->eps2]/Ip->eps;
     726          35 :       S->t = stack_sprintf("I*{%ld}", indice);
     727          35 :       S->pages = "159-177";
     728          35 :       S->g = groupH(indice);
     729          35 :       return indice + 5;
     730             :     case 3:
     731          21 :       S->t = "III";
     732          21 :       S->pages = "161-177";
     733          21 :       S->g = cyclic(2);
     734          21 :       return 2;
     735             :     case 9:
     736          21 :       S->t = "III*";
     737          21 :       S->pages = "162-177";
     738          21 :       S->g = cyclic(2);
     739          21 :       return 8;
     740             :     case 2:
     741          21 :       S->t = "II";
     742          21 :       S->pages = "159-174";
     743          21 :       S->g = cyclic(1);
     744          21 :       return 1;
     745             :     case 8:
     746          28 :       S->t = "IV*";
     747          28 :       S->pages = "160-175";
     748          28 :       S->g = cyclic(3);
     749          28 :       return 7;
     750             :     case 4:
     751          21 :       S->t = "IV";
     752          21 :       S->pages = "160-174";
     753          21 :       S->g = cyclic(3);
     754          21 :       return 3;
     755             :     case 10:
     756          14 :       S->t = "II*";
     757          14 :       S->pages = "160-174";
     758          14 :       S->g = cyclic(1);
     759          14 :       return 9;
     760           0 :     default: pari_err_BUG("get_red [type]");
     761           0 :       S->t = "";
     762           0 :       S->pages = ""; /* gcc -Wall */
     763           0 :       S->g = NULL;
     764           0 :       return -1; /*notreached*/
     765             :   }
     766             : }
     767             : 
     768             : static long labelm3(GEN polh, GEN theta, long alpha, long dismin, struct igusa *I, struct igusa_p *Ip);
     769             : 
     770             : /* Ip->tt = 1 */
     771             : static long
     772          21 : tame_1(struct igusa *I, struct igusa_p *Ip)
     773             : {
     774          21 :   GEN p = Ip->p, val = Ip->val;
     775             :   GEN r, n, pro1, pro2;
     776          21 :   long condp = -1, va0, va5;
     777          21 :   va0 = myval(I->a0,p);
     778          21 :   va5 = myval(I->A5,p);
     779          21 :   if (!gequal0(I->A5) && 20*va0+val[6] > 6*va5)
     780             :   {
     781          14 :     pro1 = frac2s(val[6]-2*va5, 20);
     782          14 :     pro2 = frac2s(5*val[6]-6*va5, 40);
     783             :   }
     784             :   else
     785             :   {
     786           7 :     pro1 = frac2s(10*va0-val[6], 30);
     787           7 :     pro2 = frac2s(5*va0-val[6], 10);
     788             :   }
     789          21 :   n = lcmii(denom(pro1),denom(pro2));
     790          21 :   r = modii(gmul(n,pro1), n);
     791          21 :   switch(itos(n))
     792             :   {
     793             :     case 1:
     794           0 :       condp = 0;
     795           0 :       Ip->type = "[I{0-0-0}] page 155";
     796           0 :       Ip->neron = cyclic(1); break;
     797             :     case 2:
     798          14 :       switch(itos(r))
     799             :       {
     800             :         case 0:
     801           7 :           condp = 4;
     802           7 :           Ip->type = "[I*{0-0-0}] page 155";
     803           7 :           Ip->neron = mkvecsmall4(2,2,2,2); break;
     804             :         case 1:
     805           7 :           condp = 2;
     806           7 :           Ip->type = "[II] page 155";
     807           7 :           Ip->neron = cyclic(1); break;
     808           0 :         default: pari_err_BUG("tame_1 [bug1]");
     809             :       }
     810          14 :       break;
     811             :     case 4:
     812           7 :       condp = 4;
     813           7 :       Ip->type = "[VI] page 156";
     814           7 :       Ip->neron = dicyclic(2,2); break;
     815           0 :     default: pari_err_BUG("tame_1 [bug8]");
     816             :   }
     817          21 :   return condp;
     818             : }
     819             : 
     820             : static void
     821         203 : tame_234_init(struct igusa *I, struct igusa_p *Ip, long v12,
     822             :                 long *pn, long *pq, long *pr, long *flc)
     823             : {
     824             :   long va0, va5, vb2;
     825         203 :   GEN p = Ip->p, pro1, pro2, n, r, q;
     826         203 :   va0 = myval(I->a0,p);
     827         203 :   va5 = myval(I->A5,p);
     828         203 :   vb2 = myval(I->B2,p);
     829         203 :   if (9*vb2 >= 6*va0+v12 && 36*va5 >= 120*va0+5*v12)
     830             :   {
     831          42 :     pro1 = frac2s(12*va0-v12, 36);
     832          42 :     pro2 = frac2s(6*va0-v12, 12);
     833          42 :     n = lcmii(denom(pro1),denom(pro2));
     834          42 :     r = gmul(n,pro1);
     835          42 :     q = gmul(n,pro2);
     836          42 :     *flc = 1;
     837             :   }
     838         161 :   else if (120*va0+5*v12 > 36*va5 && 60*vb2 >= 12*va5+5*v12)
     839             :   {
     840          49 :     pro1 = frac2s(36*va5-25*v12, 240);
     841          49 :     n = denom(pro1);
     842          49 :     q = gmul(n,pro1);
     843          49 :     r = gmulsg(-2,q);
     844          49 :     *flc = 1;
     845             :   }
     846         112 :   else if (6*va0+v12 > 9*vb2 && 12*va5+5*v12 > 60*vb2)
     847             :   {
     848         112 :     pro1 = frac2s(v12-6*vb2, 12);
     849         112 :     pro2 = frac2s(v12-9*vb2, 12);
     850         112 :     n = lcmii(denom(pro1),denom(pro2));
     851         112 :     r = gmul(n,pro1);
     852         112 :     q = gmul(n,pro2);
     853         112 :     *flc = 2;
     854             :   }
     855             :   else
     856             :   {
     857           0 :     pari_err_BUG("tame234 [bug9]");
     858         203 :     return; /*not reached*/
     859             :   }
     860         203 :   r = gmod(r,n);
     861         203 :   q = gmod(q,n);
     862         203 :   *pn = itos(n);
     863         203 :   *pq = itos(q);
     864         203 :   *pr = itos(r);
     865             : }
     866             : 
     867             : /* Ip->tt = 2 */
     868             : static long
     869          91 : tame_2(struct igusa *I, struct igusa_p *Ip, long v12)
     870             : {
     871          91 :   long condp = -1, d, n, q, r, flc;
     872          91 :   GEN val = Ip->val;
     873          91 :   tame_234_init(I, Ip, v12, &n, &q, &r, &flc);
     874          91 :   d = n * (6*val[6]-5*val[7]) / 6;
     875          91 :   switch(n)
     876             :   {
     877           7 :     case 1: condp = 1;
     878           7 :       Ip->type = stack_sprintf("[I{%ld-0-0}] page 170", d);
     879           7 :       Ip->neron = cyclic(d); break;
     880             :     case 2:
     881          21 :       switch(r)
     882             :       {
     883           7 :         case 0: condp = 4;
     884           7 :           Ip->type = stack_sprintf("[I*{%ld-0-0}] page 171",d/2);
     885           7 :           Ip->neron = gconcat(dicyclic(2,2),groupH(d/2)); break;
     886             :         case 1:
     887          14 :           switch(q)
     888             :           {
     889           7 :             case 0: condp = 2;
     890           7 :               Ip->type = stack_sprintf("[II*{%ld-0}] page 172",d/2);
     891           7 :               Ip->neron = cyclic(1); break;
     892           7 :             case 1: condp = 3;
     893           7 :               Ip->type = stack_sprintf("[II{%ld-0}] page 171",d/2);
     894           7 :               Ip->neron = cyclic(2*d); break;
     895           0 :             default: pari_err_BUG("tame2 [bug10]");
     896             :           }
     897          14 :           break;
     898           0 :         default: pari_err_BUG("tame2 [bug11]");
     899             :       }
     900          21 :       break;
     901          14 :     case 3: condp = 3;
     902          14 :       Ip->neron = cyclic(d);
     903          14 :       switch(r)
     904             :       {
     905             :         case 1:
     906           7 :           Ip->type = stack_sprintf("[IV-II{%ld}] page 175", (d-2)/3);
     907           7 :           break;
     908             :         case 2:
     909           7 :           Ip->type = stack_sprintf("[IV*-II{%ld}] page 175", (d-1)/3);
     910           7 :           break;
     911           0 :         default: pari_err_BUG("tame2 [bug12]");
     912             :       }
     913          14 :       break;
     914             :     case 4:
     915          42 :       switch(r)
     916             :       {
     917             :         case 1:
     918          21 :           switch(q)
     919             :           {
     920          14 :             case 1: condp = 3;
     921          14 :               Ip->type = stack_sprintf("[III-II{%ld}] page 177",(d-2)/4);
     922          14 :               Ip->neron = cyclic(d/2); break;
     923           7 :             case 3: condp = 4;
     924           7 :               Ip->type = stack_sprintf("[III*-II*{%ld}] page 178",(d-2)/4);
     925           7 :               Ip->neron = cyclic(8); break;
     926           0 :             default: pari_err_BUG("tame2 [bug13]");
     927             :           }
     928          21 :           break;
     929             :         case 3:
     930          21 :           switch(q)
     931             :           {
     932           7 :             case 1: condp = 4;
     933           7 :               Ip->type = stack_sprintf("[III-II*{%ld}] page 178",(d-2)/4);
     934           7 :               Ip->neron = cyclic(8); break;
     935          14 :             case 3: condp = 3;
     936          14 :               Ip->type = stack_sprintf("[III*-II{%ld}] page 178",(d-2)/4);
     937          14 :               Ip->neron = cyclic(d/2); break;
     938           0 :             default: pari_err_BUG("tame2 [bug14]");
     939             :           }
     940          21 :           break;
     941           0 :         default: pari_err_BUG("tame2 [bug15]");
     942             :       }
     943          42 :       break;
     944             :     case 6:
     945           7 :       switch(r)
     946             :       {
     947           7 :         case 2: condp = 4;
     948           7 :           Ip->type = stack_sprintf("[II*-II*{%ld}] page 176", (d-4)/6);
     949           7 :           Ip->neron = groupH((d+2)/6); break;
     950           0 :         case 4: condp = 4;
     951           0 :           Ip->type = stack_sprintf("[II-II*{%ld}] page 176", (d-2)/6);
     952           0 :           Ip->neron = groupH((d+4)/6); break;
     953             :           break;
     954           0 :         default: pari_err_BUG("tame2 [bug16]");
     955             :       }
     956           7 :       break;
     957           0 :     default: pari_err_BUG("tame2 [bug17]");
     958             :   }
     959          91 :   return condp;
     960             : }
     961             : 
     962             : /* Ip->tt = 3 */
     963             : static long
     964          56 : tame_3(struct igusa *I, struct igusa_p *Ip, long v12)
     965             : {
     966          56 :   long condp = -1, n, q, r, flc;
     967             :   long va5, d1, d2;
     968          56 :   GEN val = Ip->val, e1, e2;
     969          56 :   tame_234_init(I, Ip, v12, &n, &q, &r, &flc);
     970             : 
     971          56 :   va5 = 2*val[6]-5*val[3];
     972          56 :   e1 = gmin(stoi(val[7]-3*val[3]),gmul2n(stoi(va5),-2));
     973          56 :   e2 = gsub(gmul2n(stoi(va5),-1),e1);
     974          56 :   d1 = itos(gmulsg(n,e1));
     975          56 :   d2 = itos(gmulsg(n,e2));
     976          56 :   switch(n)
     977             :   {
     978          14 :     case 1: condp = 2;
     979          14 :       Ip->type = stack_sprintf("[I{%ld-%ld-0}] page 179", d1,d2);
     980          14 :       Ip->neron = dicyclic(d1,d2); break;
     981             :     case 2:
     982          28 :       switch(r)
     983             :       {
     984          14 :         case 0: condp = 4;
     985          14 :           Ip->type = stack_sprintf("[I*{%ld-%ld-0}] page 180", d1/2,d2/2);
     986          14 :           Ip->neron = gconcat(groupH(d1/2),groupH(d2/2)); break;
     987             :         case 1:
     988          14 :           switch(flc)
     989             :           {
     990          14 :             case 1:condp = 3;
     991          14 :               Ip->type = stack_sprintf("[2I{%ld}-0] page 181", d1);
     992          14 :               Ip->neron = cyclic(d1); break;
     993           0 :             case 2: condp = 3;
     994           0 :               Ip->type = stack_sprintf("[II{%ld-%ld}] page 182",d1/2,d2/2);
     995           0 :               if ((d1*d2-4)&7)
     996           0 :                 Ip->neron = cyclic(2*d1);
     997             :               else
     998           0 :                 Ip->neron = dicyclic(d1,2);
     999             :               /* FIXME: "or" same with d1<->d2 */
    1000           0 :               break;
    1001             :           }
    1002          14 :           break;
    1003           0 :         default: pari_err_BUG("tame3 [bug20]");
    1004             :       }
    1005          28 :       break;
    1006          14 :     case 4: condp = 4;
    1007          14 :       Ip->type = stack_sprintf("[III{%ld}] page 182", d1/2);
    1008          14 :       Ip->neron = groupH(d1/2); break;
    1009           0 :     default: pari_err_BUG("tame3 [bug21]");
    1010             :   }
    1011          56 :   return condp;
    1012             : }
    1013             : 
    1014             : /* Ip->tt = 4 */
    1015             : static long
    1016          56 : tame_4(struct igusa *I, struct igusa_p *Ip, long v12)
    1017             : {
    1018          56 :   long condp = -1, d1, d2, d3, f1, f2, g, h, n, q, r, flc;
    1019          56 :   GEN val = Ip->val, e1, e2, e3, vl, vn, vm;
    1020          56 :   tame_234_init(I, Ip, v12, &n, &q, &r, &flc);
    1021          56 :   vl = stoi(val[6]-5*val[1]);
    1022          56 :   vn = stoi(val[7]-6*val[1]);
    1023          56 :   vm = stoi(val[2]-2*val[1]);
    1024          56 :   e1 = gmin3(gdivgs(vl,3), gmul2n(vn,-1), vm);
    1025          56 :   e2 = gmin(gmul2n(gsub(vl,e1),-1), gsub(vn,e1));
    1026          56 :   e3 = gsub(vl,gadd(e1,e2));
    1027          56 :   d1 = itos(gmulsg(n,e1));
    1028          56 :   d2 = itos(gmulsg(n,e2));
    1029          56 :   d3 = itos(gmulsg(n,e3));
    1030          56 :   g = d1*d2 + d1*d3 + d2*d3;
    1031          56 :   h = cgcd(cgcd(d1,d2),d3);
    1032          56 :   switch(n)
    1033             :   {
    1034           7 :     case 1: condp = 2;
    1035           7 :       Ip->type = stack_sprintf("[I{%ld-%ld-%ld}] page 182",d1,d2,d3);
    1036           7 :       Ip->neron = dicyclic(h,g/h); break;
    1037             :     case 2:
    1038          49 :       switch(r)
    1039             :       {
    1040           7 :         case 0: condp = 4;
    1041           7 :           Ip->type = stack_sprintf("[I*{%ld-%ld-%ld}] page 183",d1/2,d2/2,d3/2);
    1042           7 :           Ip->neron = gconcat(groupH(g/4), groupH(2-((h&2)>>1))); break;
    1043             :         case 1:
    1044          42 :           if      (d1 == d2 || d1 == d3) f2 = d1;
    1045           0 :           else if (d2 == d3) f2 = d2;
    1046             :           else {
    1047           0 :             pari_err_BUG("tame4 [bug23]");
    1048           0 :             return -1; /*not reached*/
    1049             :           }
    1050          42 :           f1 = d1+d2+d3-2*f2;
    1051          42 :           switch(q)
    1052             :           {
    1053          14 :             case 0: condp = 3;
    1054          14 :               Ip->type = stack_sprintf("[II*{%ld-%ld}] page 184", f1/2,f2);
    1055          14 :               Ip->neron = cyclic(f2); break;
    1056          28 :             case 1: condp = 3;
    1057          28 :               Ip->type = stack_sprintf("[II{%ld-%ld}] page 183", f1/2,f2);
    1058          28 :               Ip->neron = cyclic(2*f1+f2); break;
    1059           0 :             default: pari_err_BUG("tame4 [bug24]");
    1060             :           }
    1061          42 :           break;
    1062           0 :         default: pari_err_BUG("tame4 [bug25]");
    1063             :       }
    1064          49 :       break;
    1065           0 :     case 3: condp = 4;
    1066           0 :       Ip->type = stack_sprintf("[III{%ld}] page 184",d1);
    1067           0 :       Ip->neron = (d1%3)? cyclic(9): dicyclic(3,3); break;
    1068           0 :     case 6: condp = 4;
    1069           0 :       Ip->type = stack_sprintf("[III*{%ld}] page 184",d1/2);
    1070           0 :       Ip->neron = cyclic(1); break;
    1071           0 :     default: pari_err_BUG("tame4 [bug26]");
    1072             :   }
    1073          56 :   return condp;
    1074             : }
    1075             : 
    1076             : /* p = 3 */
    1077             : static void
    1078          91 : tame_567_init_3(struct igusa_p *Ip, GEN dk,
    1079             :                 long *pd, long *pn, long *pdm, long *pr)
    1080             : {
    1081          91 :   long n = 1 + Ip->r1/6;
    1082          91 :   *pd = itos(gmulgs(dk,n));
    1083          91 :   *pn = n;
    1084          91 :   *pr = -1; /* unused */
    1085          91 :   *pdm = 0;
    1086          91 : }
    1087             : 
    1088             : static void
    1089         609 : tame_567_init(struct igusa *I, struct igusa_p *Ip, GEN dk,
    1090             :               long *pd, long *pn, long *pdm, long *pr)
    1091             : {
    1092             :   long va0, va2, va3, va5, vb2;
    1093             :   long d, v1, v2;
    1094             :   GEN r, n, m;
    1095             :   GEN pro1, dm, rk;
    1096         609 :   GEN p = Ip->p, val = Ip->val;
    1097             :   long v5;
    1098             : 
    1099         609 :   if (equalis(p, 3)) { tame_567_init_3(Ip, dk, pd, pn, pdm, pr); return; }
    1100             :   /* assume p > 3 */
    1101         518 :   va0 = myval(I->a0,p);
    1102         518 :   va2 = myval(I->A2,p);
    1103         518 :   va3 = myval(I->A3,p);
    1104         518 :   va5 = myval(I->A5,p);
    1105         518 :   vb2 = myval(I->B2,p);
    1106         518 :   v5 = myval(subii(mulii(I->A2,I->A3),mulsi(3,I->A5)),p);
    1107        1036 :   rk = gadd(frac2s(va0, 2),
    1108             :             gmin3(gmul2n(dk,-1),
    1109         518 :                   frac2s(2*va3-3*va2, 8),
    1110         518 :                   frac2s(2*v5 - 5*va2, 12)));
    1111         518 :   v1 = 2*va3-4*va0-val[1];
    1112         518 :   v2 = 6*va5-20*va0-5*val[1];
    1113             :   /* the definition of n differs according to the parity of val[1] */
    1114         518 :   if (! odd(val[Ip->eps2]))
    1115             :   {
    1116         427 :     if (3*vb2 >= 2*va0+2*val[1] && v1 >= 0 && v2 >= 0
    1117         245 :                                 && (v1 == 0 || v2 == 0))
    1118             :     { /* Prop 4.3.1 (a) */
    1119          14 :       pro1 = frac2s(va0+val[1], 6);
    1120          14 :       n = lcmii(denom(dk),denom(pro1));
    1121          14 :       r = gmul(n,pro1);
    1122             :     }
    1123         413 :     else if (20*va0+5*val[1] > 6*va5 && 10*vb2 >= 2*va5+5*val[1])
    1124             :     { /* Prop 4.3.1 (b) */
    1125         182 :       pro1 = frac2s(2*va5+val[1], 8);
    1126         182 :       n = lcmii(denom(dk),denom(pro1));
    1127         182 :       r = gmul(n,pro1);
    1128             :     }
    1129         231 :     else if (2*va0+2*val[1] > 3*vb2 && 2*va5+5*val[1] > 10*vb2)
    1130             :     { /* Prop 4.3.1 (c) */
    1131           0 :       pro1 = gmul2n(stoi(vb2),-2);
    1132           0 :       n = lcmii(denom(dk),denom(pro1));
    1133           0 :       r = gmul(n,pro1);
    1134             :     }
    1135         231 :     else if (3*vb2 >= 2*va0+2*val[1] && 2*va3 > 4*va0+val[1]
    1136         231 :                                      && 6*va5 > 20*va0+5*val[1])
    1137             :     { /* Prop 4.3.1 (d) */
    1138         231 :       if (gequal0(I->A2)) pari_err_BUG("tame567 [bug27]");
    1139         231 :       n = lcmii(denom(dk),denom(rk));
    1140         231 :       r = gmul(n,rk);
    1141             :     }
    1142             :     else
    1143             :     {
    1144           0 :       pari_err_BUG("tame567 [bug29]");
    1145           0 :       return; /*not reached*/
    1146             :     }
    1147             :   }
    1148             :   else
    1149             :   {
    1150          91 :     m = denom(dk);
    1151          91 :     r = gmul(m,dk);
    1152          91 :     n = gmul2n(m,1);
    1153             :   }
    1154         518 :   d = itos(gmul(n,dk));
    1155         518 :   dm = modsi(d,n);
    1156         518 :   r = modii(r,n);
    1157         518 :   *pd = d;
    1158         518 :   *pn = itos(n);
    1159         518 :   *pr = itos(r);
    1160         518 :   *pdm = itos(dm);
    1161             : }
    1162             : 
    1163             : static long
    1164         329 : tame_5(struct igusa *I, struct igusa_p *Ip, GEN dk)
    1165             : {
    1166         329 :   long condp = -1, d, n, dm, r;
    1167         329 :   GEN val = Ip->val;
    1168             : 
    1169         329 :   tame_567_init(I, Ip, dk, &d, &n, &dm, &r);
    1170         329 :   if (! odd(val[Ip->eps2]))
    1171             :   {
    1172         266 :     switch(n)
    1173             :     {
    1174           7 :       case 1: condp = 0;
    1175           7 :         Ip->type = stack_sprintf("[I{0}-I{0}-%ld] page 158", d);
    1176           7 :         Ip->neron = cyclic(1); break;
    1177             :       case 2:
    1178          14 :         switch(dm)
    1179             :         {
    1180           7 :           case 0: condp = 4;
    1181           7 :             Ip->type = stack_sprintf("[I*{0}-I*{0}-%ld] page 158",(d-2)/2);
    1182           7 :             Ip->neron = mkvecsmall4(2,2,2,2); break;
    1183           7 :           case 1: condp = 2;
    1184           7 :             Ip->type = stack_sprintf("[I{0}-I*{0}-%ld] page 159",(d-1)/2);
    1185           7 :             Ip->neron = dicyclic(2,2); break;
    1186             :         }
    1187          14 :         break;
    1188             :       case 3:
    1189          35 :         switch(dm)
    1190             :         {
    1191           7 :           case 0: condp = 4;
    1192           7 :             Ip->type = stack_sprintf("[IV-IV*-%ld] page 165",(d-3)/3);
    1193           7 :             Ip->neron = dicyclic(3,3); break;
    1194             :           case 1:
    1195          14 :             switch(r)
    1196             :             {
    1197           7 :               case 0: case 1: condp = 2;
    1198           7 :                 Ip->type = stack_sprintf("[I{0}-IV-%ld] page 160",(d-1)/3);
    1199           7 :                 Ip->neron = cyclic(3); break;
    1200           7 :               case 2: condp = 4;
    1201           7 :                 Ip->type = stack_sprintf("[IV*-IV*-%ld] page 166",(d-4)/3);
    1202           7 :                 Ip->neron = dicyclic(3,3); break;
    1203             :             }
    1204          14 :             break;
    1205             :           case 2:
    1206          14 :             switch(r)
    1207             :             {
    1208           7 :               case 0: case 2: condp = 2;
    1209           7 :                 Ip->type = stack_sprintf("[I{0}-IV*-%ld] page 160",(d-2)/3);
    1210           7 :                 Ip->neron = cyclic(3); break;
    1211           7 :               case 1: condp = 4;
    1212           7 :                 Ip->type = stack_sprintf("[IV-IV-%ld] page 165",(d-2)/3);
    1213           7 :                 Ip->neron = dicyclic(3,3); break;
    1214             :             }
    1215          14 :             break;
    1216             :         }
    1217          35 :         break;
    1218             :       case 4:
    1219          49 :         switch(dm)
    1220             :         {
    1221           7 :           case 0: condp = 4;
    1222           7 :             Ip->type = stack_sprintf("[III-III*-%ld] page 169",(d-4)/4);
    1223           7 :             Ip->neron = dicyclic(2,2); break;
    1224             :           case 1:
    1225          14 :             switch(r)
    1226             :             {
    1227           7 :               case 0: case 1: condp = 2;
    1228           7 :                 Ip->type = stack_sprintf("[I{0}-III-%ld] page 161",(d-1)/4);
    1229           7 :                 Ip->neron = cyclic(2); break;
    1230           7 :               case 2: case 3: condp = 4;
    1231           7 :                 Ip->type = stack_sprintf("[I*{0}-III*-%ld] page 162",(d-5)/4);
    1232           7 :                 Ip->neron = mkvecsmall3(2,2,2); break;
    1233             :             }
    1234          14 :             break;
    1235          14 :           case 2: condp = 4;
    1236          14 :             Ip->neron = dicyclic(2,2);
    1237          14 :             switch(r)
    1238             :             {
    1239             :               case 1:
    1240           7 :                 Ip->type = stack_sprintf("[III-III-%ld] page 169",(d-2)/4);
    1241           7 :                 break;
    1242             :               case 3:
    1243           7 :                 Ip->type = stack_sprintf("[III*-III*-%ld] page 169",(d-6)/4);
    1244           7 :                 break;
    1245           0 :               default: pari_err_BUG("tame5 [bug29]");
    1246             :             }
    1247          14 :             break;
    1248             :           case 3:
    1249          14 :             switch(r)
    1250             :             {
    1251           7 :               case 0: case 3: condp = 2;
    1252           7 :                 Ip->type = stack_sprintf("[I{0}-III*-%ld] page 162",(d-3)/4);
    1253           7 :                 Ip->neron = cyclic(2); break;
    1254           7 :               case 1: case 2: condp = 4;
    1255           7 :                 Ip->type = stack_sprintf("[I*{0}-III-%ld] page 162",(d-3)/4);
    1256           7 :                 Ip->neron = mkvecsmall3(2,2,2); break;
    1257             :             }
    1258          14 :             break;
    1259             :         }
    1260          49 :         break;
    1261             :       case 6:
    1262         105 :         switch(dm)
    1263             :         {
    1264           7 :           case 0: condp = 4;
    1265           7 :             Ip->type = stack_sprintf("[II-II*-%ld] page 163",(d-6)/6);
    1266           7 :             Ip->neron = cyclic(1); break;
    1267             :           case 1:
    1268          21 :             switch(r)
    1269             :             {
    1270           7 :               case 0: case 1: condp = 2;
    1271           7 :                 Ip->type = stack_sprintf("[I{0}-II-%ld] page 159",(d-1)/6);
    1272           7 :                 Ip->neron = cyclic(1); break;
    1273           7 :               case 2: case 5: condp = 4;
    1274           7 :                 Ip->type = stack_sprintf("[II*-IV-%ld] page 164",(d-7)/6);
    1275           7 :                 Ip->neron = cyclic(3); break;
    1276           7 :               case 3: case 4: condp = 4;
    1277           7 :                 Ip->type = stack_sprintf("[I*{0}-IV*-%ld] page 161",(d-7)/6);
    1278           7 :                 Ip->neron = mkvecsmall2(6,2); break;
    1279             :             }
    1280          21 :             break;
    1281             :           case 2:
    1282          21 :             switch(r)
    1283             :             {
    1284          14 :               case 1: condp = 4;
    1285          14 :                 Ip->type = stack_sprintf("[II-II-%ld] page 163",(d-2)/6);
    1286          14 :                 Ip->neron = cyclic(1); break;
    1287           7 :               case 3: case 5: condp = 4;
    1288           7 :                 Ip->type = stack_sprintf("[I*{0}-II*-%ld] page 160",(d-8)/6);
    1289           7 :                 Ip->neron = dicyclic(2,2); break;
    1290           0 :               default: pari_err_BUG("tame5 [bug30]");
    1291             :             }
    1292          21 :             break;
    1293             :           case 3:
    1294          14 :             Ip->neron = cyclic(3);
    1295          14 :             switch(r)
    1296             :             {
    1297           7 :               case 1: case 2: condp = 4;
    1298           7 :                 Ip->type = stack_sprintf("[II-IV-%ld] page 164",(d-3)/6);
    1299           7 :                 break;
    1300           7 :               case 4: case 5: condp = 4;
    1301           7 :                 Ip->type = stack_sprintf("[II*-IV*-%ld] page 164",(d-9)/6);
    1302           7 :                 break;
    1303           0 :               default: pari_err_BUG("tame5 [bug31]");
    1304             :             }
    1305          14 :             break;
    1306             :           case 4:
    1307          21 :             switch(r)
    1308             :             {
    1309           7 :               case 1: case 3: condp = 4;
    1310           7 :                 Ip->type = stack_sprintf("[I*{0}-II-%ld] page 160",(d-4)/6);
    1311           7 :                 Ip->neron = dicyclic(2,2); break;
    1312          14 :               case 5: condp = 4;
    1313          14 :                 Ip->type = stack_sprintf("[II*-II*-%ld] page 163",(d-10)/6);
    1314          14 :                 Ip->neron = cyclic(1); break;
    1315           0 :               default: pari_err_BUG("tame5 [bug32]");
    1316             :             }
    1317          21 :             break;
    1318             :           case 5:
    1319          21 :             switch(r)
    1320             :             {
    1321           7 :               case 0: case 5: condp = 2;
    1322           7 :                 Ip->type = stack_sprintf("[I{0}-II*-%ld] page 160",(d-5)/6);
    1323           7 :                 Ip->neron = cyclic(1); break;
    1324           7 :               case 1: case 4: condp = 4;
    1325           7 :                 Ip->type = stack_sprintf("[II-IV*-%ld] page 164",(d-5)/6);
    1326           7 :                 Ip->neron = cyclic(3); break;
    1327           7 :               case 2: case 3: condp = 4;
    1328           7 :                 Ip->type = stack_sprintf("[I*{0}-IV-%ld] page 161",(d-5)/6);
    1329           7 :                 Ip->neron = mkvecsmall2(6,2); break;
    1330             :             }
    1331          21 :             break;
    1332           0 :           default: pari_err_BUG("tame5 [bug33]");
    1333             :         }
    1334         105 :         break;
    1335             :       case 12:
    1336          56 :         condp = 4;
    1337          56 :         switch(dm)
    1338             :         {
    1339             :           case 1:
    1340          14 :             switch(r)
    1341             :             {
    1342             :               case 3: case 10:
    1343           7 :                 Ip->type = stack_sprintf("[II*-III-%ld] page 166",(d-13)/12);
    1344           7 :                 Ip->neron = cyclic(2); break;
    1345             :               case 4: case 9:
    1346           7 :                 Ip->type = stack_sprintf("[IV-III*-%ld] page 167",(d-13)/12);
    1347           7 :                 Ip->neron = cyclic(6); break;
    1348           0 :               default: pari_err_BUG("tame5 [bug34]");
    1349             :             }
    1350          14 :             break;
    1351             :           case 5:
    1352          14 :             switch(r)
    1353             :             {
    1354             :               case 2: case 3:
    1355           7 :                 Ip->type = stack_sprintf("[II-III-%ld] page 166",(d-5)/12);
    1356           7 :                 Ip->neron = cyclic(2); break;
    1357             :               case 8: case 9:
    1358           7 :                 Ip->type = stack_sprintf("[IV*-III*-%ld] page 168",(d-17)/12);
    1359           7 :                 Ip->neron = cyclic(6); break;
    1360           0 :               default: pari_err_BUG("tame5 [bug35]");
    1361             :             }
    1362          14 :             break;
    1363             :           case 7:
    1364          14 :             switch(r)
    1365             :             {
    1366             :               case 3: case 4:
    1367           7 :                 Ip->type = stack_sprintf("[IV-III-%ld] page 167",(d-7)/12);
    1368           7 :                 Ip->neron = cyclic(6); break;
    1369             :               case 9: case 10:
    1370           7 :                 Ip->type = stack_sprintf("[II*-III*-%ld] page 167",(d-19)/12);
    1371           7 :                 Ip->neron = cyclic(2); break;
    1372           0 :               default: pari_err_BUG("tame5 [bug36]");
    1373             :             }
    1374          14 :             break;
    1375             :           case 11:
    1376          14 :             switch(r)
    1377             :             {
    1378             :               case 3: case 8:
    1379           7 :                 Ip->type = stack_sprintf("[IV*-III-%ld] page 168",(d-11)/12);
    1380           7 :                 Ip->neron = cyclic(6); break;
    1381             :               case 2: case 9:
    1382           7 :                 Ip->type = stack_sprintf("[II-III*-%ld] page 166",(d-11)/12);
    1383           7 :                 Ip->neron = cyclic(2); break;
    1384           0 :               default: pari_err_BUG("tame5 [bug37]");
    1385             :             }
    1386          14 :             break;
    1387           0 :           default: pari_err_BUG("tame5 [bug38]");
    1388             :         }
    1389          56 :         break;
    1390           0 :       default: pari_err_BUG("tame5 [bug39]");
    1391             :     }
    1392             :   }
    1393             :   else
    1394             :   {
    1395          63 :     r %= (n >> 1);
    1396          63 :     switch(n)
    1397             :     {
    1398           7 :       case 2: condp = 2;
    1399           7 :         Ip->type = stack_sprintf("[2I{0}-%ld] page 159",(d/2));
    1400           7 :         Ip->neron = cyclic(1); break;
    1401          14 :       case 4: condp = 4;
    1402          14 :         Ip->type = stack_sprintf("[2I*{0}-%ld] page 159",(d/2-1)/2);
    1403          14 :         Ip->neron = dicyclic(2,2); break;
    1404          14 :       case 6: condp = 4;
    1405          14 :         Ip->neron = cyclic(3);
    1406          14 :         switch(r)
    1407             :           {
    1408             :           case 1:
    1409           7 :             Ip->type = stack_sprintf("[2IV-%ld] page 165",(d/2-1)/3);
    1410           7 :             break;
    1411             :           case 2:
    1412           7 :             Ip->type = stack_sprintf("[2IV*-%ld] page 165",(d/2-2)/3);
    1413           7 :             break;
    1414           0 :           default: pari_err_BUG("tame5 [bug40]");
    1415             :           }
    1416          14 :         break;
    1417          14 :       case 8: condp = 4;
    1418          14 :         Ip->neron = cyclic(2);
    1419          14 :         switch(r)
    1420             :         {
    1421             :           case 1:
    1422           7 :             Ip->type = stack_sprintf("[2III-%ld] page 168",(d/2-1)/4);
    1423           7 :             break;
    1424             :           case 3:
    1425           7 :             Ip->type = stack_sprintf("[2III*-%ld] page 168",(d/2-3)/4);
    1426           7 :             break;
    1427           0 :           default: pari_err_BUG("tame5 [bug41]");
    1428             :         }
    1429          14 :         break;
    1430          14 :       case 12: condp = 4;
    1431          14 :         Ip->neron = cyclic(1);
    1432          14 :         switch(r)
    1433             :         {
    1434             :           case 1:
    1435           7 :             Ip->type = stack_sprintf("[2II-%ld] page 162",(d/2-1)/6);
    1436           7 :             break;
    1437             :           case 5:
    1438           7 :             Ip->type = stack_sprintf("[2II*-%ld] page 163",(d/2-5)/6);
    1439           7 :             break;
    1440           0 :           default: pari_err_BUG("tame5 [bug42]");
    1441             :         }
    1442          14 :         break;
    1443           0 :       default: pari_err_BUG("tame5 [bug43]");
    1444             :     }
    1445             :   }
    1446         329 :   return condp;
    1447             : }
    1448             : 
    1449             : static long
    1450         189 : tame_6(struct igusa *I, struct igusa_p *Ip, GEN dk,
    1451             :          GEN polh, GEN theta, long alpha, long dismin)
    1452             : {
    1453         189 :   long condp = -1, d, d1, n, dm, r;
    1454         189 :   GEN val = Ip->val, d1k;
    1455             : 
    1456         189 :   tame_567_init(I, Ip, dk, &d, &n, &dm, &r);
    1457         189 :   d1k = frac2s(Ip->eps*(val[6]-val[7])+val[Ip->eps2], Ip->eps);
    1458         189 :   d1 = itos(gmulsg(n,d1k));
    1459         189 :   switch(n)
    1460             :   {
    1461          56 :     case 1: condp = 1;
    1462          56 :       Ip->type = stack_sprintf("[I{%ld}-I{0}-%ld] page 170",d1,d);
    1463          56 :       Ip->neron = cyclic(d1); break;
    1464             :     case 2:
    1465          28 :       switch(dm)
    1466             :       {
    1467           7 :         case 0: condp = 4;
    1468           7 :           Ip->type=stack_sprintf("[I*{0}-I*{%ld}-%ld] page 171", d1/2,(d-2)/2);
    1469           7 :           Ip->neron = gconcat(groupH(d1/2), dicyclic(2,2)); break;
    1470          21 :         case 1: return labelm3(polh,theta,alpha,dismin,I,Ip);
    1471           0 :         default: pari_err_BUG("tame6 [bug44]");
    1472             :       }
    1473           7 :       break;
    1474          14 :     case 3: condp = 3;
    1475          14 :       Ip->neron = dicyclic(3,d1/3);
    1476          14 :       switch(dm)
    1477             :       {
    1478             :         case 1:
    1479           7 :           Ip->type = stack_sprintf("[IV-I{%ld}-%ld] page 173",d1/3,(d-1)/3);
    1480           7 :           break;
    1481             :         case 2:
    1482           7 :           Ip->type = stack_sprintf("[IV*-I{%ld}-%ld] page 173",d1/3,(d-2)/3);
    1483           7 :           break;
    1484           0 :         default: pari_err_BUG("tame6 [bug45]");
    1485             :       }
    1486          14 :       break;
    1487             :     case 4:
    1488          35 :       switch(dm)
    1489             :       {
    1490             :         case 1:
    1491          21 :           switch(r)
    1492             :           {
    1493           7 :             case 0: case 1: condp = 3;
    1494           7 :               Ip->type=stack_sprintf("[III-I{%ld}-%ld] page 176",d1/4,(d-1)/4);
    1495           7 :               Ip->neron = dicyclic(2,d1/4); break;
    1496          14 :             case 2: case 3: condp = 4;
    1497          14 :               Ip->type=stack_sprintf("[III*-I*{%ld}-%ld] page 177",d1/4,(d-5)/4);
    1498          14 :               Ip->neron = gconcat(groupH(d1/4), cyclic(2)); break;
    1499             :               break;
    1500           0 :             default: pari_err_BUG("tame6 [bug46]");
    1501             :           }
    1502          21 :           break;
    1503             :         case 3:
    1504          14 :           switch(r)
    1505             :           {
    1506           7 :             case 0: case 3: condp = 3;
    1507           7 :               Ip->type=stack_sprintf("[III*-I{%ld}-%ld] page 176",d1/4,(d-3)/4);
    1508           7 :               Ip->neron = dicyclic(2,d1/4); break;
    1509           7 :             case 1: case 2: condp = 4;
    1510           7 :               Ip->type=stack_sprintf("[III-I*{%ld}-%ld] page 177",d1/4,(d-3)/4);
    1511           7 :               Ip->neron = gconcat(groupH(d1/4), cyclic(2)); break;
    1512           0 :             default: pari_err_BUG("tame6 [bug47]");
    1513             :           }
    1514          14 :           break;
    1515           0 :         default: pari_err_BUG("tame6 [bug48]");
    1516             :       }
    1517          35 :       break;
    1518             :     case 6:
    1519          56 :       switch(dm)
    1520             :       {
    1521             :         case 1:
    1522          21 :           switch(r)
    1523             :           {
    1524           7 :             case 0: case 1: condp = 3;
    1525           7 :               Ip->type = stack_sprintf("[II-I{%ld}-%ld] page 172",d1/6,(d-1)/6);
    1526           7 :               Ip->neron = cyclic(d1/6); break;
    1527          14 :             case 3: case 4: condp = 4;
    1528          14 :               Ip->type=stack_sprintf("[IV*-I*{%ld}-%ld] page 174",d1/6,(d-7)/6);
    1529          14 :               Ip->neron = gconcat(groupH(d1/6), cyclic(3)); break;
    1530           0 :             default: pari_err_BUG("tame6 [bug49]");
    1531             :           }
    1532          21 :           break;
    1533          14 :         case 2: condp = 4;
    1534          14 :           Ip->type = stack_sprintf("[II*-I*{%ld}-%ld] page 174",d1/6,(d-8)/6);
    1535          14 :           Ip->neron = groupH(d1/6); break;
    1536           7 :         case 4: condp = 4;
    1537           7 :           Ip->type = stack_sprintf("[II-I*{%ld}-%ld] page 173",d1/6,(d-4)/6);
    1538           7 :           Ip->neron = groupH(d1/6); break;
    1539             :         case 5:
    1540          14 :           switch(r)
    1541             :           {
    1542           7 :             case 0: case 5: condp = 3;
    1543           7 :               Ip->type=stack_sprintf("[II*-I{%ld}-%ld] page 172",d1/6,(d-5)/6);
    1544           7 :               Ip->neron = cyclic(d1/6); break;
    1545           7 :             case 2: case 3: condp = 4;
    1546           7 :               Ip->type=stack_sprintf("[IV-I*{%ld}-%ld] page 174",d1/6,(d-5)/6);
    1547           7 :               Ip->neron = gconcat(groupH(d1/6), cyclic(3)); break;
    1548           0 :             default: pari_err_BUG("tame6 [bug50]");
    1549             :           }
    1550          14 :           break;
    1551           0 :         default: pari_err_BUG("tame6 [bug51]");
    1552             :       }
    1553          56 :       break;
    1554           0 :     default: pari_err_BUG("tame6 [bug52]");
    1555             :   }
    1556         168 :   return condp;
    1557             : }
    1558             : 
    1559             : static long
    1560          91 : tame_7(struct igusa *I, struct igusa_p *Ip, GEN dk,
    1561             :          GEN polh, GEN theta, long alpha, long dismin)
    1562             : {
    1563          91 :   long condp = -1, d, d1, d2, n, dm, r;
    1564          91 :   GEN val = Ip->val, d1k, d2k, pro1;
    1565             : 
    1566          91 :   tame_567_init(I, Ip, dk, &d, &n, &dm, &r);
    1567          91 :   pro1 = frac2s(Ip->eps*val[6]+val[Ip->eps2]-3*Ip->eps*val[3], Ip->eps);
    1568          91 :   d1k = gmin(stoi(val[7]-3*val[3]),gmul2n(pro1,-1));
    1569          91 :   d2k = gsub(pro1,d1k);
    1570             : 
    1571          91 :   d1 = itos(gmulsg(n,d1k));
    1572          91 :   d2 = itos(gmulsg(n,d2k));
    1573          91 :   switch(n)
    1574             :   {
    1575          42 :     case 1: condp = 2;
    1576          42 :       Ip->type = stack_sprintf("[I{%ld}-I{%ld}-%ld] page 179",d1,d2,d);
    1577          42 :       Ip->neron = dicyclic(d1,d2); break;
    1578             :     case 2:
    1579          35 :       if ( odd(val[Ip->eps2]) )
    1580             :       {
    1581          14 :         condp = 3;
    1582          14 :         Ip->type = stack_sprintf("[2I{%ld}-%ld] page 181",d1,d/2);
    1583          14 :         Ip->neron = cyclic(d1);
    1584             :       }
    1585          21 :       else if (dm == 0)
    1586             :       {
    1587          14 :         condp = 4;
    1588          14 :         Ip->type = stack_sprintf("[I*{%ld}-I*{%ld}-%ld] page 180", d1/2,d2/2,(d-2)/2);
    1589          14 :         Ip->neron = gconcat(groupH(d1/2),groupH(d2/2));
    1590             :       }
    1591             :       else
    1592             :       {
    1593             :         GEN H;
    1594           7 :         if (d1 != d2) return labelm3(polh,theta,alpha,dismin,I,Ip);
    1595           0 :         condp = 3; H = groupH(d1/2);
    1596           0 :         Ip->type = stack_sprintf("[I{%ld}-I*{%ld}-%ld] page 180", d1/2,d1/2,(d-1)/2);
    1597           0 :         Ip->neron = gconcat(H, H);
    1598             :       }
    1599          28 :       break;
    1600          14 :     case 4: condp = 4;
    1601          14 :       Ip->type = stack_sprintf("[2I*{%ld}-%ld] page 181",d1/2,(d-2)/4);
    1602          14 :       Ip->neron = groupH(d1/2); break;
    1603           0 :     default: pari_err_BUG("tame7 [bug55]");
    1604             :   }
    1605          84 :   return condp;
    1606             : }
    1607             : 
    1608             : static long
    1609         833 : tame(GEN polh, GEN theta, long alpha, long dismin, struct igusa *I, struct igusa_p *Ip)
    1610             : {
    1611         833 :   GEN val = Ip->val, dk;
    1612         833 :   Ip->tame = 1;
    1613         833 :   switch(Ip->tt)
    1614             :   {
    1615          21 :     case 1: return tame_1(I, Ip);
    1616          91 :     case 2: return tame_2(I, Ip, myval(I->i12,  Ip->p));
    1617          56 :     case 3: return tame_3(I, Ip, 3*myval(I->i4, Ip->p));
    1618          56 :     case 4: return tame_4(I, Ip, 6*myval(I->j2, Ip->p));
    1619             :     case 5:
    1620         329 :       dk = frac2s(Ip->eps*val[6]-5*val[Ip->eps2], 12*Ip->eps);
    1621         329 :       return tame_5(I, Ip, dk);
    1622             :     case 6:
    1623         189 :       dk = frac2s(Ip->eps*val[7]-6*val[Ip->eps2], 12*Ip->eps);
    1624         189 :       return tame_6(I, Ip, dk, polh, theta, alpha, dismin);
    1625             :     case 7:
    1626          91 :       dk = frac2s(Ip->eps*val[3]-2*val[Ip->eps2], 4*Ip->eps);
    1627          91 :       return tame_7(I, Ip, dk, polh, theta, alpha, dismin);
    1628             :   }
    1629           0 :   return -1; /*not reached*/
    1630             : }
    1631             : 
    1632             : /* maxc = maximum conductor valuation at p */
    1633             : static long
    1634         455 : get_maxc(GEN p)
    1635             : {
    1636         455 :   switch (itos_or_0(p))
    1637             :   {
    1638           0 :     case 2:  return 20; break;
    1639         266 :     case 3:  return 10; break;
    1640           7 :     case 5:  return 9; break;
    1641         182 :     default: return 4; break; /* p > 5 */
    1642             :   }
    1643             : }
    1644             : 
    1645             : /* p = 3 */
    1646             : static long
    1647          77 : quartic(GEN polh, long alpha, long dismin, struct igusa_p *Ip)
    1648             : {
    1649          77 :   GEN theta, val = Ip->val, p = Ip->p;
    1650          77 :   GEN polf = polymini_zi2(ZX_Z_mul(polh, powiu(p, alpha)));
    1651          77 :   long condp = -1, d, R, r1, beta;
    1652          77 :   theta = gel(polf,1);
    1653          77 :   beta = itos(gel(polf,2));
    1654          77 :   if (odd(beta)) pari_err_BUG("quartic [type over Z[i] must be [K-K-(2*m)]]");
    1655          77 :   R = beta/2;
    1656          77 :   r1 = itos(gmulgs(theta,6));
    1657          77 :   switch(Ip->tt)
    1658             :   {
    1659          63 :     case 1: case 5: d = 0;break;
    1660           0 :     case 3: d = val[6] - 5*val[3]/2;break;
    1661          14 :     case 7: d = val[6] - 3*val[3] + val[Ip->eps2]/Ip->eps;break;
    1662           0 :     default: pari_err_BUG("quartic [type choices]");
    1663           0 :              d = 0; /*not reached*/
    1664             :   }
    1665          77 :   switch(r1)
    1666             :   {
    1667             :     case 0:
    1668          21 :       if (d)
    1669             :       {
    1670           7 :         condp = 3;
    1671           7 :         Ip->type = stack_sprintf("[2I{%ld}-%ld] page 181",d,R);
    1672           7 :         Ip->neron = cyclic(d);
    1673             :       }
    1674             :       else
    1675             :       {
    1676          14 :         condp = 2;
    1677          14 :         Ip->neron = cyclic(1);
    1678          14 :         if (R) Ip->type = stack_sprintf("[2I{0}-%ld] page 159",R);
    1679           7 :         else   Ip->type = "[II] page 155";
    1680             :       }
    1681          21 :       break;
    1682           7 :     case 6: condp = 4;
    1683           7 :       Ip->type = stack_sprintf("[2I*{%ld}-%ld] pages 159, 181",d,R);
    1684           7 :       Ip->neron = dicyclic(2,2); break;
    1685           7 :     case 3: condp = 4;
    1686           7 :       Ip->type = stack_sprintf("[2III-%ld] page 168",R);
    1687           7 :       Ip->neron = cyclic(2); break;
    1688           7 :     case 9: condp = 4;
    1689           7 :       Ip->type = stack_sprintf("[2III*-%ld] page 168",R);
    1690           7 :       Ip->neron = cyclic(2); break;
    1691           7 :     case 2: condp = dismin-12*R-13;
    1692           7 :       Ip->type = stack_sprintf("[2II-%ld] page 162",R);
    1693           7 :       Ip->neron = cyclic(1); break;
    1694          14 :     case 8: condp = dismin-12*R-19;
    1695          14 :       Ip->type = stack_sprintf("[2IV*-%ld] page 165",R);
    1696          14 :       Ip->neron = cyclic(3); break;
    1697           7 :     case 4: condp = dismin-12*R-15;
    1698           7 :       Ip->type = stack_sprintf("[2IV-%ld] page 165",R);
    1699           7 :       Ip->neron = cyclic(3); break;
    1700           7 :     case 10: condp = dismin-12*R-21;
    1701           7 :       Ip->type = stack_sprintf("[2II*-%ld] page 163",R);
    1702           7 :       Ip->neron = cyclic(1); break;
    1703           0 :     default: pari_err_BUG("quartic [type1]");
    1704             :   }
    1705          77 :   if (condp > get_maxc(p) || condp < 0) pari_err_BUG("quartic [conductor]");
    1706          77 :   return condp;
    1707             : }
    1708             : 
    1709             : static long
    1710         252 : litredtp(long alpha, long alpha1, GEN theta, GEN theta1, GEN polh, GEN polh1,
    1711             :          long dismin, struct igusa *I, struct igusa_p *Ip)
    1712             : {
    1713         252 :   GEN val = Ip->val, p = Ip->p;
    1714         252 :   long condp = -1, indice, d, R = Ip->R;
    1715             : 
    1716         252 :   if ((Ip->r1 == 0||Ip->r1 == 6) && (Ip->r2 == 0||Ip->r2 == 6))
    1717             :   { /* (r1,r2) = (0,0), (0,6), (6,0) or (6,6) */
    1718         154 :     if (Ip->tt == 5)
    1719             :     {
    1720          21 :       switch(Ip->r1 + Ip->r2)
    1721             :       {
    1722             :       case 0: /* (0,0) */
    1723           7 :         condp = 0;
    1724           7 :         Ip->type = stack_sprintf("[I{0}-I{0}-%ld] page 158",R);
    1725           7 :         Ip->neron = cyclic(1); break;
    1726             :       case 6: /* (0,6) or (6,0) */
    1727           7 :         condp = 2;
    1728           7 :         Ip->type = stack_sprintf("[I*{0}-I{0}-%ld] page 159",R);
    1729           7 :         Ip->neron = dicyclic(2,2); break;
    1730             :       case 12: /* (6,6) */
    1731           7 :         condp = 4;
    1732           7 :         Ip->type = stack_sprintf("[I*{0}-I*{0}-%ld] page 158",R);
    1733           7 :         Ip->neron = mkvecsmall4(2,2,2,2); break;
    1734             :       }
    1735          21 :       return condp;
    1736             :     }
    1737         133 :     if (Ip->r1 == Ip->r2) return tame(polh, theta, alpha, dismin, I, Ip);
    1738          42 :     if (Ip->tt == 6)
    1739             :     {
    1740          28 :       d = val[6] - val[7] + (val[Ip->eps2]/Ip->eps);
    1741          28 :       if (Ip->r1 && alpha1 == 0) /* H(px) / p^3 */
    1742          21 :         polh1 = RgX_Rg_div(RgX_unscale(polh1,p), powiu(p,3));
    1743          28 :       if (FpX_is_squarefree(FpX_red(polh1,p),p))
    1744           7 :       { indice = 0; condp = 3-Ip->r2/6; }
    1745             :       else
    1746          21 :       { indice = d; condp = 3-Ip->r1/6; }
    1747             :     }
    1748             :     else
    1749             :     { /* Ip->tt == 7 */
    1750             :       long d1;
    1751          14 :       d = val[6] - 3*val[3] + (val[Ip->eps2]/Ip->eps);
    1752          14 :       if (gequal1(theta1)) /* H(px) / p^3 */
    1753          14 :         polh1 = RgX_Rg_div(RgX_unscale(polh1,p), powiu(p,3));
    1754          14 :       d1 = minss(val[7]-3*val[3],d/2);
    1755          14 :       if (d == 2*d1) indice = d1;
    1756             :       else
    1757             :       {
    1758          14 :         indice = discpart(polh1,p,d1+1);
    1759          14 :         if (indice>= d1+1) indice = d-d1;
    1760          14 :         else indice = d1;
    1761             :       }
    1762          14 :       condp = 3;
    1763             :     }
    1764          42 :     if (Ip->r1)
    1765             :     { /* (6,0) */
    1766          35 :       Ip->neron = gconcat(cyclic(d-indice),groupH(indice));
    1767          35 :       if (Ip->tt == 6)
    1768          21 :         Ip->type = stack_sprintf("[I*{%ld}-I{%ld}-%ld] page 170",indice,d-indice,R);
    1769             :       else
    1770          14 :         Ip->type = stack_sprintf("[I*{%ld}-I{%ld}-%ld] page 180",indice,d-indice,R);
    1771             :     }
    1772             :     else
    1773             :     { /* (0,6) */
    1774           7 :       Ip->neron = gconcat(cyclic(indice),groupH(d-indice));
    1775           7 :       if (Ip->tt == 6)
    1776           7 :         Ip->type = stack_sprintf("[I{%ld}-I*{%ld}-%ld] page 170", indice,d-indice,R);
    1777             :       else
    1778           0 :         Ip->type = stack_sprintf("[I{%ld}-I*{%ld}-%ld] page 180", indice,d-indice,R);
    1779             :     }
    1780          42 :     return condp;
    1781             :   }
    1782          98 :   if (Ip->tt == 7) pari_err_BUG("litredtp [switch ri]");
    1783             :   {
    1784             :     struct red S1, S;
    1785         196 :     long comp = get_red(&S1, Ip, polh1, p, alpha1, Ip->r1)
    1786          98 :               + get_red(&S,  Ip, polh, p, alpha, Ip->r2);
    1787          98 :     Ip->type = stack_sprintf("[%s-%s-%ld] pages %s", S1.t, S.t, R, S.pages);
    1788          98 :     Ip->neron = gconcat(S1.g, S.g);
    1789          98 :     condp = (R >= 0)? dismin-comp+2-12*R: dismin-comp+4;
    1790             :   }
    1791          98 :   if (condp > get_maxc(p)) pari_err_BUG("litredtp [conductor]");
    1792          98 :   return condp;
    1793             : }
    1794             : 
    1795             : static long
    1796         231 : labelm3(GEN polh, GEN theta, long alpha, long dismin,
    1797             :         struct igusa *I, struct igusa_p *Ip)
    1798             : {
    1799         231 :   GEN polh1, theta1, polf, val = Ip->val, p = Ip->p;
    1800             :   long alpha1, lambda, beta, R;
    1801             : 
    1802         231 :   polh1 = polh;
    1803         231 :   theta1 = theta;
    1804         231 :   alpha1 = alpha;
    1805         231 :   polf = polymini(ZX_Z_mul(RgX_recip6(polh), powiu(p,alpha)), p);
    1806         231 :   polh  = gel(polf,1);
    1807         231 :   lambda= itos(gel(polf,2));
    1808         231 :   theta = gel(polf,3);
    1809         231 :   alpha = itos(gel(polf,4));
    1810         231 :   beta  = itos(gel(polf,6));
    1811         231 :   if (lambda != 3) pari_err_BUG("labelm3 [lambda = 3]");
    1812         231 :   R = beta-alpha1-alpha;
    1813         231 :   if (odd(R)) pari_err_BUG("labelm3 [R odd]");
    1814         231 :   R /= 2;
    1815         231 :   if (R <= -2) pari_err_BUG("labelm3 [R <= -2]");
    1816         231 :   if (val[Ip->eps2] % (2*Ip->eps)) pari_err_BUG("labelm3 [val(eps2)]");
    1817         231 :   if (R >= 0 && (alpha+alpha1) >= 1) pari_err_BUG("labelm3 [minimal equation]");
    1818         231 :   Ip->r1 = itos(gmulgs(theta1,6)) + 6*alpha1;
    1819         231 :   Ip->r2 = itos(gmulgs(theta, 6)) + 6*alpha;
    1820         231 :   Ip->R = R;
    1821         231 :   return litredtp(alpha, alpha1, theta, theta1, polh, polh1, dismin, I, Ip);
    1822             : }
    1823             : 
    1824             : /* p = 3 */
    1825             : static long
    1826          21 : quadratic(GEN polh, long alpha, long dismin,
    1827             :           struct igusa *I, struct igusa_p *Ip)
    1828             : {
    1829             :   long alpha1, beta, R;
    1830             :   GEN polf, polh1, theta, theta1;
    1831          21 :   alpha1 = alpha;
    1832          21 :   polf = polymini_zi(ZX_Z_mul(polh, powiu(Ip->p,alpha)));
    1833          21 :   theta = gel(polf,1);
    1834          21 :   alpha = itos(gel(polf,2));
    1835          21 :   beta  = itos(gel(polf,3));
    1836          21 :   if (alpha && beta >= 1) pari_err_BUG("quadratc");
    1837          21 :   R = beta-alpha;
    1838          21 :   if (R >= 0 && alpha1)
    1839             :   {
    1840           0 :     dismin -= 10;
    1841           0 :     if (DEBUGLEVEL)
    1842           0 :       err_printf("(Care: minimal discriminant over Z[i] smaller than over Z)\n");
    1843             :   }
    1844          21 :   Ip->r1 = itos(gmulgs(theta,6))+6*alpha;
    1845          21 :   Ip->r2 = Ip->r1;
    1846          21 :   Ip->R = R;
    1847          21 :   alpha1 = alpha;
    1848          21 :   theta1 = theta;
    1849          21 :   polh1 = polh; /* FIXME !!! */
    1850          21 :   return litredtp(alpha, alpha1, theta, theta1, polh, polh1, dismin, I, Ip);
    1851             : }
    1852             : 
    1853             : static long
    1854        1365 : genus2localred(struct igusa *I, struct igusa_p *Ip, GEN p, GEN polmini)
    1855             : {
    1856             :   GEN val, polh, theta, list, c1, c2, c3, c4, c5, c6, prod;
    1857             :   long i, vb5, vb6, d, dismin, alpha, lambda;
    1858        1365 :   long condp = -1, indice, vc6, mm, nb, dism;
    1859             : 
    1860        1365 :   val = cgetg(8, t_VECSMALL);
    1861        1365 :   Ip->tame = 0;
    1862        1365 :   Ip->neron = NULL;
    1863        1365 :   Ip->type = NULL;
    1864        1365 :   Ip->p = p;
    1865        1365 :   Ip->val = val;
    1866        1365 :   val[1] = myval(I->j2,p);
    1867        1365 :   val[2] = myval(I->j4,p);
    1868        1365 :   val[3] = myval(I->i4,p);
    1869        1365 :   val[4] = myval(I->j6,p);
    1870        1365 :   val[5] = myval(I->j8,p);
    1871        1365 :   val[6] = myval(I->j10,p);
    1872        1365 :   val[7] = myval(I->i12,p);
    1873        1365 :   dismin = val[6];
    1874        1365 :   stable_reduction(I, Ip);
    1875        1365 :   if (dismin == 0)
    1876             :   {
    1877           7 :     Ip->tame = 1;
    1878           7 :     Ip->type = "[I{0-0-0}] page 155";
    1879           7 :     Ip->neron = cyclic(1); return 0;
    1880             :   }
    1881        1358 :   if (dismin == 1)
    1882             :   {
    1883           0 :     Ip->type = "[I{1-0-0}] page 170";
    1884           0 :     Ip->neron = cyclic(1); return 1;
    1885             :   }
    1886        1358 :   if (dismin == 2) switch(Ip->tt)
    1887             :   {
    1888             :     case 2:
    1889           0 :       Ip->type = "[I{2-0-0}] page 170";
    1890           0 :       Ip->neron = cyclic(2); return 1;
    1891             :     case 3:
    1892           0 :       Ip->type = "[I{1-1-0}] page 179";
    1893           0 :       Ip->neron = cyclic(1); return 2;
    1894             :     case 5:
    1895          14 :       if (cmpis(p,3) <= 0) pari_err_BUG("genus2localred [tt 1]");
    1896          14 :       Ip->type = "[I{0}-II-0] page 159";
    1897          14 :       Ip->neron = cyclic(1); return 2;
    1898           0 :     default: pari_err_BUG("genus2localred [tt 2]");
    1899             :   }
    1900        1344 :   if (equaliu(p,2)) return -1;
    1901        1330 :   polh = gel(polmini,1);
    1902        1330 :   lambda = itos(gel(polmini,2));
    1903        1330 :   theta = gel(polmini,3);
    1904        1330 :   alpha = itos(gel(polmini,4));
    1905        1330 :   if (!gequal0(gel(polmini,5)))
    1906          21 :     return equalis(p,3)? quadratic(polh, alpha, dismin, I, Ip):
    1907             :                          tame(polh, theta, alpha, dismin, I, Ip);
    1908        1309 :   if (gequal0(theta) && lambda<= 2)
    1909             :   {
    1910           7 :     if (Ip->tt >= 5) pari_err_BUG("genus2localred [tt 3]");
    1911           7 :     return tame(polh, theta, alpha, dismin, I, Ip);
    1912             :   }
    1913        1302 :   if (dismin == 3)
    1914             :   {
    1915           7 :     switch(Ip->tt)
    1916             :     {
    1917           0 :       case 2: return tame(polh, theta, alpha, dismin, I, Ip);
    1918           0 :       case 3: Ip->type = "[I{2-1-0}] page 179"; Ip->neron = cyclic(2); return 2;
    1919           7 :       case 4: Ip->type = "[I{1-1-1}] page 182"; Ip->neron = cyclic(3); return 2;
    1920             :       case 5:
    1921           0 :         if (equalis(p,3) && !gequal(theta,ghalf))
    1922           0 :           return labelm3(polh,theta,alpha,dismin,I,Ip);
    1923           0 :         Ip->type = "[I{0}-III-0] page 161"; Ip->neron = cyclic(2); return 2;
    1924             :       case 6:
    1925           0 :         if (equalis(p,3)) pari_err_BUG("genus2localred [conductor]");
    1926           0 :         Ip->type = "[I{1}-II-0] page 172"; Ip->neron = cyclic(1); return 3;
    1927             :     }
    1928           0 :     pari_err_BUG("genus2localred [switch tt 4]");
    1929           0 :     return -1; /* not reached */
    1930             :   }
    1931        1295 :   switch(lambda)
    1932             :   {
    1933             :     case 0:
    1934         357 :       switch(itos(gmulgs(theta, 60))+alpha)
    1935             :       {
    1936             :         case 10:
    1937           7 :           condp = dismin-1;
    1938           7 :           Ip->type = "[V] page 156";
    1939           7 :           Ip->neron = cyclic(3); break;
    1940             :         case 11:
    1941           7 :           condp = dismin-11;
    1942           7 :           Ip->type = "[V*] page 156";
    1943           7 :           Ip->neron = cyclic(3); break;
    1944             :         case 12:
    1945           7 :           condp = dismin-2;
    1946           7 :           Ip->type = "[IX-2] page 157";
    1947           7 :           Ip->neron = cyclic(5); break;
    1948             :         case 13:
    1949          14 :           condp = dismin-12;
    1950          14 :           Ip->type = "[VIII-4] page 157";
    1951          14 :           Ip->neron = cyclic(1); break;
    1952             :         case 24:
    1953           7 :           condp = dismin-8;
    1954           7 :           Ip->type = "[IX-4] page 158";
    1955           7 :           Ip->neron = cyclic(5);
    1956           7 :           break;
    1957             :         case 15: case 16:
    1958          14 :           if (Ip->tt>= 5) pari_err_BUG("genus2localred [tt 6]");
    1959          14 :           return tame(polh, theta, alpha, dismin, I, Ip);
    1960             :         case 20: case 21:
    1961             :           {
    1962             :             GEN b0, b1, b2, b3, b4, b5, b6, b02, b03, b04, b05;
    1963         112 :             RgX_to_6(polh, &b0,&b1,&b2,&b3,&b4,&b5,&b6);
    1964         112 :             vb5 = myval(b5,p);
    1965         112 :             vb6 = myval(b6,p);
    1966         112 :             if (vb6 >= 3)
    1967             :             {
    1968          14 :               if (vb5 < 2) pari_err_BUG("genus2localred [red1]");
    1969          14 :               if (vb5 >= 3)
    1970             :               {
    1971           7 :                 condp = dismin-8;
    1972           7 :                 Ip->type = "[II*-IV-(-1)] page 164";
    1973           7 :                 Ip->neron = cyclic(3);
    1974             :               }
    1975             :               else
    1976             :               {
    1977           7 :                 condp = dismin-7;
    1978           7 :                 Ip->type = "[IV-III*-(-1)] page 167";
    1979           7 :                 Ip->neron = cyclic(6);
    1980             :               }
    1981          14 :               break;
    1982             :             }
    1983          98 :             if (dvdii(b0,p)) pari_err_BUG("genus2localred [b0]");
    1984          98 :             b02 = gsqr(b0);
    1985          98 :             b03 = gmul(b02, b0);
    1986          98 :             b04 = gmul(b03, b0);
    1987          98 :             b05 = gmul(b04, b0);
    1988          98 :             c1 = gmul2n(b1,-1);
    1989          98 :             c2 = gmul2n(gsub(gmul(b0,b2), gsqr(c1)),-1);
    1990          98 :             c3 = gmul2n(gsub(gmul(b02,b3), gmul2n(gmul(c1,c2),1)),-1);
    1991          98 :             c4 = gsub(gmul(b03,b4), gadd(gmul2n(gmul(c1,c3),1),gsqr(c2)));
    1992          98 :             c5 = gsub(gmul(b04,b5), gmul2n(gmul(c2,c3),1));
    1993          98 :             c6 = gsub(gmul(b05,b6), gsqr(c3));
    1994             :             /* b0^5*H(x/b0) = (x^3+c1*x^2+c2*x+c3)^2+c4*x^2+c5*x+c6 */
    1995          98 :             vc6 = myval(c6,p);
    1996          98 :             if (vc6 == 2)
    1997             :             {
    1998           7 :               if (alpha)
    1999             :               {
    2000           0 :                 condp = dismin-16;
    2001           0 :                 Ip->type = "[IV] page 155";
    2002           0 :                 Ip->neron = cyclic(1);
    2003             :               }
    2004             :               else
    2005             :               {
    2006           7 :                 condp = dismin-6;
    2007           7 :                 Ip->type = "[III] page 155";
    2008           7 :                 Ip->neron = dicyclic(3,3);
    2009             :               }
    2010             :             }
    2011             :             else
    2012             :             {
    2013          91 :               if (myval(c3,p) > 1) pari_err_BUG("genus2localred [c3]");
    2014          91 :               mm = min3(3*myval(c4,p)-4, 3*myval(c5,p)-5, 3*vc6-6);
    2015          91 :               if (alpha)
    2016             :               {
    2017          35 :                 condp = dismin-mm-16;
    2018          35 :                 Ip->type = stack_sprintf("[III*{%ld}] page 184", mm);
    2019          35 :                 Ip->neron = cyclic(1);
    2020             :               }
    2021             :               else
    2022             :               {
    2023          56 :                 condp = dismin-mm-6;
    2024          56 :                 Ip->type = stack_sprintf("[III{%ld}] page 184", mm);
    2025          56 :                 Ip->neron = (mm%3)? cyclic(9): dicyclic(3,3);
    2026             :               }
    2027             :             }
    2028             :           }
    2029          98 :           break;
    2030             :         case 30:
    2031         378 :           return equalis(p,3)? quartic(polh, alpha, dismin, Ip)
    2032         189 :                              : tame(polh, theta, alpha, dismin, I, Ip);
    2033           0 :         default: pari_err_BUG("genus2localred [red2]");
    2034             :       }
    2035         154 :       break;
    2036             :     case 1:
    2037         105 :       switch(itos(gmulgs(theta, 60))+alpha)
    2038             :       {
    2039             :         case 12:
    2040           7 :           condp = dismin;
    2041           7 :           Ip->type = "[VIII-1] page 156";
    2042           7 :           Ip->neron = cyclic(1); break;
    2043             :         case 13:
    2044           7 :           condp = dismin-10;
    2045           7 :           Ip->type = "[IX-3] page 157";
    2046           7 :           Ip->neron = cyclic(5); break;
    2047             :         case 24:
    2048           7 :           condp = dismin-4;
    2049           7 :           Ip->type = "[IX-1] page 157";
    2050           7 :           Ip->neron = cyclic(5); break;
    2051             :         case 25:
    2052           7 :           condp = dismin-14;
    2053           7 :           Ip->type = "[VIII-3] page 157";
    2054           7 :           Ip->neron = cyclic(1); break;
    2055             :         case 36:
    2056           7 :           condp = dismin-8;
    2057           7 :           Ip->type = "[VIII-2] page 157";
    2058           7 :           Ip->neron = cyclic(1); break;
    2059             :         case 15:
    2060           7 :           condp = dismin-1;
    2061           7 :           Ip->type = "[VII] page 156";
    2062           7 :           Ip->neron = cyclic(2); break;
    2063             :         case 16:
    2064           7 :           condp = dismin-11;
    2065           7 :           Ip->type = "[VII*] page 156";
    2066           7 :           Ip->neron = cyclic(2); break;
    2067             :         case 20:
    2068          14 :           if (cmpis(p,3))
    2069             :           {
    2070           7 :             d = 6*val[6]-5*val[7]-2;
    2071           7 :             if (d%6) pari_err_BUG("genus2localred [index]");
    2072           7 :             dism = (d/6);
    2073             :           }
    2074             :           else
    2075             :           {
    2076           7 :             list = padicfactors(polh,p,dismin-5);
    2077           7 :             nb = lg(list);
    2078           7 :             prod = pol_1(varn(polh));
    2079          21 :             for(i = 1;i<nb;i++)
    2080             :             {
    2081          14 :               GEN c = gel(list,i);
    2082          14 :               if (valp(gel(c,2)) && degpol(c)<= 2) prod = RgX_mul(prod,c);
    2083             :             }
    2084           7 :             if (degpol(prod) > 2) pari_err_BUG("genus2localred [padicfactors]");
    2085           7 :             dism = valp(RgX_disc(prod)) - 1;
    2086             :           }
    2087          14 :           condp = dismin-dism-3;
    2088          14 :           Ip->type = stack_sprintf("[II-II*{%ld}] page 176", dism);
    2089          14 :           Ip->neron = groupH(dism+1); break;
    2090             :         case 21:
    2091          14 :           vb6 = myval(RgX_coeff(polh,0),p);
    2092          14 :           if (vb6<2) pari_err_BUG("genus2localred [red3]");
    2093          14 :           condp = dismin-14;
    2094          14 :           Ip->type = "[IV*-II{0}] page 175";
    2095          14 :           Ip->neron = cyclic(1); break;
    2096             :         case 30:
    2097          28 :           vb5 = myval(RgX_coeff(polh,1),p);
    2098          28 :           if (vb5 == 2)
    2099             :           {
    2100          21 :             if (Ip->tt >= 5) pari_err_BUG("genus2localred [tt 6]");
    2101          21 :             return tame(polh, theta, alpha, dismin, I, Ip);
    2102             :           }
    2103           7 :           condp = dismin-7;
    2104           7 :           Ip->type = "[II*-III-(-1)] page 167";
    2105           7 :           Ip->neron = cyclic(2); break;
    2106             :       }
    2107          84 :       break;
    2108             :     case 2:
    2109         147 :       if (equalis(denom(theta),4))
    2110             :       {
    2111          28 :         if (Ip->tt>4) pari_err_BUG("genus2localred [tt 5]");
    2112          28 :         return tame(polh, theta, alpha, dismin, I, Ip);
    2113             :       }
    2114         119 :       if (!equalis(p,3) && equalis(denom(theta),3))
    2115          21 :         return tame(polh, theta, alpha, dismin, I, Ip);
    2116          98 :       list = padicfactors(polh,p,dismin-10*alpha);
    2117          98 :       nb = lg(list); prod = pol_1(varn(polh));
    2118         336 :       for(i = 1;i<nb;i++)
    2119             :       {
    2120         238 :         GEN c = gel(list,i);
    2121         238 :         if (!valp(gel(c,2))) prod = RgX_mul(prod,c);
    2122             :       }
    2123          98 :       switch(degpol(prod))
    2124             :       {
    2125             :         GEN e0, e1, e2;
    2126             :         case 0:
    2127           0 :           dism = 0; break;
    2128             :         case 1:
    2129           7 :           e1 = gel(prod,3);
    2130           7 :           dism = 2*valp(e1); break;
    2131             :         case 2:
    2132          91 :           e0 = gel(prod,2);
    2133          91 :           e1 = gel(prod,3);
    2134          91 :           e2 = gel(prod,4);
    2135          91 :           dism = valp(gsub(gsqr(e1),gmul2n(gmul(e0,e2),2))); break;
    2136             :         default:
    2137           0 :           pari_err_BUG("genus2localred [padicfactors 2]");
    2138           0 :           dism = 0;
    2139             :       }
    2140          98 :       switch(itos(gmulgs(theta,12))+alpha-4)
    2141             :       {
    2142             :         case 0:
    2143          14 :           condp = dismin-dism-1;
    2144          14 :           Ip->type = stack_sprintf("[IV-II{%ld}] page 175", dism);
    2145          14 :           Ip->neron = cyclic(3*dism+2); break;
    2146             :         case 1:
    2147           7 :           condp = dismin-dism-10;
    2148           7 :           Ip->type = stack_sprintf("[II*-II*{%ld}] page 176",dism);
    2149           7 :           Ip->neron = groupH(dism+1); break;
    2150             :           break;
    2151             :         case 2: case 3:
    2152          70 :           if (myval(RgX_coeff(polh,0),p) == 2)
    2153             :           {
    2154          56 :             if (Ip->tt>4) pari_err_BUG("genus2localred [tt 5]");
    2155          56 :             return tame(polh, theta, alpha, dismin, I, Ip);
    2156             :           }
    2157          14 :           dism++;
    2158          14 :           indice = val[6]-(5*val[3]/2)-dism;
    2159          14 :           condp = dismin-dism-indice-2;
    2160          14 :           Ip->type = stack_sprintf("[II{%ld-%ld}] page 182", dism,indice);
    2161          14 :           Ip->neron = both_odd(dism,indice)? dicyclic(2,2*dism): cyclic(4*dism);
    2162          14 :           break;
    2163             :         case 4:
    2164           7 :           condp = dismin-dism-5;
    2165           7 :           Ip->type = stack_sprintf("[IV*-II{%ld}] page 175",dism+1);
    2166           7 :           Ip->neron = cyclic(3*dism+4); break;
    2167             :       }
    2168          42 :       break;
    2169             :     case 3:
    2170         686 :       if (!equalis(p,3) || Ip->tt <= 4)
    2171         483 :         return tame(polh, theta, alpha, dismin, I, Ip);
    2172         203 :       return labelm3(polh,theta,alpha,dismin,I,Ip); /* p = 3 */
    2173           0 :     default: pari_err_BUG("genus2localred [switch lambda]");
    2174             :   }
    2175         280 :   if (condp < 2 || condp > get_maxc(p))
    2176           0 :     pari_err_BUG("genus2localred [conductor]");
    2177         280 :   return condp;
    2178             : }
    2179             : 
    2180             : static long
    2181        2688 : chk_pol(GEN P) {
    2182        2688 :   switch(typ(P))
    2183             :   {
    2184        1302 :     case t_INT: break;
    2185        1386 :     case t_POL: RgX_check_ZX(P,"genus2red"); return varn(P); break;
    2186           0 :     default: pari_err_TYPE("genus2red", P);
    2187             :   }
    2188        1302 :   return -1;
    2189             : }
    2190             : 
    2191             : /* P,Q are ZX, study Y^2 + Q(X) Y = P(X) */
    2192             : GEN
    2193        1344 : genus2red(GEN PQ, GEN p)
    2194             : {
    2195        1344 :   pari_sp av = avma;
    2196             :   struct igusa I;
    2197             :   GEN P, Q, D;
    2198             :   GEN j22, j42, j2j6, a0,a1,a2,a3,a4,a5,a6, V,polr,facto,factp, vecmini, cond;
    2199             :   long i, l, dd, vP,vQ;
    2200             : 
    2201        1344 :   PQ = Q_remove_denom(PQ, &D);
    2202        1344 :   if (typ(PQ) == t_VEC && lg(PQ) == 3)
    2203             :   {
    2204          70 :     P = gel(PQ,1);
    2205          70 :     Q = gel(PQ,2);
    2206             :   }
    2207             :   else
    2208             :   {
    2209        1274 :     P = PQ;
    2210        1274 :     Q = gen_0;
    2211             :   }
    2212             : 
    2213        1344 :   vP = chk_pol(P);
    2214        1344 :   vQ = chk_pol(Q);
    2215        1344 :   if (vP < 0)
    2216             :   {
    2217           7 :     if (vQ < 0) pari_err_TYPE("genus2red",mkvec2(P,Q));
    2218           7 :     P = scalarpol(P,vQ);
    2219             :   }
    2220        1337 :   else if (vQ < 0) Q = scalarpol(Q,vP);
    2221        1344 :   if (p && typ(p) != t_INT) pari_err_TYPE("genus2red", p);
    2222        1344 :   if (D) P = ZX_Z_mul(P,D);
    2223             : 
    2224        1344 :   polr = ZX_add(ZX_sqr(Q), gmul2n(P,2)); /* ZX */
    2225        1344 :   switch(degpol(polr))
    2226             :   {
    2227        1344 :     case 5: case 6: break;
    2228           0 :     default: pari_err_DOMAIN("genus2red","genus","!=", gen_2,mkvec2(P,Q));
    2229             :   }
    2230             : 
    2231        1344 :   RgX_to_6(polr, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
    2232        1344 :   I.j10 = !signe(a0)? mulii(sqri(a1), ZX_disc(polr)): ZX_disc(polr);
    2233        1344 :   if (!signe(I.j10))
    2234           0 :     pari_err_DOMAIN("genus2red","genus","<",gen_2,mkvec2(P,Q));
    2235        1344 :   I.j10 = gmul2n(I.j10, -12); /* t_INT */
    2236             : 
    2237        1344 :   if (p == NULL)
    2238             :   {
    2239          28 :     facto = factor(absi(I.j10));
    2240          28 :     factp = gel(facto,1);
    2241             :   }
    2242             :   else
    2243             :   {
    2244        1316 :     factp = mkcol(p);
    2245        1316 :     facto = mkmat2(factp, mkcol(gen_1));
    2246             :   }
    2247        1344 :   l = lg(factp);
    2248        1344 :   vecmini = cgetg(l, t_COL);
    2249        2709 :   for(i = 1; i<l; i++)
    2250             :   {
    2251        1365 :     GEN l = gel(factp,i), pm;
    2252        1365 :     if (i == 1 && equalis(l, 2)) { gel(vecmini,1) = gen_0; continue; }
    2253        1351 :     gel(vecmini,i) = pm = polymini(polr, l);
    2254        1351 :     polr = RgX_Rg_mul(gel(pm,1), powii(l, gel(pm,4)));
    2255             :   }
    2256        1344 :   RgX_to_6(polr, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
    2257        1344 :   I.j10 = !signe(a0)? mulii(sqri(a1), ZX_disc(polr)): ZX_disc(polr);
    2258        1344 :   I.j10 = gmul2n(I.j10,-12);
    2259             : 
    2260        1344 :   I.a0 = a0;
    2261        1344 :   I.A2 = apol2(a0,a1,a2);
    2262        1344 :   I.A3 = apol3(a0,a1,a2,a3);
    2263        1344 :   I.A5 = apol5(a0,a1,a2,a3,a4,a5);
    2264        1344 :   I.B2 = bpol2(a0,a1,a2,a3,a4);
    2265             : 
    2266        1344 :   I.j2 = igusaj2(a0,a1,a2,a3,a4,a5,a6);
    2267        1344 :   I.j4 = igusaj4(a0,a1,a2,a3,a4,a5,a6);
    2268        1344 :   I.i4 = gsub(gsqr(I.j2), gmulsg(24,I.j4));
    2269        1344 :   I.j6 = igusaj6(a0,a1,a2,a3,a4,a5,a6);
    2270        1344 :   j42 = gsqr(I.j4);
    2271        1344 :   j22 = gsqr(I.j2);
    2272        1344 :   j2j6 = gmul(I.j2,I.j6);
    2273        1344 :   I.j8 = gmul2n(gsub(j2j6,j42), -2);
    2274        1344 :   I.i12= gmul2n(gsub(gadd(gmul(j22,j42),gmulsg(36,gmul(j2j6,I.j4))),
    2275             :                      gadd(gadd(gmulsg(32,gmul(j42,I.j4)),gmul(j2j6,j22)),gmulsg(108,gsqr(I.j6)))),-2);
    2276             : 
    2277        2709 :   for(i = 1; i < l; i++)
    2278        1365 :     gcoeff(facto,i,2) = stoi(Q_pval(I.j10, gel(factp,i)));
    2279        1344 :   dd = polval(polr,gen_2) & (~1); /* = 2 floor(val/2) */
    2280        1344 :   polr = gmul2n(polr, -dd);
    2281             : 
    2282        1344 :   V = cgetg(l, t_VEC);
    2283        2709 :   for (i = 1; i < l; i++)
    2284             :   {
    2285        1365 :     GEN q = gel(factp,i), red, N = NULL;
    2286             :     struct igusa_p Ip;
    2287        1365 :     long f = genus2localred(&I, &Ip, q, gel(vecmini,i));
    2288        1365 :     gcoeff(facto,i,2) = stoi(f);
    2289        1365 :     if (Ip.tame) Ip.type = stack_strcat("(tame) ", Ip.type);
    2290        1365 :     if (f >= 0)
    2291        1351 :       N = zv_snf(Ip.neron);
    2292        1365 :     if (DEBUGLEVEL)
    2293             :     {
    2294           0 :       if (!p) err_printf("p = %Ps\n", q);
    2295           0 :       err_printf("(potential) stable reduction: %Ps\n", Ip.stable);
    2296           0 :       if (f >= 0) {
    2297           0 :         err_printf("reduction at p: %s, %Ps", Ip.type, N);
    2298           0 :         err_printf(", f = %ld\n", f);
    2299             :       }
    2300             :     }
    2301        1365 :     red = f >= 0? mkvec2(strtoGENstr(Ip.type), N): cgetg(1, t_VEC);
    2302        1365 :     gel(V, i) = mkvec3(q, Ip.stable, red);
    2303             :   }
    2304        1344 :   if (p) V = gel(V,1);
    2305        1344 :   cond = factorback(facto);
    2306             :   /* remove denominator 2 coming from f = -1 in genuslocalred(, p = 2) */
    2307        1344 :   if (typ(cond) != t_INT) cond = gel(cond,1);
    2308        1344 :   return gerepilecopy(av, mkvec4(cond, facto, polr, V));
    2309             : }

Generated by: LCOV version 1.11