package Metric_System is
------------------------------------------------------------------
--| Specification for Metric System Package
--| Author: Michael B. Feldman, The George Washington University
--| Last Modified: September 1995
------------------------------------------------------------------
-- Type definition
type Metric(Mass, Length, Time : Integer) is private;
-- constrained subtypes
subtype Scalar is Metric(0, 0, 0);
subtype Accel is Metric(0, 1, -2);
subtype Area is Metric(0, 2, 0);
subtype Length is Metric(0, 1, 0);
subtype Distance is Metric(0, 1, 0);
subtype Mass is Metric(1, 0, 0);
subtype Time is Metric(0, 0, 1);
subtype Velocity is Metric(0, 1, -1);
subtype Volume is Metric(0, 3, 0);
-- exported exception
Dimension_Error : exception;
-- exported unit constants; these will be defined in full below
Gram : constant Metric;
METER : constant Metric;
SEC : constant Metric;
Square_M : constant Metric;
Cubic_M : constant Metric;
M_per_Sec : constant Metric;
M_per_Sec2 : constant Metric;
function "*" (Left : Float; Right : Metric) return Metric;
-- Pre: Left and Right are defined
-- Post: constructor: produces a metric quantity from a Float one
function Value(Left : Metric) return Float;
-- Pre: Left is defined
-- Post: selector: returns the Float (dimensionless) part
-- of a metric quantity
function "<" (Left, Right : Metric) return Boolean;
function "<=" (Left, Right : Metric) return Boolean;
function ">" (Left, Right : Metric) return Boolean;
function ">=" (Left, Right : Metric) return Boolean;
-- Pre: Left and Right are defined
-- Post: the usual comparison operations
-- Raises: Dimension_Error if Left and Right
-- have different dimensions
function "+" (Right : Metric) return Metric;
function "-" (Right : Metric) return Metric;
function "abs" (Right : Metric) return Metric;
-- Pre: Right is defined
-- Post: the usual monadic arithmetic operations;
-- the dimensions of Right are, of course, preserved
function "+" (Left, Right : Metric) return Metric;
function "-" (Left, Right : Metric) return Metric;
-- Pre: Left and Right are defined
-- Post: the usual additive operations are performed on the
-- numeric parts of Left and Right; the dimensions are preserved
-- Raises: Dimension_Error if Left and Right
-- have different dimensions
function "*" (Left, Right : Metric) return Metric;
function "/" (Left, Right : Metric) return Metric;
-- Pre: Left and Right are defined
-- Post: the usual multiplication and division operations
-- are performed on the numeric parts of Left and Right;
-- the dimensions are added pairwise (multiplication)
-- or subtracted pairwise (division)
-- Left and Right need not have the same dimensions.
private
-- A Metric quantity is a 3-discriminant variant record,
-- with no default values. Each object of the type must
-- therefore be constrained to a subtype, that is, to a
-- fixed set of dimensions. This is physically realistic.
type Metric(Mass, Length, Time : Integer) is record
Value : Float := 0.0;
end record;
Gram : constant Metric := (1, 0, 0, 1.0);
Meter : constant Metric := (0, 1, 0, 1.0);
Sec : constant Metric := (0, 0, 1, 1.0);
Square_M : constant Metric := (0, 2, 0, 1.0);
Cubic_M : constant Metric := (0, 3, 0, 1.0);
M_per_Sec : constant Metric := (0, 1, -1, 1.0);
M_per_Sec2 : constant Metric := (0, 1, -2, 1.0);
end Metric_System;