------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 1995 by International Computer Science Institute            --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------

-- Author: Benedict A. Gomes <gomes@samosa.ICSI.Berkeley.EDU>

abstract class $NFE{NTP} < $NIL,$STR,$IS_EQ is
   -- Abstract class defined over numeric field elements.  Due to
   -- contravariance, we need to parametrize over NTP which is the
   -- type of the argument to many of the defined routines.  Note that
   -- this abstraction is not under $IS_LT{T}, since elements such as
   -- complex numbers are incomparable
   -- 
   -- The subtyping structure is:
   --   $NFE{T}  --- $NUMBER{T} ------ $REAL_NUMBER{T} -- FLT
   --                                                  -- FLTD
   --                           ------ INT 
   --           --- $CPX_NUMBER{ETP,T} --- CPX
   
   zero: NTP;
   -- Return the zero value

   maxval: NTP;;
   -- Return the maximal allowed value

   one: NTP;
   -- Return a unit value

   create(v: INT): SAME;
   -- Create a number from the floating point value. There might
   -- be some loss or gain of precision.
   
   create(v: FLT): SAME;
   -- Create a number from the floating point value. There might
   -- be some loss or gain of precision.
   
   create(v: FLTD): SAME;
   -- Create from a double value in some reasonable way
   
   -- minval: SAME;
   -- Return the minimal allowed value (not yet defined for FLT)
   
   times(n: NTP): SAME;
   -- Return self * n

   plus(n: NTP): SAME;
   -- Return self+n
   
   minus(n: NTP): SAME;
   -- Return self - n
   
   div(n: NTP): SAME;
   -- Return the quotient of self and "n"

   negate: NTP;
   -- Return the negation of self

   abs: NTP;
   -- Return the absolute value of self
   
end; -- class $NFE
-------------------------------------------------------------------
abstract class $NUMBER{NTP} < $IS_LT{NTP},$NFE{NTP} is
   -- Abstraction over Real numbers and Integers This abstraction is
   -- needed to add in the the constraint that numbers are comparable,
   -- unlike general field elements which might not be.
   
end; -- class $NUMBER
-------------------------------------------------------------------
abstract class $REAL_NUMBER{NTP} < $NUMBER{NTP} is
   -- In addition to generic number properties, defines
   -- functions that are applicable to floating point values
   
   exp:NTP;
   -- Return the exponent of the number
   
   cos: NTP;
   -- Return the cosine of self
   
   sin: NTP;
   -- Return the sine of self

   sqrt: NTP;
   -- Return the square root of self
   
   atan2(arg: NTP): SAME;
   -- The arc tangent of self divided by arg in the range [-pi/2, pi/2].
   -- It chooses the quadrant specified by (self, arg).

   acos:SAME;
   -- The arc cosine of self in the range [0.0 to pi]
   
   asin:SAME;
   -- The arc cosine of self in the range [0.0 to pi]

   log:SAME;
   -- Logarithm of self

   is_nan: BOOL;
   -- Is not a number.  This only makes sense for IEEE real
   -- numbers.  This class may need to be factored if
   -- we have non-IEEE real numbers at some point
   
end;
-------------------------------------------------------------------
abstract class $CPX_NUMBER{ETP<$REAL_NUMBER{ETP},NTP} < $NFE{NTP} is
   -- Complex numbers are strictly more general than real numbers.
   -- The right abstraction would be to force real numbers to povide a
   -- "zero" real part, but this is quite awkward. It is simpler to
   -- enforce no relationship, which conforms to the way we seem to
   -- actually deal with complex and real numbers

   create(re,im: ETP): SAME;
   -- Create a complex number with a real "re" and imaginary "im" part 
   
   create_real(repart: ETP): SAME;
   -- Create a complex number with real part = "re" and imaginary part
   -- equal to zero

   re: ETP;
   -- Real part
   
   im: ETP;
   -- Imaginary part

   conjugate: SAME;
   
end;
-------------------------------------------------------------------

