123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288(*
* Number - Generic interface for numbers
* Copyright (C) 2007 Bluestorm <bluestorm dot dylc on-the-server gmail dot com>
* 2008 David Teller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version,
* with the special exception on linking described in file LICENSE.
*
* 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 the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)type'anumeric={zero:'a;one:'a;neg:'a->'a;succ:'a->'a;pred:'a->'a;abs:'a->'a;add:'a->'a->'a;sub:'a->'a->'a;mul:'a->'a->'a;div:'a->'a->'a;modulo:'a->'a->'a;pow:'a->'a->'a;compare:'a->'a->int;of_int:int->'a;to_int:'a->int;of_string:string->'a;to_string:'a->string;of_float:float->'a;to_float:'a->float}(**
The infix operators
*)moduletypeInfix=sigtypebat__infix_tval(+):bat__infix_t ->bat__infix_t->bat__infix_tval(-):bat__infix_t ->bat__infix_t->bat__infix_tval(*):bat__infix_t ->bat__infix_t->bat__infix_tval(/):bat__infix_t ->bat__infix_t->bat__infix_tval(**):bat__infix_t ->bat__infix_t->bat__infix_tval(--):bat__infix_t ->bat__infix_t->bat__infix_tBatEnum.tval(---):bat__infix_t ->bat__infix_t->bat__infix_tBatEnum.tendmoduletypeCompare =sigtypebat__compare_tval(<>):bat__compare_t->bat__compare_t->boolval(>=):bat__compare_t->bat__compare_t->boolval(<=):bat__compare_t->bat__compare_t->boolval(>):bat__compare_t->bat__compare_t->boolval(<):bat__compare_t->bat__compare_t->boolval(=):bat__compare_t->bat__compare_t->boolend(** Idea from Shawn Wagner's mathlib *)moduletypeRefOps=sigtypebat__refops_tval(+=):bat__refops_tref->bat__refops_t->unitval(-=):bat__refops_tref->bat__refops_t->unitval(*=):bat__refops_t ref->bat__refops_t->unitval(/=):bat__refops_tref->bat__refops_t->unitend(**
The full set of operations of a type of numbers
*)moduletypeNumeric=sigtypettypediscrete=tvalzero:tvalone :tvalneg :t->tval abs:t->tval add:t->t->tvalsub:t->t->tvalmul:t->t->tvaldiv:t->t->tvalmodulo:t->t->tvalpow:t->t->tvalcompare:t->t->intvalequal:t->t-> boolvalord:tBatOrd.ordvalof_int:int->tvalto_int:t->intvalof_float:float->tvalto_float:t->floatvalof_string:string ->tvalto_string:t->stringvaloperations:tnumericvalsucc:t->tvalpred:t->tmoduleInfix:Infixwithtypebat__infix_t=tmoduleCompare:Comparewithtypebat__compare_t=tincludeInfixwithtypebat__infix_t=t(* Removed compare operators from base module, as they shadow
polymorphic ones from stdlib
include Compare with type bat__compare_t = t*)includeRefOpswithtypebat__refops_t=tendmoduletypeBounded=sigtypeboundedvalmin_num:boundedvalmax_num:boundedendmoduletypeDiscrete=sigtypediscretevalto_int:discrete->intvalsucc:discrete->discretevalpred:discrete->discreteval(--):discrete->discrete->discrete BatEnum.tval(---):discrete ->discrete->discrete BatEnum.tend(**
The smallest set of operations supported by every set of numbers
*)moduletypeNUMERIC_BASE=sigtypet(** A type of numbers*)valzero:tvalone:t(** {6 Arithmetic operations}
Depending on the implementation, some of these operations
{i may} raise exceptions at run-time to represent over/under-flows.*)valneg:t->tvalsucc:t->tvalpred:t->tvalabs:t->tvaladd:t->t->tvalsub:t->t->tvalmul:t->t->tvaldiv:t->t->tvalmodulo:t->t->tvalpow:t->t->tvalcompare:t->t->int(** {6 Conversions} *)valof_int:int->t(** Convert this number to the closest integer.*)valto_int:t->int(** Convert an integer to the closest element of set [t].*)valof_string:string->t(** Convert the representation of a number to the corresponding
number. @raise Invalid_argument if the string does not represent
a valid number of type [t]*)valto_string:t->stringvalof_float:float ->tvalto_float:t->floatend(**
Automatic generation of infix operators of a NUMERIC_BASE
*)moduleMakeInfix(Base:NUMERIC_BASE):Infixwithtypebat__infix_t=Base.t=structtypebat__infix_t=Base.tlet(+),(-),(*),(/),(**)=Base.add,Base.sub,Base.mul,Base.div,Base.powlet(--)xy=BatEnum.seqxBase.succ(funx->Base.comparexy<=0)let(---)xy=ifBase.comparexy<=0thenx--yelseBatEnum.seqxBase.pred(funx->Base.comparexy>=0)end(**
Automatic generation of comparison operations of a NUMERIC_BASE
*)moduleMakeCompare(Base:NUMERIC_BASE):Comparewithtypebat__compare_t=Base.t=structtypebat__compare_t=Base.tlet(=)ab=Base.compareab=0let(<)ab=Base.compareab<0let(>)ab=Base.compareab>0let(<=)ab=Base.compareab<=0let(>=)ab=Base.compareab>=0let(<>)ab=Base.compareab<>0endmoduleMakeRefOps(Base:NUMERIC_BASE):RefOpswithtypebat__refops_t=Base.t=structtypebat__refops_t=Base.tlet(+=)ab=a:=Base.add!ablet(-=)ab=a:=Base.sub!ablet(*=)ab=a:=Base.mul!ablet(/=)ab=a:=Base.div!abend(**
Automateddefinition of operators for a given numeric type.
see open...in...
*)moduleMakeNumeric(Base:NUMERIC_BASE):Numericwithtypet=Base.t=structincludeBaseletoperations={zero=Base.zero;one=Base.one;neg=Base.neg;succ=Base.succ;pred=Base.pred;abs=Base.abs;add=Base.add;sub=Base.sub;mul=Base.mul;div=Base.div;modulo=Base.modulo;pow=Base.pow;compare=Base.compare;of_int=Base.of_int;to_int=Base.to_int;of_float=Base.of_float;to_float=Base.to_float;of_string=Base.of_string;to_string=Base.to_string;}typediscrete=tletequalxy=Base.comparexy=0letordxy=BatOrd.ord0(Base.comparexy)moduleInfix=MakeInfix(Base)moduleCompare=MakeCompare(Base)includeInfixincludeMakeRefOps(Base)end(**
A generic implementation of fast exponentiation
*)letgeneric_pow~zero~one~div_two~mod_two~mul:(*)an=letrecpowan=ifn=zerothenoneelseifn=onethen aelseletb=powa(div_twon)inb*b*(ifmod_twon=zerothenoneelsea)inifn<zerotheninvalid_arg"pow"elsepowanexceptionOverflowexceptionNaN