@@ -1766,6 +1766,7 @@ void walk_v(t_level *cur_level, mpz_t start) {
17661766 fail ("TODO: walk_v.end > 2^64" );
17671767}
17681768
1769+ /* test the case where v_i has all divisors accounted for */
17691770void walk_1 (t_level * cur_level , uint vi ) {
17701771#ifdef SQONLY
17711772 if (!cur_level -> have_square )
@@ -1836,6 +1837,101 @@ void walk_1(t_level *cur_level, uint vi) {
18361837 return ;
18371838}
18381839
1840+ /* test a set of cases where v_i will have all divisors accounted for */
1841+ void walk_1_set (t_level * cur_level , uint vi , ulong plow , ulong phigh , uint x ) {
1842+ #ifdef SQONLY
1843+ if (!cur_level -> have_square )
1844+ return ;
1845+ #endif
1846+ if (minp && cur_level -> maxp <= minp )
1847+ plow = minp ;
1848+
1849+ uint t [k ];
1850+ uint need_prime [k ];
1851+ uint need_square [k ];
1852+ uint need_other [k ];
1853+ uint npc = 0 , nqc = 0 , noc = 0 ;
1854+ for (uint vj = 0 ; vj < k ; ++ vj ) {
1855+ if (vi == vj )
1856+ continue ;
1857+ t_value * vjp = & value [vj ];
1858+ t_allocation * ajp = (vjp -> vlevel ) ? & vjp -> alloc [vjp -> vlevel - 1 ] : NULL ;
1859+ t [vj ] = ajp ? ajp -> t : n ;
1860+ if (t [vj ] == 1 )
1861+ fail ("should never see multiple values with t==1" );
1862+ if (t [vj ] == 2 )
1863+ need_prime [npc ++ ] = vj ;
1864+ else if (t [vj ] & 1 )
1865+ need_prime [npc ++ ] = vj ;
1866+ else
1867+ need_other [noc ++ ] = vj ;
1868+ }
1869+
1870+ level_setp (cur_level , plow );
1871+ t_value * vip = & value [vi ];
1872+ t_allocation * aip = vip -> vlevel ? & vip -> alloc [vip -> vlevel - 1 ] : NULL ;
1873+ while (1 ) {
1874+ ulong p = prime_iterator_next (& cur_level -> piter );
1875+ if (p > phigh )
1876+ break ;
1877+ if (need_work ) {
1878+ /* temporarily make this prime power visible to diag code */
1879+ t_allocation * a2ip = & vip -> alloc [vip -> vlevel ++ ];
1880+ a2ip -> p = p ;
1881+ a2ip -> x = x ;
1882+ diag_plain ();
1883+ -- vip -> vlevel ;
1884+ }
1885+ mpz_ui_pow_ui (Z (w1_v ), p , x - 1 );
1886+ if (aip )
1887+ mpz_mul (Z (w1_v ), Z (w1_v ), aip -> q );
1888+ mpz_sub_ui (Z (w1_v ), Z (w1_v ), TYPE_OFFSET (vi ));
1889+
1890+ if (mpz_cmp (Z (w1_v ), min ) < 0 )
1891+ break ;
1892+ ++ countw ;
1893+
1894+ for (uint vj = 0 ; vj < k ; ++ vj ) {
1895+ t_value * vjp = & value [vj ];
1896+ t_allocation * ajp = (vjp -> vlevel ) ? & vjp -> alloc [vjp -> vlevel - 1 ]
1897+ : NULL ;
1898+ mpz_add_ui (Z (w1_j ), Z (w1_v ), TYPE_OFFSET (vj ));
1899+ if (ajp ) {
1900+ mpz_fdiv_qr (Z (w1_j ), Z (w1_r ), Z (w1_j ), ajp -> q );
1901+ if (mpz_sgn (Z (w1_r )) != 0 )
1902+ goto reject_this_one ;
1903+ mpz_gcd (Z (w1_r ), Z (w1_j ), ajp -> q );
1904+ if (mpz_cmp (Z (w1_r ), Z (zone )) != 0 )
1905+ goto reject_this_one ;
1906+ }
1907+ mpz_set (wv_o [vj ], Z (w1_j ));
1908+ }
1909+ ++ countwi ;
1910+ for (uint i = 0 ; i < npc ; ++ i )
1911+ if (!_GMP_is_prob_prime (wv_o [need_prime [i ]]))
1912+ goto reject_this_one ;
1913+ for (uint i = 0 ; i < nqc ; ++ i )
1914+ if (!is_taux (wv_o [need_square [i ]], t [need_square [i ]], 1 ))
1915+ goto reject_this_one ;
1916+ oc_t = t ;
1917+ qsort (need_other , noc , sizeof (uint ), & other_comparator );
1918+ #ifdef PARALLEL
1919+ if (!test_1multi (need_other , noc , t ))
1920+ goto reject_this_one ;
1921+ #else
1922+ for (uint i = 0 ; i < noc ; ++ i )
1923+ if (!is_taux (wv_o [need_other [i ]], t [need_other [i ]], 1 ))
1924+ goto reject_this_one ;
1925+ #endif
1926+ candidate (Z (w1_v ));
1927+ if (improve_max )
1928+ return ;
1929+ reject_this_one :
1930+ ;
1931+ }
1932+ return ;
1933+ }
1934+
18391935/* When some v_j is known to be of the form m.z^g, we keep a running set
18401936 * of possible values of z: z == ((rq + i)/q_j)^{ 1/g } mod aq/q_j.
18411937 * If no such residues exist, this returns FALSE to signal that this
@@ -2878,6 +2974,11 @@ e_pux prep_unforced_x(t_level *prev, t_level *cur, ulong p, bool forced) {
28782974 return PUX_ALL_DONE ;
28792975 } else if (limp < p + 1 )
28802976 return PUX_SKIP_THIS_X ; /* nothing to do here */
2977+ if (nextt == 1 ) {
2978+ walk_1_set (cur , vi , p , limp , x );
2979+ return PUX_SKIP_THIS_X ;
2980+ }
2981+
28812982 mpz_add_ui (Z (r_walk ), max , vi );
28822983#ifdef LARGE_MIN
28832984 mpz_sub (Z (r_walk ), Z (r_walk ), min );
0 commit comments