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 2702 : RgX_to_06(GEN q, GEN *a0, GEN *a1, GEN *a2, GEN *a3, GEN *a4, GEN *a5, GEN *a6)
22 : {
23 2702 : *a0 = gen_0;
24 2702 : *a1 = gen_0;
25 2702 : *a2 = gen_0;
26 2702 : *a3 = gen_0;
27 2702 : *a4 = gen_0;
28 2702 : *a5 = gen_0;
29 2702 : *a6 = gen_0;
30 2702 : switch(degpol(q))
31 : {
32 1918 : case 6: *a0 = gel(q,8); /*fall through*/
33 2702 : case 5: *a1 = gel(q,7); /*fall through*/
34 2702 : case 4: *a2 = gel(q,6); /*fall through*/
35 2702 : case 3: *a3 = gel(q,5); /*fall through*/
36 2702 : case 2: *a4 = gel(q,4); /*fall through*/
37 2702 : case 1: *a5 = gel(q,3); /*fall through*/
38 2702 : case 0: *a6 = gel(q,2); /*fall through*/
39 : }
40 2702 : }
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 2345 : igusaj2(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5, GEN a6)
53 : {
54 2345 : pari_sp av = avma;
55 2345 : return gerepileupto(av, gmul2n(gadd(gsub(gadd(gmul(gmulsg(-120, a0), a6), gmul(gmulsg(20, a1), a5)), gmul(gmulsg(8, a2), a4)), gmulsg(3, gsqr(a3))), -2));
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 2345 : igusaj4(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5, GEN a6)
63 : {
64 2345 : pari_sp av = avma;
65 2345 : return gerepileupto(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 2345 : igusaj6(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5, GEN a6)
84 : {
85 2345 : pari_sp av = avma;
86 2345 : return gerepileupto(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 gerepileupto(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 gerepileupto(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) = gerepileupto(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 gerepileupto(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 2282 : apol2(GEN a0, GEN a1, GEN a2)
215 : {
216 2282 : 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 2282 : apol3(GEN a0, GEN a1, GEN a2, GEN a3)
224 : {
225 2282 : 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 2282 : apol5(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4, GEN a5)
233 : {
234 2282 : 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 2282 : bpol2(GEN a0, GEN a1, GEN a2, GEN a3, GEN a4)
242 : {
243 2282 : 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 38451 : myval(GEN x, GEN p) { return signe(x)? Z_pval(x,p): VERYBIG; }
249 : static long
250 2982 : my3val(GEN x) { return signe(x)? Z_lval(x,3): VERYBIG; }
251 : /* b in Z[i], return v_3(b) */
252 : static long
253 1491 : 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 3129 : min3(long a, long b, long c)
268 : {
269 3129 : long m = a;
270 3129 : if (b < m) m = b;
271 3129 : if (c < m) m = c;
272 3129 : 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 392 : RgX_recip6(GEN x)
282 : {
283 392 : long lx = lg(x), i, j;
284 392 : GEN y = cgetg(9, t_POL);
285 392 : y[1] = x[1];
286 2940 : for (i=8,j=2; j < lx; i--,j++) gel(y,i) = gel(x,j);
287 588 : for ( ; j < 9; i--,j++) gel(y,i) = gen_0;
288 392 : return normalizepol_lg(y, 9);
289 : }
290 : /* extract coefficients a0,...a3 of a polynomial a0 X^6 + ... + a6 */
291 : static void
292 2282 : RgX_to_03(GEN q, GEN *a0, GEN *a1, GEN *a2, GEN *a3)
293 : {
294 2282 : *a0 = gen_0;
295 2282 : *a1 = gen_0;
296 2282 : *a2 = gen_0;
297 2282 : *a3 = gen_0;
298 2282 : switch(degpol(q))
299 : {
300 1491 : case 6: *a0 = gel(q,8); /*fall through*/
301 2282 : case 5: *a1 = gel(q,7); /*fall through*/
302 2282 : case 4: *a2 = gel(q,6); /*fall through*/
303 2282 : case 3: *a3 = gel(q,5); /*fall through*/
304 : }
305 2282 : }
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 2842 : theta_j(GEN B, GEN p, long j)
334 : {
335 2842 : long i, t = VERYBIG;
336 13916 : for(i = 1+j; i <= 6; i++)
337 11074 : t = minss(t, myval(RgX_coeff(B,6-i), p) * (60 / (i-j)));
338 2842 : return t;
339 : }
340 : /* compute 6 * theta_3 for B in Z[i][X], p = 3 */
341 : static long
342 28 : theta_3_zi(GEN B)
343 : {
344 28 : long v2 = myval_zi(RgX_coeff(B,2));
345 28 : long v1 = myval_zi(RgX_coeff(B,1));
346 28 : long v0 = myval_zi(RgX_coeff(B,0));
347 28 : 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 987 : factmz(GEN Q, GEN p, long *maxord)
363 : {
364 987 : GEN z = FpX_factor_squarefree(Q, p);
365 987 : long m = lg(z)-1; /* maximal multiplicity */
366 987 : *maxord = m;
367 987 : return (m >= 3)? FpX_oneroot(gel(z,m), p): NULL;
368 : }
369 : static long
370 2695 : get_lambda(GEN H, GEN p)
371 : {
372 2695 : if (!dvdii(RgX_coeff(H,3), p)) return 3;
373 1197 : if (!dvdii(RgX_coeff(H,4), p)) return 2;
374 931 : if (!dvdii(RgX_coeff(H,5), p)) return 1;
375 721 : 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 2583 : polymini(GEN H, GEN p)
390 : {
391 2583 : long t60, alpha, lambda, quad = 0, beta = 0;
392 : GEN Hp;
393 :
394 2583 : alpha = ZX_pvalrem(H, p, &H) & 1;
395 2583 : lambda = get_lambda(H, p);
396 2583 : if (lambda < 0) { H = RgX_recip6(H); lambda = get_lambda(H, p); }
397 0 : for(;;)
398 : {
399 : for(;;)
400 259 : { /* lambda <= 3, t60 = 60*theta */
401 : GEN rac;
402 : long e, maxord;
403 2842 : t60 = theta_j(H,p,lambda); e = t60 / 60;
404 2842 : 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 2842 : Hp = FpX_red(H, p); if (t60) break;
415 :
416 973 : rac = factmz(Hp,p, &maxord);
417 973 : if (maxord <= 2)
418 : {
419 693 : if (degpol(Hp) <= 3) break;
420 175 : goto end;
421 : }
422 : /* maxord >= 3 */
423 280 : if (!rac) { quad = 1; goto end; }
424 259 : if (signe(rac)) H = ZX_translate(H, rac);
425 259 : lambda = 6 - maxord;
426 : }
427 2408 : if (lambda <= 2)
428 : {
429 1043 : if (myval(RgX_coeff(H,2),p) > 1-alpha &&
430 875 : myval(RgX_coeff(H,1),p) > 2-alpha &&
431 693 : 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 1043 : break;
438 : }
439 : /* lambda = 3 */
440 1365 : 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_translate(H,rac);
470 0 : t60 = theta_j(H,p,3);
471 0 : if (t60 < 60) break;
472 : }
473 : }
474 : }
475 2583 : end:
476 2583 : 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 14 : zi_pow3mod(GEN a)
482 : {
483 : GEN x, y;
484 14 : if (typ(a) != t_COMPLEX) return gmodgs(a,3);
485 7 : x = gmodgs(gel(a,1), 3);
486 7 : y = gmodgs(gel(a,2), 3);
487 7 : return mkcomplex(x, negi(y));
488 : }
489 : static GEN
490 21 : polymini_zi(GEN pol) /* polynome minimal dans Z[i] */
491 : {
492 21 : GEN polh, rac, a0, a1, a2, a3, a4, a5, a6, p = utoipos(3);
493 21 : long alpha, beta = 0, t6;
494 :
495 21 : alpha = ZX_pval(pol,p) & 1;
496 21 : polh = alpha? RgX_Rg_div(pol, p): pol;
497 21 : rac = mkcomplex(Fp_div(RgX_coeff(polh,3), RgX_coeff(polh,6), p), gen_1);
498 : for(;;)
499 7 : {
500 : long e;
501 28 : polh = RgX_translate(polh, rac);
502 28 : t6 = theta_3_zi(polh); e = t6 / 6;
503 28 : if (e)
504 : {
505 14 : GEN pe = powiu(p,e);
506 14 : polh = RgX_Rg_div(RgX_unscale(polh,pe), powiu(pe,3));
507 14 : alpha = (alpha+e)&1;
508 14 : t6 -= e * 6; beta += e;
509 : }
510 28 : RgX_to_06(polh, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
511 28 : if (t6 || !myval_zi(a4) || !myval_zi(a5)) break;
512 7 : rac = zi_pow3mod(gdiv(a6, gneg(a3)));
513 : }
514 21 : if (alpha && myval_zi(a0) >= 3 && myval_zi(a1) >= 2 && myval_zi(a2) >= 1)
515 : {
516 14 : t6 += 6; beta--; alpha = 0;
517 : }
518 21 : if (alpha && beta >= 1) pari_err_BUG("quadratic");
519 21 : 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_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 2324 : 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 2324 : GEN j2 = I->j2, i4 = I->i4, j4 = I->j4, j6 = I->j6, j8 = I->j8;
591 2324 : GEN val, J, v, Ieps, j10 = I->j10, i12 = I->i12;
592 : long s, r1, r2, r3, r4, i, eps;
593 :
594 2324 : Ip->abe = 0;
595 2324 : Ip->tor = 0;
596 2324 : Ip->tame = 0;
597 2324 : Ip->neron = NULL;
598 2324 : Ip->type = NULL;
599 2324 : Ip->p = p;
600 2324 : Ip->val = val = cgetg(9, t_VECSMALL);
601 2324 : val[1] = myval(j2,p);
602 2324 : val[2] = myval(j4,p);
603 2324 : val[3] = myval(i4,p);
604 2324 : val[4] = myval(j6,p);
605 2324 : val[5] = myval(j8,p);
606 2324 : val[6] = myval(j10,p);
607 2324 : val[7] = myval(i12,p);
608 2324 : switch(itos_or_0(p))
609 : {
610 21 : case 2: eps = 4; val[8] = val[5]; Ieps = j8; break;
611 476 : case 3: eps = 3; val[8] = val[4]; Ieps = j6; break;
612 1827 : default: eps = 1; val[8] = val[1]; Ieps = gdivgs(j2,12); break;
613 : }
614 :
615 2324 : v = cgetg(8,t_VECSMALL);
616 18592 : for(i = 1; i <= 7; i++) v[i] = val[i] * d[i];
617 2324 : s = vecsmall_min(v);
618 2324 : Ip->eps = eps;
619 :
620 2324 : r1 = 3*eps*val[3];
621 2324 : r3 = eps*val[6] + val[8];
622 2324 : r2 = eps*val[7];
623 2324 : r4 = min3(r1, r2, r3);
624 :
625 : /* s = max(v_p(X) / deg(X)) */
626 2324 : J = cgetg(1, t_VEC);
627 2324 : if (s == v[6])
628 280 : Ip->tt = 1;
629 2044 : else if (s == v[7])
630 : {
631 217 : J = mkvec( Fp_to_mod(gmod(gdiv(gpowgs(i4,3),i12), p), p) );
632 217 : Ip->tt = 2;
633 : }
634 1827 : else if (s == v[3])
635 350 : Ip->tt = (val[2] == val[3] || 2*val[4] == 3*val[3])? 3: 4;
636 1477 : else if (r3 == r4)
637 : {
638 903 : GEN a,b, P, sj, pj, t = gmul(gpowgs(j10,eps),Ieps);
639 903 : sj = gaddsg(1728, gdiv(gpowgs(i12,eps), t));
640 903 : pj = gdiv(gpowgs(i4,3*eps), t);
641 903 : a = gmod(sj, p);
642 903 : b = gmod(pj, p);
643 903 : P = mkpoln(3, gen_1, Fp_neg(a,p), b, 0); /* X^2 - SX + P: roots j1,j2 */
644 903 : J = FpX_roots(P, p);
645 903 : 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 553 : case 1:
653 553 : a = Fp_to_mod(gel(J,1), p);
654 553 : J = mkvec2(a, a); break;
655 350 : case 2:
656 350 : settyp(J, t_VEC);
657 350 : J = FpV_to_mod(J, p); break;
658 : }
659 903 : Ip->tt = 5;
660 : }
661 574 : else if (r2 == r4)
662 : {
663 413 : J = mkvec( Fp_to_mod(gmod(gdiv(gpowgs(i4,3),i12), p), p) );
664 413 : Ip->tt = 6;
665 : }
666 : else
667 161 : Ip->tt = 7; /* r1 == r4 */
668 2324 : Ip->stable = mkvec2(stoi(Ip->tt), J);
669 2324 : }
670 :
671 : struct red {
672 : const char *t, *pages;
673 : double tnum;
674 : GEN g;
675 : };
676 :
677 : /* destroy v */
678 : static GEN
679 2303 : zv_snf(GEN v)
680 : {
681 2303 : long i, l = lg(v);
682 5110 : for (i = 1; i < l; i++)
683 : {
684 2807 : long j, a = v[i];
685 4025 : for (j = i+1; j < l; j++)
686 : {
687 1218 : long b = v[j], d = ugcd(a,b);
688 1218 : v[i] = a = a*(b/d);
689 1218 : v[j] = d;
690 : }
691 : }
692 2422 : for (i = l-1; i > 0; i--)
693 1967 : if (v[i] != 1) { setlg(v, i+1); break; }
694 2303 : return zv_to_ZV(v);
695 : }
696 :
697 : static GEN
698 2100 : cyclic(long n)
699 2100 : { return (n <= 1)? cgetg(1, t_VECSMALL): mkvecsmall(n); }
700 : static GEN
701 553 : dicyclic(long a, long b)
702 : {
703 : long d;
704 553 : if (!a) a = 1;
705 553 : if (!b) b = 1;
706 553 : if (a < b) lswap(a,b);
707 553 : d = ugcd(a,b);
708 553 : if (d == 1) return cyclic(a*b);
709 462 : 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 252 : get_red(struct red *S, struct igusa_p *Ip, GEN polh, GEN p, long alpha, long r)
717 : {
718 252 : GEN val = Ip->val;
719 : long indice;
720 252 : switch(r)
721 : {
722 42 : case 0:
723 42 : indice = FpX_is_squarefree(FpX_red(polh,p), p)
724 : ? 0
725 42 : : val[6] - val[7] + val[8]/Ip->eps;
726 42 : S->t = stack_sprintf("I{%ld}", indice);
727 42 : S->tnum = 1;
728 42 : S->pages = "159-177";
729 42 : if (indice==0) Ip->abe += 1; else Ip->tor += 1;
730 42 : S->g = cyclic(indice);
731 42 : 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 28 : case 2:
755 28 : S->t = "II";
756 28 : S->tnum = 2;
757 28 : S->pages = "159-174";
758 28 : S->g = cyclic(1);
759 28 : 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 2562 : ssQ_red(long a, long b, long *n, long *d)
790 : {
791 2562 : long g = ugcd(labs(a), b);
792 2562 : if (g > 1) { a /= g; b /= g; }
793 2562 : *n = a; *d = b;
794 2562 : }
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 280 : 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 280 : ssQ_red(a, b, &A,&B);
819 280 : ssQ_red(c, d, &C,&D);
820 280 : g = ugcd(B,D);
821 280 : *n = B * (D/g);
822 280 : *r = umodsu(A * (D/g), *n);
823 280 : *q = umodsu(C * (B/g), *n);
824 280 : }
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 371 : tame_234_init(struct igusa *I, struct igusa_p *Ip, long *n, long *q, long *r)
872 : {
873 371 : long va0, va5, vb2, v12 = -1, flc = 1;
874 371 : GEN p = Ip->p;
875 371 : switch(Ip->tt)
876 : {
877 175 : case 2: v12 = myval(I->i12, Ip->p); break;
878 98 : case 3: v12 = 3*myval(I->i4, Ip->p); break;
879 98 : case 4: v12 = 6*myval(I->j2, Ip->p); break;
880 : }
881 371 : va0 = myval(I->a0,p);
882 371 : va5 = myval(I->A5,p);
883 371 : vb2 = myval(I->B2,p);
884 371 : if (9*vb2 >= 6*va0+v12 && 36*va5 >= 120*va0+5*v12)
885 : {
886 84 : get_nrq(12*va0-v12,36, 6*va0-v12,12, n, r, q);
887 : }
888 287 : 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 196 : get_nrq(v12-6*vb2,12, v12-9*vb2,12, n,r,q);
896 196 : flc = 0;
897 : }
898 371 : return flc;
899 : }
900 :
901 : /* Ip->tt = 2 */
902 : static long
903 175 : tame_2(struct igusa *I, struct igusa_p *Ip)
904 : {
905 175 : long condp = -1, d, n, q, r;
906 175 : GEN val = Ip->val;
907 175 : (void)tame_234_init(I, Ip, &n, &q, &r);
908 175 : d = n * (6*val[6]-5*val[7]) / 6;
909 175 : switch(n)
910 : {
911 14 : case 1: condp = 1;
912 14 : Ip->type = stack_sprintf("[I{%ld-0-0}] page 170", d);
913 14 : Ip->abe = Ip->tor = 1;
914 14 : 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 175 : return condp;
1004 : }
1005 :
1006 : /* Ip->tt = 3 */
1007 : static long
1008 98 : tame_3(struct igusa *I, struct igusa_p *Ip)
1009 : {
1010 98 : long condp = -1, n, q, r, va5, d1, d2;
1011 98 : long flc = tame_234_init(I, Ip, &n, &q, &r);
1012 98 : GEN val = Ip->val;
1013 :
1014 98 : va5 = 2*val[6]-5*val[3];
1015 98 : d1 = minss(n * (val[7]-3*val[3]), n * va5 / 4);
1016 98 : d2 = n * va5 / 2 - d1;
1017 98 : switch(n)
1018 : {
1019 21 : case 1: condp = 2;
1020 21 : Ip->type = stack_sprintf("[I{%ld-%ld-0}] page 179", d1,d2);
1021 21 : Ip->abe = 0; Ip->tor = 2;
1022 21 : 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 98 : return condp;
1052 : }
1053 :
1054 : /* Ip->tt = 4 */
1055 : static long
1056 98 : tame_4(struct igusa *I, struct igusa_p *Ip)
1057 : {
1058 98 : long condp = -1, d1,d2,d3, f1,f2, g, h, n, q, r, vl,vn,vm, e1,e2,e3;
1059 98 : GEN val = Ip->val;
1060 98 : (void)tame_234_init(I, Ip, &n, &q, &r);
1061 98 : vl = val[6]-5*val[1];
1062 98 : vn = val[7]-6*val[1];
1063 98 : vm = val[2]-2*val[1]; /* all >= 0 */
1064 98 : e1 = min3(2*vl, 3*vn, 6*vm);
1065 98 : e2 = minss(6*vl - e1, 12*vn - 2*e1); /* >= 0 */
1066 98 : e3 = 12*vl - (2*e1+e2); /* >= 0 */
1067 98 : d1 = e1*n / 6;
1068 98 : d2 = e2*n / 12;
1069 98 : d3 = e3*n / 12;
1070 98 : g = d1*d2 + d1*d3 + d2*d3;
1071 98 : h = ugcd(ugcd(d1,d2),d3);
1072 98 : switch(n)
1073 : {
1074 14 : case 1: condp = 2;
1075 14 : Ip->type = stack_sprintf("[I{%ld-%ld-%ld}] page 182",d1,d2,d3);
1076 14 : Ip->abe = 0; Ip->tor = 2;
1077 14 : 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 98 : return condp;
1119 : }
1120 :
1121 : /* p = 3 */
1122 : static void
1123 91 : tame_567_init_3(struct igusa_p *Ip, long dk,
1124 : long *pd, long *pn, long *pdm, long *pr)
1125 : {
1126 91 : long n = 1 + Ip->r1/6;
1127 91 : *pd = n * dk / 36; /* / (12*Ip->eps) */
1128 91 : *pn = n;
1129 91 : *pr = -1; /* unused */
1130 91 : *pdm = 0;
1131 91 : }
1132 :
1133 : /* (4.3) */
1134 : static void
1135 1113 : 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 1113 : GEN p = Ip->p, val = Ip->val;
1140 :
1141 1113 : 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 140 : tame_7(struct igusa *I, struct igusa_p *Ip)
1609 : {
1610 140 : long condp = -1, d, D, d1, d2, n, dm, r, dk;
1611 140 : GEN val = Ip->val;
1612 :
1613 140 : dk = 3*(Ip->eps*val[3]-2*val[8]);
1614 140 : tame_567_init(I, Ip, dk, &d, &n, &dm, &r);
1615 140 : D = n * (Ip->eps*(val[6]-3*val[3])+val[8]) / Ip->eps;
1616 140 : d1 = minss(n * (val[7]-3*val[3]), D/2);
1617 140 : d2 = D - d1;
1618 : /* d1 <= d2 */
1619 140 : switch(n)
1620 : {
1621 49 : case 1: condp = 2;
1622 49 : Ip->type = stack_sprintf("[I{%ld}-I{%ld}-%ld] page 179",d1,d2,d);
1623 49 : Ip->abe = 0; Ip->tor = 2;
1624 49 : 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 126 : 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 1533 : tame(GEN polh, long t60, long alpha, long Dmin, struct igusa *I, struct igusa_p *Ip)
1662 : {
1663 : long d;
1664 1533 : Ip->tame = 1;
1665 1533 : switch(Ip->tt)
1666 : {
1667 49 : case 1: return tame_1(I,Ip);
1668 175 : case 2: return tame_2(I,Ip);
1669 98 : case 3: return tame_3(I,Ip);
1670 98 : 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 140 : default:d = tame_7(I,Ip); break;
1674 : }
1675 462 : if (d < 0) d = labelm3(polh,t60,alpha,Dmin,I,Ip); /* => tt=6 or 7 */
1676 462 : return d;
1677 : }
1678 :
1679 : /* maxc = maximum conductor valuation at p */
1680 : static long
1681 686 : get_maxc(GEN p)
1682 : {
1683 686 : switch (itos_or_0(p))
1684 : {
1685 0 : case 2: return 20; break;
1686 301 : case 3: return 10; break;
1687 14 : case 5: return 9; break;
1688 371 : 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 301 : 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 301 : GEN val = Ip->val, p = Ip->p;
1768 301 : long condp = -1, indice, d, page;
1769 :
1770 301 : 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 175 : 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 154 : 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 126 : if (Ip->tt == 7) pari_err_BUG("litredtp [switch ri]");
1830 : {
1831 126 : struct red __S1, __S2, *S1 = &__S1, *S2 = &__S2;
1832 126 : long f1 = get_red(S1, Ip, polh1, p, alpha1, Ip->r1);
1833 126 : long f2 = get_red(S2, Ip, polh, p, alpha, Ip->r2);
1834 : /* reorder to normalize representation */
1835 126 : if (S1->tnum > S2->tnum || (S1->tnum == S2->tnum && f1 > f2))
1836 56 : { struct red *S = S1; S1 = S2; S2 = S; }
1837 126 : Ip->type = stack_sprintf("[%s-%s-%ld] pages %s", S1->t,S2->t, R, S1->pages);
1838 126 : Ip->neron = shallowconcat(S1->g, S2->g);
1839 126 : condp = Dmin - (f1 + f2) + ((R >= 0)? 2-12*R: 4);
1840 : }
1841 126 : if (condp > get_maxc(p)) pari_err_BUG("litredtp [conductor]");
1842 126 : return condp;
1843 : }
1844 :
1845 : static long
1846 280 : labelm3(GEN h1, long t60_1, long alpha1, long Dmin, struct igusa *I, struct igusa_p *Ip)
1847 : {
1848 280 : GEN h, pm, vs, val = Ip->val, p = Ip->p;
1849 : long alpha, t60, lambda, beta, R;
1850 :
1851 280 : pm = polymini(ZX_Z_mul(RgX_recip6(h1), powiu(p,alpha1)), p);
1852 280 : h = gel(pm,1); vs = gel(pm,2);
1853 280 : lambda= vs[1];
1854 280 : t60 = vs[2];
1855 280 : alpha = vs[3];
1856 280 : beta = vs[5];
1857 280 : if (lambda != 3) pari_err_BUG("labelm3 [lambda != 3]");
1858 280 : R = beta-(alpha1+alpha);
1859 280 : if (odd(R)) pari_err_BUG("labelm3 [R odd]");
1860 280 : R /= 2;
1861 280 : if (R <= -2) pari_err_BUG("labelm3 [R <= -2]");
1862 280 : if (val[8] % (2*Ip->eps)) pari_err_BUG("labelm3 [val(eps2)]");
1863 280 : if (R >= 0 && (alpha+alpha1) >= 1) pari_err_BUG("labelm3 [minimal equation]");
1864 280 : Ip->r1 = t60_1 / 10 + 6*alpha1;
1865 280 : Ip->r2 = t60 / 10 + 6*alpha;
1866 280 : return litredtp(alpha, alpha1, t60, t60_1, h, h1, Dmin, R, I, Ip);
1867 : }
1868 :
1869 : /* p = 3 */
1870 : static long
1871 21 : quadratic(GEN polh, long alpha, long Dmin, struct igusa *I, struct igusa_p *Ip)
1872 : {
1873 21 : long alpha1 = alpha, beta, t6, R;
1874 21 : GEN vs = polymini_zi(ZX_Z_mul(polh, powiu(Ip->p,alpha)));
1875 21 : t6 = vs[1];
1876 21 : alpha = vs[2];
1877 21 : beta = vs[3];
1878 21 : R = beta-alpha;
1879 21 : if (R >= 0 && alpha1)
1880 : {
1881 0 : Dmin -= 10;
1882 0 : if (DEBUGLEVEL)
1883 0 : err_printf("(Care: minimal discriminant over Z[i] smaller than over Z)\n");
1884 : }
1885 21 : Ip->r2 = Ip->r1 = t6 + 6*alpha;
1886 21 : return litredtp(alpha, alpha, t6*10, t6*10, polh, polh, Dmin, R, I, Ip);
1887 : }
1888 :
1889 : static long
1890 2324 : 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 2324 : long condp = -1, indice, vc6, mm, nb, dism;
1895 :
1896 2324 : stable_reduction(I, Ip, p);
1897 2324 : val = Ip->val; Dmin = val[6];
1898 2324 : 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 2310 : if (Dmin == 1)
1906 : {
1907 14 : Ip->type = "[I{1-0-0}] page 170";
1908 14 : Ip->abe = Ip->tor = 1;
1909 14 : Ip->neron = cyclic(1); return 1;
1910 : }
1911 2296 : if (Dmin == 2) switch(Ip->tt)
1912 : {
1913 0 : case 2:
1914 0 : Ip->type = "[I{2-0-0}] page 170";
1915 0 : Ip->abe = Ip->tor = 1;
1916 0 : Ip->neron = cyclic(2); return 1;
1917 0 : case 3:
1918 0 : Ip->type = "[I{1-1-0}] page 179";
1919 0 : Ip->abe = 0; Ip->tor = 2;
1920 0 : Ip->neron = cyclic(1); return 2;
1921 14 : case 5:
1922 14 : if (cmpis(p,3) <= 0) pari_err_BUG("genus2localred [tt 1]");
1923 14 : Ip->type = "[I{0}-II-0] page 159";
1924 14 : Ip->abe = 1; Ip->tor = 0;
1925 14 : Ip->neron = cyclic(1); return 2;
1926 0 : default: pari_err_BUG("genus2localred [tt 2]");
1927 : }
1928 2282 : if (absequaliu(p,2)) return -1;
1929 2261 : polh = gel(polmini,1); vs = gel(polmini,2);
1930 2261 : lambda = vs[1];
1931 2261 : t60 = vs[2];
1932 2261 : alpha = vs[3];
1933 2261 : if (vs[4]) return equaliu(p,3)? quadratic(polh, alpha, Dmin, I, Ip):
1934 0 : tame(polh, t60, alpha, Dmin, I, Ip);
1935 2240 : if (!t60 && lambda<= 2)
1936 : {
1937 7 : if (Ip->tt >= 5) pari_err_BUG("genus2localred [tt 3]");
1938 7 : return tame(polh, t60, alpha, Dmin, I, Ip);
1939 : }
1940 2233 : if (Dmin == 3)
1941 : {
1942 7 : switch(Ip->tt)
1943 : {
1944 0 : case 2: return tame(polh, t60, alpha, Dmin, I, Ip);
1945 0 : case 3:
1946 0 : Ip->type = "[I{2-1-0}] page 179";
1947 0 : Ip->abe = 0; Ip->tor = 2;
1948 0 : Ip->neron = cyclic(2);
1949 0 : return 2;
1950 7 : case 4:
1951 7 : Ip->type = "[I{1-1-1}] page 182";
1952 7 : Ip->abe = 0; Ip->tor = 2;
1953 7 : Ip->neron = cyclic(3);
1954 7 : 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 2226 : switch(lambda)
1968 : {
1969 595 : case 0:
1970 595 : switch(t60+alpha)
1971 : {
1972 14 : case 10:
1973 14 : condp = Dmin-1;
1974 14 : Ip->type = "[V] page 156";
1975 14 : 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 259 : 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 1183 : case 3:
2209 1183 : if (!equaliu(p,3) || Ip->tt <= 4)
2210 952 : return tame(polh, t60, alpha, Dmin, I, Ip);
2211 231 : return labelm3(polh,t60,alpha,Dmin,I,Ip); /* p = 3 */
2212 0 : default: pari_err_BUG("genus2localred [switch lambda]");
2213 : }
2214 476 : if (condp < 2 || condp > get_maxc(p))
2215 0 : pari_err_BUG("genus2localred [conductor]");
2216 476 : return condp;
2217 : }
2218 :
2219 : static GEN
2220 2282 : hyperellintegralmodel(GEN PQ)
2221 : {
2222 : GEN D;
2223 2282 : PQ = Q_remove_denom(PQ, &D);
2224 2282 : 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 2282 : genus2red(GEN PQ, GEN p)
2235 : {
2236 2282 : 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 2282 : PQ = hyperellminimalmodel(hyperellintegralmodel(PQ), NULL, p ? mkvec(p): p);
2242 2282 : P = gel(PQ,1);
2243 2282 : Q = gel(PQ,2);
2244 2282 : if (p && typ(p) != t_INT) pari_err_TYPE("genus2red", p);
2245 :
2246 2282 : polr = ZX_add(ZX_sqr(Q), gmul2n(P,2)); /* ZX */
2247 2282 : switch(degpol(polr))
2248 : {
2249 2282 : case 5: case 6: break;
2250 0 : default: pari_err_DOMAIN("genus2red","genus","!=", gen_2,mkvec2(P,Q));
2251 : }
2252 :
2253 2282 : RgX_to_03(polr, &a0,&a1,&a2,&a3);
2254 2282 : I.j10 = !signe(a0)? mulii(sqri(a1), ZX_disc(polr)): ZX_disc(polr);
2255 2282 : if (!signe(I.j10))
2256 0 : pari_err_DOMAIN("genus2red","genus","<",gen_2,mkvec2(P,Q));
2257 2282 : I.j10 = gmul2n(I.j10, -12); /* t_INT */
2258 :
2259 2282 : if (p == NULL)
2260 : {
2261 49 : facto = absZ_factor(I.j10);
2262 49 : factp = gel(facto,1);
2263 : }
2264 : else
2265 : {
2266 2233 : factp = mkcol(p);
2267 2233 : facto = mkmat2(factp, mkcol(gen_1));
2268 : }
2269 2282 : l = lg(factp);
2270 2282 : vecmini = cgetg(l, t_COL);
2271 4606 : for(i = 1; i<l; i++)
2272 : {
2273 2324 : GEN l = gel(factp,i), pm;
2274 2324 : if (i == 1 && absequaliu(l, 2)) { gel(vecmini,1) = gen_0; continue; }
2275 2303 : gel(vecmini,i) = pm = polymini(polr, l);
2276 2303 : polr = ZX_Q_mul(gel(pm,1), powiu(l, gel(pm,2)[3]));
2277 : }
2278 2282 : RgX_to_06(polr, &a0,&a1,&a2,&a3,&a4,&a5,&a6);
2279 2282 : I.j10 = !signe(a0)? mulii(sqri(a1), ZX_disc(polr)): ZX_disc(polr);
2280 2282 : I.j10 = gmul2n(I.j10,-12);
2281 :
2282 2282 : I.a0 = a0;
2283 2282 : I.A2 = apol2(a0,a1,a2);
2284 2282 : I.A3 = apol3(a0,a1,a2,a3);
2285 2282 : I.A5 = apol5(a0,a1,a2,a3,a4,a5);
2286 2282 : I.B2 = bpol2(a0,a1,a2,a3,a4);
2287 :
2288 2282 : I.j2 = igusaj2(a0,a1,a2,a3,a4,a5,a6);
2289 2282 : I.j4 = igusaj4(a0,a1,a2,a3,a4,a5,a6);
2290 2282 : I.i4 = gsub(gsqr(I.j2), gmulsg(24,I.j4));
2291 2282 : I.j6 = igusaj6(a0,a1,a2,a3,a4,a5,a6);
2292 2282 : j42 = gsqr(I.j4);
2293 2282 : j22 = gsqr(I.j2);
2294 2282 : j2j6 = gmul(I.j2,I.j6);
2295 2282 : I.j8 = gmul2n(gsub(j2j6,j42), -2);
2296 2282 : 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 4606 : for(i = 1; i < l; i++)
2300 2324 : gcoeff(facto,i,2) = stoi(Q_pval(I.j10, gel(factp,i)));
2301 2282 : dd = ZX_pval(polr,gen_2) & (~1); /* = 2 floor(val/2) */
2302 2282 : polr = gmul2n(polr, -dd);
2303 :
2304 2282 : V = cgetg(l, t_VEC);
2305 4606 : for (i = 1; i < l; i++)
2306 : {
2307 2324 : GEN q = gel(factp,i), red, N = NULL;
2308 : struct igusa_p Ip;
2309 2324 : long f = genus2localred(&I, &Ip, q, gel(vecmini,i));
2310 2324 : gcoeff(facto,i,2) = stoi(f);
2311 2324 : if (Ip.tame) Ip.type = stack_strcat("(tame) ", Ip.type);
2312 2324 : if (f >= 0)
2313 2303 : N = zv_snf(Ip.neron);
2314 2324 : 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 2324 : red = f >= 0? mkvec2(strtoGENstr(Ip.type), N): cgetg(1, t_VEC);
2324 2324 : gel(V, i) = mkvec4(q, Ip.stable, red, mkvecsmall3(Ip.abe,Ip.tor,2-(Ip.tor+Ip.abe)));
2325 : }
2326 2282 : if (p) V = gel(V,1);
2327 2282 : cond = factorback(facto);
2328 : /* remove denominator 2 coming from f = -1 in genuslocalred(, p = 2) */
2329 2282 : if (typ(cond) != t_INT) cond = gel(cond,1);
2330 2282 : return gerepilecopy(av, mkvec4(cond, facto, PQ, V));
2331 : }
|