function CongruentNumberCurve(n) return EllipticCurve([-n^2,0]); end function; function TunnelsCriterion(n) n := SquareFree(n); bnd := Floor(Sqrt(n))+1; box := [-bnd..bnd]; set8 := []; set32 := []; if IsOdd(n) then // set8 := [ : x in box, y in box, z in box | 2*x^2 + y^2 + 8*z^2 eq n]; // set32 := [ : x in box, y in box, z in box | 2*x^2 + y^2 + 32*z^2 eq n]; for x in box do for z in box do t, y := IsSquare(n - 2*x^2 - 8*z^2); if t and y in box then Append(~set8, ); end if; t, y := IsSquare(n - 2*x^2 - 32*z^2); if t and y in box then Append(~set32, ); end if; end for; end for; else // set8 := [ : x in box, y in box, z in box | 4*x^2 + y^2 + 8*z^2 eq n div 2]; // set32 := [ : x in box, y in box, z in box | 4*x^2 + y^2 + 32*z^2 eq n div 2]; for x in box do for z in box do t, y := IsSquare((n div 2) - 4*x^2 - 8*z^2); if t and y in box then Append(~set8, ); end if; t, y := IsSquare((n div 2) - 4*x^2 - 32*z^2); if t and y in box then Append(~set32, ); end if; end for; end for; end if; return #set8 eq 2*#set32, set8, set32; end function; function abRepresentation(X,Y,Z) /************************************************************* Assume that (X, Y, Z) form a primitive Pythagorean triple with Y even. This function returns relatively prime integers a, b with X = a^2 - b^2, Y = 2ab, and Z = a^2 + b^2. *************************************************************/ assert IsEven(Y); assert X^2 + Y^2 eq Z^2; assert GCD([X, Y, Z]) eq 1; u := X/Z; v := Y/Z; alpha := v/(u+1); a := Denominator(alpha); b := Numerator(alpha); assert X eq a^2 - b^2; assert Y eq 2*a*b; assert Z eq a^2 + b^2; return a,b; end function; function RationalSqrt(x) assert Type(x) in {RngIntElt, FldRatElt}; assert x ge 0; R := RealField(2000); a := R!Numerator(x); assert IsSquare(a); b := R!Denominator(x); assert IsSquare(b); sqrt := Round(Sqrt(a))/Round(Sqrt(b)); assert sqrt^2 eq x; return sqrt; end function; function CongruentTriangle(P) assert Type(P) eq PtEll; // P should be a point on y^2 = x^3 - n^2*x. n := Integers()!RationalSqrt(-aInvariants(Curve(Parent(P)))[4]); P := 2*P; x := P[1]/P[3]; y := P[2]/P[3]; u := RationalSqrt(x); v := y/u; t := Denominator(u); a,b := abRepresentation(t^2*v, t^2*n, t^2*x); return [Abs(2*a/t), Abs(2*b/t), Abs(2*u)]; end function; function CongruentRep(n) // Assume that n is a congruent number. Try to find a triangle that // realizes it as a congruent number. E := CongruentNumberCurve(n); G,f := MordellWeilGroup(E); if Ngens(G) le 2 then l,r := RankBounds(E); if r gt 0 then print n, "is probably a congruent number, but I didn't find a representation."; else print n, "is not a congruent number."; end if; return 0; end if; return CongruentTriangle(f(G.3)), f(G.3); end function;