/*
BASED ON TABES
*/

/*
Check if homogeneous in x, y, z (there can be other variables...)
Returns the degree >= 0 if yes
Returns -1 else
*/
check_hom(f) =
{
local(k, l, m, a, b, c, d, g, h);
if(f,,return(0));
k = poldegree(f, x);
g = polcoeff(f, k, x);
l = poldegree(g, y);
h = polcoeff(g, l, y);
m = poldegree(g, z);
/* this is the degree of f */
d = k + l + m;
a = 0;
while(a <= k,
  g = polcoeff(f, a, x);
  l = poldegree(g, y);
  if(a + l > d, return(-1));
  b = 0;
  while(b <= l,
    h = polcoeff(g, b, y);
    if(h - subst(h, z, 1)*z^(d - a - b), return(-1));
    b = b + 1
  );
  a = a + 1
);
return(d)
}

/*
Assume that the homogeneous coordinates on P^1 are x, y
Returns the degree if it is a morphism
Else returns -1
*/
morphism(f, g, h) =
{
local(d);
/* Check for common zeros */
if(gcd(f, gcd(g, h)) != 1,
  print("Not a morphism because common zero!");
  return(-1),
  /* check the polynomials are homogeneous*/
  if(check_hom(f) < 0 || check_hom(g) < 0 || check_hom(h) < 0,
    print("Not a morphism because not homogeneous!");
    return(-1),
    /*check the polynomials are of the same degree*/
    d = check_hom(f);
    if(check_hom(g) != d || check_hom(h) != d,
      print("Not a morphism as degrees are not equal!");
      return(-1),
      print("This triple defines a morphism!");
      return(d)
    )
  )
)
}

conic(p , f , g , h) =
{
if(morphism(f,g,h) == 2,
  ivector = vector(6);
  ivector[1] = A;
  ivector[2] = B;	
  ivector[3] = C;
  ivector[4] = D;
  ivector[5] = E;
  ivector[6] = F;
  total = A*f^2 + B*f*g + C*f*h + D*g^2 + E*g*h + F*h^2;
  total = subst(total, y, 1);
  m = matrix(5,6);
  for(i=0,4,
    coef = polcoeff(total, i, x);
    for(j=1,6,
      m[i+1,j] = polcoeff(coef, 1, ivector[j])
    )
  );
  if( p == 0,
    final = matker(m);
    print("And parametrizes the conic given by ", [A,B,C,D,E,F]);
    return(final~),
    m = m * Mod(1,p);
    final = matker(m);
    print("And parametrizes the conic given by ", [A,B,C,D,E,F]);
    return(final~)
  ) 
)
}