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

Generated by: LCOV version 2.0-1