test_roots = ->
	run_test [

		"roots(x)",
		"0",

		"roots(2^x-y,y)",
		"2^x",

		"roots(x^2)",
		"0",

		"roots(x^3)",
		"0",

		"roots(2 x)",
		"0",

		"roots(2 x^2)",
		"0",

		"roots(2 x^3)",
		"0",

		"roots(6+11*x+6*x^2+x^3)",
		"(-3,-2,-1)",

		"roots(a*x^2+b*x+c)",
		"(-b/(2*a)-(-4*a*c+b^2)^(1/2)/(2*a),-b/(2*a)+(-4*a*c+b^2)^(1/2)/(2*a))",

		"roots(3+7*x+5*x^2+x^3)",
		"(-3,-1)",

		"roots(x^3+x^2+x+1)",
		"(-1,-i,i)",

		"roots(x^4+1)",
		"Stop: roots: the polynomial is not factorable, try nroots",

		"roots(x^2==1)",
		"(-1,1)",

		"roots(3 x + 12 == 24)",
		"4",

		"y=roots(x^2+b*x+c/k)[1]",
		"",

		"y^2+b*y+c/k",
		"0",

		"y=roots(x^2+b*x+c/k)[2]",
		"",

		"y^2+b*y+c/k",
		"0",

		"y=roots(a*x^2+b*x+c/4)[1]",
		"",

		"a*y^2+b*y+c/4",
		"0",

		"y=roots(a*x^2+b*x+c/4)[2]",
		"",

		"a*y^2+b*y+c/4",
		"0",

		"y=quote(y)",
		"",

		# --------------------------------------------
		# some more tests with 3rd degree polynomials
		# including use of cubic formula.
		# Only the ones marked "DOES use cubic formula"
		# actually do so, all other examples manage to
		# be reduced via factoring.
		# --------------------------------------------

		"roots(x^3 + x^2 + x + 1)",
		"(-1,-i,i)",
		
		"roots(2*x^3 + 3*x^2 - 11*x - 6)",
		"(-3,-1/2,2)",

		"roots(x^3 - 7*x^2 + 4*x + 12)",
		"(-1,2,6)",

		"roots(x^3 + 1)",
		"(-1,1/2-1/2*i*3^(1/2),1/2+1/2*i*3^(1/2))",
		
		"roots(x^3 - 1)",
		"(1,-1/2-1/2*i*3^(1/2),-1/2+1/2*i*3^(1/2))",
		
		# DOES use cubic formula
		"thePoly = x^3 + d",
		"",
			
		"roots(thePoly)",
		"(-d^(1/3),1/2*d^(1/3)*(1-i*3^(1/2)),1/2*d^(1/3)*(1+i*3^(1/2)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",

		# DOES use cubic formula
		# the actual format of this solution might change, the important thing
		# is that the next few tests work, where we plug in the
		# symbolic solutions in the polynomial again and we check that we
		# get the zeroes.

		"thePoly = a*x^3 + b*x^2 + c*x + d",
		"",
			
		"roots(thePoly)",
		"((-3/2*i*a*c+1/2*i*b^2-1/2*i*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(2/3)-b*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(1/3)/(3^(1/2))+b^2/(2*3^(1/2))+(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(2/3)/(2*3^(1/2))-1/2*3^(1/2)*a*c)/(3^(1/2)*a*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(1/3)),(3/2*i*a*c-1/2*i*b^2+1/2*i*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(2/3)-b*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(1/3)/(3^(1/2))+b^2/(2*3^(1/2))+(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(2/3)/(2*3^(1/2))-1/2*3^(1/2)*a*c)/(3^(1/2)*a*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(1/3)),(a*c-1/3*b*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(1/3)-1/3*b^2-1/3*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(2/3))/(a*(-9/2*a*b*c+b^3+1/2*(-27*a^2*b^2*c^2+108*a^2*b^3*d-486*a^3*b*c*d+108*a^3*c^3+729*a^4*d^2)^(1/2)+27/2*a^2*d)^(1/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",

		"roots(x^3 + 6x - 20)",
		"(2,-1-3*i,-1+3*i)",

		"roots(x^3 - 6x - 40)",
		"(4,-2-i*2^(1/2)*3^(1/2),-2+i*2^(1/2)*3^(1/2))",
			
		"roots(x^3 + x^2 - 5x - 5)",
		"(-1,-5^(1/2),5^(1/2))",
			
		"roots(x^3 - 8x + 3)",
		"(-3,3/2-1/2*5^(1/2),3/2+1/2*5^(1/2))",
			
		"roots(x^3 - 8x - 3)",
		"(3,-3/2-1/2*5^(1/2),-3/2+1/2*5^(1/2))",
			
		"roots(x^3 - 18x + 35)",
		"(-5,5/2-1/2*i*3^(1/2),5/2+1/2*i*3^(1/2))",

		# DOES use cubic formula
		"thePoly = x^3 - 3x + 1",
		"",
			
		"roots(thePoly)",
		"((-9*i+3*3^(1/2)+i*(27/2+27/2*i*3^(1/2))^(2/3)+(27/2+27/2*i*3^(1/2))^(2/3)/(3^(1/2)))/(2*3^(1/2)*(27/2+27/2*i*3^(1/2))^(1/3)),(9*i+3*3^(1/2)-i*(27/2+27/2*i*3^(1/2))^(2/3)+(27/2+27/2*i*3^(1/2))^(2/3)/(3^(1/2)))/(2*3^(1/2)*(27/2+27/2*i*3^(1/2))^(1/3)),(-3-1/3*(27/2+27/2*i*3^(1/2))^(2/3))/((27/2+27/2*i*3^(1/2))^(1/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",
			
		# DOES use cubic formula
		"thePoly = x^3 - 3x - 1",
		"",
			
		"roots(thePoly)",
		"((-9*i+3*3^(1/2)+i*(-27/2+27/2*i*3^(1/2))^(2/3)+(-27/2+27/2*i*3^(1/2))^(2/3)/(3^(1/2)))/(2*3^(1/2)*(-27/2+27/2*i*3^(1/2))^(1/3)),(9*i+3*3^(1/2)-i*(-27/2+27/2*i*3^(1/2))^(2/3)+(-27/2+27/2*i*3^(1/2))^(2/3)/(3^(1/2)))/(2*3^(1/2)*(-27/2+27/2*i*3^(1/2))^(1/3)),(-3-1/3*(-27/2+27/2*i*3^(1/2))^(2/3))/((-27/2+27/2*i*3^(1/2))^(1/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",
			
		"roots(x^3 - 15x - 4)",
		"(4,-2-3^(1/2),-2+3^(1/2))",
			
		"roots(2*x^3 - 4x^2 - 22*x + 24)",
		"(-3,1,4)",

		# DOES use cubic formula
		"thePoly = 3*x^3 - 10*x^2 - 14*x + 27",
		"",
			
		"roots(thePoly)",
		"(10/9-226/(9*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3))-1/9*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3),10/9+113/(9*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3))+1/18*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3)-113*i/(3*3^(1/2)*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3))+i*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3)/(6*3^(1/2)),10/9+113/(9*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3))+1/18*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3)+113*i/(3*3^(1/2)*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3))-i*(781/2+9/2*i*3^(1/2)*97^(1/2)*1933^(1/2))^(1/3)/(6*3^(1/2)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",
			

		# DOES use cubic formula
		"thePoly = 1*x^3 + 6*x^2 - 12*x + 8",
		"",
			
		"roots(thePoly)",
		"(-2+2^(1/3)+2^(2/3)-i*2^(1/3)*3^(1/2)+i*2^(2/3)*3^(1/2),-2+2^(1/3)+2^(2/3)+i*2^(1/3)*3^(1/2)-i*2^(2/3)*3^(1/2),-2*(1+2^(1/3)+2^(2/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",


		"roots(1*x^3 + 6*x^2 + 12*x + 8)",
		"-2",
			
		# DOES use cubic formula
		"thePoly = 1*x^3 + 0*x^2 + 12*x - 10",
		"",
			
		"roots(thePoly)",
		"((-18*i-6*3^(1/2)-1/2*i*(-135+27*89^(1/2))^(2/3)+(-135+27*89^(1/2))^(2/3)/(2*3^(1/2)))/(3^(1/2)*(-135+27*89^(1/2))^(1/3)),(18*i-6*3^(1/2)+1/2*i*(-135+27*89^(1/2))^(2/3)+(-135+27*89^(1/2))^(2/3)/(2*3^(1/2)))/(3^(1/2)*(-135+27*89^(1/2))^(1/3)),(12-1/3*(-135+27*89^(1/2))^(2/3))/((-135+27*89^(1/2))^(1/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",
			
		"roots(1*x^3 + 0*x^2 - 18*x + 35)",
		"(-5,5/2-1/2*i*3^(1/2),5/2+1/2*i*3^(1/2))",

		# DOES use cubic formula
		"thePoly = 1*x^3 + 0*x^2 - 3*x - 6",
		"",
			
		"roots(thePoly)",
		"((-9*i+3*3^(1/2)+i*(-81+54*2^(1/2))^(2/3)+(-81+54*2^(1/2))^(2/3)/(3^(1/2)))/(2*3^(1/2)*(-81+54*2^(1/2))^(1/3)),(9*i+3*3^(1/2)-i*(-81+54*2^(1/2))^(2/3)+(-81+54*2^(1/2))^(2/3)/(3^(1/2)))/(2*3^(1/2)*(-81+54*2^(1/2))^(1/3)),(-3-1/3*(-81+54*2^(1/2))^(2/3))/((-81+54*2^(1/2))^(1/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",
			
		"roots(2*x^3 - 30*x^2 + 162*x - 350)",
		"(7,4-3*i,4+3*i)",

		"roots(1*x^3 - 4*x^2 - 6*x + 5)",
		"(5,-1/2-1/2*5^(1/2),-1/2+1/2*5^(1/2))",

		# DOES use cubic formula
		"thePoly = 3*x^3 + 6*x^2 + 4*x + 9",
		"",
			
		"roots(thePoly)",
		"(-2/3-1/3*73^(1/3),-2/3+1/6*73^(1/3)-i*73^(1/3)/(2*3^(1/2)),-2/3+1/6*73^(1/3)+i*73^(1/3)/(2*3^(1/2)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",

		# DOES use cubic formula
		"thePoly = 3*x^3 + 21*x^2 + 2*x + 3",
		"",
			
		"roots(thePoly)",
		"(-7/3-47/((18117/2+27/2*34949^(1/2))^(1/3))-1/9*(18117/2+27/2*34949^(1/2))^(1/3),-7/3+47/(2*(18117/2+27/2*34949^(1/2))^(1/3))+1/18*(18117/2+27/2*34949^(1/2))^(1/3)-i*(18117/2+27/2*34949^(1/2))^(1/3)/(6*3^(1/2))+47*i*3^(1/2)/(2*(18117/2+27/2*34949^(1/2))^(1/3)),-7/3+47/(2*(18117/2+27/2*34949^(1/2))^(1/3))+1/18*(18117/2+27/2*34949^(1/2))^(1/3)+i*(18117/2+27/2*34949^(1/2))^(1/3)/(6*3^(1/2))-47*i*3^(1/2)/(2*(18117/2+27/2*34949^(1/2))^(1/3)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",

		# DOES use cubic formula
		"thePoly = 3*x^3 - 6*x^2 + 4*x - 5",
		"",
			
		"roots(thePoly)",
		"(2/3-1/3*(-1)^(1/3)*37^(1/3),2/3+1/6*(-1)^(1/3)*37^(1/3)-(-1)^(5/6)*37^(1/3)/(2*3^(1/2)),2/3+1/6*(-1)^(1/3)*37^(1/3)+(-1)^(5/6)*37^(1/3)/(2*3^(1/2)))",
			
		"(simplify(subst(last[1],x,thePoly)) == 0) and (simplify(subst(last[2],x,thePoly)) == 0) and (simplify(subst(last[3],x,thePoly)) == 0)",
		"1",

		"roots(8*x^3 - 36*x^2 + 54*x - 27)",
		"3/2",

		"roots(3*x^3 - 5*x^2 - 1*x - 2)",
		"(2,-1/6-1/6*i*11^(1/2),-1/6+1/6*i*11^(1/2))",


		# DOES use cubic formula
		"thePoly = 3*x^3 - 6*x^2 + 4*x - i",
		"",
			
		"roots(thePoly)",
		"(2/3-1/9*(108-243/2*i+27/2*(-1)^(-1/2+arctan(144/17)/(2*pi))*5^(1/2)*29^(1/2))^(1/3),2/3+1/18*(108-243/2*i+27/2*(-1)^(-1/2+arctan(144/17)/(2*pi))*5^(1/2)*29^(1/2))^(1/3)-i*(108-243/2*i+27/2*(-1)^(-1/2+arctan(144/17)/(2*pi))*5^(1/2)*29^(1/2))^(1/3)/(6*3^(1/2)),2/3+1/18*(108-243/2*i+27/2*(-1)^(-1/2+arctan(144/17)/(2*pi))*5^(1/2)*29^(1/2))^(1/3)+i*(108-243/2*i+27/2*(-1)^(-1/2+arctan(144/17)/(2*pi))*5^(1/2)*29^(1/2))^(1/3)/(6*3^(1/2)))",

		"(abs(float(subst(last[1],x,thePoly))) < float(2*10^(-15))) and (abs(float(subst(last[2],x,thePoly))) < float(2*10^(-15))) and (abs(float(subst(last[3],x,thePoly))) < float(2*10^(-15)))",
		"1",


		# DOES use cubic formula
		"thePoly = x^3+i",
		"",
			
		"roots(thePoly)",
		"(1/2*(-1)^(1/6)-1/2*(-1)^(2/3)*3^(1/2),-(-1)^(1/6),1/2*(-1)^(1/6)*(1+i*3^(1/2)))",

		"(abs(float(subst(last[1],x,thePoly))) < float(2*10^(-15))) and (abs(float(subst(last[2],x,thePoly))) < float(2*10^(-15))) and (abs(float(subst(last[3],x,thePoly))) < float(2*10^(-15)))",
		"1",


		# DOES use cubic formula
		"thePoly = x^3-i",
		"",
			
		"roots(thePoly)",
		"(-i,1/2*(i-3^(1/2)),1/2*(i+3^(1/2)))",

		"(abs(float(subst(last[1],x,thePoly))) < float(2*10^(-15))) and (abs(float(subst(last[2],x,thePoly))) < float(2*10^(-15))) and (abs(float(subst(last[3],x,thePoly))) < float(2*10^(-15)))",
		"1",



		# we meddled with the "thePoly" variable, now clean up
		"thePoly = quote(thePoly)",
		"",

	]
