+ M2 --no-readline --print-width 98
Macaulay2, version 1.15
--loading configuration for package "FourTiTwo" from file /home/ubuntuasus/.Macaulay2/init-FourTiTwo.m2
--loading configuration for package "Topcom" from file /home/ubuntuasus/.Macaulay2/init-Topcom.m2
with packages: ConwayPolynomials, Elimination, IntegralClosure, InverseSystems, LLLBases,
               PrimaryDecomposition, ReesAlgebra, TangentCone, Truncations

i1 : 
     ---------------------------------------------------------------------
     -- Theorem 3.3: Unirationality of M_{12,4} via Geiß construction 
     ---------------------------------------------------------------------
     load "UnirationalPointedCurves.m2"

i2 : -- We want to construct a curve in P^1xP^2 with genus 12 and bidegree (7,10).
     -- We follow Geiß' construction and try to construct it from K, the truncated
     -- deficiency module it should have.
     S=ZZ/32009[x_0,x_1,y_0..y_2,Degrees=>{2:{1,0},3:{0,1}}];

i3 : M=random(S^{6:{0,0}},S^{10:{0,-1},7:{-1,0}});

             6       17
o3 : Matrix S  <--- S

i4 : K=coker M;

i5 : matrix apply(toList(0..5),i->apply(toList(0..2),j->hilbertFunction({i,j},K)))

o5 = | 6 8 6 |
     | 5 0 0 |
     | 4 0 0 |
     | 3 0 0 |
     | 2 0 0 |
     | 1 0 0 |

              6        3
o5 : Matrix ZZ  <--- ZZ

i6 : -- Taking K as the cokernel of a general matrix M with the entries as above,
     -- the Hilbert function of K is not the one we want, as there is a missing 4 in degree (1,1).
     -- Hence: we have to produce M such that the cokernel does have that Hilbert function!
     -- One possibility is to produce M=A|B in two steps.
     -- We start from a random A.
     A=random(S^{6:{0,0}},S^{7:{-1,0}});

             6       7
o6 : Matrix S  <--- S

i7 : matrix apply(toList(0..5),i->apply(toList(0..2),j->hilbertFunction({i,j},coker A)))

o7 = | 6 18 36 |
     | 5 15 30 |
     | 4 12 24 |
     | 3 9  18 |
     | 2 6  12 |
     | 1 3  6  |

              6        3
o7 : Matrix ZZ  <--- ZZ

i8 : -- In degree (1,1), the orthogonal to the image of A has dimension 15 as expected.
     -- Let's compute elements in degree (1,1) which are orthogonal to image(A).
     ortElA=complementBasis({1,1},A);

             6       15
o8 : Matrix S  <--- S

i9 : -- They are indeed 15. We select four of them: we want the image of B to be orthogonal to them
     -- as well, so that coker(A|B) will contain them.
     ortEl=ortElA*random(source ortElA,(ring source ortElA)^4);

             6       4
o9 : Matrix S  <--- S

i10 : -- By Macaulay's apolarity, the degree (1,1) part of the module generated by the columns of B
      -- will be orthogonal to the 4 columns of ortEl if and only if the columns of B (which have
      -- degree (0,1)) are orthogonal to the partial derivatives (with respect to x_0 and x_1) of the
      -- 4 columns of ortEl.
      -- We differentiate each column by x_0,x_1.
      varsToDerive=flatten entries basis({1,0},S)

o10 = {x , x }
        0   1

o10 : List

i11 : columns:=entries transpose ortEl;

i12 : genEls=flatten apply(varsToDerive,V->apply(columns, C->(
            apply(C,c->derive(V,c))
            )));

i13 : P=transpose matrix genEls;

              6       8
o13 : Matrix S  <--- S

i14 : -- We get 8 columns, which are elements of S^6 in degree {0,1}. Now we compute a basis of the
      -- orthogonal complement.
      possColumnsOfB=complementBasis({0,1},P);

              6       10
o14 : Matrix S  <--- S

i15 : -- We have 10 elements. We need to choose the columns of B as linear combinations of these
      -- elements. How many columns does B have? Exactly ten! So we take all of them.
      B=matrix entries possColumnsOfB; 

              6       10
o15 : Matrix S  <--- S

i16 : matrix apply(toList(0..5),i->apply(toList(0..2),j->hilbertFunction({i,j},coker (A|B))))

o16 = | 6 8 6 |
      | 5 4 0 |
      | 4 0 0 |
      | 3 0 0 |
      | 2 0 0 |
      | 1 0 0 |

               6        3
o16 : Matrix ZZ  <--- ZZ

i17 : -- The Hilbert function is the desired one!
      -- Now, we just use Geiß' construction to reconstruct the curve from the module.
      K=coker(A|B);

i18 : resK=res K;

i19 : F1=S^{9:{-1,-1},3:{-1,-2}};

i20 : IC=ideal syz(resK.dd_2 *random(resK_2,F1));

o20 : Ideal of S

i21 : ICsat=saturate(IC,ideal(S_0*S_2));

o21 : Ideal of S

i22 : -- We check that ICsat is a smooth curve of genus 12 an bidegree (7,10).
      codim ICsat

o22 = 2

i23 : time isSmoothP1P2 ICsat -- takes about 72 seconds
     -- used 73.8052 seconds

o23 = true

i24 : multidegree ICsat

                 2
o24 = 10T T  + 7T
         0 1     1

o24 : ZZ[T , T ]
          0   1

i25 : genusP1P2 ICsat

o25 = 12

i26 : -- It should be contained in at least 2 hypersurfaces of degree (2,4).
      tally degrees ICsat

o26 = Tally{{0, 10} => 1}
            {1, 7} => 6
            {2, 4} => 2
            {2, 5} => 4
            {3, 4} => 6
            {4, 3} => 3

o26 : Tally

i27 : -- We take the two hypersurfaces and compute the residual curve.
      CI=cIntContaining({{2,4},{2,4}},ICsat);

o27 : Ideal of S

i28 : ID=saturate(CI:ICsat,ideal(S_0*S_2));

o28 : Ideal of S

i29 : -- ID should be a smooth curve in P^1xP^2 with genus 4 and bidegree (9,6)
      -- which intersects ICsat in only ordinary double points.
      codim ID

o29 = 2

i30 : genusP1P2 ID

o30 = 4

i31 : multidegree ID

                2
o31 = 6T T  + 9T
        0 1     1

o31 : ZZ[T , T ]
          0   1

i32 : time isSmoothP1P2 ID -- takes about 21 seconds
     -- used 20.6111 seconds

o32 = true

i33 : time isOrdDoublePointsP1P2(CI) -- takes about 19 seconds
     -- used 20.0158 seconds

o33 = true

i34 : -- It should be contained in at least 6 hypersurfaces of degree (2,4),  
      -- so that we can impose up to 4 points.
      tally degrees ID

o34 = Tally{{0, 6} => 1}
            {1, 5} => 6
            {2, 4} => 6
            {6, 3} => 1

o34 : Tally

i35 : NPoints=apply(4,i->ideal(random({1,0},S),random({0,1},S),random({0,1},S)));

i36 : DandNPoints=intersect(NPoints|{ID});

o36 : Ideal of S

i37 : -- We take the two hypersurfaces and do liaison backwards.
      CI2=cIntContaining({{2,4},{2,4}},DandNPoints);

o37 : Ideal of S

i38 : IC2=saturate(CI2:ID,ideal(S_0*S_2));

o38 : Ideal of S

i39 : -- It should be a smooth curve in P^1xP^2 with genus 12 and bidegree (7,10)
      -- containing the 4 points.
      codim IC2

o39 = 2

i40 : genusP1P2 IC2

o40 = 12

i41 : multidegree IC2

                 2
o41 = 10T T  + 7T
         0 1     1

o41 : ZZ[T , T ]
          0   1

i42 : isSubset(IC2, intersect NPoints)

o42 = true

i43 : time isSmoothP1P2 IC2 -- takes about 80 seconds
     -- used 75.5416 seconds

o43 = true

i44 :