-- Source "../../../home/achilles/scroll.coc";

Define Scroll(A,B)
  ScrollRing ::=  Q[x[0..A],y[0..B]];
  Using ScrollRing Do
  M := Mat([Concat(x[0]..x[A-1],y[0]..y[B-1]),
  Concat(x[1]..x[A],y[1]..y[B])]);
  Return Ideal(Minors(2,M));
  EndUsing;
EndDefine;

Define BiDegree(I,A,B)
  F := Flatten([[1 | X In 1..A],[0 | X In 1..B]]);
  S := Flatten([[0 | X In 1..A],[1 | X In 1..B]]);
  G:= Mat([[1 | X In 1..(A+B)], F, S]);
  H := HilbertSeriesMultiDeg(CurrentRing()/I, G);
  Num := Sum([X[1]*LogToTerm(X[2]) | X In @H[1]]);
  N := Eval(Num, [1, 1-Indet(1), 1-Indet(2)]);
  M := Min([Deg(X) | X In Monomials(N)]);
  P := Sum([X In Monomials(N) | Deg(X) = M]);
  PrintLn [CoeffOfTerm(X,P) | 
  X In Support((Indet(1)+Indet(2))^M)];
Return P;
EndDefine;

Define RuledJoin(I,J)
  N := NumIndets();
  JoinRing ::= CoeffRing[x[1..N],y[1..N]];
  Using JoinRing Do
  IndetJoinRing := Indets();
  X := IndetJoinRing[1]..IndetJoinRing[N];
  Y := IndetJoinRing[N+1]..IndetJoinRing[2N];
  FX := RMap(X); FY := RMap(Y);
  JoinIdeal := Image(I,FX) + Image(J,FY);
  DiagonalIdeal := Ideal(X - Y);
  EndUsing;
  Return [JoinIdeal, DiagonalIdeal];
EndDefine;

Define BlowUp(I,J)
  N := NumIndets();
  M := Len(J);
  AuxiliaryRing ::= CoeffRing[x[1..N],t[1..M],s], Elim(s);
  Using AuxiliaryRing Do
    IndetAuxiliaryRing := Indets();
    X := IndetAuxiliaryRing[1]..IndetAuxiliaryRing[N];
    T := IndetAuxiliaryRing[N+1]..IndetAuxiliaryRing[N+M];
    FX := RMap(X);
    FI := Image(I,FX);
    FJ := Image(J,FX);
    A := Ideal(T-s*Gens(FJ)) + FI;
    B := Elim(s,A);
    AssGrad := B + FJ;
  EndUsing;
  BlowUpRing ::= CoeffRing[x[1..N],t[1..M]];
  Using BlowUpRing Do
    G := RMap(Concat(Indets(),[0]));
    IdealOfBlowUp := Image(B,G);
    IdealOfAssGrad := Image(AssGrad,G);
  EndUsing;
  Destroy AuxiliaryRing;
  Return [IdealOfBlowUp, IdealOfAssGrad];
EndDefine;

Define EmbJoin(I,J)
  N := NumIndets();
  V := Indets();
  AuxiliaryRing ::= CoeffRing[x[1..N],y[1..N]], Elim(x[1]..x[N]);
  Using AuxiliaryRing Do
    IndetAuxiliaryRing := Indets();
    X := IndetAuxiliaryRing[1]..IndetAuxiliaryRing[N];
    Y := IndetAuxiliaryRing[N+1]..IndetAuxiliaryRing[2*N]; 
    FX := RMap(X);
    FY := RMap(X+Y);
    FI := Image(I,FX);
    FJ := Image(J,FY);
    J := Elim(x[1]..x[N],FI+FJ);
  EndUsing;
  F := RMap(Concat(Indets(),Indets()));
  J := Image(J,F);
  Destroy AuxiliaryRing;
  Return J;
EndDefine;
 
