;; -*-theme-d-*-

;; Copyright (C) 2008-2018 Tommi Höynälänmaa
;; Distributed under GNU Lesser General Public License version 3,
;; see file doc/LGPL-3.


(define-interface (standard-library real-math)

  (import (standard-library core)
	  (standard-library rational))

  ;; The following values have been taken from the C math.h header.
  (define gl-r-pi 3.14159265358979323846)
  (define gl-r-pi/2 1.57079632679489661923)
  (define gl-r-pi/4 0.78539816339744830962)
  (define gl-r-1/pi 0.31830988618379067154)
  (define gl-r-2/pi 0.63661977236758134308)
  (define gl-r-2/sqrtpi 1.12837916709551257390)
  (define gl-r-sqrt2 1.41421356237309504880)
  (define gl-r-1/sqrt2 0.70710678118654752440)
  (define gl-r-e 2.7182818284590452354)
  (define gl-r-log2e 1.4426950408889634074)
  (define gl-r-log10e 0.43429448190325182765)
  (define gl-r-ln2 0.69314718055994530942)
  (define gl-r-ln10 2.30258509299404568402)

  ;; Not sure if there are enough digits in the following two values.
  (define gl-r-pi/ln10 1.3643763538418412)
  (define gl-r-pi/ln2 4.5323601418271942)

  (define <real-number> (:union <real> <rational> <integer>))

  (declare rational->real (:simple-proc (<rational>) <real> pure))

  (declare real-rational= (:simple-proc (<real> <rational>) <boolean> pure))
  (declare rational-real= (:simple-proc (<rational> <real>) <boolean> pure))

  (declare real-rational< (:simple-proc (<real> <rational>) <boolean> pure))
  (declare rational-real< (:simple-proc (<rational> <real>) <boolean> pure))

  (declare real-rational<= (:simple-proc (<real> <rational>) <boolean> pure))
  (declare rational-real<= (:simple-proc (<rational> <real>) <boolean> pure))

  (declare real-rational> (:simple-proc (<real> <rational>) <boolean> pure))
  (declare rational-real> (:simple-proc (<rational> <real>) <boolean> pure))

  (declare real-rational>= (:simple-proc (<real> <rational>) <boolean> pure))
  (declare rational-real>= (:simple-proc (<rational> <real>) <boolean> pure))

  (declare real-rational+ (:simple-proc (<real> <rational>) <real> pure))
  (declare rational-real+ (:simple-proc (<rational> <real>) <real> pure))

  (declare real-rational- (:simple-proc (<real> <rational>) <real> pure))
  (declare rational-real- (:simple-proc (<rational> <real>) <real> pure))

  (declare real-rational* (:simple-proc (<real> <rational>) <real> pure))
  (declare rational-real* (:simple-proc (<rational> <real>) <real> pure))

  (declare real-rational/ (:simple-proc (<real> <rational>) <real> pure))
  (declare rational-real/ (:simple-proc (<rational> <real>) <real> pure))

  (declare-method = (:simple-proc (<real> <rational>) <boolean> pure))
  (declare-method = (:simple-proc (<rational> <real>) <boolean> pure))

  (declare-method < (:simple-proc (<real-number> <real-number>) <boolean>
				  pure))
  (declare-method < (:simple-proc (<real> <rational>) <boolean> pure))
  (declare-method < (:simple-proc (<rational> <real>) <boolean> pure))

  (declare-method <= (:simple-proc (<real-number> <real-number>) <boolean>
				   pure))
  (declare-method <= (:simple-proc (<real> <rational>) <boolean> pure))
  (declare-method <= (:simple-proc (<rational> <real>) <boolean> pure))

  (declare-method > (:simple-proc (<real-number> <real-number>) <boolean>
				  pure))
  (declare-method > (:simple-proc (<real> <rational>) <boolean> pure))
  (declare-method > (:simple-proc (<rational> <real>) <boolean> pure))

  (declare-method >= (:simple-proc (<real-number> <real-number>) <boolean>
				   pure))
  (declare-method >= (:simple-proc (<real> <rational>) <boolean> pure))
  (declare-method >= (:simple-proc (<rational> <real>) <boolean> pure))

  (declare-method + (:simple-proc (<real-number> <real-number>) <real-number>
				  pure))
  (declare-method + (:simple-proc (<real> <rational>) <real> pure))
  (declare-method + (:simple-proc (<rational> <real>) <real> pure))

  (declare-method - (:simple-proc (<real-number> <real-number>) <real-number>
				  pure))
  (declare-method - (:simple-proc (<real> <rational>) <real> pure))
  (declare-method - (:simple-proc (<rational> <real>) <real> pure))

  (declare-method * (:simple-proc (<real-number> <real-number>) <real-number>
				  pure))
  (declare-method * (:simple-proc (<real> <rational>) <real> pure))
  (declare-method * (:simple-proc (<rational> <real>) <real> pure))

  (declare-method / (:simple-proc (<real-number> <real-number>) <real-number>
				  pure))
  (declare-method / (:simple-proc (<real> <rational>) <real> pure))
  (declare-method / (:simple-proc (<rational> <real>) <real> pure))

  (declare-method - (:simple-proc (<real-number>) <real-number> pure))

  (declare-method abs (:simple-proc (<real-number>) <real-number> pure))

  (declare-method square (:simple-proc (<real-number>) <real-number> pure))

  (declare-method sign (:simple-proc (<real-number>) <integer> pure))

  (declare r-sqrt (:simple-proc (<real>) <real> (pure)))
  (declare r-expt (:simple-proc (<real> <real>) <real> (pure)))
  (declare r-sin (:simple-proc (<real>) <real> (pure)))
  (declare r-cos (:simple-proc (<real>) <real> (pure)))
  (declare r-tan (:simple-proc (<real>) <real> (pure)))
  (declare r-asin (:simple-proc (<real>) <real> (pure)))
  (declare r-acos (:simple-proc (<real>) <real> (pure)))
  (declare r-atan (:simple-proc (<real>) <real> (pure)))
  (declare r-atan2 (:simple-proc (<real> <real>) <real> (pure)))
  (declare r-exp (:simple-proc (<real>) <real> (pure)))
  (declare r-log (:simple-proc (<real>) <real> (pure)))
  (declare r-log10 (:simple-proc (<real>) <real> (pure)))
  (declare r-sinh (:simple-proc (<real>) <real> (pure)))
  (declare r-cosh (:simple-proc (<real>) <real> (pure)))
  (declare r-tanh (:simple-proc (<real>) <real> (pure)))
  (declare r-asinh (:simple-proc (<real>) <real> (pure)))
  (declare r-acosh (:simple-proc (<real>) <real> (pure)))
  (declare r-atanh (:simple-proc (<real>) <real> (pure)))

  (declare i-sqrt (:simple-proc (<integer>) (:union <real> <integer>) pure))
  (declare rat-sqrt (:simple-proc (<rational>)
				  (:union <real> <rational> <integer>) pure))

  (declare string->real-number (:simple-proc (<string>) <real-number> pure)))
