Added compute_forgetful_signs to main. Set up mpimain to compute
forgetful spectral sequence over Z/97 for all links with 14 or fewer crossings.
This commit is contained in:
parent
177b37bb57
commit
f2375a2d9e
17
cube_impl.h
17
cube_impl.h
@ -365,6 +365,13 @@ cube<R>::compute_dinv (unsigned c)
|
||||
if (!unsigned_bittest (i, c))
|
||||
continue;
|
||||
|
||||
int sign = 1;
|
||||
for (unsigned j = 1; j < c; j ++)
|
||||
{
|
||||
if (unsigned_bittest (i, j))
|
||||
sign *= -1;
|
||||
}
|
||||
|
||||
smoothing from_s (kd, smallbitset (n_crossings, i));
|
||||
|
||||
unsigned i2 = unsigned_bitclear (i, c);
|
||||
@ -398,12 +405,12 @@ cube<R>::compute_dinv (unsigned c)
|
||||
j2 = unsigned_bitset (j2, x);
|
||||
j2 = unsigned_bitclear (j2, y);
|
||||
|
||||
p[generator (i, j)].muladd (1, generator (i2, j2));
|
||||
p[generator (i, j)].muladd (sign, generator (i2, j2));
|
||||
|
||||
j2 = unsigned_bitclear (j2, x);
|
||||
j2 = unsigned_bitset (j2, y);
|
||||
|
||||
p[generator (i, j)].muladd (1, generator (i2, j2));
|
||||
p[generator (i, j)].muladd (sign, generator (i2, j2));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -411,7 +418,7 @@ cube<R>::compute_dinv (unsigned c)
|
||||
j2 = unsigned_bitclear (j2, x);
|
||||
j2 = unsigned_bitclear (j2, y);
|
||||
|
||||
p[generator (i, j)].muladd (1, generator (i2, j2));
|
||||
p[generator (i, j)].muladd (sign, generator (i2, j2));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -425,7 +432,7 @@ cube<R>::compute_dinv (unsigned c)
|
||||
// 1 -> 1
|
||||
j2 = unsigned_bitset (j2, x);
|
||||
|
||||
p[generator (i, j)].muladd (1, generator (i2, j2));
|
||||
p[generator (i, j)].muladd (sign, generator (i2, j2));
|
||||
}
|
||||
else if ((unsigned_bittest (j, a)
|
||||
&& !unsigned_bittest (j, b))
|
||||
@ -435,7 +442,7 @@ cube<R>::compute_dinv (unsigned c)
|
||||
// a, b -> x
|
||||
j2 = unsigned_bitclear (j2, x);
|
||||
|
||||
p[generator (i, j)].muladd (1, generator (i2, j2));
|
||||
p[generator (i, j)].muladd (sign, generator (i2, j2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ knot_diagram::knot_diagram (const planar_diagram &pd)
|
||||
crossings[c] = basedvector<unsigned, 1> (4);
|
||||
}
|
||||
|
||||
smallbitset done (num_edges ());
|
||||
set<unsigned> done;
|
||||
for (unsigned c0 = 1; c0 <= n_crossings; c0 ++)
|
||||
{
|
||||
for (unsigned i0 = 1; i0 <= 2; i0 ++)
|
||||
@ -521,6 +521,63 @@ knot_diagram::rotate_crossing (unsigned c)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
knot_diagram::total_linking_number () const
|
||||
{
|
||||
unionfind<1> u (num_edges ());
|
||||
|
||||
for (unsigned i = 1; i <= n_crossings; i ++)
|
||||
{
|
||||
u.join (ept_edge (crossings[i][1]),
|
||||
ept_edge (crossings[i][3]));
|
||||
u.join (ept_edge (crossings[i][2]),
|
||||
ept_edge (crossings[i][4]));
|
||||
}
|
||||
unsigned n = u.num_sets ();
|
||||
|
||||
map<unsigned, unsigned> root_comp;
|
||||
unsigned t = 0;
|
||||
for (unsigned i = 1; i <= num_edges (); i ++)
|
||||
{
|
||||
if (u.find (i) == i)
|
||||
{
|
||||
++ t;
|
||||
root_comp.push (i, t);
|
||||
}
|
||||
}
|
||||
assert (t == n);
|
||||
|
||||
unsigned total_lk = 0;
|
||||
|
||||
for (unsigned i = 1; i <= n; i ++)
|
||||
for (unsigned j = i + 1; j <= n; j ++)
|
||||
{
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
int lk = 0;
|
||||
for (unsigned x = 1; x <= n_crossings; x ++)
|
||||
{
|
||||
unsigned r1 = root_comp(u.find (ept_edge (crossings[x][1]))),
|
||||
r2 = root_comp(u.find (ept_edge (crossings[x][2])));
|
||||
if (((r1 == i) && (r2 == j))
|
||||
|| ((r2 == i) && (r1 == j)))
|
||||
{
|
||||
if (is_to_ept (crossings[x][1]) == is_to_ept (crossings[x][4]))
|
||||
lk ++;
|
||||
else
|
||||
lk --;
|
||||
}
|
||||
}
|
||||
assert (is_even (lk));
|
||||
lk /= 2;
|
||||
|
||||
total_lk += std::abs (lk);
|
||||
}
|
||||
|
||||
return total_lk;
|
||||
}
|
||||
|
||||
knot_diagram::knot_diagram (connect_sum,
|
||||
const knot_diagram &d1,
|
||||
const knot_diagram &d2)
|
||||
|
@ -157,6 +157,8 @@ class knot_diagram
|
||||
|
||||
int writhe () const { return (int)nplus - (int)nminus; }
|
||||
|
||||
unsigned total_linking_number () const;
|
||||
|
||||
basedvector<basedvector<int, 1>, 1> planar_diagram_crossings () const;
|
||||
|
||||
hash_t hash_self () const;
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
#include <knotkit.h>
|
||||
|
||||
#define HOME "/u/cseed/src/knotkit/"
|
||||
#define HOME "/Users/cotton/src/knotkit/"
|
||||
|
||||
bool verbose = 0;
|
||||
|
||||
|
180
main.cpp
180
main.cpp
@ -849,6 +849,183 @@ test_forgetful_ss ()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_forgetful_signs ()
|
||||
{
|
||||
typedef Zp<97> R;
|
||||
|
||||
#if 0
|
||||
for (unsigned i = 1; i <= 14; i ++)
|
||||
for (unsigned j = 1; j <= mt_links (i, 0); j ++)
|
||||
{
|
||||
knot_diagram kd (mt_link (i, 0, j));
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
for (unsigned i = 2; i <= 16; i ++)
|
||||
for (unsigned j = i; j <= 16; j ++)
|
||||
{
|
||||
knot_diagram kd (torus_knot (i, j));
|
||||
assert (kd.n_crossings == (i - 1) * j
|
||||
&& kd.n_crossings <= i * (j - 1));
|
||||
if (kd.n_crossings > 13)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
unsigned n = kd.num_components ();
|
||||
if (n < 2)
|
||||
continue;
|
||||
assert (n < 97);
|
||||
|
||||
show (kd); newline ();
|
||||
|
||||
unionfind<1> u (kd.num_edges ());
|
||||
for (unsigned i = 1; i <= kd.n_crossings; i ++)
|
||||
{
|
||||
u.join (kd.ept_edge (kd.crossings[i][1]),
|
||||
kd.ept_edge (kd.crossings[i][3]));
|
||||
u.join (kd.ept_edge (kd.crossings[i][2]),
|
||||
kd.ept_edge (kd.crossings[i][4]));
|
||||
}
|
||||
|
||||
map<unsigned, unsigned> root_comp;
|
||||
unsigned t = 0;
|
||||
for (unsigned i = 1; i <= kd.num_edges (); i ++)
|
||||
{
|
||||
if (u.find (i) == i)
|
||||
{
|
||||
++ t;
|
||||
root_comp.push (i, t);
|
||||
}
|
||||
}
|
||||
assert (t == n);
|
||||
|
||||
basedvector<R, 1> comp_weight (n);
|
||||
for (unsigned i = 1; i <= n; i ++)
|
||||
comp_weight[i] = R ((int)i);
|
||||
|
||||
map<unsigned, R> crossing_over_sign;
|
||||
|
||||
// crossings
|
||||
set<unsigned> pending;
|
||||
set<unsigned> finished;
|
||||
|
||||
crossing_over_sign.push (1, R (1));
|
||||
pending.push (1);
|
||||
|
||||
while (pending.card () > 0)
|
||||
{
|
||||
unsigned x = pending.pop ();
|
||||
finished.push (x);
|
||||
|
||||
R s = crossing_over_sign(x);
|
||||
|
||||
for (unsigned j = 1; j <= 4; j ++)
|
||||
{
|
||||
unsigned p = kd.crossings[x][j];
|
||||
R t = kd.is_over_ept (p) ? s : -s; // sign of (x, p)
|
||||
|
||||
unsigned q = kd.edge_other_ept (p);
|
||||
unsigned x2 = kd.ept_crossing[q];
|
||||
|
||||
R u = kd.is_over_ept (q) ? -t : t;
|
||||
|
||||
if (crossing_over_sign % x2)
|
||||
assert (crossing_over_sign(x2) == u);
|
||||
else
|
||||
crossing_over_sign.push (x2, u);
|
||||
|
||||
if (! (finished % x2))
|
||||
pending += x2;
|
||||
}
|
||||
}
|
||||
assert (finished.card () == kd.n_crossings);
|
||||
|
||||
#if 0
|
||||
printf ("crossing_over_sign:\n");
|
||||
for (unsigned i = 1; i <= kd.n_crossings; i ++)
|
||||
{
|
||||
printf (" % 2d: ", i);
|
||||
display (crossing_over_sign(i));
|
||||
}
|
||||
#endif
|
||||
|
||||
cube<R> c (kd);
|
||||
#if 0
|
||||
for (unsigned i = 0; i < c.n_resolutions; i ++)
|
||||
{
|
||||
smallbitset state (kd.n_crossings, i);
|
||||
smoothing s (kd, state);
|
||||
s.show_self (kd, state);
|
||||
newline ();
|
||||
}
|
||||
#endif
|
||||
|
||||
mod_map<R> untwisted_d = c.compute_d (1, 0, 0, 0, 0);
|
||||
assert (untwisted_d.compose (untwisted_d) == 0);
|
||||
|
||||
mod_map<R> d = untwisted_d;
|
||||
for (unsigned x = 1; x <= kd.n_crossings; x ++)
|
||||
{
|
||||
unsigned p1 = kd.crossings[x][1],
|
||||
p2 = kd.crossings[x][2];
|
||||
assert (kd.is_over_ept (p2));
|
||||
|
||||
unsigned r1 = u.find (kd.ept_edge (p1)),
|
||||
r2 = u.find (kd.ept_edge (p2));
|
||||
|
||||
unsigned c1 = root_comp(r1),
|
||||
c2 = root_comp(r2);
|
||||
|
||||
if (c1 != c2)
|
||||
{
|
||||
R s = crossing_over_sign(x);
|
||||
|
||||
R w_under = comp_weight[c1];
|
||||
R w_over = comp_weight[c2];
|
||||
|
||||
d = d + c.compute_dinv (x)*(s*(w_over - w_under))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// display ("d:\n", d);
|
||||
|
||||
// mod_map<Z> h = d.compose (d);
|
||||
// display ("h:\n", h);
|
||||
|
||||
assert (d.compose (d) == 0);
|
||||
|
||||
ptr<const module<R> > Ek = c.khC;
|
||||
mod_map<R> dk = d;
|
||||
|
||||
unsigned kinf;
|
||||
for (int dq = 0;; dq -= 2)
|
||||
{
|
||||
chain_complex_simplifier<R> s (Ek, dk, dq);
|
||||
Ek = s.new_C;
|
||||
dk = s.new_d;
|
||||
|
||||
printf ("|E%d| = %d\n", ((- dq) / 2) + 1, Ek->dim ());
|
||||
if (dk == 0)
|
||||
{
|
||||
kinf = ((- dq) / 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned total_lk = kd.total_linking_number ();
|
||||
|
||||
unsigned trivial_bound = total_lk == 0 ? 2 : total_lk;
|
||||
|
||||
printf ("kinf = %d, trivial bound = %d (total_lk = %d)\n",
|
||||
kinf, trivial_bound, total_lk);
|
||||
|
||||
if (trivial_bound < kinf)
|
||||
printf (" > BETTER\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Kh homotopy type:
|
||||
- check for CP^2,
|
||||
- mutation invariance
|
||||
@ -1578,6 +1755,9 @@ convert_15 ()
|
||||
int
|
||||
main ()
|
||||
{
|
||||
test_forgetful_signs ();
|
||||
return 0;
|
||||
|
||||
find_width4_in_h0 ();
|
||||
// convert_15 ();
|
||||
// test_knot_sq ();
|
||||
|
240
mpimain.cpp
240
mpimain.cpp
@ -14,11 +14,24 @@ master ()
|
||||
{
|
||||
basedvector<knot_desc, 1> work;
|
||||
|
||||
for (unsigned i = 1; i <= 14; i ++)
|
||||
for (unsigned j = 1; j <= mt_links (i, 0); j ++)
|
||||
{
|
||||
knot_diagram kd (mt_links (i, 0, j));
|
||||
unsigned n = kd.num_components ();
|
||||
if (n < 2)
|
||||
continue;
|
||||
|
||||
work.append (knot_desc (knot_desc::MT, i, j));
|
||||
}
|
||||
|
||||
#if 0
|
||||
basedvector<basedvector<unsigned, 1>, 1> groups = mutant_knot_groups (15);
|
||||
|
||||
for (unsigned i = 1; i <= groups.size (); i ++)
|
||||
for (unsigned j = 1; j <= groups[i].size (); j ++)
|
||||
work.append (knot_desc (knot_desc::HTW, 15, groups[i][j]));
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
for (unsigned i = 14; i >= 1; i --)
|
||||
@ -87,6 +100,198 @@ master ()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
file_exists (const char *file)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
if (stat (file, &stat_buf) != 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
stderror ("stat: %s", file);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
compute_forgetful (int rank, knot_desc desc, const char *buf)
|
||||
{
|
||||
knot_diagram kd = desc.diagram ();
|
||||
|
||||
typedef Zp<97> R;
|
||||
|
||||
unsigned n = kd.num_components ();
|
||||
assert (n >= 2);
|
||||
assert (n < 97);
|
||||
|
||||
printf ("[% 2d] ", rank);
|
||||
show (kd);
|
||||
newline ();
|
||||
|
||||
unionfind<1> u (kd.num_edges ());
|
||||
for (unsigned i = 1; i <= kd.n_crossings; i ++)
|
||||
{
|
||||
u.join (kd.ept_edge (kd.crossings[i][1]),
|
||||
kd.ept_edge (kd.crossings[i][3]));
|
||||
u.join (kd.ept_edge (kd.crossings[i][2]),
|
||||
kd.ept_edge (kd.crossings[i][4]));
|
||||
}
|
||||
|
||||
map<unsigned, unsigned> root_comp;
|
||||
unsigned t = 0;
|
||||
for (unsigned i = 1; i <= kd.num_edges (); i ++)
|
||||
{
|
||||
if (u.find (i) == i)
|
||||
{
|
||||
++ t;
|
||||
root_comp.push (i, t);
|
||||
}
|
||||
}
|
||||
assert (t == n);
|
||||
|
||||
basedvector<R, 1> comp_weight (n);
|
||||
for (unsigned i = 1; i <= n; i ++)
|
||||
comp_weight[i] = R ((int)i);
|
||||
|
||||
map<unsigned, R> crossing_over_sign;
|
||||
|
||||
// crossings
|
||||
set<unsigned> pending;
|
||||
set<unsigned> finished;
|
||||
|
||||
crossing_over_sign.push (1, R (1));
|
||||
pending.push (1);
|
||||
|
||||
while (pending.card () > 0)
|
||||
{
|
||||
unsigned x = pending.pop ();
|
||||
finished.push (x);
|
||||
|
||||
R s = crossing_over_sign(x);
|
||||
|
||||
for (unsigned j = 1; j <= 4; j ++)
|
||||
{
|
||||
unsigned p = kd.crossings[x][j];
|
||||
R t = kd.is_over_ept (p) ? s : -s; // sign of (x, p)
|
||||
|
||||
unsigned q = kd.edge_other_ept (p);
|
||||
unsigned x2 = kd.ept_crossing[q];
|
||||
|
||||
R u = kd.is_over_ept (q) ? -t : t;
|
||||
|
||||
if (crossing_over_sign % x2)
|
||||
assert (crossing_over_sign(x2) == u);
|
||||
else
|
||||
crossing_over_sign.push (x2, u);
|
||||
|
||||
if (! (finished % x2))
|
||||
pending += x2;
|
||||
}
|
||||
}
|
||||
assert (finished.card () == kd.n_crossings);
|
||||
|
||||
#if 0
|
||||
printf ("crossing_over_sign:\n");
|
||||
for (unsigned i = 1; i <= kd.n_crossings; i ++)
|
||||
{
|
||||
printf (" % 2d: ", i);
|
||||
display (crossing_over_sign(i));
|
||||
}
|
||||
#endif
|
||||
|
||||
cube<R> c (kd);
|
||||
#if 0
|
||||
for (unsigned i = 0; i < c.n_resolutions; i ++)
|
||||
{
|
||||
smallbitset state (kd.n_crossings, i);
|
||||
smoothing s (kd, state);
|
||||
s.show_self (kd, state);
|
||||
newline ();
|
||||
}
|
||||
#endif
|
||||
|
||||
mod_map<R> untwisted_d = c.compute_d (1, 0, 0, 0, 0);
|
||||
assert (untwisted_d.compose (untwisted_d) == 0);
|
||||
|
||||
mod_map<R> d = untwisted_d;
|
||||
for (unsigned x = 1; x <= kd.n_crossings; x ++)
|
||||
{
|
||||
unsigned p1 = kd.crossings[x][1],
|
||||
p2 = kd.crossings[x][2];
|
||||
assert (kd.is_over_ept (p2));
|
||||
|
||||
unsigned r1 = u.find (kd.ept_edge (p1)),
|
||||
r2 = u.find (kd.ept_edge (p2));
|
||||
|
||||
unsigned c1 = root_comp(r1),
|
||||
c2 = root_comp(r2);
|
||||
|
||||
if (c1 != c2)
|
||||
{
|
||||
R s = crossing_over_sign(x);
|
||||
|
||||
R w_under = comp_weight[c1];
|
||||
R w_over = comp_weight[c2];
|
||||
|
||||
d = d + c.compute_dinv (x)*(s*(w_over - w_under))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// display ("d:\n", d);
|
||||
|
||||
// mod_map<Z> h = d.compose (d);
|
||||
// display ("h:\n", h);
|
||||
|
||||
assert (d.compose (d) == 0);
|
||||
|
||||
ptr<const module<R> > Ek = c.khC;
|
||||
mod_map<R> dk = d;
|
||||
|
||||
basedvector<multivariate_laurentpoly<Z>, 1> pages;
|
||||
|
||||
unsigned kinf;
|
||||
for (int dq = 0;; dq -= 2)
|
||||
{
|
||||
chain_complex_simplifier<R> s (Ek, dk, dq);
|
||||
Ek = s.new_C;
|
||||
dk = s.new_d;
|
||||
|
||||
pages.append (Ek->free_poincare_polynomial ());
|
||||
|
||||
printf ("[% 2d] ", rank);
|
||||
printf ("|E%d| = %d\n", ((- dq) / 2) + 1, Ek->dim ());
|
||||
if (dk == 0)
|
||||
{
|
||||
kinf = ((- dq) / 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned total_lk = kd.total_linking_number ();
|
||||
|
||||
unsigned trivial_bound = total_lk == 0 ? 2 : total_lk;
|
||||
|
||||
printf ("[% 2d] ", rank);
|
||||
printf ("kinf = %d, trivial bound = %d (total_lk = %d)\n",
|
||||
kinf, trivial_bound, total_lk);
|
||||
|
||||
if (trivial_bound < kinf)
|
||||
{
|
||||
printf ("[% 2d] ", rank);
|
||||
printf (" > BETTER\n");
|
||||
}
|
||||
fflush (stdout);
|
||||
|
||||
assert (desc.t == knot_desc::MT);
|
||||
gzfile_writer w (buf);
|
||||
write (w, desc);
|
||||
write (w, pages);
|
||||
}
|
||||
|
||||
void
|
||||
slave ()
|
||||
{
|
||||
@ -106,40 +311,13 @@ slave ()
|
||||
|
||||
printf ("[% 2d] CMD_DO %s\n", rank, desc.name ().c_str ());
|
||||
|
||||
assert (desc.t == knot_desc::MT);
|
||||
char buf[1000];
|
||||
sprintf (buf, "/scratch/network/cseed/incoming/K%d_%d.dat.gz",
|
||||
sprintf (buf, "/scratch/network/cseed/forgetful/L%d_%d.dat.gz",
|
||||
desc.i, desc.j);
|
||||
|
||||
struct stat stat_buf;
|
||||
if (stat (buf, &stat_buf) != 0)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
knot_diagram kd = desc.diagram ();
|
||||
|
||||
cube<Z2> c (kd);
|
||||
mod_map<Z2> d = c.compute_d (1, 0, 0, 0, 0);
|
||||
|
||||
chain_complex_simplifier<Z2> s (c.khC, d, 1);
|
||||
assert (s.new_d == 0);
|
||||
|
||||
steenrod_square sq (c, d, s);
|
||||
mod_map<Z2> sq1 = sq.sq1 ();
|
||||
mod_map<Z2> sq2 = sq.sq2 ();
|
||||
|
||||
assert (sq1.compose (sq1) == 0);
|
||||
assert (sq2.compose (sq2) + sq1.compose (sq2).compose (sq1) == 0);
|
||||
|
||||
gzfile_writer w (buf);
|
||||
write (w, sq1);
|
||||
write (w, sq2);
|
||||
}
|
||||
else
|
||||
{
|
||||
stderror ("stat: %s", buf);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (! file_exits ())
|
||||
compute_forgetful (rank, desc, buf);
|
||||
else
|
||||
printf ("skip %s: exists.\n", buf);
|
||||
|
||||
|
@ -63,7 +63,7 @@ class chain_complex_simplifier
|
||||
public:
|
||||
chain_complex_simplifier (ptr<const module<R> > C_,
|
||||
const mod_map<R> &d_,
|
||||
int dh);
|
||||
int dq);
|
||||
|
||||
};
|
||||
|
||||
@ -145,7 +145,7 @@ chain_complex_simplifier<R>::cancel (unsigned i, R b, unsigned j)
|
||||
template<class R>
|
||||
chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
|
||||
const mod_map<R> &d_,
|
||||
int dh)
|
||||
int dq)
|
||||
: C(C_), n(C_->dim ()), d(d_),
|
||||
new_d_columns(n),
|
||||
preim(n),
|
||||
@ -172,9 +172,8 @@ chain_complex_simplifier<R>::chain_complex_simplifier (ptr<const module<R> > C_,
|
||||
for (linear_combination_const_iter<R> j = new_d_columns[i]; j; j ++)
|
||||
{
|
||||
grading jgr = C->generator_grading (j.key ());
|
||||
// assert (jgr.h >= igr.h);
|
||||
if (j.val ().is_unit ()
|
||||
// && jgr.h - igr.h == dh
|
||||
&& jgr.q - igr.q == dq
|
||||
)
|
||||
{
|
||||
cancel (i, j.val (), j.key ());
|
||||
|
Loading…
Reference in New Issue
Block a user