File : units.ads
-- Generic package to deal with dimensional values.
-- The user should be able to compute with the values with respect to
-- the units. Dimension errors (on addition) should be statically catched.
generic
type Accuracy is digits <>;
package Units is
-- Unit is a composite of a numeric and a unit dimension.
type Unit is private;
-- Dimension counts how much of the units are included.
-- http://physics.nist.gov/cuu/Units/units.html
type Dimension is record
length, time, mass, current, temperature, substance_amount,
luminous_intensity : Integer;
end record;
-- The base system of the dimension space.
dim_meter : constant Dimension := (length => 1, others => 0);
dim_second : constant Dimension := (time => 1, others => 0);
dim_kilogram : constant Dimension := (mass => 1, others => 0);
dim_ampere : constant Dimension := (current => 1, others => 0);
dim_kelvin : constant Dimension := (temperature => 1, others => 0);
dim_mol : constant Dimension := (substance_amount => 1, others => 0);
dim_candela : constant Dimension := (luminous_intensity => 1, others => 0);
-- Negate, multiply, divide, expotentiate and output values.
function "-" (a : Unit) return Unit;
function "*" (a, b : Unit) return Unit;
function "/" (a, b : Unit) return Unit;
function "**" (a : Unit; b : Integer) return Unit;
function To_String (a : Unit) return String;
-- Multiply, divide, expotentiate and output Dimensions.
function "*" (a, b : Dimension) return Dimension;
function "/" (a, b : Dimension) return Dimension;
function "**" (a : Dimension; b : Integer) return Dimension;
function To_String (a : Dimension) return String;
-- Possible prefixes for all units.
-- http://physics.nist.gov/cuu/Units/prefixes.html
type Prefix is (yocto, zepto, atto, femto, pico, nano, micro, milli, centi,
deci, deka, hecto, kilo, kibi, mega, mebi, giga, gibi, tera, tebi, peta,
pebi, exa, exbi, zetta, yotta);
-- In order to catch dimension errors statically and input new values,
-- every point the the discrete dimension space may generate new types.
generic
dim : Dimension;
package Special_Units is
-- Such a dimensional value a given point is a pure numeric.
type Special_Unit is private;
-- Read in new values from extern.
function "+" (v : Accuracy) return Special_Unit;
function "*" (v : Accuracy; p : Prefix) return Special_Unit;
-- Add and subctract values of the same dimension.
function "+" (a, b : Special_Unit) return Special_Unit;
function "-" (a, b : Special_Unit) return Special_Unit;
-- Conversion between a generic unit and a special one.
-- BUG! Converting from a Unit to a Special_Unit may raise an Error
-- on runtime. Of course the compiler can be determine the dimension
-- on compile time and may reject the conversion, but ...
function "+" (a : Special_Unit) return Unit;
Dimension_Error : exception;
function "+" (a : Unit) return Special_Unit;
private
type Special_Unit is record
value : Accuracy;
end record;
end Special_Units;
private
type Unit is record
value : Accuracy;
dim : Dimension;
end record;
end Units;