anchor.diff:      override this.ToString () =
           match this with
           | Z z ->
  -            z.ToString()
  +            z.ToString ()
           | Q q ->
  -            q.ToString()
  +            q.ToString ()
   
       member this.StructuredDisplayString =
           this.ToString ()
  
positive.code: open System.Globalization
  
  
  [<AutoOpen>]
  module private BigRationalLargeImpl =
      let ZeroI = BigInteger (0)
      let OneI = BigInteger (1)
      let bigint (x : int) = BigInteger (x)
      let ToDoubleI (x : BigInteger) = float x
      let ToInt32I (x : BigInteger) = int32 x
  
  
  [<CustomEquality; CustomComparison>]
  type BigRationalLarge =
      // invariants: (p,q) in lowest form, q >= 0
      | Q of BigInteger * BigInteger
  
      member x.IsNegative =
          let (Q (ap, _)) = x
          sign ap < 0
  
      member x.IsPositive =
          let (Q (ap, _)) = x
          sign ap > 0
  
      member x.Numerator =
          let (Q (p, _)) = x in p
  
      member x.Denominator =
          let (Q (_, q)) = x in q
  
      member x.Sign =
          let (Q (p,_) ) = x
          sign p
  
      override this.GetHashCode () =
          BigRationalLarge.Hash this
  
      override this.ToString () =
          let (Q (p, q)) = this
          if q.IsOne then
              p.ToString()
          else
              p.ToString() + "/" + q.ToString()
  
      static member Hash (Q (ap, aq)) =
          // This hash code must be identical to the hash for BigInteger when the numbers coincide.
          if aq.IsOne then ap.GetHashCode ()
          else (ap.GetHashCode () <<< 3) + aq.GetHashCode ()
  
      static member Equals(Q (ap, aq), Q (bp, bq)) =
          // normal form, so structural equality
          BigInteger.(=) (ap, bp) && BigInteger.(=) (aq, bq)
  
      static member LessThan (Q (ap, aq), Q (bp, bq)) =
          BigInteger.(<) (ap * bq, bp * aq)
  
      // TODO: performance improvement possible here
      static member Compare (p, q) =
          if BigRationalLarge.LessThan (p, q) then -1
          elif BigRationalLarge.LessThan (q, p)then 1
          else 0
  
      static member ToDouble (Q (p, q)) =
          ToDoubleI p / ToDoubleI q
  
      static member Normalize (p : BigInteger, q : BigInteger) =
          if q.IsZero then
              (* throw for any x/0 *)
              raise <| System.DivideByZeroException ()
          elif q.IsOne then
              Q (p, q)
          else
              let k = BigInteger.GreatestCommonDivisor (p, q)
              let p = p / k
              let q = q / k
              if sign q < 0 then
                  Q (-p, -q)
              else Q (p, q)
  
      static member Rational (p : int, q : int) =
          BigRationalLarge.Normalize (bigint p, bigint q)
  
      // TODO : Rename to Rational? It doesn't seem like we need to force the overload resolution here with a separate name...
      static member RationalZ (p, q) =
          BigRationalLarge.Normalize (p, q)
  
      /// Return the negation of a rational number
      static member (~-) (Q (bp, bq)) =
          // still coprime, bq >= 0
          Q(-bp, bq)
      
      /// Return the sum of two rational numbers
      static member (+) (Q (ap, aq), Q (bp, bq)) =
          BigRationalLarge.Normalize ((ap * bq) + (bp * aq), aq * bq)
      
      /// Return the difference of two rational numbers
      static member (-) (Q (ap, aq), Q (bp, bq)) =
          BigRationalLarge.Normalize ((ap * bq) - (bp * aq), aq * bq)
      
      /// Return the product of two rational numbers
      static member (*) (Q (ap, aq), Q (bp, bq)) =
          BigRationalLarge.Normalize (ap * bp, aq * bq)
      
      /// Return the ratio of two rational numbers
      static member (/) (Q (ap, aq), Q (bp, bq)) =
          BigRationalLarge.Normalize (ap * bq, aq * bp)
  
      /// Return the given rational number
      static member ( ~+ ) (n1 : BigRationalLarge) = n1
  
      //
      static member Parse (str : string) =
          let len = str.Length
          if len=0 then invalidArg "str" "empty string";
          let j = str.IndexOf '/'
          if j >= 0 then
              let p = BigInteger.Parse (str.Substring(0,j))
              let q = BigInteger.Parse (str.Substring(j+1,len-j-1))
              BigRationalLarge.RationalZ (p,q)
          else
              let p = BigInteger.Parse str
              BigRationalLarge.RationalZ (p,OneI)
  
      override this.Equals(that : obj) =
          match that with
          | :? BigRationalLarge as that ->
              BigRationalLarge.Equals(this,that)
          | _ -> false
  
      interface System.IComparable with
  
negative.code:     static member Parse (str : string) =
          Q (BigRationalLarge.Parse str)
  
      // TODO : Optimize this by implementing a proper comparison function (so we only do one comparison instead of two).
      interface System.IComparable with
          member this.CompareTo (obj : obj) =
              match obj with
  