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

Generated by: LCOV version 1.11