Basic cohomology code for non prime power groups — "p_group_cohomology" 3.3.2 documentation

# Basic cohomology code for non prime power groups

This module contains `MODCOHO`, that provides a framework for the computation of the cohomology rings with coefficients in \(\mathbb F_p\) for any finite group.

It is based on the stable element method of Henri Cartan and Samuel Eilenberg [CartanEilenberg] and uses a completeness criterion based on the Poincaré series [King]. The stable element method involves the computation of cohomology rings of finite \(p\)-groups, which is based on the class `COHO`. See `pGroupCohomology` for an introduction.

AUTHORS:

- Simon King <simon.king@uni-jena.de>

`pGroupCohomology.modular_cohomology.` `COHO_from_key`(key)

  Auxiliary function for getting a cohomology ring out of some internal description.

  NOTE:

  This function is only of internal use. In future, this function should be replaced by a relational data base. The function returns the completed cohomology ring.

  TESTS:

      sage: from pGroupCohomology import CohomologyRing
      sage: from pGroupCohomology.modular_cohomology import COHO_from_key
      sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
      sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
      sage: H.make(3)

  We remove `H` from the cache. The cohomology of its underlying subgroup is still there, and is returned by `COHO_from_key`:

      sage: del CohomologyRing._cache[H._key]
      sage: H.subgroup_cohomology() is COHO_from_key(H.subgroup_cohomology()._key)
      True

  When calling for the cohomology key of `H`, it can not be found in the cache. Instead, it is reloaded from disk:

      sage: H is COHO_from_key(H._key)
      False

  In fact, it is not only reloaded, but it is completely computed, in contrast to `H`:

      sage: print(H)
      Cohomology ring of SmallGroup(720,763) with coefficients in GF(2)
      <BLANKLINE>
      Computed up to degree 3
      Minimal list of generators:
      [c_2_1: 2-Cocycle in H^*(SmallGroup(720,763); GF(2)),
       c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)),
       b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
       c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
      Minimal list of algebraic relations:
      []
      sage: print(COHO_from_key(H._key))
      Cohomology ring of SmallGroup(720,763) with coefficients in GF(2)
      <BLANKLINE>
      Computation complete
      Minimal list of generators:
      [c_2_1: 2-Cocycle in H^*(SmallGroup(720,763); GF(2)),
       c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)),
       b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
       c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
      Minimal list of algebraic relations:
      [b_3_3*c_3_2+c_2_1*c_1_0*b_3_3]

class `pGroupCohomology.modular_cohomology.` `MODCOHO`(G, p, HP, Subgroup, **kwds)

  Modular cohomology rings of finite groups that are not of prime power order.

  Normally, instances of this class should be created using the constructor `CohomologyRing()`, since this takes care of uniqueness of parent structures. See `CohomologyRing()` and `pGroupCohomology` for an introduction.

  EXAMPLES:

      sage: from pGroupCohomology import CohomologyRing
      sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
      sage: G = libgap.SmallGroup(48,36)
      sage: H1 = CohomologyRing(G, prime=2, GroupName='SomeGroup', from_scratch=True)
      sage: H1.make()
      sage: H1.poincare_series()
      1/(-t^3 + 3*t^2 - 3*t + 1)
      sage: H2 = CohomologyRing(48,36, prime=2)   # indirect doctest

  In order to save resources, the cohomology ring is cached and then reloaded even if a different definition is provided:

      sage: H1 is H2
      True
      sage: print(H2)
      Cohomology ring of SomeGroup with coefficients in GF(2)
      <BLANKLINE>
      Computation complete
      Minimal list of generators:
      [c_2_5: 2-Cocycle in H^*(SomeGroup; GF(2)),
       b_1_0: 1-Cocycle in H^*(SomeGroup; GF(2)),
       b_1_1: 1-Cocycle in H^*(SomeGroup; GF(2)),
       c_1_2: 1-Cocycle in H^*(SomeGroup; GF(2))]
      Minimal list of algebraic relations:
      [b_1_0*b_1_1]
      sage: H2 is loads(dumps(H2))
      True

  `HilbertPoincareTest`(forced=None)

    Try to prove completeness of the ring structure using the Poincaré series.

    OUTPUT:

    `True`, `False` or `None`, depending on whether the Hilbert-Poincaré criterion proves completeness or incompleteness of the ring approximation or was not conclusive.

    ASSUMPTION:

    The generating set is already complete.

    THEORY:

    If the cohomology ring has depth at least \(D\) and has a homogeneous system of parameters of degrees \(d_1,...,d_r\) , and if the current approximation of the cohomology ring has a complete generating set and is known at least out to degree \(\sum d_i-D\), then the approximation is complete if and only if its Poincaré series multiplied by \(\prod (1-t^{d_i})\) is a polynomial of degree at most \(\sum d_i-D\). See [King] for more details.

    EXAMPLES:

    We compute a cohmology ring step by step, in order to demonstrate what happens behind the scenes when launching `make()`. Be aware that this is not recommended.

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(384, 5602, prime=2, from_scratch=True)

    In the following line, we are cheating a bit: Without it, other parameters would be found for \(H\).

        sage: H.sylow_cohomology().find_dickson()
        True
        sage: H.make(4)

    In the current ring approximation, a degree bound for the generators was determined by `generator_degbound()` and stored in some attribute. Apparently, all generators have been found:

        sage: H.degbound_for_gens
        4
        sage: H.all_generators_found
        True
        sage: H.degvec
        [2, 2, 4, 1, 1, 3, 3, 3]

    We did not bother to find filter regular parameters yet:

        sage: H.filter_regular_parameters()

    Indeed, we expect a relation in degree 6:

        sage: H.expect_last_relation()
        6

    Nevertheless, it is possible to find filter regular parameters for the cohomology ring in this approximation. Again, this function would not be called in an automatic computation, thus resulting in different parameters:

        sage: H.find_dickson()
        True
        sage: H.filter_regular_parameters()
        ['b_1_1^2*b_3_1^2+...',
         'b_3_9^4+...',
         'b_1_1^2*b_3_1^4+...',
         'b_1_0^3*b_3_0^2*b_3_1^2+...']

    So, they live in degrees 4, 12, 14 and 15. It would be possible to find a last filter-regular parameter in degree 1, but that would still not allow to apply the Benson criterion. When we invest considerably more time, we could find algebraically independent (but not necessarily filter-regular) parameters in much smaller degrees 4, 12, 2 and 1, by calling

        sage: H.parameters()                    # not tested
        ['b_1_1^4+b_1_0^3*b_1_1+b_1_0^4+b_2_4*b_1_1^2+b_2_4*b_1_0^2+b_2_4^2+b_2_3^2+c_4_15',
         'b_3_9^4+b_3_1^4+b_3_0^4+b_1_1^6*b_3_1^2+b_1_0^2*b_1_1^4*b_3_1^2+b_1_0^3*b_3_0^2*b_3_1+b_1_0^4*b_1_1^8+b_1_0^6*b_3_1^2+b_1_0^6*b_3_0*b_3_1+b_1_0^6*b_3_0^2+b_1_0^8*b_1_1^4+b_2_4*b_1_0^4*b_3_0*b_3_1+b_2_4*b_1_0^7*b_3_1+b_2_4^2*b_1_1^2*b_3_1^2+b_2_4^2*b_1_0^2*b_3_0^2+b_2_4^2*b_1_0^2*b_1_1^6+b_2_4^2*b_1_0^8+b_2_4^4*b_1_1^4+b_2_4^4*b_1_0^2*b_1_1^2+b_2_4^4*b_1_0^4+b_2_3*b_1_0^4*b_3_0^2+b_2_3*b_2_4*b_1_0^5*b_3_0+b_2_3^2*b_1_0^2*b_3_0^2+b_2_3^4*b_1_0^4+c_4_15*b_1_1^2*b_3_1^2+c_4_15*b_1_1^5*b_3_1+c_4_15*b_1_0*b_1_1^4*b_3_1+c_4_15*b_1_0*b_1_1^7+c_4_15*b_1_0^2*b_3_1^2+c_4_15*b_1_0^5*b_3_0+b_2_4*c_4_15*b_1_1^3*b_3_1+b_2_4*c_4_15*b_1_1^6+b_2_4*c_4_15*b_1_0*b_1_1^5+b_2_4*c_4_15*b_1_0^2*b_1_1*b_3_1+b_2_4^2*c_4_15*b_1_1*b_3_1+b_2_4^2*c_4_15*b_1_0*b_3_0+b_2_4^3*c_4_15*b_1_1^2+b_2_4^3*c_4_15*b_1_0*b_1_1+b_2_3*c_4_15*b_1_0^3*b_3_0+b_2_3*b_2_4*c_4_15*b_1_0^4+b_2_3^2*c_4_15*b_1_0*b_3_0+b_2_3^3*c_4_15*b_1_0^2+c_4_15^2*b_1_1*b_3_1+c_4_15^2*b_1_0*b_3_0+c_4_15^2*b_1_0^4+b_2_4*c_4_15^2*b_1_0*b_1_1+b_2_4*c_4_15^2*b_1_0^2+b_2_4^2*c_4_15^2+b_2_3^2*c_4_15^2',
         'b_2_4+b_2_3',
         'b_1_1+b_1_0']

    However, all the above effort was in vain (that’s why we removed that test), as The Poincaré series shows that the approximation cannot be complete: The Poincaré series’ denominator does not divide \((1-t^{4})(1-t^{12})(1-t^{2})(1-t)\), where the exponents are given by the degrees of the above set of algebraically independent parameters:

        sage: p = H.poincare_series()
        sage: t = p.parent().gen()
        sage: (p*(1-t^4)*(1-t^12)*(1-t^2)*(1-t)).denominator().monic()
        t^6 - 2*t^3 + 1

    Let us continue the computation step by step. Of course, normally we would just do `H.make()` instead.

        sage: H.next()
        sage: H.next()
        sage: H.knownDeg
        6

    The parameters found above are of high degrees, and hence it seems hopeless to apply any of our criteria with them. But we do find algebraically dependent parameters in relatively small degrees:

        sage: H.dependent_parameters()
        ['b_1_0', 'b_1_1', 'c_4_15', 'b_3_1', 'b_3_9', 'b_2_3', 'b_2_4']

    With these parameters, the Symonds criterion (see `SymondsTest()`) has a chance to apply in degrees strictly greater than \(0 + 0 + 3 + 2 + 2 + 1 + 1 = 9\). However, in this example we could do better, with the Hilbert–Poincaré criterion and an existence proof of parameters over a finite extension field. Again, since the test would take a very long time, we remove it from our test suite.

        sage: H.parameter_degrees_over_field_extension()    # not tested
        ((4, 2, 1, 3), 3, True)

    This would indeed take so long that in practical computations one would be better off to apply an easier completeness criterion in higher degree see below.

    Anyway, there is a finite extension field over which there is some hsop in degrees 4, 2, 1, and 3, the depth of the cohomology ring is at least three, and our heuristics did not find parameters in these degrees, i.e., we use an existence result of parameters over a finite extension field. Since \(4 + 2 + 1 + 3 - 3 = 7\), we still can not prove completeness of the current degree six ring approximation, and thus compute the next degree. In order to avoid automatic application of a completeness criterion, we use the method `next()`. There are no further relations in degree 7, but finally the Poincaré series satisfies the condition of the completeness criterion:

        sage: H.next()
        sage: H.knownDeg
        7
        sage: H.last_interesting_degree()
        6
        sage: p = H.poincare_series()
        sage: (p*(1-t^4)*(1-t^2)*(1-t)*(1-t^3)).denominator()
        1
        sage: H.knownDeg > (p*(1-t^4)*(1-t^2)*(1-t)*(1-t^3)).numerator().degree()
        True

    Thus the Hilbert–Poincaré criterion proves the completeness of the ring approximation, using parameters (over an extension field) in degrees 4, 2, 1, and 3.

    It should be noted that the above example was rather artificial and does not show how one should compute a cohomology ring. So, in a last step, we compute the same ring again from scratch using the default algorithms.

        sage: CohomologyRing.doctest_setup()
        sage: Hdefault = CohomologyRing(384, 5602, prime=2, from_scratch=True)
        sage: Hdefault.make()
        sage: H == Hdefault
        True
        sage: Hdefault._method      # indirect doctest
        'Hilbert-Poincar&eacute;'
        sage: H.knownDeg
        7
        sage: Hdefault.knownDeg
        9

    The default way of computation verifies completeness only in degree 9, whereas our manual computation succeeded in degree 7. Nonetheless, the default computations is a lot faster, since the time spent to compute better parameters outweighs the time spent to compute two additional degrees of the ring structure. Interestingly, our heuristics to compute algebraically independent parameters can provide better parameters when using default algorithms, and is faster:

        sage: Hdefault.parameters()
        ['c_4_15',
         'b_1_0^2+b_2_4+b_2_3',
         'b_3_9+b_3_1+b_3_0+b_2_4*b_1_0',
         'b_1_1+b_1_0']

  `InitSubgroups`()

    Initialize data that are related with \(p\)-elementary abelian subgroups.

    NOTE:

    This method should only be of internal use.

    TESTS:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(48,50,prime=2, from_scratch=True)

    We destroy the subgroup information…

        sage: H.subgps = None
        sage: H.subg = None

    … and reconstruct it:

        sage: H.InitSubgroups()
        sage: sorted(H.subgpDickson.items())
        [((16, 14),
          [D_0: 8-Cocycle in H^*(SmallGroup(16,14); GF(2)),
           D_1: 12-Cocycle in H^*(SmallGroup(16,14); GF(2)),
           D_2: 14-Cocycle in H^*(SmallGroup(16,14); GF(2)),
           D_3: 15-Cocycle in H^*(SmallGroup(16,14); GF(2))])]
        sage: sorted(H.subgps.items())
        [((16, 14), H^*(SmallGroup(16,14); GF(2)))]

  `PrescribedRestrictions`(L)

    Try to construct a cochain of `self` that has given restrictions to the elementary abelian subgroups.

    INPUT:

    - `L`: a list of elements of the form `[i,C]`, where

      - `i`: the number of a special subgroup

      - `C`: a cochain (type <MODCOCH>) of the `i`-th special subgroup

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
        sage: H.make(4)

    We now want to construct an element of `H` that restricts to a Dickson element `D` of degree 4 in the maximal elementary abelian subgroups, which are all of rank 3.

        sage: r1 = H.restriction_maps()[2][1]
        sage: r2 = H.restriction_maps()[3][1]
        sage: V = r1.codomain()
        sage: from pGroupCohomology.cochain import MODCOCH
        sage: D = MODCOCH(V,'c_1_2^4+c_1_1^2*c_1_2^2+c_1_1^4+c_1_0*c_1_1*c_1_2^2+c_1_0*c_1_1^2*c_1_2+c_1_0^2*c_1_2^2+c_1_0^2*c_1_1*c_1_2+c_1_0^2*c_1_1^2+c_1_0^4',name='D')
        sage: D
        D: 4-Cocycle in H^*(SmallGroup(8,5); GF(2))
        sage: H.PrescribedRestrictions([[2,D],[3,D]])
        (c_1_0)*(b_3_3)+((c_1_0)*(c_3_2))+((c_2_1)^2)+((c_1_0)^4): 4-Cocycle in H^*(SmallGroup(720,763); GF(2))

  `autosave_name`()

    Return the default file name for saving `self`.

    NOTE:

    The default folder is in the current workspace. The file name is derived from the given group name.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: tmp = tmp_dir()
        sage: CohomologyRing.set_workspace(tmp)
        sage: X = CohomologyRing(720,763,prime=2)
        sage: G = libgap.SymmetricGroup(6)
        sage: Y = CohomologyRing(G,prime=2,GroupName='SymmetricGroup(6)', from_scratch=True)
        sage: X.autosave_name().startswith(tmp.replace('//','/'))
        True
        sage: X.autosave_name()
        '.../H720gp763mod2.sobj'
        sage: Y.autosave_name()
        '.../HSymmetricGroup_6_mod2.sobj'

  `decomposable_classes`(n, forced=False)

    Vector space basis of the degree \(n\) part of `self`, expressed as polynomials.

    INPUT:

    - `n` (integer): The degree to be studied.

    - `forced` (optional boolean, default `False`): If `True`, force re-computation.

    OUTPUT:

    A list of degree-`n` elements of `self` that are expressed as polynomials in the generators of `self` and form a vector space basis for the `n`-th cohomology group.

    ASSUMPTION:

    The ring structure must be known at least out to degree `n`. Otherwise, a `RuntimeError` is raised.

    TESTS:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)

    We compute the ring structure only to degree 2 and then ask for the decomposable classes in degree 3, which yields an error:

        sage: H.make(2)
        sage: H.decomposable_classes(3)
        Traceback (most recent call last):
        ...
        RuntimeError: Ring structure in degree 3 is not known yet

    We fool `H` into believing that it is known in degree 3, and try again:

        sage: H.knownDeg = 3
        sage: sorted(H.decomposable_classes(3))
        [c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]

    This result is wrong, since there are further cohomology elements in degree 3. But the result is cached. So, when we now really compute the ring structure in degree 3 and ask again, we still get the wrong answer:

        sage: H.knownDeg = 2
        sage: H.next()
        sage: sorted(H.decomposable_classes(3))
        [c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]

    The correct answer is given when we force re-computation, and then the correct result is in the cache:

        sage: sorted(H.decomposable_classes(3,forced=True))
        [b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2+c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
        sage: sorted(H.decomposable_classes(3))
        [b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2+c_2_1*c_1_0+c_1_0^3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]

  `dickson_in_subgroup`(id)

    Compute Dickson classes for an elementary abelian group, considered as subgroup of the group of `self`.

    INPUT:

    - `id`: the small groups address (pair of integers) of some elementary abelian subgroup of self

    OUTPUT:

    Let \(G\) be the finite group whose cohomology ring `self` represents. The attribute `subgbDickson` of self is changed and contains elements of degree \(p^{r}-p^{r-i}\) of the cohomology ring of the elementary abelian group \(V\) described by `id`, where \(r\) is the \(p\)-rank of \(G\), and \(i = 1,...,r\). These elements are constructed using Dickson invariants in the polynomial part of the cohomology of \(V\).

    NOTE:

    For the completeness criteria we are using, it is essential to construct homogeneous systems of parameters for the ring approximation that give rise to parameters of the cohomology ring. Using simultaneous lifts of (powers of) the Dickson elements in the special subgroups found with dickson_in_subgroup, one can even find a hsop that is filter regular. However, if \(p^{r}-p^{r-i}\) is too large, one should use `find_dickson()`, that avoids the construction of elements of high degrees.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(162,19,prime=3)
        sage: sorted(H.subgroups().items())
        [((3, 1), H^*(SmallGroup(3,1); GF(3))),
         ((9, 2), H^*(SmallGroup(9,2); GF(3))),
         ((27, 5), H^*(SmallGroup(27,5); GF(3)))]
        sage: H.dickson_in_subgroup((9,2))
        sage: H.dickson_in_subgroup((27,5))
        sage: sorted(H.subgpDickson.items())
        [((9, 2),
          [D_0: 36-Cocycle in H^*(SmallGroup(9,2); GF(3)),
           D_1: 48-Cocycle in H^*(SmallGroup(9,2); GF(3)),
           D_2: 52-Cocycle in H^*(SmallGroup(9,2); GF(3))]),
         ((27, 5),
          [D_0: 36-Cocycle in H^*(SmallGroup(27,5); GF(3)),
           D_1: 48-Cocycle in H^*(SmallGroup(27,5); GF(3)),
           D_2: 52-Cocycle in H^*(SmallGroup(27,5); GF(3))])]

  `duflot_regular_sequence`()

    Return a Duflot regular sequence.

    NOTE:

    A Duflot regular sequence is a sequence of elements that restricts to a regular sequence in the cohomology of the greatest central elementary abelian subgroup of a Sylow subgroup. It is known that a Duflot regular sequence of length equal to the rank of the centre of a Sylow subgroup exists.

    A Duflot regular sequence is actually regular, but in general the length of a maximal regular sequence exceeds the length of a Duflot regular sequence.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: X = CohomologyRing(720,763,prime=2)
        sage: X.make()
        sage: X.duflot_regular_sequence()
        ['c_1_0', 'c_2_1']

    Actually, the cohomology ring is Cohen-Macaulay, hence, we have a regular sequence of length three:

        sage: X.filter_regular_parameters()
        ['c_1_0', 'c_2_1', 'b_3_3+c_3_2']
        sage: X.a_invariants()
        [-Infinity, -Infinity, -Infinity, -3]

    However, this regular sequence is not Duflot regular, because the restriction to the first special subgroup, which is the greatest central elementary abelian subgroup of the Sylow subgroup, does not form a regular sequence:

        sage: from pGroupCohomology.cohomology import is_filter_regular_parameter_system
        sage: r = X.restriction_maps()[1][1]
        sage: r
        Induced homomorphism of degree 0 from H^*(SmallGroup(720,763); GF(2)) to H^*(SmallGroup(4,2); GF(2))
        sage: rest = [r(X(p)).as_polynomial() for p in X.filter_regular_parameters()]; rest
        ['c_1_0', 'c_1_1^2', 'c_1_0*c_1_1^2']
        sage: singular(r.codomain()).set_ring()

    The fact that the annulator of the last parameter has dimension one in degrees zero and one means that the last parameter is filter regular, but not regular.

    > sage: is_filter_regular_parameter_system(‘std(0)’, rest) [[0], [0], [1, 1], [1, 1]]

    Often, a Duflot regular sequence can be formed by generators of the cohomology ring. Actually, to some extent this is how the generators are chosen. However, in general the Duflot regular elements returned by this method are not generators:

        sage: H = CohomologyRing(48,50, prime=2)
        sage: H.make()
        sage: H.duflot_regular_sequence()
        ['c_2_3', 'c_2_2', 'c_3_1', 'c_3_7+(c_3_0)']

  `element_as_polynomial`(c)

    Express an element of `self` as a polynomial in the generators.

    INPUT:

    `c` of type `MODCOCH`: An element of `self`

    OUTPUT:

    `c`, after changing its name so that it describes `c` as a polynomial.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(720,763,prime=2)
        sage: H.make()
        sage: c = H.1*H.2+H.3+H.4
        sage: c.setname('foobar')
        sage: c
        foobar: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))
        sage: H.element_as_polynomial(c)
        b_3_3+c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))
        sage: c
        b_3_3+c_3_2+c_2_1*c_1_0: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))

  `find_relations`(n, rank=None)

    Determine cohomology relations and optionally a basis for the decomposable subspace in a given degree.

    INPUT:

    - `n` (integer): The degree to be studied.

    - `rank` (optional integer, default `None`): The dimension of the `n`-th cohomology group (if this happens to be known).

    OUPUT:

    The relation ideal in the underlying Singular session is updated, and two lists `D` and `R` are returned, where `D` can also be `None`.

    If the optional parameter `rank` is provided, then it will be assumed that it is the dimension of the `n`-th cohomology group (considered as a vector space). If it is found that all stable elements in the cohomology of the underlying subgroup are decomposable and if `rank` is `None`, then `D` is `None`, indicating that the cohomology ring being studied has no minimal generator in degree `n`. Otherwise, `D` is a list of `MODCOCH` providing a basis for the decomposable subspace of the \(n\)-th cohomology group.

    The list `R` provides algebraic relations in degree `n` that hold between the cohomology generators.

    NOTE:

    This method should only be of internal use. The relation ideal in the Singular interface is updated (since it reduces traffic in the interface if this is done as soon as the relations are computed), but the list of relations is not updated. This may yield unexpected behaviour.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)

    There are no generators yet, and by consequence there are no decomposable elements or relations:

        sage: H.find_relations(1)
        ([], [])

    After computing degree 1, it turns out that the only decomposable element (i.e., an element that can be expressed as a polynomial of previously found generators) is the degree-1 generator, and there are of course no relations:

        sage: H.make(1)
        sage: H.find_relations(1)
        ([c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2))], [])

    We happen to know that the dimension of \(H^2\) is two. So, in degree two, the decomposable elements are returned, since there will be a generator in that degree:

        sage: H.find_relations(2, rank=2)
        ([c_1_0^2: 2-Cocycle in H^*(SmallGroup(720,763); GF(2))], [])

    We happen to know that the last generator is in degree three, while the dimension of \(H^6\) is ten. There is a relation in degree six. Since there are no generators in degree six, the decomposable subspace is not provided:

        sage: H.make(3)
        sage: H.find_relations(6, rank=10)
        (None, ['b_3_3*c_3_2+c_2_1*c_1_0*b_3_3'])

    The ideal in the Singular session is updated, but the list of relations isn’t:

        sage: H.rels()
        []
        sage: H.set_ring()
        sage: H.relation_ideal()
        b_3_3*c_3_2+c_2_1*c_1_0*b_3_3

    Therefore, when we now repeat the quest for relations, we don’t find any. However, this method can still be used for getting the decomposable subspace, by dropping the optional parameter:

        sage: H.find_relations(6)
        ([c_1_0^3*b_3_3: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_3_2^2+c_2_1*c_1_0*c_3_2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          b_3_3^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_2_1*c_1_0*b_3_3: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_3_2^2+c_2_1*c_1_0*c_3_2+c_1_0^3*c_3_2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_3_2^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_3_2^2+c_2_1^2*c_1_0^2: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_2_1*c_1_0^4: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          b_3_3^2+c_3_2^2+c_2_1*c_1_0*c_3_2+c_2_1^3: 6-Cocycle in H^*(SmallGroup(720,763); GF(2)),
          c_3_2^2+c_2_1^2*c_1_0^2+c_1_0^6: 6-Cocycle in H^*(SmallGroup(720,763); GF(2))],
         [])

  `generator_degbound`()

    Find a bound for the degree of cohomology generators.

    THEORY:

    IF `H` is a modular cohomology ring of a non prime power group, computed as a sub-ring of `H.subgroup_cohomology()`, then the latter is a finitely generated module over the former, via the restriction map. One can show that a minimal generating set of `H` has degrees bounded by the maximal degree of a module generator of `H.subgroup_cohomology()`.

    OUTPUT:

    `None`. Attributes `degbound_for_gens` (the currently found maximal possible degree of a generator) and `all_generators_found` (`True`, if there will be no further generators) are set, and there is some log.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: G = libgap.MathieuGroup(11)
        sage: H = CohomologyRing(G,prime=2,GroupName='M11', from_scratch=True)
        sage: H.make(4)
        sage: CohomologyRing.global_options('info')
        sage: H.generator_degbound()
        H^*(M11; GF(2)):
            New generators will be found at most in degree 5
        sage: CohomologyRing.global_options('warn')
        sage: H.degbound_for_gens
        5
        sage: print(H.all_generators_found)
        None

    So, there may be further generators in degree 5. Indeed, there are:

        sage: H.make(5)
        sage: H.generator_degbound()
        sage: H.all_generators_found
        True
        sage: sorted(H.gens())
        [1,
         b_3_0: 3-Cocycle in H^*(M11; GF(2)),
         c_4_0: 4-Cocycle in H^*(M11; GF(2)),
         b_5_0: 5-Cocycle in H^*(M11; GF(2))]

    These are all generators, and completeness of the ring structure is proved in degree 10:

        sage: H.make()
        sage: H.knownDeg
        10
        sage: sorted(H.gens())
        [1,
         b_3_0: 3-Cocycle in H^*(M11; GF(2)),
         c_4_0: 4-Cocycle in H^*(M11; GF(2)),
         b_5_0: 5-Cocycle in H^*(M11; GF(2))]

  `group`()

    Return a permutation group equivalent to the one defining `self`.

    NOTE:

    “Equivalent” means that mapping an initial segment of the list of generators results in a group isomorphism. It is cached. If GAP crashes, the group is reconstructed.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: X = CohomologyRing(720,763,prime=2)
        sage: G = X.group()
        sage: G
        Group([ (1,2), (1,2,3,4,5,6) ])
        sage: G is X.group()
        True

  `make`(max_deg=- 1)

    Compute the cohomology ring structure, either completely or out to a specific degree.

    INPUT:

    `max_deg` (optional integer): If provided, compute at most out to this degree.

    EXAMPLES:

    The group we are using in this example is `MathieuGroup(12)`.

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: G = libgap.eval('Group([(1,2,3,4,5,6,7,8,9,10,11),(3,7,11,8)(4,10,5,6),(1,12)(2,11)(3,6)(4,8)(5,9)(7,10)])')
        sage: H = CohomologyRing(G,prime=3,GroupName='M12', from_scratch=True)

    We let compute the ring structure out to degree 16. The program tries to find parameters and tests whether there will be further generators.

        sage: H.make(16)
        sage: H.filter_regular_parameters()
        ['b_4_0^3-c_12_0', 'b_16_3-b_16_1+b_4_0^4-b_4_0*c_12_0']
        sage: H.all_generators_found
        True

    Using `make` without an optional argument results in a complete computation. Completeness is proved in degree 32, which is exactly where the last relation can be found:

        sage: H.make()
        sage: H.completed
        True
        sage: H.knownDeg
        32
        sage: H.lastRel
        32

    We devise two methods to prove completeness of the ring structure for non prime power groups: The Hilbert–Poincaré criterion and the Symonds criterion. We start with Hilbert–Poincaré:

        sage: p = H.poincare_series(); p
        (t^24 - 2*t^23 + 3*t^22 - 3*t^21 + 5*t^20 - 6*t^19 + 7*t^18 - 7*t^17 + 9*t^16 - 9*t^15 + 12*t^14 - 11*t^13 + 12*t^12 - 11*t^11 + 12*t^10 - 9*t^9 + 9*t^8 - 7*t^7 + 7*t^6 - 6*t^5 + 5*t^4 - 3*t^3 + 3*t^2 - 2*t + 1)/(t^26 - 2*t^25 + 3*t^24 - 4*t^23 + 5*t^22 - 6*t^21 + 7*t^20 - 8*t^19 + 9*t^18 - 10*t^17 + 11*t^16 - 12*t^15 + 12*t^14 - 12*t^13 + 12*t^12 - 12*t^11 + 11*t^10 - 10*t^9 + 9*t^8 - 8*t^7 + 7*t^6 - 6*t^5 + 5*t^4 - 4*t^3 + 3*t^2 - 2*t + 1)
        sage: H.parameters()
        ['b_4_0^3-c_12_0', 'b_16_3-b_16_1+b_4_0^4-b_4_0*c_12_0']
        sage: t = p.parent().gen(0)
        sage: p*(1-t^12)*(1-t^16)
        t^26 + t^23 + 2*t^22 + t^21 + t^19 + 2*t^18 + 2*t^17 + 3*t^16 + 4*t^15 + 2*t^14 + 2*t^13 + 2*t^12 + 4*t^11 + 3*t^10 + 2*t^9 + 2*t^8 + t^7 + t^5 + 2*t^4 + t^3 + 1
        sage: H.knownDeg >= (12 + 16) - H.depth()
        True
        sage: 26 <= H.knownDeg
        True

    The last few lines actually prove that the ring structure is complete—see `HilbertPoincareTest()` for the background. In this example, the Hilbert Poincaré test has actually been used when calling `make()`:

        sage: H._method
        'Hilbert-Poincar&eacute;'

    We have parameters in degree 12 and 16. We need to know the ring structure at least out to degree \((12-1)+(16-1)+1=27\), and we need to show that as a module over these parameters, the ring approximation is generated in at most the degree out to which we know the ring structure. This is indeed the case:

        sage: H.knownDeg
        32
        sage: H.set_ring()
        sage: B = (H.relation_ideal()+singular.ideal(H.parameters())).groebner().kbase()
        sage: max([int(p.deg()) for p in B])
        26

    Given these data, it may surprise why it was needed to compute out to degree 32 and not just 27. But simply there is a relation in degree 32, and without the final relation, the module structure of the ring approximation would not be finitely generated:

        sage: (singular.ideal(H.rels()[:-1])+singular.ideal(H.parameters())).groebner().GKdim()
        1

    TESTS:

    In the following example, one of our criteria correctly determined the degree bound 19 when being called in degree 18. But after finding the last relation in degree 19, the previously obtained degree bound has not been used and the completion test has not been repeated. This is fixed now:

        sage: H = CohomologyRing(1620, 244, prime=3, from_scratch=True)
        sage: H.make()
        sage: H.knownDeg
        19
        sage: print(H)
        Cohomology ring of SmallGroup(1620,244) with coefficients in GF(3)
        <BLANKLINE>
        Computation complete
        Minimal list of generators:
        [a_2_1: 2-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         b_2_0: 2-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         c_4_3: 4-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_6_1: 6-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         c_8_4: 8-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         c_12_11: 12-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_1_0: 1-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_3_0: 3-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_3_1: 3-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_3_4: 3-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_7_0: 7-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_7_4: 7-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_7_5: 7-Cocycle in H^*(SmallGroup(1620,244); GF(3)),
         a_11_4: 11-Cocycle in H^*(SmallGroup(1620,244); GF(3))]
        Minimal list of algebraic relations:
        [a_2_1^2,
         a_2_1*b_2_0,
         a_2_1*a_3_0,
         a_2_1*a_3_1,
         a_2_1*a_3_4,
         b_2_0*a_3_0,
         b_2_0*a_3_4,
         a_3_0*a_3_4,
         a_3_1*a_3_4-a_2_1*c_4_3,
         a_2_1*a_6_1,
         a_2_1*a_7_0,
         a_2_1*a_7_4,
         a_2_1*a_7_5,
         a_6_1*a_3_0,
         a_6_1*a_3_1-b_2_0*a_6_1*a_1_0,
         a_6_1*a_3_4,
         b_2_0*a_7_5,
         a_3_0*a_7_0,
         a_3_0*a_7_5,
         a_3_1*a_7_4-b_2_0*a_1_0*a_7_4,
         a_3_1*a_7_5+a_2_1*c_8_4,
         a_3_4*a_7_0,
         a_3_4*a_7_4+a_2_1*c_8_4,
         a_3_4*a_7_5,
         b_2_0^2*a_6_1-a_3_1*a_7_0+b_2_0*a_1_0*a_7_0+c_4_3*a_6_1,
         c_8_4*a_3_4+c_4_3*a_7_5,
         b_2_0^2*a_7_4-c_8_4*a_3_1+c_4_3*a_7_4+b_2_0*c_8_4*a_1_0,
         a_6_1^2,
         a_2_1*a_11_4,
         a_6_1*a_7_0,
         a_6_1*a_7_4,
         a_6_1*a_7_5,
         a_3_0*a_11_4,
         a_3_1*a_11_4-b_2_0*a_1_0*a_11_4-a_6_1*c_8_4,
         a_3_4*a_11_4,
         a_7_0*a_7_4+a_6_1*c_8_4,
         a_7_0*a_7_5,
         a_7_4*a_7_5+a_2_1*c_12_11,
         c_12_11*a_3_1-c_8_4*a_7_4-b_2_0*c_12_11*a_1_0,
         c_12_11*a_3_4+c_8_4*a_7_5,
         b_2_0^2*a_11_4-c_8_4*a_7_0+c_4_3*a_11_4,
         b_2_0^2*c_12_11-c_8_4^2+c_4_3*c_12_11,
         a_6_1*a_11_4,
         a_7_0*a_11_4,
         a_7_4*a_11_4-a_6_1*c_12_11,
         a_7_5*a_11_4,
         c_12_11*a_7_0-c_8_4*a_11_4]

  `next`(Forced=False, KeepDecomposables=False)

    Compute the next degree of the cohomology ring approximation.

    NOTE:

    There is no comppletion test performed.

    EXAMPLES:

    First, we take care that the state of the cohomology rings of the elementary abelian subgroups and of the Sylow subgroup are in a well defined state, independent of the content of the local sources. In this example, we also illustrate logging.

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: X = CohomologyRing(4,2, from_scratch=True)
        sage: X.make()
        sage: X = CohomologyRing(8,5, from_scratch=True)
        sage: X.make()
        sage: X = CohomologyRing(16,11, from_scratch=True)
        sage: X.make()
        sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
        sage: CohomologyRing.global_options('info')
        sage: H.next()
        H^*(SmallGroup(720,763); GF(2)):
            Computing ring approximation in degree 1
            Determining stable subspace in degree 1
        H^*(D8xC2; GF(2)):
            Determine degree 1 standard monomials
        H^*(SmallGroup(8,5); GF(2)):
            Determine degree 1 standard monomials
        H^*(SmallGroup(4,2); GF(2)):
            Determine degree 1 standard monomials
        H^*(SmallGroup(720,763); GF(2)):
            Setting up conditions to determine stable elements
            Solving equations
            We have to choose 1 new generator in degree 1
        H^*(SmallGroup(4,2); GF(2)):
            Determine degree 1 standard monomials
        H^*(SmallGroup(8,5); GF(2)):
            Determine degree 1 standard monomials
        H^*(SmallGroup(720,763); GF(2)):
            > There are 0 nilpotent generators in degree 1
            > There are 0 "boring" generators in degree 1
            > There is 1 Duflot generator in degree 1
            Try to find new Duflot-regular element in degree 1
        explore_one_parameter:
            1 = (2-1)^1 parameter candidates
            We found a parameter.
            > It is regular.
        H^*(SmallGroup(720,763); GF(2)):
            Found extension of the Duflot regular sequence
            Degree 1 of the visible ring structure is computed!
            Storing ring approximation
        sage: H.next()
            Computing ring approximation in degree 2
            Determining stable subspace in degree 2
        H^*(D8xC2; GF(2)):
            Determine degree 2 standard monomials
        H^*(SmallGroup(8,5); GF(2)):
            Determine degree 2 standard monomials
        H^*(SmallGroup(4,2); GF(2)):
            Determine degree 2 standard monomials
        H^*(SmallGroup(720,763); GF(2)):
            Setting up conditions to determine stable elements
            Solving equations
            Exploring relations in degree 2
            Determine degree 2 standard monomials
            Express 1 standard monomial as cocycle
            Found 0 relations in degree 2
            We have to choose 1 new generator in degree 2
        H^*(SmallGroup(4,2); GF(2)):
            Determine degree 2 standard monomials
        H^*(SmallGroup(8,5); GF(2)):
            Determine degree 2 standard monomials
        H^*(SmallGroup(720,763); GF(2)):
            > There are 0 nilpotent generators in degree 2
            > There are 0 "boring" generators in degree 2
            > There is 1 Duflot generator in degree 2
            Try to find new Duflot-regular element in degree 2
        explore_one_parameter:
            1 = (2-1)^1 parameter candidates
            We found a parameter.
            > It is regular.
        H^*(SmallGroup(720,763); GF(2)):
            Found extension of the Duflot regular sequence
            Degree 2 of the visible ring structure is computed!
            Storing ring approximation

    So, apparently the stable subspace of the cohomology ring of the underlying subgroup `D8xC2` is computed in each degree, then it is determined how much of it is decomposable, and new generators are chosen accordingly.

    We continue the computation out to degree 5, turning off the log. There is still no relation:

        sage: CohomologyRing.global_options('warn')
        sage: H.make(5)
        sage: print(H)
        Cohomology ring of SmallGroup(720,763) with coefficients in GF(2)
        <BLANKLINE>
        Computed up to degree 5
        Minimal list of generators:
        [c_2_1: 2-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_1_0: 1-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         b_3_3: 3-Cocycle in H^*(SmallGroup(720,763); GF(2)),
         c_3_2: 3-Cocycle in H^*(SmallGroup(720,763); GF(2))]
        Minimal list of algebraic relations:
        []

    Resuming logging, we compute the next degree. Meanwhile the program has tested that it found all generators. Thus, it is not needed to compute the stable subspace in advance, as can be seen in the log.

        sage: CohomologyRing.global_options('info')
        sage: H.next()
        H^*(SmallGroup(720,763); GF(2)):
            Computing ring approximation in degree 6
            All generators are known
            Exploring relations in degree 6
            Determine degree 6 standard monomials
            Express 11 standard monomials as cocycles
            Found 1 relations in degree 6
            There is no new generator in degree 6
            Try to lift 1st power of 1st Dickson invariant
            Exploring relations in degree 6
            Determine degree 6 standard monomials
            Express 10 standard monomials as cocycles
            Found 0 relations in degree 6
            Factorising an element; it can be interrupted with Ctrl-c
            Degree 6 of the visible ring structure is computed!
            Storing ring approximation

    There is no completion test performed. But in fact, the completion test is successful:

        sage: H.completed
        False
        sage: H.test_for_completion()
            Compute dependent_parameters
            Try to find a set of generators over which the cohomology ring is finite.
            Computing complete Groebner basis
            Trying Symonds' criterion
            Successful application of the Symonds criterion
        True
        sage: H.completed
        True

  `parameter_degrees_over_field_extension`(forced=False)

    Temporarily cached method: Returns the degrees of parameters over a field extension.

    INPUT:

    - forced: If True then the cache is overridden.

    OUTPUT:

    - A tuple of integers providing the degrees of a homogeneous system of algebraically independent parameters that exist when replacing the base field of this cohomology ring by a finite field extension.

    - An integer, providing a lower bound for the depth of this cohomology ring.

    - A bool, which is True if an existence proof was used, and False if the parameters have actually been constructed without extending the base field.

    Three times None is returned, if no parameters could be found.

    TODO:

    Find a better example! Here, we do parts of the quest for parameters in a non-automatic way. This is to get a good example, in which it is possible to benefit from an existence proof of parameters over a finite extension field. However, the automatically chosen parameters happen to be good enough, so that an application of Symonds’ completeness criterion, without using an existence proof, is the easiest way to prove completeness.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(384,5602, prime=2, from_scratch=True)

    In the following line, we are cheating a bit. Without it, other parameters would be found for \(H\).

        sage: H.sylow_cohomology().find_dickson()
        True
        sage: H.make(3)

    The degree is too low, hence, no parameters can be found:

        sage: H.parameter_degrees_over_field_extension()
        (None, None, None)

    After computing out to degree six, parameters in degrees 4, 6, 1 and 4 can be explicitly constructed:

        sage: H.make(6)
        sage: H.parameters()
        ['b_1_1^4+b_1_0^3*b_1_1+b_1_0^4+b_2_4*b_1_1^2+b_2_4*b_1_0^2+b_2_4^2+b_2_3^2',
         'b_3_9^2+b_3_1^2+b_1_0*b_1_1^2*b_3_1+b_1_0^6+b_2_4*b_1_0*b_3_1+b_2_4*b_1_0*b_3_0+b_2_4*b_1_0*b_1_1^3+b_2_4*b_1_0^4+b_2_4^2*b_1_1^2+b_2_4^3+b_2_3*b_2_4^2+b_2_3^2*b_2_4',
         'b_1_1+b_1_0',
         'c_4_15']

    But it can be shown that there exists a field extension over which there exist parameters in smaller degrees:

        sage: H.sylow_cohomology().depth()
        3
        sage: H.parameter_degrees_over_field_extension()
        ((4, 1, 4, 3), 3, True)

    These return values tell us that there is a finite field extension over which there exists parameters in degrees 4, 1, 4, 3, that the depth of the cohomology ring is at least three (which is the depth of the cohomology ring of a Sylow 2-subgroup), and that such low parameter degrees seem impossible to achieve without extending the base field. By the Hilbert-Poincaré criterion, we may hope to prove completeness of the ring presentation in degree \(4+1+4+3-3\), hence, in degree 9. This is indeed possible:

        sage: H.make()
        sage: H.knownDeg
        9
        sage: H._method
        'Hilbert-Poincar&eacute;'
        sage: CohomologyRing.set_local_sources(False)

  `parameters_from_sylow_subgroup`()

    Try to obtain filter regular parameters from those of a Sylow subgroup.

    THEORY:

    In the case of a prime power group, a filter regular homogeneous system of parameters can be obtained by starting with the Duflot generators (they form a regular sequence) together with lifts of Dickson elements in the cohomology of maximal elementary abelian subgroups, restricted to a complement of the center.

    For non prime power groups, the situation is more difficult. We do find a Duflot regular sequence, but it is, in general, not formed by generators — see `duflot_regular_sequence()`. And in general, it is impossible to lift the Dickson elements restricted to a complement of the centre of the Sylow subgroup. Therefore, the default construction of a filter regular homogeneous system of parameters relies on the Dickson elements, without restriction.

    These may be of rather high degree. Therefore, we always try whether by chance the restricted Dickson elements found for the Sylow subgroup happen to be stable. If only the last parameter can not be lifted, `find_small_last_parameter()` may help to find a filter regular homogeneous system of parameters in small degrees.

    EXAMPLE:

    Since the construction depends on data in the cohomology ring of a subgroup, we ensure that this ring is not simply taken from the local sources, and compute it from scratch:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: X = CohomologyRing(64,138,from_scratch=True)
        sage: H = CohomologyRing(576,204,prime=2)
        sage: H.make()

    In this example, all but the last parameter from the Sylow subgroup can be lifted. A last parameter can be easily found. Theorems imply that, we thus obtain a filter regular system of parameters, which we can verify:

        sage: P = H.parameters_from_sylow_subgroup(); P
        ['c_4_6',
         'b_1_0*b_3_0+b_1_0^4+b_2_2^2+b_2_0^2',
         'b_3_1*b_3_2+b_3_1^2+b_3_0^2+b_1_0^3*b_3_0+b_2_2*b_1_0*b_3_0+b_2_2^2*b_1_0^2+b_2_0*b_2_2^2+b_2_0^3+c_4_6*b_1_0^2',
         None]
        sage: P[-1] = H.find_small_last_parameter(P)
        sage: P
        ['c_4_6',
         'b_1_0*b_3_0+b_1_0^4+b_2_2^2+b_2_0^2',
         'b_3_1*b_3_2+b_3_1^2+b_3_0^2+b_1_0^3*b_3_0+b_2_2*b_1_0*b_3_0+b_2_2^2*b_1_0^2+b_2_0*b_2_2^2+b_2_0^3+c_4_6*b_1_0^2',
         'b_1_0']
        sage: H.raw_filter_degree_type(P)
        ([-1, -1, -1, 9, 11],
         [[0],
          [0],
          [0],
          [0, 0, 1, 3, 2, 4, 4, 2, 3, 1],
          [1, 0, 2, 4, 2, 5, 5, 2, 4, 2, 0, 1]],
         [4, 4, 6, 1])

    The degrees are 4, 4, 6, 1. The degrees of the original parameters, namely obtained by unrestricted Dickson elements, are 8, 12, 14, 15, the last Dickson element being replacable by a factor in degree 1:

        sage: H.find_dickson()
        True
        sage: H.Dickson
        ['b_1_0^2*b_3_0^2+b_1_0^8+b_2_2^4+b_2_0^4+c_4_6*b_1_0*b_3_0+b_2_2*c_4_6*b_1_0^2+c_4_6^2',
         'b_3_1^3*b_3_2+b_1_0^3*b_3_0^3+b_1_0^6*b_3_0^2+b_6_9*b_3_0^2+b_6_9^2+b_2_2*b_1_0*b_3_0^3+b_2_2*b_6_9*b_1_0*b_3_0+b_2_2^2*b_1_0^2*b_3_0^2+b_2_2^3*b_3_0^2+b_2_2^4*b_1_0^4+b_2_0^2*b_2_2^4+b_2_0^3*b_3_1^2+b_2_0^6+c_4_6*b_1_0^2*b_3_0^2+c_4_6*b_1_0^5*b_3_0+c_4_6*b_6_9*b_1_0^2+b_2_2*c_4_6*b_1_0^6+b_2_2^2*c_4_6*b_1_0*b_3_0+c_4_6^2*b_1_0*b_3_0+c_4_6^2*b_1_0^4+b_2_2^2*c_4_6^2+b_2_0^2*c_4_6^2',
         'b_1_0^5*b_3_0^3+b_6_9*b_1_0^2*b_3_0^2+b_6_9^2*b_1_0^2+b_2_2*b_1_0^3*b_3_0^3+b_2_2*b_6_9*b_1_0^3*b_3_0+b_2_2^2*b_1_0^4*b_3_0^2+b_2_2^3*b_1_0^2*b_3_0^2+c_4_6*b_1_0*b_3_0^3+c_4_6*b_1_0^4*b_3_0^2+c_4_6*b_6_9*b_1_0^4+c_4_6^2*b_3_1*b_3_2+c_4_6^2*b_3_1^2+c_4_6^2*b_3_0^2+b_2_2*c_4_6^2*b_1_0*b_3_0+b_2_2*c_4_6^2*b_1_0^4+b_2_2^2*c_4_6^2*b_1_0^2+b_2_0*b_2_2^2*c_4_6^2+b_2_0^3*c_4_6^2+c_4_6^3*b_1_0^2',
         'b_1_0']

  `set_ring`()

    Set the underlying ring in the Singular interface.

    TESTS:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(48,48,prime=2, from_scratch=True)
        sage: H.make(2)
        sage: H.set_ring()

    This is the underlying ring out to degree 2:

        sage: singular('basering')
        polynomial ring, over a field, global ordering
        // coefficients: ZZ/2
        // number of vars : 3
        //        block   1 : ordering M
        //                  : names    c_2_3 b_1_0 c_1_1
        //                  : weights      2     1     1
        //                  : weights     -1     0    -1
        //                  : weights     -1     0     0
        //        block   2 : ordering C

    There are more generators in higher degree:

        sage: H.make()
        sage: H.set_ring()
        sage: singular('basering')
        polynomial ring, over a field, global ordering
        // coefficients: ZZ/2
        // number of vars : 4
        //        block   1 : ordering M
        //                  : names    c_2_3 b_1_0 c_1_1 c_3_6
        //                  : weights      2     1     1     3
        //                  : weights     -1     0    -1    -1
        //                  : weights     -1     0     0     0
        //                  : weights      0    -1     0     0
        //        block   2 : ordering C

    A Groebner basis of the cohomology ring’s relation ideals is available as follows:

        sage: H.relation_ideal()
        b_1_0*c_3_6+c_2_3*b_1_0*c_1_1

  `stable_space`(n)

    return a basis for the subspace of stable cocycles of the underlying subgroup in a given degree.

    INPUT:

    `n`, the degree (integer)

    OUTPUT:

    - a list of elements (`MODCOCH`) of `self` whose restriction to the underlying subgroup yield a basis for the space of stable elements in degree `n`.

    - a list of standard monomials of the underlying cohomology ring of a subgroup

    - a list of those standard monomials of the underlying cohomology ring of a subgroup that occur as leading monomials of stable elements

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: G = libgap.MathieuGroup(11)
        sage: H = CohomologyRing(G,prime=2,GroupName='M11', from_scratch=True)

    It may easily be that there are no stable cocycles in a given degree:

        sage: H.stable_space(1)
        ([], [], [])
        sage: H.stable_space(2)
        ([], [], [])

    The first stable element, yielding the first generator of `H`, can be found in degree 3:

        sage: g,M,MS = H.stable_space(3)
        sage: g
        [Gen1: 3-Cocycle in H^*(M11; GF(2))]
        sage: M
        ['b_3_0', 'b_1_0^3']
        sage: M == H._HP.standard_monomials(3)
        True
        sage: g[0].val_str()
        'b_3_0'

    Here, the stable element of `H._HP` happens to be a monomial. This is not always the case:

        sage: g,M,MS = H.stable_space(4)
        sage: g[0].val_str()
        'b_1_0^4+c_4_2'
        sage: MS
        ['b_1_0^4']

  `stable_to_polynomial`(c, verify=True)

    Express a stable cohomology element of a subgroup as a polynomial in the generators of `self`.

    INPUT:

    - `c`: an element of `self` or of the cohomology ring of one of the subgroups used to compute `self`.

    - `verify` (optional boolean): If true (default), test whether `c` really is stable, before trying to express it in `self`.

    OUTPUT:

    An element of `self` (type `MODCOCH`) corresponding to `c`, or `None` if `c` is not stable and if `verify` is true. If `c` is not stable and `verify` is not true, then an error is raised.

    EXAMPLES:

    We work with the mod-2 cohomology of the Mathieu group \(M_{12}\).

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()   # Reset and disallow web access
        sage: G = libgap.eval('Group([(1,2,3,4,5,6,7,8,9,10,11), (3,7,11,8)(4,10,5,6), (1,12)(2,11)(3,6)(4,8)(5,9)(7,10)])')
        sage: H = CohomologyRing(G,prime=2,GroupName='M12', from_scratch=True)
        sage: H.make()
        sage: HS = H.sylow_cohomology()
        sage: HU = H.subgroup_cohomology()

    We first consider elements of `HS` and `HU` that are stable:

        sage: H.stable_to_polynomial(HS('b_1_2^6+b_1_1^2*b_1_2^4+b_1_1^6+b_2_4^2*b_1_1*b_1_2+b_2_4^3'))
        b_3_0*b_3_1+b_2_0^3: 6-Cocycle in H^*(M12; GF(2))
        sage: H.stable_to_polynomial(HU('b_2_0*b_2_2*b_3_4+c_4_6*b_3_1'))
        c_4_0*b_3_1: 7-Cocycle in H^*(M12; GF(2))

    An element of `H` is simply expressed as a polynomial, changing its name accordingly:

        sage: cG = H.1*H.2+H.3+H.4*H.5
        sage: cG.setname('foobar')
        sage: cG
        foobar: 6-Cocycle in H^*(M12; GF(2))
        sage: H.stable_to_polynomial(cG)
        b_3_0*b_3_1+b_6_3+b_2_0*c_4_0: 6-Cocycle in H^*(M12; GF(2))
        sage: cG
        b_3_0*b_3_1+b_6_3+b_2_0*c_4_0: 6-Cocycle in H^*(M12; GF(2))

    By default, it is tested whether the input is stable. If it isn’t, it is stated in the log, and `None` is returned.

        sage: cS2 = HS('b_2_4^2*b_1_1*b_1_2+b_2_4^2*b_2_5+b_2_4^3+c_4_14*b_1_2^2')
        sage: CohomologyRing.global_options('debug')
        sage: print(H.stable_to_polynomial(cS2))
        H^*(M12; GF(2)):
                  Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
        H^*(SmallGroup(192,1494); GF(2)):
                  Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
                  Stability condition #0 is violated
        None
        sage: CohomologyRing.global_options('warn')
        sage: cS3 = HS('c_4_14*b_1_0')
        sage: CohomologyRing.global_options('debug')
        sage: print(H.stable_to_polynomial(cS3))
        H^*(M12; GF(2)):
                  Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
        H^*(SmallGroup(192,1494); GF(2)):
                  Try to express a supposedly stable element of H^*(Syl2(M12); GF(2)) as a polynomial
                  Input is indeed stable in this ring...
        H^*(M12; GF(2)):
                  Stability condition #0 is violated
        None
        sage: CohomologyRing.global_options('warn')

    According to the log, `cS3` can be expressed in `HU` (not in `H`, however), and indeed:

        sage: HU.stable_to_polynomial(cS3)
        c_4_6*b_1_0: 5-Cocycle in H^*(SmallGroup(192,1494); GF(2))

    Using the option `verify=False` will be a little faster, since it is not verified whether the input is stable before trying to lift. If it isn’t, an error is raised.

        sage: HU.stable_to_polynomial(cS3, verify=False)
        c_4_6*b_1_0: 5-Cocycle in H^*(SmallGroup(192,1494); GF(2))
        sage: H.stable_to_polynomial(cS3, verify=False)
        Traceback (most recent call last):
        ...
        ValueError: Apparently the given cochain does not belong to H^*(M12; GF(2))

  `subgroup`()

    Return the subgroup to which the stable element method is applied.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(1440,80,prime=2)
        sage: H.subgroup().IdGroup()
        [ 288, 46 ]
        sage: H.subgroup_cohomology()
        H^*(SmallGroup(288,46); GF(2))
        sage: H.group().IsSubgroup(H.subgroup())
        true
        sage: H.subgroup().IsSubgroup(H.sylow_subgroup())
        true

  `subgroup_cohomology`()

    Return the cohomology of the subgroup to which the stable element method is applied.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: tmp = tmp_dir()
        sage: CohomologyRing.set_workspace(tmp)
        sage: H = CohomologyRing(1440,80,prime=2)
        sage: H.subgroup().IdGroup()
        [ 288, 46 ]
        sage: H.subgroup_cohomology()
        H^*(SmallGroup(288,46); GF(2))
        sage: H.group().IsSubgroup(H.subgroup())
        true
        sage: H.subgroup().IsSubgroup(H.sylow_subgroup())
        true

  `sylow_cohomology`()

    Return the cohomology ring of a Sylow subgroup.

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(1440,80,prime=2)
        sage: H.sylow_subgroup().IdGroup()
        [ 32, 3 ]
        sage: H.sylow_cohomology()
        H^*(SmallGroup(32,3); GF(2))

  `sylow_subgroup`()

    Return the Sylow subgroup which is used to compute `self`

    EXAMPLES:

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: H = CohomologyRing(1440,80,prime=2)
        sage: H.sylow_subgroup().IdGroup()
        [ 32, 3 ]
        sage: H.sylow_cohomology()
        H^*(SmallGroup(32,3); GF(2))
        sage: H.group().IsSubgroup(H.sylow_subgroup())
        true

  `test_for_completion`(forced=False)

    Perform completion tests.

    OUTPUT:

    `True` (complete), `False` (incomplete), `None` (can’t be decided yet) The attribute `completed` is set accordingly.

    NOTE:

    This method first invokes `generator_degbound()` to test whether all generators are known. If this is the case, the last degree of relations is estimated. Eventually, either `SymondsTest()` or `HilbertPoincareTest()` is called.

    EXAMPLES:

    This example shows what happens behind the scenes when `H.make()` is called. We use `MathieuGroup(11)`.

        sage: from pGroupCohomology import CohomologyRing
        sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
        sage: G = libgap.MathieuGroup(11)
        sage: H = CohomologyRing(G,prime=2,GroupName='M11', from_scratch=True)
        sage: H.make(3)
        sage: H.test_for_completion()
        False

    The reason is that there is no maximal Duflot regular sequence yet:

        sage: H.duflot_regular_sequence()
        []

    So, we proceed to degree 4:

        sage: H.next()
        sage: H.duflot_regular_sequence()
        ['c_4_0']

    We have a Duflot regular sequence, but it is possible that there are more generators in degree 5:

        sage: CohomologyRing.global_options('info')
        sage: H.test_for_completion()
        H^*(M11; GF(2)):
            Try to find a bound for the degree of generators
            > New generators will be found at most in degree 5
        False

    In degree 5, it turns out that parameters can be found. But, since we expect a relation at least in degree 10, the completion criterion is still not invoked. However, there are now nice filter regular parameters:

        sage: CohomologyRing.global_options('warn')
        sage: H.next()
        sage: CohomologyRing.global_options('info')
        sage: H.test_for_completion()
        H^*(M11; GF(2)): We expect a relation in degree at least 10
        sage: H.filter_regular_parameters()
            Compute filter_regular_parameters
            Trying to lift the parameters of H^*(SD16; GF(2))
        H^*(SmallGroup(48,29); GF(2)):
            Exploring relations in degree 1
            Determine degree 1 standard monomials
            Express 1 standard monomial as cocycle
            Found 0 relations in degree 1
        H^*(M11; GF(2)):
            One parameter could not be lifted
            Testing whether parameters of the cohomology ring can be found
            > Yes
            Compute find_small_last_parameter
            Computing complete Groebner basis
            Compute _parameter_restrictions
        Induced homomorphism of degree 0 from H^*(M11; GF(2)) to H^*(SmallGroup(4,2); GF(2)):
            Compute restricted parameters
        H^*(M11; GF(2)):
            Compute _get_obvious_parameter
            Compute _parameter_restrictions
            compute radicals of restricted parameter ideal
            Compute _parameter_restrictions
        Induced homomorphism of degree 0 from H^*(M11; GF(2)) to H^*(SmallGroup(4,2); GF(2)):
            Compute restricted parameters
        H^*(M11; GF(2)):
            Determine degree 1 standard monomials
            Compute _get_obvious_parameter
            Determine degree 2 standard monomials
            Compute _get_obvious_parameter
            Determine degree 3 standard monomials
            --> Last parameter found in degree 3
        ['c_4_0', 'b_3_0']

    We continue out to degree 10, and then test again. In this case, the Symonds criterion is chosen for the test:

        sage: CohomologyRing.global_options('warn')
        sage: H.next()
        sage: H.next()
        sage: H.next()
        sage: H.next()
        sage: H.next()
        sage: CohomologyRing.global_options('info')
        sage: H.test_for_completion()
        H^*(M11; GF(2)):
            Compute dependent_parameters
            Try to find a set of generators over which the cohomology ring is finite.
            Computing complete Groebner basis
            Trying Symonds' criterion
            Successful application of the Symonds criterion
        True
        sage: CohomologyRing.global_options('warn')
        sage: H.completed
        True

    In the following example, it occurs that the ring approximation out to degree 10 does contain elements that give rise to parameters for the cohomology ring:

        sage: H = CohomologyRing(864*2,206,prime=2)
        sage: H.make(10)
        sage: H.verify_parameters_exist()
        True
        sage: H.dependent_parameters()
        ['b_1_0', 'c_6_13', 'c_4_5', 'c_2_1']

    But the dependent parameters of the ring approximation are not enough to apply the Symonds criterion:

        sage: H.SymondsTest(H.dependent_parameters(), [1,6,6,4,2]) is None
        True

    In fact, it turns out that the simultaneous lifts of Dickson invariants, that are guaranteed to yield parameters of the cohomology ring, are not parameters of the ring approximation:

        sage: H.find_dickson()
        True
        sage: H.Dickson
        ['...b_1_0^8+...',
         '...c_4_5^2*b_1_0^4+...',
         '...c_2_1*c_6_12^2+...',
         'b_1_0']
        sage: H.set_ring()
        sage: singular.ideal(H.Dickson+H.rels()).groebner().dim() > 0
        True

    we can find smaller elements that are guaranteed to yield parameters of the complete cohomology ring, but of course the ring approximation is not complete yet:

        sage: H.parameters()
        ['c_2_1', 'c_4_5', 'c_6_13', 'b_1_0']
        sage: H.test_for_completion()
        False

    It turns out that the last relation is in fact found in degree 12, and then of course the complete cohomology ring is finite over both the elements obtained from the Dickson invariants and the system of parameters in smaller degrees:

        sage: H.make()
        sage: H.last_interesting_degree()
        12
        sage: H.rels()[-1]
        '...c_6_12^2+...'
        sage: H.parameters()
        ['c_2_1', 'c_4_5', 'c_6_13', 'b_1_0']
        sage: H.set_ring()
        sage: singular.ideal(H.Dickson+H.rels()).groebner().dim()
        0
        sage: singular.ideal(H.parameters()+H.rels()).groebner().dim()
        0

`pGroupCohomology.modular_cohomology.` `MODCOHO_unpickle`(*L)

  COHO_unpickle.

  TESTS:

      sage: from pGroupCohomology import CohomologyRing
      sage: CohomologyRing.doctest_setup()       # reset, block web access, use temporary workspace
      sage: H = CohomologyRing(720,763,prime=2, from_scratch=True)
      sage: H.make(3)
      sage: H is loads(dumps(H)) #indirect doctest
      True