home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / test / adaf85.doc < prev    next >
Encoding:
Text File  |  1988-05-03  |  236.2 KB  |  8,765 lines

  1. The messages and programs contained in this file were received from
  2. Ed Colbert in conjunction with Ada Fair '85. If there are any questions
  3. with respect to this file please contact Mr. Colbert at :
  4. trwrb!trwspp!spp1!colbert(ampersand)Berkeley . ( Note: I am unable to
  5. transmit an ampersand over the net without the host saying 'BAD" things
  6. about my computer literacy. ) RAY SZYMANSKI -----------
  7.  
  8. This is the 1st of 4 messages that you should receive.  Included are the
  9. rules for running the programs, a copy of 3 universial arithmatic packages,
  10. and a copy of the 24 programs that were used this year.  This years programs
  11. consisted of all of last years programs plus 1 new one, a real world Physics
  12. problem.  All of the programs have been tested on a number of validated
  13. compilers and are correct to the best of our knowledge (there was a logic
  14. bug in boolvec.ada, but that has been corrected in the copy I am sending
  15. you).
  16.  
  17.  
  18.  
  19. --------------------------------------------------------------------------
  20. ------------------------- Rules ------------------------------------------
  21. --------------------------------------------------------------------------
  22.    1. All  rules apply equally to all vendors participating.  Every effort
  23.       will be made to assure fairness in the treatment of the vendors.
  24.  
  25.    2. All vendors must perform the tests in accordance with  these  rules.
  26.       Each   vendor  is  responsible  for  complying  with  them  and  for
  27.       accurately reporting  the  results  of  all  the  tests  which  were
  28.       submitted, including any tests not performed.
  29.  
  30.    3. If more than one Ada toolset or host/target environment is used, the
  31.       vendor should make  a  complete,  independent  report  of  the  test
  32.       results for each distinct combination of tools, host, and target.
  33.  
  34.    4. All  tests  must be performed using the source code in its original,
  35.       official format, without alteration of any kind, except as directed.
  36.       Where   implementation  differences  may  effect  the  source  code,
  37.       directions for alteration may be supplied to the vendors in  written
  38.       form,  embedded  in  the  source  code as comments, or orally by the
  39.       Technical Chair or his authorized representative.   Any  alterations
  40.       made  to  a  test in the absence of such directions or which violate
  41.       the  clear  intent  of  the  directions  given   are   grounds   for
  42.       disqualification of the vendor on that test.
  43.  
  44.    5. The  test  source  files  must  be submitted as single compilations,
  45.       regardless of the number of compilation units they  contain,  unless
  46.       specific directions to the contrary are given.  All pragmas which an
  47.       implementation can obey  must  be  obeyed.    In  particular,  range
  48.       checking  must not be suppressed except where directed by pragmas in
  49.       the source code.  A compilation listing file must  be  generated  by
  50.       each  compilation.    Unless  specifically  requested,  no linker or
  51.       loader outputs are  required.    Execution  outputs  must  be  those
  52.       produced  by  the  Ada program and its run-time environment, without
  53.       alteration of any kind.  The information submitted as official  test
  54.       results  must  represent a complete, continuous, and self-consistent
  55.       sequence of  operations  in  which  the  unaltered  output  of  each
  56.       operation  is  the  input  of the next.  The image which is executed
  57.       must be precisely that which is directly produced  by  the  sequence
  58.       described  above.    The  intent  of  this  rule  is  to  avoid  any
  59.       inconsistency between the options used in  different  parts  of  the
  60.       test  sequence and to make sure that timing and performance data are
  61.       measured for that specific sequence only.    Additional  information
  62.       which  was  not produced in that sequence may not be included in the
  63.       official test results, but may  be  submitted  as  a  supplement  as
  64.       described below.
  65.  
  66.    6. All  timing information which is requested (other than that obtained
  67.       directly by the program using the Calendar package) shall  be  given
  68.       in  terms  of  differences  in  the actual time of day ("wall clock"
  69.       time), accurate to the nearest second (or  tenth  of  a  second,  if
  70.       possible).    Compilation,  link  or  binding,  and  load times must
  71.       include the time required to load and initialize the programs  which
  72.       perform these processes.  Compilation times include all intermediate
  73.       translations performed (e.g., from assembly code  to  native  object
  74.       code),  and specifically must include those not performed by the Ada
  75.       compiler itself.   The  sum  of  the  times  given  for  each  phase
  76.       (compilation,  linking,  etc.)  must  be equal to the actual elapsed
  77.       time  for  the  entire  sequence,  starting   with   initiation   of
  78.       compilation and ending with completion of execution.
  79.  
  80.    7. Size  information  shall  be given in bytes, accurate to the nearest
  81.       byte if  possible.    Module  object  code  size  does  not  include
  82.       predefined packages such as Text_IO and Calendar which were "with"ed
  83.       or the run-time support library or the underlying  operating  system
  84.       if any.
  85.  
  86.    8. In  the  event  that a test is found to be defective for any reason,
  87.       including (but not  restricted  to)  invalid  Ada  code,  functional
  88.       errors,  or unclear directions for its execution, it will be dropped
  89.       from the test suite and will not be considered further unless it can
  90.       be  corrected  easily  and  all  participating  vendors can be given
  91.       timely notification of the corrections.
  92.  
  93.    9. Any test may be challenged by any vendor stating their  belief  that
  94.       it  is  defective  and  why  they feel that it is.  (Suggestions for
  95.       fixing the defects will be gratefully received.)    Such  challenges
  96.       will  be  taken  under  advisement  by  the  Technical Chair and his
  97.       appointed representatives and will be  considered  and  accepted  or
  98.       rejected  as  expeditiously as possible.  Only those challenges made
  99.       before the date of the fair  will  be  considered  unless  there  is
  100.       unanimous agreement between all vendors and the Technical Chair that
  101.       a test is defective, in which case a challenge may  be  accepted  on
  102.       the  spot.  In the case of a rejected challenge, vendors may include
  103.       their objections with their results.
  104.  
  105.   10. In case  of  ambiguities  or  contradictions  in  these  rules,  the
  106.       interpretation  of  the  Technical Chair shall prevail.  Suggestions
  107.       for future changes to these rules which would improve  them  in  any
  108.       way,  particularly in their fairness, clarity of interpretation, and
  109.       usefulness to the Ada community are always welcome.
  110.  
  111.   11. Several copies of these rules will  be  made  available  for  public
  112.       inspection and reference at the Fair.
  113.  
  114.   12. Vendors  are requested to present two copies of a written summary of
  115.       their results and two copies of the compilation listing of each test
  116.       program  to  the  Technical  Chair  at least 30 minutes prior to the
  117.       opening of the demonstration period (scheduled  for  10:00am  on  30
  118.       June,  1984).    Additional  documentation which may be specifically
  119.       required for each test and supplemental information which the vendor
  120.       desires  to  supply  for  each  test should be submitted at the same
  121.       time.  In particular, cross reference  listings,  set/use  listings,
  122.       assembly  listings,  linkage  and  load  maps,  etc., which were not
  123.       generated in the official test  sequence,  may  be  included.    The
  124.       summary  of  results shall categorize the results in accordance with
  125.       the program outlined below:
  126.  
  127.     with Text_IO; use Text_IO;
  128.     procedure Summarize is
  129.  
  130.        type Vendor_Name is (<List of participating vendors>, None);
  131.        Vendor : Vendor_Name := None;
  132.  
  133.        Columns : constant := 80;
  134.  
  135.        subtype Comment is String (1 .. Columns);
  136.        Blank_Comment : constant Comment := (1 .. Columns => ' ');
  137.  
  138.        type Note is array (1 .. 5) of String (1 .. Columns);
  139.        Blank_Note : constant Note := (1 .. 5 => (1 .. Columns => ' '));
  140.  
  141.        Compilation_Environment : Note := Blank_Note;
  142.        Execution_Environment : Note := Blank_Note;
  143.  
  144.        type Test_Result is (Passed,
  145.                             Failed,
  146.                             Uncertain,
  147.                             Unable_To_Run,
  148.                             Not_Attempted,
  149.                             Disqualified,
  150.                             Test_Has_Been_Dropped);
  151.  
  152.        Seconds : constant Integer := 1;
  153.  
  154.        type Size is digits 6;
  155.        Kilo_Bytes : constant Size := 1.0; -- represents 1024 bytes
  156.  
  157.        type Result_Record is
  158.           record
  159.             Class : Test_Result := Not_Attempted;
  160.             Class_Comment : Comment := Blank_Comment;
  161.  
  162.             Challenged_By_Vendor : Boolean := False;
  163.             Challenge_Comment : Comment := Blank_Comment;
  164.  
  165.             -- Officially requested results go here:
  166.             Performance_Data : Note := Blank_Note;
  167.             Performance_Comment : Comment := Blank_Comment;
  168.  
  169.             -- Explanations and objections go here:
  170.             Explanations : Note := Blank_Note;
  171.  
  172.             -- This includes any intermediate translations by other
  173.             -- compilers or assemblers:
  174.             Compilation_Time : Duration := 0.0 * Seconds;
  175.             Compilation_Comment : Comment := Blank_Comment;
  176.  
  177.             -- A value of zero indicates load- or execution-time binding:
  178.  
  179.             Link_Or_Binding_Time : Duration := 0.0 * Seconds;
  180.             Linkage_Comment : Comment := Blank_Comment;
  181.  
  182.             -- A value of zero indicates load time is included in
  183.             -- execution time (and cannot be reported separately).
  184.             Load_Time : Duration := 0.0 * Seconds;
  185.             Loading_Comment : Comment := Blank_Comment;
  186.  
  187.             -- This includes Load_Time if it is not reported above:
  188.             Execution_Time : Duration := 0.0 * Seconds;
  189.             Execution_Comment : Comment := Blank_Comment;
  190.  
  191.             -- This includes only the units whose source is in the
  192.             -- compilation;
  193.             -- it excludes predefined packages which they "with":
  194.             Object_Code_Size : Size := 0.000 * Kilo_Bytes;
  195.             Object_Code_Comment : Comment := Blank_Comment;
  196.  
  197.             -- This includes pure code only; it excludes data and the
  198.             -- run-time support library:
  199.             Code_Image_Size : Size := 0.000 * Kilo_Bytes;
  200.             Code_Image_Comment : Comment := Blank_Comment;
  201.  
  202.             -- This includes it all -- code, data, and run-time support:
  203.             Maximum_Memory_Used : Size := 0.000 * Kilo_Bytes;
  204.             Memory_Used_Comment : Comment := Blank_Comment;
  205.           end record;
  206.  
  207.        Number_Of_Programs : constant
  208.                                := <Number actually submitted to vendors>;
  209.  
  210.        type Number is range 1 .. Number_Of_Programs;
  211.  
  212.        type Result_Array is array (Number) of Result_Record;
  213.  
  214.        Results : Result_Array;
  215.  
  216.        procedure Put (N : Note) is ... end Put;
  217.  
  218.        procedure Put (R : Result_Record) is ... end Put;
  219.  
  220.     begin
  221.  
  222.       Set_Line(To => 10);
  223.       Set_Column(To => 31);
  224.       Put_Line("LA AdaTEC Ada* Fair");
  225.  
  226.       Set_Column(To => 33);
  227.       Put_Line("30 June, 1984");
  228.  
  229.       Set_Column(To => 29);
  230.       Put_Line("COMPILER TEST RESULTS");
  231.       New_Line;
  232.  
  233.       Vendor := <This vendor's name>;
  234.       Set_Column(To => <TBD>);
  235.       Put(Vendor);
  236.       New_Line(2);
  237.  
  238.       Compilation_Environment
  239.          := <Description of the host computer and compiler toolset>;
  240.       Put(Compilation_Environment);
  241.       New_Line;
  242.       Execution_Environment
  243.          := <Description of the target computer and run-time environment>;
  244.       Put(Execution_Environment);
  245.  
  246.       Set_Line(To => 55);
  247.       Put("* Ada is a registered trademark of the U.S. Government " &
  248.           "(Ada Joint Program Office)");
  249.  
  250.       Results := <Vendor's actual results>;
  251.  
  252.       for N in Number loop
  253.          New_Page;
  254.          Put(Results(N));
  255.       end loop;
  256.  
  257.     end Summarize;
  258.  
  259.  
  260. -------------------------------------------------------------------
  261. ---------------------  Next  Program  -----------------------------
  262. -------------------------------------------------------------------
  263.  
  264.  
  265. --
  266. -- Version: @(#)akerman.ada    2.4        Date: 6/3/85
  267. --
  268. -- Author:  Brian A. Wichmann
  269. --        National Physical Laboratory
  270. --        Teddington, Middlesex TW11 OLW, UK
  271. --
  272. -- Modified by LA AdaTEC to conform to ANSI Standard Ada & to test
  273. -- for significance of elapsed time.
  274. --
  275. -- [Extracts from: "Latest resuts from the procedure calling test,
  276. --  Ackermann's function", B. A. Wichamann,  NPL Report DITC 3/82,
  277. --  ISSN 0143-7348]
  278. --
  279. -- Ackermann's function has been used to measure the procedure calling
  280. -- overhead in languages which support recursion [Algol-like languages,
  281. -- Assembly Languages, & Basic]
  282. --
  283. -- Ackermann's function is a small recursive function .... Although of
  284. -- no particular interest in itself, the function does perform other
  285. -- operations common to much systems programming (testing for zero,
  286. -- incrementing and decrementing integers).  The function has two
  287. -- parameters M and N, the test being for (3, N) with N in the range
  288. -- 1 to 6.
  289. --
  290. -- [End of Extract]
  291. --
  292. -- The object code size of the Ackermann function should be reported in
  293. -- 8-bit bytes, as well as, the Average Number of Instructions Executed
  294. -- per Call of the Ackermann function.  Also,  if the stack space is
  295. -- exceeded, report the parameter values used as input to the initial
  296. -- invocation of the Ackermann function.
  297. --
  298. -- The Average Number of Instructions Executed Per Call should preferably
  299. -- be determined by examining the object code and calculating the number
  300. -- of instructions executed for a significant number of calls of the
  301. -- Ackermann function (see below).  If that is not possible,
  302. -- please make an estimate based the average execution time per machine
  303. -- instruction for the target machine and the average time per call for
  304. -- a significant number of calls.  Clearly indicate whether the Average
  305. -- Number of Instructions Executed Per Call is an estimate or not.
  306. --
  307. -- Note:  In order for the measurement to be meaningful, it must be the 
  308. -- only program executing while the test is run.  The number of calls is
  309. -- significant if the elapsed time for the initial invocation of the
  310. -- Ackermann's function is at least 100 times Duration'Small & at least
  311. -- 100 times System.Tick).
  312. --
  313.  
  314. with Text_IO;  use Text_IO;
  315. with Calendar; use Calendar;
  316. with System;   use System;
  317.  
  318. procedure Time_Ackermann is
  319.  
  320.    type Real_Time is digits Max_Digits;
  321.  
  322.    Start_Time :   Time;
  323.    Elapsed_Time : Duration;
  324.    Average_Time : Real_Time;
  325.  
  326.    package Duration_IO is new Fixed_IO (Duration);
  327.    use Duration_IO;
  328.  
  329.    package Real_Time_IO is new Float_IO (Real_Time);
  330.    use Real_Time_IO;
  331.  
  332.    package Int_IO is new Integer_IO (Integer);
  333.    use Int_IO;
  334.  
  335.    I, J, K, K1, Calls: Integer;
  336.  
  337.    function Ackermann (M, N: Natural)  return Natural is
  338.    begin
  339.      if M = 0     then
  340.        return N + 1;
  341.      elsif N = 0  then
  342.        return Ackermann (M - 1, 1);
  343.      else
  344.        return Ackermann (M - 1, Ackermann (M, N -1 ));
  345.      end if;
  346.    end Ackermann;
  347.  
  348. begin
  349.   K := 16;
  350.   K1 := 1;
  351.   I := 1;
  352.  
  353.   while K1 < Integer'Last / 512  loop
  354.   
  355.     Start_Time := Clock;
  356.     J :=  Ackermann (3, I);
  357.     Elapsed_Time :=  Clock - Start_Time;
  358.     
  359.     if J /= K - 3  then
  360.       Put_line (" *** Wrong Value ***");
  361.     end if;
  362.     
  363.     Calls := (512*K1 - 15*K + 9*I + 37) / 3;
  364.  
  365.     Put ("Number of Calls = ");
  366.     Put (Calls, Width => 0);
  367.     new_line;
  368.     Put ("Elapsed Time    = ");
  369.     Put (Elapsed_Time, Fore => 0);
  370.     Put (" seconds   -- precision is ");
  371.     if (Elapsed_Time < 100 * Duration'Small  or
  372.         Elapsed_Time < 100 * System.Tick)  then
  373.       Put_line ("Insignificant");
  374.     else
  375.       Put_line ("Significant");
  376.     end if;
  377.  
  378.     Average_Time := Real_Time (Elapsed_Time) / Real_Time (Calls);
  379.     Put ("Average Time per call = ");
  380.     Put (Average_Time, Fore => 0);
  381.     Put_Line (" seconds");
  382.     new_line;
  383.     
  384.     I  := I + 1;
  385.     K1 := 4 * K1;
  386.     K  := 2 * K;
  387.   end loop;
  388.  
  389.   Put_Line (" End of Ackermann Test");
  390. exception
  391.   when Storage_Error =>
  392.     New_line;
  393.     Put ("Stack space exceeded for Ackermann ( 3, " );
  394.     Put (I);
  395.     Put_line ( ")" );
  396.     new_line;
  397.     Put_Line (" End of Ackermann Test");
  398. end Time_Ackermann;
  399.  
  400.  
  401. -------------------------------------------------------------------
  402. ---------------------  Next  Program  -----------------------------
  403. -------------------------------------------------------------------
  404. --
  405. -- Version: @(#)boolvec.ada    1.4        Date: 6/17/85
  406. --
  407. -- Author:  Edward Colbert
  408. --        Ada Technology Group
  409. --        Information Software Systems Lab
  410. --        Defense Systems Group
  411. --        TRW
  412. --        Redondo Beach, CA
  413. --
  414. -- This program measures the time required for the "and" operation on the
  415. -- elements of a boolean vector
  416. --
  417. -- Note:  In order for the measurement to be meaningful, it must be the 
  418. -- only program executing while the test is run.  
  419. --
  420. -- Please set Iterations large enough to provide at least two significant 
  421. -- digits in the average times, i.e., the difference between 
  422. -- the elapsed time and the loop time must be at least 100 times 
  423. -- Duration'Small & at least 100 times System.Tick.
  424. --
  425.  
  426. with Text_IO; use Text_IO;
  427. with Calendar; use Calendar;
  428. with System; use System;
  429. procedure Boolean_Vector_AND_Test is
  430.  
  431.    Iterations : constant Positive := 1000;
  432.  
  433.    type Real_Time is digits Max_Digits;
  434.  
  435.    Start_Time : Time;
  436.    Loop_Time : Duration;
  437.    Elapsed_Time : Duration;
  438.    Average_Time : Real_Time;
  439.  
  440.    package Duration_IO is new Fixed_IO (Duration);
  441.    use Duration_IO;
  442.  
  443.    package Real_Time_IO is new Float_IO (Real_Time);
  444.    use Real_Time_IO;
  445.  
  446.    package Int_IO is new Integer_IO (Integer);
  447.    use Int_IO;
  448.  
  449.    Vector_Size : constant Positive := 25;
  450.    type vector is array (1..Vector_Size) of Boolean;
  451.    
  452.    v1, v2, vector_result: vector;
  453.    count:  integer := integer'first;    -- used in timing loop
  454.  
  455. begin
  456.  
  457.    -- Initialize Vectors
  458.    for N in vector'range loop
  459.       v1(N) := true;
  460.       v2(N) := boolean'val (N mod 2);
  461.    end loop;
  462.  
  463.    -- Measure the timing loop overhead.
  464.    Start_Time := Clock;
  465.    for N in 1 .. Iterations loop
  466.       count := count + 1;        -- prevent optimization
  467.    end loop;
  468.    Loop_Time := Clock - Start_Time;
  469.  
  470.  
  471.    -- Measure the time including the adding of vector elements
  472.    Start_Time := Clock;
  473.    for N in 1 .. Iterations loop
  474.       count := count + 1;        -- prevent optimization
  475.       vector_result := v1 and v2;
  476.    end loop;
  477.    Elapsed_Time := Clock - Start_Time;
  478.  
  479.  
  480.    Put("Loop time = ");
  481.    Put(Loop_Time, Fore => 0);
  482.    Put(" seconds for ");
  483.    Put(Vector_Size, Width => 0);
  484.    Put_Line(" iterations");
  485.  
  486.  
  487.    Put("Elapsed time = ");
  488.    Put(Elapsed_Time, Fore => 0);
  489.    Put(" seconds for ");
  490.    Put(Vector_Size, Width => 0);
  491.    Put_Line(" iterations");
  492.  
  493.    Average_Time := Real_Time(Elapsed_Time - Loop_Time)/Real_Time(Iterations);
  494.    Put("Average time for " & '"' & "and" & '"' &
  495.        " of 2 arrays (" & Integer'Image (Vector_Size) & " elements) = ");
  496.    Put(Average_Time, Fore => 0);
  497.    Put_Line(" seconds");
  498.  
  499.    New_Line;
  500.    if (Elapsed_Time - Loop_Time < 100 * Duration'Small or
  501.        Elapsed_Time - Loop_Time < 100 * System.Tick)    then
  502.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  503.    else
  504.       Put_Line("** TEST PASSED **");
  505.    end if;
  506.  
  507. end Boolean_Vector_AND_Test;
  508.  
  509.  
  510. -------------------------------------------------------------------
  511. ---------------------  Next  Program  -----------------------------
  512. -------------------------------------------------------------------
  513.  
  514.  
  515. --
  516. -- Version: @(#)bsearch.ada    1.1     Date: 5/30/84
  517. --
  518. -- Authors:  Marion Moon and Bryce Bardin
  519. --           Software Engineering Division
  520. --           Ground Systems Group
  521. --           Hughes Aircraft Company
  522. --           Fullerton, CA
  523. --
  524. -- This package implements a generic binary search function.
  525. -- It was designed to allow the use of an enumeration type for the table 
  526. -- index (a feature of possibly dubious utility, but included here for 
  527. -- uniformity with other generic operations on unconstrained arrays).
  528. --
  529.  
  530. generic
  531.  
  532.    type Index is (<>);
  533.    type Item is limited private;
  534.    type Table is array (Index range <>) of Item;
  535.  
  536.    with function "=" (Left, Right : Item) return Boolean is <>;
  537.    with function ">" (Left, Right : Item) return Boolean is <>;
  538.  
  539. package Searching is
  540.  
  541.    function Index_Of (Key : in Item; Within : in Table) return Index;
  542.    -- Returns the Index of the Item in Within which matches Key 
  543.    -- if there is one, otherwise raises Not_Found.
  544.  
  545.    Not_Found : exception;
  546.    -- Raised if the search fails.
  547.  
  548. end Searching;
  549.  
  550.  
  551. package body Searching is
  552.  
  553.    function Index_Of (Key : in Item; Within : in Table) return Index is
  554.  
  555.       Low : Index := Within'First;
  556.       Mid : Index;
  557.       Hi  : Index := Within'Last;
  558.  
  559.    begin
  560.  
  561.       loop
  562.  
  563.      if Low > Hi then
  564.         raise Not_Found;
  565.      end if;
  566.  
  567.      -- Calculate the mean Index value, using an expression
  568.      -- which can never overflow:
  569.      Mid := Index'Val(Index'Pos(Low)/2 + Index'Pos(Hi)/2 + 
  570.         (Index'Pos(Low) rem 2 + Index'Pos(Hi) rem 2)/2);
  571.  
  572.      if Within(Mid) = Key then
  573.  
  574.         return Mid;
  575.  
  576.      elsif Within(Mid) > Key then
  577.  
  578.         -- This can raise Constraint_Error, but in that case 
  579.         -- the search has failed:
  580.         Hi := Index'Pred(Mid);
  581.  
  582.      else
  583.  
  584.         -- This can raise Constraint_Error, but in that case 
  585.         -- the search has failed:
  586.         Low := Index'Succ(Mid);
  587.  
  588.      end if;
  589.  
  590.       end loop;
  591.  
  592.    exception
  593.  
  594.       when Constraint_Error =>
  595.      raise Not_Found;
  596.  
  597.    end Index_Of;
  598.  
  599. end Searching;
  600.  
  601.  
  602. -- This procedure tests the binary search package at the extreme limits 
  603. -- of its index type.
  604. with Searching;
  605. with System; use System;
  606. with Text_IO; use Text_IO;
  607. procedure Main is
  608.  
  609.    type Big_Integer is range Min_Int .. Max_Int;
  610.    type Table is array (Big_Integer range <>) of Character;
  611.  
  612.    package Table_Search is 
  613.       new Searching (Big_Integer, Character, Table);
  614.    use Table_Search;
  615.  
  616.    T1 : constant Table (Big_Integer'First .. Big_Integer'First + 2) := "XYZ";
  617.    T2 : constant Table (Big_Integer'Last - 3 .. Big_Integer'Last) := "ABCD";
  618.  
  619.    Index : Big_Integer;
  620.    Key : Character;
  621.    subtype Alpha is Character range 'A' .. 'Z';
  622.  
  623.    package Big_IO is new Integer_IO (Big_Integer);
  624.    use Big_IO;
  625.  
  626.    procedure Put_Match (Index : Big_Integer; Key : Character) is
  627.    begin
  628.       Put("The index for the key value of '" & Key & "' is ");
  629.       Put(Index, Width => 0);
  630.       Put('.');
  631.       New_Line;
  632.    end Put_Match;
  633.  
  634. begin
  635.  
  636.    begin
  637.       for C in reverse Alpha loop
  638.      Key := C;
  639.      Index := Index_Of (Key, Within => T1);
  640.      Put_Match(Index, Key);
  641.       end loop;
  642.    exception
  643.       when Not_Found =>
  644.      Put("Key '");
  645.      Put(Key);
  646.      Put_Line("' not found.");
  647.    end;
  648.  
  649.    begin
  650.       for C in Alpha loop
  651.      Key := C;
  652.      Index := Index_Of (Key, Within => T2);
  653.      Put_Match(Index, Key);
  654.       end loop;
  655.    exception
  656.       when Not_Found =>
  657.      Put("Key '");
  658.      Put(Key);
  659.      Put_Line("' not found.");
  660.    end;
  661.  
  662. end Main;
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669. -------------------------------------------------------------------
  670. ---------------------  Next  Program  -----------------------------
  671. -------------------------------------------------------------------
  672.  
  673.  
  674. --
  675. -- Version: @(#)cauchfl.ada    1.1        Date: 6/3/84
  676. --
  677.  
  678. with text_io; use text_io;
  679. procedure cauchy is
  680. --
  681. --  This test of floating point accuracy based on computing the inverses
  682. --  of Cauchy matricies.  These are N x N matricies for which the i, jth
  683. --  entry is 1 / (i + j - 1).  The inverse is computed using determinants.
  684. --  As N increases, the determinant rapidly approaches zero.  The inverse 
  685. --  is computed exactly and then checked by multiplying it by the original
  686. --  matrix.
  687. --
  688. --     Gerry Fisher
  689. --     Computer Sciences Corporation
  690. --     May 27, 1984
  691.  
  692.   type REAL is digits 6;
  693.  
  694.   type MATRIX is array(POSITIVE range <>, POSITIVE range <>) of REAL;
  695.  
  696.   trials : constant := 5;
  697.   FAILED : Boolean  := FALSE;
  698.  
  699.   function cofactor(A : MATRIX; i, j : POSITIVE) return MATRIX is
  700.     B : MATRIX(A'FIRST(1) .. A'LAST(1) - 1, A'FIRST(2) .. A'LAST(2) - 1);
  701.     x : REAL;
  702.   begin
  703.     for p in A'RANGE(1) loop
  704.       for q in A'RANGE(2) loop
  705.     x := A(p, q);
  706.     if    p < i and then q < j then
  707.       B(p, q) := x;
  708.     elsif p < i and then q > j then
  709.       B(p, q - 1) := x;
  710.     elsif p > i and then q < j then
  711.       B(p - 1, q) := x;
  712.     elsif p > i and then q > j then
  713.       B(p - 1, q - 1) := x;
  714.     end if;
  715.       end loop;
  716.     end loop;
  717.     return B;
  718.   end cofactor;
  719.  
  720.   function det(A : MATRIX) return REAL is
  721.     D : REAL;
  722.     k : INTEGER;
  723.   begin
  724.     if A'LENGTH = 1 then
  725.       D := A(A'FIRST(1), A'FIRST(2));
  726.     else
  727.       D := 0.0;
  728.       k := 1;
  729.       for j in A'RANGE(2) loop
  730.     D := D + REAL(k) * A(A'FIRST(1), j) * det(cofactor(A, A'FIRST(1), j));
  731.     k := - k;
  732.       end loop;
  733.     end if;
  734.     return D;
  735.   end det;
  736.  
  737.   function init(n : positive) return MATRIX is
  738.     B : MATRIX(1 .. n, 1 .. n);
  739.   begin
  740.     for i in B'RANGE(1) loop
  741.       for j in B'RANGE(2) loop
  742.         B(i, j) := 1.0 / REAL(i + j - 1);
  743.       end loop;
  744.     end loop;
  745.     return B;
  746.   end init;
  747.  
  748.   function inverse(A : MATRIX) return MATRIX is
  749.     B : MATRIX(A'RANGE(1), A'RANGE(2));
  750.     D : REAL := det(A);
  751.     E : REAL;
  752.   begin
  753.     if A'LENGTH = 1 then
  754.       return (1 .. 1 => (1 .. 1 => 1.0 / D));
  755.     end if;
  756.     for i in B'RANGE(1) loop
  757.       for j in B'RANGE(2) loop
  758.     B(i, j) := REAL((-1) ** (i + j)) * (det(cofactor(A, i, j)) / D);
  759.       end loop;
  760.     end loop;
  761.  
  762.     -- Now check the inverse
  763.  
  764.     for i in A'RANGE loop
  765.       for j in A'RANGE loop
  766.     E := 0.0;
  767.     for k in A'RANGE loop
  768.       E := E + A(i, k) * B(k, j);
  769.     end loop;
  770.     if (i  = j and then E /= 1.0) or else
  771.        (i /= j and then E /= 0.0) then
  772.       raise PROGRAM_ERROR;
  773.     end if;
  774.       end loop;
  775.     end loop;
  776.  
  777.     return B;
  778.   end inverse;
  779.  
  780.  
  781. begin
  782.   put_line("*** TEST Inversion of Cauchy Matricies.");
  783.  
  784.   for N in 1 .. trials loop
  785.   begin
  786.     declare
  787.       A : constant MATRIX := init(N);
  788.       B : constant MATRIX := inverse(A);
  789.     begin
  790.       put_line("*** REMARK: The Cauchy Matrix of size" & integer'image(N) &
  791.                " successfully inverted.");
  792.     end;
  793.   exception
  794.     when PROGRAM_ERROR => 
  795.       put_line("*** REMARK: The Cauchy Matrix of size" & integer'image(N) &
  796.                " not successfully inverted.");
  797.     when NUMERIC_ERROR =>
  798.       put_line("*** REMARK: The Cauchy Matrix of size" & integer'image(N) &
  799.                " appears singular.");
  800.     when others =>
  801.       put_line("*** REMARK: Unexpected exception raised.");
  802.       raise;
  803.   end;
  804.   end loop;
  805.  
  806.   put_line("*** FINISHED Matrix Inversion Test.");
  807.  
  808. end cauchy;
  809.  
  810.  
  811.  
  812.  
  813. -------------------------------------------------------------------
  814. ---------------------  Next  Program  -----------------------------
  815. -------------------------------------------------------------------
  816.  
  817.  
  818. --
  819. -- Version: @(#)cauchfx.ada    1.1        Date: 6/3/84
  820. --
  821.  
  822. with text_io; use text_io;
  823. procedure cauchy is
  824. --
  825. --  This test of fixed point accuracy based on computing the inverses
  826. --  of Cauchy matricies.  These are N x N matricies for which the i, jth
  827. --  entry is 1 / (i + j - 1).  The inverse is computed using determinants.
  828. --  As N increases, the determinant rapidly approaches zero.  The inverse 
  829. --  is computed exactly and then checked by multiplying it by the original
  830. --  matrix.
  831. --
  832. --     Gerry Fisher
  833. --     Computer Sciences Corporation
  834. --     May 27, 1984
  835.  
  836.   type FIXED is delta 2.0**(-16) range -1000.0 .. +1000.00;
  837.  
  838.   type MATRIX is array(POSITIVE range <>, POSITIVE range <>) of FIXED;
  839.  
  840.   trials : constant := 5;
  841.   FAILED : Boolean  := FALSE;
  842.  
  843.   function cofactor(A : MATRIX; i, j : POSITIVE) return MATRIX is
  844.     B : MATRIX(A'FIRST(1) .. A'LAST(1) - 1, A'FIRST(2) .. A'LAST(2) - 1);
  845.     x : FIXED;
  846.   begin
  847.     for p in A'RANGE(1) loop
  848.       for q in A'RANGE(2) loop
  849.     x := A(p, q);
  850.     if    p < i and then q < j then
  851.       B(p, q) := x;
  852.     elsif p < i and then q > j then
  853.       B(p, q - 1) := x;
  854.     elsif p > i and then q < j then
  855.       B(p - 1, q) := x;
  856.     elsif p > i and then q > j then
  857.       B(p - 1, q - 1) := x;
  858.     end if;
  859.       end loop;
  860.     end loop;
  861.     return B;
  862.   end cofactor;
  863.  
  864.   function det(A : MATRIX) return FIXED is
  865.     D : FIXED;
  866.     k : INTEGER;
  867.   begin
  868.     if A'LENGTH = 1 then
  869.       D := A(A'FIRST(1), A'FIRST(2));
  870.     else
  871.       D := 0.0;
  872.       k := 1;
  873.       for j in A'RANGE(2) loop
  874.     D := D + k * FIXED(A(A'FIRST(1), j) * det(cofactor(A, A'FIRST(1), j)));
  875.     k := - k;
  876.       end loop;
  877.     end if;
  878.     return D;
  879.   end det;
  880.  
  881.   function init(n : positive) return MATRIX is
  882.     B : MATRIX(1 .. n, 1 .. n);
  883.   begin
  884.     for i in B'RANGE(1) loop
  885.       for j in B'RANGE(2) loop
  886.         B(i, j) := 1.0 / (i + j - 1);
  887.       end loop;
  888.     end loop;
  889.     return B;
  890.   end init;
  891.  
  892.   function inverse(A : MATRIX) return MATRIX is
  893.     B : MATRIX(A'RANGE(1), A'RANGE(2));
  894.     D : FIXED := det(A);
  895.     E : FIXED;
  896.   begin
  897.     if A'LENGTH = 1 then
  898.       return (1 .. 1 => (1 .. 1 => FIXED(FIXED(1.0) / D)));
  899.     end if;
  900.     for i in B'RANGE(1) loop
  901.       for j in B'RANGE(2) loop
  902.     B(i, j) := ((-1) ** (i + j)) * FIXED(det(cofactor(A, i, j)) / D);
  903.       end loop;
  904.     end loop;
  905.  
  906.     -- Now check the inverse
  907.  
  908.     for i in A'RANGE loop
  909.       for j in A'RANGE loop
  910.     E := 0.0;
  911.     for k in A'RANGE loop
  912.       E := E + FIXED(A(i, k) * B(k, j));
  913.     end loop;
  914.     if (i  = j and then E /= 1.0) or else
  915.        (i /= j and then E /= 0.0) then
  916.       raise PROGRAM_ERROR;
  917.     end if;
  918.       end loop;
  919.     end loop;
  920.  
  921.     return B;
  922.   end inverse;
  923.  
  924.  
  925. begin
  926.   put_line("*** TEST Inversion of Cauchy Matricies.");
  927.  
  928.   for N in 1 .. trials loop
  929.   begin
  930.     declare
  931.       A : constant MATRIX := init(N);
  932.       B : constant MATRIX := inverse(A);
  933.     begin
  934.       put_line("*** REMARK: The Cauchy Matrix of size" & integer'image(N) &
  935.                " successfully inverted.");
  936.     end;
  937.   exception
  938.     when PROGRAM_ERROR => 
  939.       put_line("*** REMARK: The Cauchy Matrix of size" & integer'image(N) &
  940.                " not successfully inverted.");
  941.     when NUMERIC_ERROR =>
  942.       put_line("*** REMARK: The Cauchy Matrix of size" & integer'image(N) &
  943.                " appears singular.");
  944.     when others =>
  945.       put_line("*** REMARK: Unexpected exception raised.");
  946.       raise;
  947.   end;
  948.   end loop;
  949.  
  950.   put_line("*** FINISHED Matrix Inversion Test.");
  951.  
  952. end cauchy;
  953.  
  954.  
  955.  
  956. -------------------------------------------------------------------
  957. ---------------------  Next  Program  -----------------------------
  958. -------------------------------------------------------------------
  959.  
  960.  
  961. --
  962. -- Version: @(#)cauchun.ada    1.1        Date: 6/3/84
  963. --
  964.  
  965. with universal_integer_arithmetic; use universal_integer_arithmetic;
  966. with universal_real_arithmetic; use universal_real_arithmetic;
  967. with text_io; use text_io;
  968. procedure cauchy is
  969. --
  970. --  This test of the Universal Arithmetic Packages computes the inverses
  971. --  of Cauchy matricies.  These are N x N matricies for which the i, jth
  972. --  entry is 1 / (i + j - 1).  The inverse is computed using determinants.
  973. --  As N increases, the determinant rapidly approaches zero.  The inverse 
  974. --  is computed exactly and then checked by multiplying it by the original
  975. --  matrix.
  976. --
  977. --     Gerry Fisher
  978. --     Computer Sciences Corporation
  979. --     May 27, 1984
  980.  
  981.   type MATRIX is array(POSITIVE range <>, POSITIVE range <>) of Universal_real;
  982.  
  983.   one    : Universal_integer := UI(1);
  984.   r_one  : Universal_real    := UR(one, one);
  985.   r_zero : Universal_real    := UR(UI(0), one);
  986.  
  987.   trials : constant := 10;
  988.   FAILED : Boolean := FALSE;
  989.  
  990.   function cofactor(A : MATRIX; i, j : POSITIVE) return MATRIX is
  991.     B : MATRIX(A'FIRST(1) .. A'LAST(1) - 1, A'FIRST(2) .. A'LAST(2) - 1);
  992.     x : Universal_real;
  993.   begin
  994.     for p in A'RANGE(1) loop
  995.       for q in A'RANGE(2) loop
  996.     x := A(p, q);
  997.     if    p < i and then q < j then
  998.       B(p, q) := x;
  999.     elsif p < i and then q > j then
  1000.       B(p, q - 1) := x;
  1001.     elsif p > i and then q < j then
  1002.       B(p - 1, q) := x;
  1003.     elsif p > i and then q > j then
  1004.       B(p - 1, q - 1) := x;
  1005.     end if;
  1006.       end loop;
  1007.     end loop;
  1008.     return B;
  1009.   end cofactor;
  1010.  
  1011.   function det(A : MATRIX) return Universal_real is
  1012.     D : Universal_real;
  1013.     k : INTEGER;
  1014.   begin
  1015.     if A'LENGTH = 1 then
  1016.       D := A(A'FIRST(1), A'FIRST(2));
  1017.     else
  1018.       D := r_zero;
  1019.       k := 1;
  1020.       for j in A'RANGE(2) loop
  1021.     D := D + UI(k) * A(A'FIRST(1), j) * det(cofactor(A, A'FIRST(1), j));
  1022.     k := - k;
  1023.       end loop;
  1024.     end if;
  1025.     return D;
  1026.   end det;
  1027.  
  1028.   function init(n : positive) return MATRIX is
  1029.     B : MATRIX(1 .. n, 1 .. n);
  1030.   begin
  1031.     for i in B'RANGE(1) loop
  1032.       for j in B'RANGE(2) loop
  1033.     B(i, j) := UR(one, UI(i + j - 1));
  1034.       end loop;
  1035.     end loop;
  1036.     return B;
  1037.   end init;
  1038.  
  1039.   function inverse(A : MATRIX) return MATRIX is
  1040.     B : MATRIX(A'RANGE(1), A'RANGE(2));
  1041.     D : Universal_real := det(A);
  1042.     E : Universal_real;
  1043.   begin
  1044.     if A'LENGTH = 1 then
  1045.       return (1 .. 1 => (1 .. 1 => r_one / D));
  1046.     end if;
  1047.     for i in B'RANGE(1) loop
  1048.       for j in B'RANGE(2) loop
  1049.     B(i, j) := UI((-1) ** (i + j)) * det(cofactor(A, i, j)) / D;
  1050.       end loop;
  1051.     end loop;
  1052.  
  1053.     -- Now check the inverse
  1054.  
  1055.     for i in A'RANGE loop
  1056.       for j in A'RANGE loop
  1057.     E := r_zero;
  1058.     for k in A'RANGE loop
  1059.       E := E + A(i, k) * B(k, j);
  1060.     end loop;
  1061.     if (i  = j and then not eql(E, r_one)) or else
  1062.        (i /= j and then not eql(E, r_zero)) then
  1063.       raise PROGRAM_ERROR;
  1064.     end if;
  1065.       end loop;
  1066.     end loop;
  1067.  
  1068.     return B;
  1069.   end inverse;
  1070.  
  1071.  
  1072. begin
  1073.   put_line("*** TEST Inversion of Cauchy Matricies.");
  1074.  
  1075.   for N in 1 .. trials loop
  1076.   begin
  1077.     declare
  1078.       A : constant MATRIX := init(N);
  1079.       B : constant MATRIX := inverse(A);
  1080.     begin
  1081.       put_line("*** REMARK: The Cauchy Matrix of size " & integer'image(N) &
  1082.                " successfully inverted.");
  1083.     end;
  1084.   exception
  1085.     when PROGRAM_ERROR => 
  1086.       put_line("*** FAILED: Matrix of size " & integer'image(N) &
  1087.                " not successfully inverted.");
  1088.       FAILED := True;
  1089.       exit;
  1090.   end;
  1091.   end loop;
  1092.  
  1093.   if not FAILED then
  1094.     put_line("*** PASSED Matrix Inversion Test.");
  1095.   end if;
  1096. end cauchy;
  1097.  
  1098.  
  1099.  
  1100. -------------------------------------------------------------------
  1101. ---------------------  Next  Program  -----------------------------
  1102. -------------------------------------------------------------------
  1103.  
  1104.  
  1105. --
  1106. -- Version: @(#)char_dir.ada    1.2        Date: 9/21/84
  1107. --
  1108. -- Author:  Edward Colbert
  1109. --        Ada Technology Group
  1110. --        Information Software Systems Lab
  1111. --        Defense Systems Group
  1112. --        TRW
  1113. --        Redondo Beach, CA
  1114. --
  1115. -- This program measures the time required for doing various file
  1116. -- operations using the Direct_IO package with Characters.
  1117. --
  1118. -- Note:  In order for the measurement to be meaningful, it must be the 
  1119. -- only program executing while the test is run.  
  1120. --
  1121. -- Please set Times large enough to provide at least two significant 
  1122. -- digits in the average times, i.e., the difference between 
  1123. -- the elapsed time and the loop time must be at least 100 times 
  1124. -- Duration'Small & at least 100 times System.Tick.
  1125. --
  1126.  
  1127. with Text_IO; use Text_IO;
  1128. with Direct_IO;
  1129. with Calendar; use Calendar;
  1130. with System; use System;
  1131. procedure Character_Direct_IO_Test is
  1132.  
  1133.    Times : constant Positive := 1000;
  1134.  
  1135.    type Real_Time is digits Max_Digits;
  1136.  
  1137.    Start_Time : Time;
  1138.    Loop_Time : Duration;
  1139.    Average_Time : Real_Time;
  1140.    Create_Time : Duration;
  1141.    Close_Time  : Duration;
  1142.    Open_Time   : Duration;
  1143.    Delete_Time : Duration;
  1144.    Read_Time   : Duration;
  1145.    Write_Time  : Duration;
  1146.  
  1147.    package Duration_IO is new Fixed_IO (Duration);
  1148.    use Duration_IO;
  1149.  
  1150.    package Real_Time_IO is new Float_IO (Real_Time);
  1151.    use Real_Time_IO;
  1152.  
  1153.    package Int_IO is new Integer_IO (Integer);
  1154.    use Int_IO;
  1155.  
  1156.    package Char_IO is new Direct_IO (Character);
  1157.    use Char_IO;
  1158.  
  1159.    file:   Char_IO.file_type;
  1160.    value:  character := 'A';
  1161.    count:  integer := integer'first;    -- used in timing loop
  1162.  
  1163. begin
  1164.  
  1165.    -- Measure the timing loop overhead.
  1166.    Start_Time := Clock;
  1167.    for N in 1 .. Times loop
  1168.       count := count + 1;        -- prevent optimization
  1169.    end loop;
  1170.    Loop_Time := Clock - Start_Time;
  1171.  
  1172.  
  1173.    -- Create a file
  1174.    Start_Time := Clock;
  1175.    Char_IO.Create (file, mode => out_file, name => "test_file");
  1176.    Create_Time := Clock - Start_Time;
  1177.  
  1178.    -- Measure the time of Writing of value
  1179.    Start_Time := Clock;
  1180.    for N in 1 .. Times loop
  1181.       count := count + 1;
  1182.       Char_IO.write (file, value);
  1183.    end loop;
  1184.    Write_Time := Clock - Start_Time;
  1185.  
  1186.    -- Close a file
  1187.    Start_Time := Clock;
  1188.    Char_IO.Close (file);
  1189.    Close_Time := Clock - Start_Time;
  1190.  
  1191.    -- Open a file
  1192.    Start_Time := Clock;
  1193.    Char_IO.Open (file, mode => in_file, name => "test_file");
  1194.    Open_Time := Clock - Start_Time;
  1195.  
  1196.    -- Measure the time of Reading of value
  1197.    Start_Time := Clock;
  1198.    for N in 1 .. Times loop
  1199.       count := count + 1;
  1200.       Char_IO.read (file, value);
  1201.    end loop;
  1202.    Read_Time := Clock - Start_Time;
  1203.  
  1204.    -- Delete a file
  1205.    Start_Time := Clock;
  1206.    Char_IO.Delete (file);
  1207.    Delete_Time := Clock - Start_Time;
  1208.  
  1209.  
  1210.    Put ("Create File Time = ");
  1211.    Put (Create_Time, Fore => 0);
  1212.    put_line (" seconds ");
  1213.  
  1214.    Put ("Close File Time = ");
  1215.    Put (Close_Time, Fore => 0);
  1216.    put_line (" seconds ");
  1217.  
  1218.    Put ("Open File Time = ");
  1219.    Put (Open_Time, Fore => 0);
  1220.    put_line (" seconds ");
  1221.  
  1222.    Put ("Delete File Time = ");
  1223.    Put (Delete_Time, Fore => 0);
  1224.    put_line (" seconds ");
  1225.  
  1226.    Put("Loop time = ");
  1227.    Put(Loop_Time, Fore => 0);
  1228.    Put(" seconds for ");
  1229.    Put(Times, Width => 0);
  1230.    Put_Line(" iterations");
  1231.  
  1232.  
  1233.    Put("Elapsed time = ");
  1234.    Put(Write_Time, Fore => 0);
  1235.    Put(" seconds for ");
  1236.    Put(Times, Width => 0);
  1237.    Put_Line(" Writes");
  1238.  
  1239.    Average_Time := Real_Time(Write_Time - Loop_Time)/Real_Time(Times);
  1240.    Put("Average time for a Write = ");
  1241.    Put(Average_Time, Fore => 0);
  1242.    Put_Line(" seconds");
  1243.  
  1244.    New_Line;
  1245.  
  1246.  
  1247.  
  1248.    Put("Elapsed time = ");
  1249.    Put(Read_Time, Fore => 0);
  1250.    Put(" seconds for ");
  1251.    Put(Times, Width => 0);
  1252.    Put_Line(" Reads");
  1253.  
  1254.    Average_Time := Real_Time(Read_Time - Loop_Time)/Real_Time(Times);
  1255.    Put("Average time for a Read = ");
  1256.    Put(Average_Time, Fore => 0);
  1257.    Put_Line(" seconds");
  1258.  
  1259.    New_Line;
  1260.  
  1261.    if (Read_Time  - Loop_Time < 100 * Duration'Small)    or
  1262.       (Read_Time  - Loop_Time < 100 * System.Tick)    or
  1263.       (Write_Time - Loop_Time < 100 * Duration'Small)    or
  1264.       (Write_Time - Loop_Time < 100 * System.Tick)    then
  1265.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  1266.    else
  1267.       Put_Line("** TEST PASSED **");
  1268.    end if;
  1269.  
  1270. end Character_Direct_IO_Test;
  1271.  
  1272.  
  1273. -------------------------------------------------------------------
  1274. ---------------------  Next  Program  -----------------------------
  1275. -------------------------------------------------------------------
  1276.  
  1277.  
  1278. --
  1279. -- Version: @(#)char_enm.ada    1.2        Date: 9/21/84
  1280. --
  1281. -- Author:  Edward Colbert
  1282. --        Ada Technology Group
  1283. --        Information Software Systems Lab
  1284. --        Defense Systems Group
  1285. --        TRW
  1286. --        Redondo Beach, CA
  1287. --
  1288. -- This program measures the time required for doing various file
  1289. -- operations using the Text_IO package & the Enumeration_IO subpackage
  1290. -- with Characters.
  1291. --
  1292. -- Note:  In order for the measurement to be meaningful, it must be the 
  1293. -- only program executing while the test is run.  
  1294. --
  1295. -- Please set Times large enough to provide at least two significant 
  1296. -- digits in the average times, i.e., the difference between 
  1297. -- the elapsed time and the loop time must be at least 100 times 
  1298. -- Duration'Small & at least 100 times System.Tick.
  1299. --
  1300.  
  1301. with Text_IO; use Text_IO;
  1302. with Calendar; use Calendar;
  1303. with System; use System;
  1304. procedure Character_Enumeration_IO_Test is
  1305.  
  1306.    Times : constant Positive := 1000;
  1307.  
  1308.    type Real_Time is digits Max_Digits;
  1309.  
  1310.    Start_Time : Time;
  1311.    Loop_Time : Duration;
  1312.    Average_Time : Real_Time;
  1313.    Create_Time : Duration;
  1314.    Close_Time  : Duration;
  1315.    Open_Time   : Duration;
  1316.    Delete_Time : Duration;
  1317.    Read_Time   : Duration;
  1318.    Write_Time  : Duration;
  1319.  
  1320.    package Duration_IO is new Fixed_IO (Duration);
  1321.    use Duration_IO;
  1322.  
  1323.    package Real_Time_IO is new Float_IO (Real_Time);
  1324.    use Real_Time_IO;
  1325.  
  1326.    package Int_IO is new Integer_IO (Integer);
  1327.    use Int_IO;
  1328.  
  1329.    package Char_IO is new Enumeration_IO (Character);
  1330.  
  1331.  
  1332.    file:   Text_IO.file_type;
  1333.    value:  character := 'A';
  1334.    count:  integer := integer'first;    -- used in timing loop
  1335.  
  1336. begin
  1337.  
  1338.    -- Measure the timing loop overhead.
  1339.    Start_Time := Clock;
  1340.    for N in 1 .. Times loop
  1341.       count := count + 1;        -- prevent optimization
  1342.    end loop;
  1343.    Loop_Time := Clock - Start_Time;
  1344.  
  1345.  
  1346.    -- Create a file
  1347.    Start_Time := Clock;
  1348.    Text_IO.Create (file, mode => out_file, name => "test_file");
  1349.    Create_Time := Clock - Start_Time;
  1350.  
  1351.    -- Measure the time of Writing of value
  1352.    Start_Time := Clock;
  1353.    for N in 1 .. Times loop
  1354.       count := count + 1;
  1355.       Char_IO.put (file, value);
  1356.    end loop;
  1357.    Write_Time := Clock - Start_Time;
  1358.  
  1359.    -- Close a file
  1360.    Start_Time := Clock;
  1361.    Text_IO.Close (file);
  1362.    Close_Time := Clock - Start_Time;
  1363.  
  1364.    -- Open a file
  1365.    Start_Time := Clock;
  1366.    Text_IO.Open (file, mode => in_file, name => "test_file");
  1367.    Open_Time := Clock - Start_Time;
  1368.  
  1369.    -- Measure the time of Reading of value
  1370.    Start_Time := Clock;
  1371.    for N in 1 .. Times loop
  1372.       count := count + 1;
  1373.       Char_IO.get (file, value);
  1374.    end loop;
  1375.    Read_Time := Clock - Start_Time;
  1376.  
  1377.    -- Delete a file
  1378.    Start_Time := Clock;
  1379.    Text_IO.Delete (file);
  1380.    Delete_Time := Clock - Start_Time;
  1381.  
  1382.  
  1383.    Put ("Create File Time = ");
  1384.    Put (Create_Time, Fore => 0);
  1385.    put_line (" seconds ");
  1386.  
  1387.    Put ("Close File Time = ");
  1388.    Put (Close_Time, Fore => 0);
  1389.    put_line (" seconds ");
  1390.  
  1391.    Put ("Open File Time = ");
  1392.    Put (Open_Time, Fore => 0);
  1393.    put_line (" seconds ");
  1394.  
  1395.    Put ("Delete File Time = ");
  1396.    Put (Delete_Time, Fore => 0);
  1397.    put_line (" seconds ");
  1398.  
  1399.    Put("Loop time = ");
  1400.    Put(Loop_Time, Fore => 0);
  1401.    Put(" seconds for ");
  1402.    Put(Times, Width => 0);
  1403.    Put_Line(" iterations");
  1404.  
  1405.  
  1406.    Put("Elapsed time = ");
  1407.    Put(Write_Time, Fore => 0);
  1408.    Put(" seconds for ");
  1409.    Put(Times, Width => 0);
  1410.    Put_Line(" Writes");
  1411.  
  1412.    Average_Time := Real_Time(Write_Time - Loop_Time)/Real_Time(Times);
  1413.    Put("Average time for a Write = ");
  1414.    Put(Average_Time, Fore => 0);
  1415.    Put_Line(" seconds");
  1416.  
  1417.    New_Line;
  1418.  
  1419.  
  1420.  
  1421.    Put("Elapsed time = ");
  1422.    Put(Read_Time, Fore => 0);
  1423.    Put(" seconds for ");
  1424.    Put(Times, Width => 0);
  1425.    Put_Line(" Reads");
  1426.  
  1427.    Average_Time := Real_Time(Read_Time - Loop_Time)/Real_Time(Times);
  1428.    Put("Average time for a Read = ");
  1429.    Put(Average_Time, Fore => 0);
  1430.    Put_Line(" seconds");
  1431.  
  1432.    New_Line;
  1433.  
  1434.    if (Read_Time  - Loop_Time < 100 * Duration'Small)    or
  1435.       (Read_Time  - Loop_Time < 100 * System.Tick)    or
  1436.       (Write_Time - Loop_Time < 100 * Duration'Small)    or
  1437.       (Write_Time - Loop_Time < 100 * System.Tick)    then
  1438.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  1439.    else
  1440.       Put_Line("** TEST PASSED **");
  1441.    end if;
  1442.  
  1443. end Character_Enumeration_IO_Test;
  1444.  
  1445.  
  1446. -------------------------------------------------------------------
  1447. ---------------------  Next  Program  -----------------------------
  1448. -------------------------------------------------------------------
  1449.  
  1450.  
  1451. --
  1452. -- Version: @(#)char_txt.ada    1.3        Date: 9/21/84
  1453. --
  1454. -- Author:  Edward Colbert
  1455. --        Ada Technology Group
  1456. --        Information Software Systems Lab
  1457. --        Defense Systems Group
  1458. --        TRW
  1459. --        Redondo Beach, CA
  1460. --
  1461. -- This program measures the time required for doing various file
  1462. -- operations using the Text_IO package with Characters.
  1463. --
  1464. -- Note:  In order for the measurement to be meaningful, it must be the 
  1465. -- only program executing while the test is run.  
  1466. --
  1467. -- Please set Times large enough to provide at least two significant 
  1468. -- digits in the average times, i.e., the difference between 
  1469. -- the elapsed time and the loop time must be at least 100 times 
  1470. -- Duration'Small & at least 100 times System.Tick.
  1471. --
  1472.  
  1473. with Text_IO; use Text_IO;
  1474. with Calendar; use Calendar;
  1475. with System; use System;
  1476. procedure Character_Text_IO_Test is
  1477.  
  1478.    Times : constant Positive := 1000;
  1479.  
  1480.    type Real_Time is digits Max_Digits;
  1481.  
  1482.    Start_Time : Time;
  1483.    Loop_Time : Duration;
  1484.    Average_Time : Real_Time;
  1485.    Create_Time : Duration;
  1486.    Close_Time  : Duration;
  1487.    Open_Time   : Duration;
  1488.    Delete_Time : Duration;
  1489.    Read_Time   : Duration;
  1490.    Write_Time  : Duration;
  1491.  
  1492.    package Duration_IO is new Fixed_IO (Duration);
  1493.    use Duration_IO;
  1494.  
  1495.    package Real_Time_IO is new Float_IO (Real_Time);
  1496.    use Real_Time_IO;
  1497.  
  1498.    package Int_IO is new Integer_IO (Integer);
  1499.    use Int_IO;
  1500.  
  1501.    file:   Text_IO.file_type;
  1502.    value:  character := 'A';
  1503.    count:  integer := integer'first;    -- used in timing loop
  1504.  
  1505. begin
  1506.  
  1507.    -- Measure the timing loop overhead.
  1508.    Start_Time := Clock;
  1509.    for N in 1 .. Times loop
  1510.       count := count + 1;        -- prevent optimization
  1511.    end loop;
  1512.    Loop_Time := Clock - Start_Time;
  1513.  
  1514.  
  1515.    -- Create a file
  1516.    Start_Time := Clock;
  1517.    Text_IO.Create (file, mode => out_file, name => "test_file");
  1518.    Create_Time := Clock - Start_Time;
  1519.  
  1520.    -- Measure the time of Writing of value
  1521.    Start_Time := Clock;
  1522.    for N in 1 .. Times loop
  1523.       count := count + 1;
  1524.       Text_IO.put (file, value);
  1525.    end loop;
  1526.    Write_Time := Clock - Start_Time;
  1527.  
  1528.    -- Close a file
  1529.    Start_Time := Clock;
  1530.    Text_IO.Close (file);
  1531.    Close_Time := Clock - Start_Time;
  1532.  
  1533.    -- Open a file
  1534.    Start_Time := Clock;
  1535.    Text_IO.Open (file, mode => in_file, name => "test_file");
  1536.    Open_Time := Clock - Start_Time;
  1537.  
  1538.    -- Measure the time of Reading of value
  1539.    Start_Time := Clock;
  1540.    for N in 1 .. Times loop
  1541.       count := count + 1;
  1542.       Text_IO.get (file, value);
  1543.    end loop;
  1544.    Read_Time := Clock - Start_Time;
  1545.  
  1546.    -- Delete a file
  1547.    Start_Time := Clock;
  1548.    Text_IO.Delete (file);
  1549.    Delete_Time := Clock - Start_Time;
  1550.  
  1551.  
  1552.    Put ("Create File Time = ");
  1553.    Put (Create_Time, Fore => 0);
  1554.    put_line (" seconds ");
  1555.  
  1556.    Put ("Close File Time = ");
  1557.    Put (Close_Time, Fore => 0);
  1558.    put_line (" seconds ");
  1559.  
  1560.    Put ("Open File Time = ");
  1561.    Put (Open_Time, Fore => 0);
  1562.    put_line (" seconds ");
  1563.  
  1564.    Put ("Delete File Time = ");
  1565.    Put (Delete_Time, Fore => 0);
  1566.    put_line (" seconds ");
  1567.  
  1568.    Put("Loop time = ");
  1569.    Put(Loop_Time, Fore => 0);
  1570.    Put(" seconds for ");
  1571.    Put(Times, Width => 0);
  1572.    Put_Line(" iterations");
  1573.  
  1574.  
  1575.    Put("Elapsed time = ");
  1576.    Put(Write_Time, Fore => 0);
  1577.    Put(" seconds for ");
  1578.    Put(Times, Width => 0);
  1579.    Put_Line(" Writes");
  1580.  
  1581.    Average_Time := Real_Time(Write_Time - Loop_Time)/Real_Time(Times);
  1582.    Put("Average time for a Write = ");
  1583.    Put(Average_Time, Fore => 0);
  1584.    Put_Line(" seconds");
  1585.  
  1586.    New_Line;
  1587.  
  1588.  
  1589.  
  1590.    Put("Elapsed time = ");
  1591.    Put(Read_Time, Fore => 0);
  1592.    Put(" seconds for ");
  1593.    Put(Times, Width => 0);
  1594.    Put_Line(" Reads");
  1595.  
  1596.    Average_Time := Real_Time(Read_Time - Loop_Time)/Real_Time(Times);
  1597.    Put("Average time for a Read = ");
  1598.    Put(Average_Time, Fore => 0);
  1599.    Put_Line(" seconds");
  1600.  
  1601.    New_Line;
  1602.  
  1603.    if (Read_Time  - Loop_Time < 100 * Duration'Small)    or
  1604.       (Read_Time  - Loop_Time < 100 * System.Tick)    or
  1605.       (Write_Time - Loop_Time < 100 * Duration'Small)    or
  1606.       (Write_Time - Loop_Time < 100 * System.Tick)    then
  1607.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  1608.    else
  1609.       Put_Line("** TEST PASSED **");
  1610.    end if;
  1611.  
  1612. end Character_Text_IO_Test;
  1613.  
  1614.  
  1615.  
  1616.  
  1617.  
  1618. -------------------------------------------------------------------
  1619. ---------------------  Next  Program  -----------------------------
  1620. -------------------------------------------------------------------
  1621.  
  1622. --
  1623. -- Version: @(#)physics.ada    1.1    Date: 6/3/85
  1624. --
  1625. -- Supplied by:  John Squires
  1626. --               Westinghouse Electric Company
  1627. -- (except as noted)
  1628. --
  1629. -- Edited by:  Jim Alstad
  1630. --             Software Engineering Laboratories
  1631. --             Radar Systems Group
  1632. --             Hughes Aircraft Company
  1633. --             El Segundo CA USA
  1634. --
  1635. -- Series of compilation units to test real-world (i.e., heavy) use
  1636. -- of packages.  Can be compilation & link time benchmark.  The main
  1637. -- program (PHYSICS_1) should execute quickly.
  1638. --
  1639. -- Two units were written by Alstad; the rest are taken from
  1640. -- the tape distributed by Squires following the San Jose SIGAda meeting
  1641. -- (winter 85).  Necessary alterations by Alstad
  1642. -- are flagged "--Alstad".  The compilation units are as follows, where
  1643. -- a trailing underscore means a specification unit:
  1644. --
  1645. --      NthRoot_                              Alstad
  1646. --      NthRoot                               Alstad
  1647. --      PHYSICAL_REAL                         Squires
  1648. --      LONG_FLT_IO                           Squires
  1649. --      PHYSICAL_UNITS_BASIC                  Squires
  1650. --      PHYSICAL_UNITS_MECHANICAL             Squires
  1651. --      PHYSICAL_UNITS_ELECTRICAL             Squires
  1652. --      PHYSICAL_UNITS_OTHER                  Squires
  1653. --      PHYSICAL_UNITS_OUTPUT_BASIC_          Squires
  1654. --      PHYSICAL_UNITS_OUTPUT_BASIC           Squires
  1655. --      PHYSICAL_UNITS_OUTPUT_MECHANICAL_     Squires
  1656. --      PHYSICAL_UNITS_OUTPUT_MECHANICAL      Squires
  1657. --      MKS_PHYSICS_MECHANICAL_               Squires
  1658. --      MKS_PHYSICS_MECHANICAL                Squires
  1659. --      PHYSICS_1                             Squires
  1660. --
  1661. --------------------------------------------------------------------------------
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671. --------------------------------------------------------------------------------
  1672. --
  1673. -- Version:  NthRoot_.ada     1.0                 Date: 5/29/85
  1674. --
  1675. -- Author:  Jim Alstad
  1676. --          Software Engineering Laboratories
  1677. --          Radar Systems Group
  1678. --          Hughes Aircraft Company
  1679. --          El Segundo CA USA
  1680. --
  1681. -- Simple generic package to compute Nth roots.
  1682. --
  1683. -- Instantiating NthRoot with N, an integer >= 2,
  1684. -- and Arith-Type, a floating point type,
  1685. -- yields NthRoot.RootOf, a function which computes
  1686. -- the Nth root of its argument.
  1687. --
  1688. -- The result is an approximation, good to (at least) four digits.
  1689. -- For simplicity, RootOf (- X) = - RootOf (X), though N may be even.
  1690. -- Arith-Type is used for intermediate calculations.
  1691. --
  1692.           generic
  1693.      N:  integer;  -- N >= 2
  1694.      type Arith_Type is digits <>;
  1695.           package
  1696. NthRoot                      is
  1697.  
  1698.      function
  1699. RootOf (X: Arith_Type) return Arith_Type;
  1700.  
  1701. end NthRoot; --spec
  1702. --------------------------------------------------------------------------------
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712. --------------------------------------------------------------------------------
  1713. --
  1714. -- Version: NthRoot.ada     1.0                         Date: 5/29/85
  1715. --
  1716. --
  1717. -- Author:  Jim Alstad
  1718. --          Software Engineering Laboratories
  1719. --          Radar Systems Group
  1720. --          Hughes Aircraft Company
  1721. --          El Segundo CA USA
  1722. --
  1723. -- Assisted by Nat Bachman (same affiliation).
  1724. --
  1725. -- Simple generic package to compute Nth roots.
  1726. --
  1727. -- The basic approach is to use Newton's method, which computes
  1728. -- successive approximations.  This may be summarized as follows.
  1729. -- Suppose a number X and a function F are given, and it is desired
  1730. -- to find a Y such that F(Y) = X.  Then Newton's method says that
  1731. -- a better approximation YNext may be found via
  1732. --      YNext = Y + (X - F(Y)) / F'(Y)     .
  1733. -- Taking F(Y) to be Y**N, Y to be RootPrev, and YNext to be Root yields
  1734. --      Root = ((X/RootPrev**(N-1)) + ((N-1)*RootPrev)) / N     ,
  1735. -- which is the formula used below.  Iteration continues until
  1736. -- Root and RootPrev differ by less than Tolerance.
  1737. --
  1738. -- Convergence is fairly fast once RootPrev gets close to the actual root.
  1739. -- To speed this up, X is "normalized" into XNorm, where 1 <= XNorm < 2**N.
  1740. -- This means that 1 <= RootOf(XNorm) < 2, so that 2.0 is used as
  1741. -- the initial approximation to RootOf(XNorm).  A side effect of this is
  1742. -- that the approximation to RootOf(XNorm) will never be less than
  1743. -- the actual root.
  1744. --
  1745. -- From a programming point of view, the main point of interest is
  1746. -- calculating XNorm (from XG1).  This involves dividing XNorm by values
  1747. -- Power(C).TwoN, while remembering corresponding values Power(C).Two
  1748. -- by which to multiply Root to compensate.  This algorithm can be
  1749. -- characterized as calculating the integer part of log(X), where
  1750. -- the log is base 2**N, by calculating the bits in its binary
  1751. -- representation from left to right (!).  The initialization of Power
  1752. -- is also interesting, as it uses an exception to terminate a loop
  1753. -- (no alternative seems as appropriate).
  1754. --
  1755. -- This routine is used as a vehicle to demonstrate Dijkstra's proof-
  1756. -- of-correctness technique, which is based on his "weakest precondition"
  1757. -- predicate transformer.  (This demonstration has not been carried
  1758. -- through 100%.)
  1759. --
  1760. -- The main consideration in designing this routine has been to achieve
  1761. -- reasonable accuracy and efficiency with broad applicability but
  1762. -- without an extended effort (i.e., it had to be interesting).
  1763. -- Consequently there are some rough edges.  Here is a partial list:
  1764. --  1.  There is no check for N < 2.
  1765. --  2.  Arith-Type'small <= abs (X) < 1 / MaxX causes numeric_error.
  1766. --
  1767. --
  1768.      package body
  1769. NthRoot          is
  1770.  
  1771.           -- - MaxX <= X <= MaxX
  1772.      MaxX:  constant Arith_Type := Arith_Type'large;
  1773.  
  1774.           -- (2**N) ** (2**(CBound + 1))  >  MaxX
  1775.      CBound:  constant := 10;
  1776.           subtype
  1777.      CIndex  is  integer range 0..CBound;
  1778.  
  1779.       -- Power assertion (after initialization):
  1780.       --     for all C in 0..CMax:
  1781.       --       RootOf(Power(C).TwoN) = Power(C).Two  &
  1782.       --       Power(C+1) = Power(C) ** 2            &
  1783.       --       Power(CMax+1).TwoN > MaxX             &
  1784.       --       Power(0).TwoN = 2**N
  1785.       -- (Power(CMax+1) is not actually computed.)
  1786.           type APower is record
  1787.            Two, TwoN:  Arith_Type;
  1788.            end record; --APower
  1789.      Power:  array (CIndex) of APower;
  1790.      CMax:  CIndex;
  1791.  
  1792.      function
  1793. RootOf (X: Arith_Type) return Arith_Type  is
  1794.  
  1795.      C:  CIndex;  -- C <= CMax
  1796.      -- Sign * (XG1 ** Inverter) = X
  1797.      Sign:  Arith_Type;  -- +1 or -1
  1798.      Inverter:  integer range -1..+1;  -- +1 or -1
  1799.      XG1:  Arith_Type;  -- 1 <= XG1 <= MaxX
  1800.      -- RootOf (XG1) = RootOf (XNorm) * Unnormalizer
  1801.      Unnormalizer:  Arith_Type;
  1802.      XNorm:  Arith_Type;  -- 1 <= XNorm < 2**N
  1803.      -- Root & RootPrev are approximations to RootOf (XNorm)
  1804.      Root, RootPrev:  Arith_Type;
  1805.      -- abs (RootOf (XNorm) - Root) <= Tolerance
  1806.      Tolerance:  constant := 1.0E-4;
  1807.  
  1808.   begin  -- body of RootOf
  1809.      if  X = 0.0
  1810.        then
  1811.       return (0.0);  -- 0 = RootOf (0)
  1812.        else
  1813.       --assert:  X /= 0
  1814.       if  X > 0.0
  1815.         then  Sign := +1.0;  XG1 := +X;
  1816.         else  Sign := -1.0;  XG1 := -X;
  1817.         end if;
  1818.       --assert:  Sign * XG1 = X  &  XG1 > 0  &  Sign = +1 or -1
  1819.       if  XG1 >= 1.0
  1820.         then  Inverter := +1;
  1821.         else  Inverter := -1;
  1822.         end if;
  1823.       XG1  :=  XG1 ** Inverter;
  1824.       --assert:  Sign * (XG1 ** Inverter) = X  &
  1825.       --         XG1 >= 1                      &
  1826.       --         Sign = +1 or -1               &
  1827.       --         Inverter = +1 or -1
  1828.       --assert:  RootOf (X) = RootOf (Sign * (XG1 ** Inverter))
  1829.       --                    = Sign * (RootOf (XG1) ** Inverter)
  1830.       --assert:  1 <= XG1 <= MaxX < (2**N) ** (2 ** (CMax + 1))
  1831.       XNorm := XG1;  Unnormalizer := 1.0;  C := CMax + 1;
  1832.       --invariant:  RootOf (XG1) = Unnormalizer * RootOf (XNorm)  &
  1833.       --            1 <= XNorm < (2**N) ** (2**C)
  1834.       --            (see also Power assertion)
  1835.       --bound:  C
  1836.       while  C /= 0  loop
  1837.            C  :=  C - 1;
  1838.            if  XNorm >= Power(C).TwoN
  1839.              then
  1840.             --assert:  RootOf (XNorm)
  1841.             --       = RootOf ((XNorm / Power(C).TwoN) * Power(C).TwoN)
  1842.             --       = RootOf (XNorm / Power(C).TwoN) * Power(C).Two
  1843.             --assert:  Power(C).TwoN <= XNorm < Power(C+1).TwoN
  1844.             --                                = Power(C).TwoN ** 2
  1845.             XNorm  :=  XNorm / Power(C).TwoN;
  1846.             --assert:  1 <= XNorm < Power(C).TwoN
  1847.             Unnormalizer  :=  Unnormalizer * Power(C).Two;
  1848.              end if;
  1849.            -- invariant has been reestablished
  1850.            end loop;
  1851.           --assert:  1 <= XNorm < Power(0).TwoN = 2**N
  1852.           --assert (incidentally):  1 <= RootOf (XNorm) < 2
  1853.  
  1854.       --invariant & bound:  supplied by Isaac Newton
  1855.       RootPrev  :=  2.0;
  1856.       loop
  1857.            Root  :=  (XNorm / (RootPrev ** (N - 1))
  1858.                       + Arith_Type (N - 1) * RootPrev )
  1859.                      / Arith_Type (N) ;
  1860.            exit when  abs (Root - RootPrev) <= Tolerance;
  1861.            RootPrev  :=  Root;
  1862.            end loop;
  1863.       --assert:  abs (Root - RootOf (XNorm) <= Tolerance)
  1864.       --         i.e., Root ~= RootOf (XNorm)
  1865.       return (Sign * ((Root * Unnormalizer) ** Inverter));
  1866.        end if;  -- X = 0.0?
  1867.      end RootOf;
  1868.  
  1869. begin  -- NthRoot body
  1870.  
  1871.      -- make Power assertion true (initialize Power)
  1872.  
  1873.      Power(0).Two  :=  2.0;  Power(0).TwoN  :=  2.0 ** N;
  1874.      
  1875.      CMax  :=  1;
  1876.      begin  -- to catch exceptions
  1877.      for C in CIndex loop  -- escape on exception
  1878.       --assert:  Power(C).TwoN < MaxX
  1879.       Power(C+1).TwoN  :=  Power(C).TwoN ** 2;  --may except
  1880.       Power(C+1).Two   :=  Power(C).Two  ** 2;
  1881.       CMax  :=  C + 1;
  1882.       end loop;
  1883.      -- should never fall out
  1884.      exception
  1885.      when numeric_error     -- on Power(C).TwoN ** 2 > MaxX
  1886.         | constraint_error  -- on C + 1 > CMax
  1887.         =>
  1888.       --assert:  Power(CMax).TwoN > MaxX
  1889.       null;  -- just leave block
  1890.      end;  -- exception block
  1891.      -- Power assertion is true
  1892.  
  1893.      end NthRoot;  -- body
  1894. --------------------------------------------------------------------------------
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904. --------------------------------------------------------------------------------
  1905.  
  1906. -- The purpose of this package is to define an Ada type that has exactly
  1907. -- the operations that are valid for any physical quantity. This package
  1908. -- is then used by the packages that define many physical units. These
  1909. -- packages are used in turn by packages that define operators on physical
  1910. -- units that produce other physical units. Additional packages in this
  1911. -- set provide for outputting of physical units, conversions between
  1912. -- physical units, and other functions needed when working with physical
  1913. -- units.
  1914. --
  1915.  
  1916. package PHYSICAL_REAL is
  1917.  
  1918.   type REAL is private ;
  1919.  
  1920. --                Operators available for all types derived from REAL
  1921. --
  1922. --     implicit :    :=    =     /=
  1923. --
  1924. --
  1925. --             Physical quantities with the same units can be added
  1926. --             preserving their physical units.
  1927.  
  1928.   function "+" ( LEFT , RIGHT : REAL ) return REAL ;
  1929.  
  1930. --             Physical quantities with the same units can be subtracted
  1931. --             preserving their physical units.
  1932.  
  1933.   function "-" ( LEFT , RIGHT : REAL ) return REAL ;
  1934.  
  1935. --             Multiplying a physical quantity by itself does not produce
  1936. --             the same physical quantity and thus must not be allowed.
  1937. --             Multiplying a physical quantity by a non dimensional quantity
  1938. --             does preserve the units of the physical quantity.
  1939.  
  1940.   function "*" ( LEFT : LONG_FLOAT ;
  1941.                  RIGHT : REAL ) return REAL ;
  1942.  
  1943.   function "*" ( LEFT : REAL ;
  1944.                  RIGHT : LONG_FLOAT ) return REAL ;
  1945.  
  1946. --             Dividing a physical quantity by a non dimensional quantity
  1947. --             preserves the units of the physical quantity.
  1948.  
  1949.   function "/" ( LEFT : REAL ;
  1950.                  RIGHT : LONG_FLOAT ) return REAL ;
  1951.  
  1952. --             Dividing a physical quantity by itself produces
  1953. --             a non dimensional value.
  1954.  
  1955.   function "/" ( LEFT , RIGHT : REAL ) return LONG_FLOAT ;
  1956.  
  1957. --               The absolute value of a physical quantity retains the
  1958. --               same physical units.
  1959.  
  1960.   function "abs" ( LEFT : REAL ) return REAL ;
  1961.  
  1962. --             Equality and inequality are implicitly defined. The other
  1963. --             relational operators must be explicitly defined.
  1964.  
  1965.   function "<" ( LEFT , RIGHT : REAL ) return BOOLEAN ;
  1966.  
  1967.   function ">" ( LEFT , RIGHT : REAL ) return BOOLEAN ;
  1968.  
  1969.   function "<=" ( LEFT , RIGHT : REAL ) return BOOLEAN ;
  1970.  
  1971.   function ">=" ( LEFT , RIGHT : REAL ) return BOOLEAN ;
  1972.  
  1973.                                                               --Alstad start
  1974. --             Taking a root of a physical quantity by itself does not produce
  1975. --             the same physical quantity and thus must not be allowed.
  1976.  
  1977.   function SQRT ( LEFT : LONG_FLOAT ) return LONG_FLOAT ;
  1978.  
  1979.   function CUBE_ROOT ( LEFT : LONG_FLOAT ) return LONG_FLOAT ;
  1980.                                                               --Alstad end
  1981.  
  1982.  
  1983. --              The primary purpose of this function for the user is
  1984. --              to make constants into values of a specific physical
  1985. --              unit.
  1986. --              The use of this function in the set of physics packages
  1987. --              is to apply the required Ada type to the result of a
  1988. --              non dimensional computation.
  1989.  
  1990.   function DIMENSION ( LEFT : LONG_FLOAT ) return REAL ;
  1991.  
  1992. --              The use of this function in the set of physics packages
  1993. --              is to take any physical quantity and get a non dimensional
  1994. --              value in the base floating point arithmetic type in order
  1995. --              to preform computation. This should not be needed by users
  1996. --              of the set of physics packages.
  1997.  
  1998.   function UNDIMENSION ( LEFT : REAL ) return LONG_FLOAT ;
  1999.  
  2000. --    For compilers that can make use of INLINE
  2001.  
  2002.   pragma INLINE ( "+" , "-" , "*" , "/" , "abs" , "<" , ">" , "<=" , ">=" ,
  2003.       DIMENSION , UNDIMENSION ) ;
  2004.  
  2005. --
  2006. private
  2007.   type REAL is new LONG_FLOAT ;  
  2008. end PHYSICAL_REAL ;
  2009.  
  2010.   with NthRoot;                                                   --Alstad
  2011. package body PHYSICAL_REAL is
  2012.  
  2013.                                                                  --Alstad start
  2014.   package Square is new NthRoot (N => 2, Arith_Type => LONG_FLOAT);
  2015.   package Cube is new NthRoot (N => 3, Arith_Type => LONG_FLOAT);
  2016.  
  2017.   function SQRT (LEFT : LONG_FLOAT) return LONG_FLOAT
  2018.     is begin
  2019.     return (Square.RootOf (LEFT));
  2020.     end;  -- SQRT
  2021.   function CUBE_ROOT (LEFT : LONG_FLOAT) return LONG_FLOAT
  2022.     is begin
  2023.     return (Cube.RootOf (LEFT));
  2024.     end;  -- SQRT
  2025.  
  2026.   pragma INLINE (SQRT, CUBE_ROOT);
  2027.                                                                  --Alstad end
  2028.  
  2029.   function "+" ( LEFT , RIGHT : REAL ) return REAL is
  2030.  
  2031.   begin
  2032.     return REAL ( LONG_FLOAT( LEFT ) + LONG_FLOAT ( RIGHT )) ;
  2033.   end "+" ;
  2034.  
  2035.   function "-" ( LEFT , RIGHT : REAL ) return REAL is
  2036.  
  2037.   begin
  2038.     return REAL ( LONG_FLOAT( LEFT ) - LONG_FLOAT ( RIGHT )) ;
  2039.   end "-" ;
  2040.  
  2041.   function "*" ( LEFT : LONG_FLOAT ;
  2042.                  RIGHT : REAL ) return REAL is
  2043.  
  2044.   begin
  2045.     return REAL ( LEFT * LONG_FLOAT( RIGHT )) ;
  2046.   end "*" ;
  2047.  
  2048.   function "*" ( LEFT : REAL ;
  2049.                  RIGHT : LONG_FLOAT ) return REAL is
  2050.  
  2051.   begin
  2052.     return REAL ( LONG_FLOAT( LEFT ) * RIGHT) ;
  2053.   end "*" ;
  2054.  
  2055.   function "/" ( LEFT : REAL ;
  2056.                  RIGHT : LONG_FLOAT ) return REAL is
  2057.  
  2058.   begin
  2059.     return REAL ( LONG_FLOAT( LEFT ) / RIGHT) ;
  2060.   end "/" ;
  2061.  
  2062.   function "/" ( LEFT , RIGHT : REAL ) return LONG_FLOAT is
  2063.  
  2064.   begin
  2065.     return LONG_FLOAT ( LEFT ) / LONG_FLOAT ( RIGHT ) ;
  2066.   end "/" ;
  2067.  
  2068.   function "abs" ( LEFT : REAL ) return REAL is
  2069.  
  2070.   begin
  2071.     return REAL ( abs( LONG_FLOAT( LEFT ))) ;
  2072.   end "abs" ;
  2073.  
  2074.   function "<" ( LEFT , RIGHT : REAL ) return BOOLEAN is
  2075.  
  2076.   begin
  2077.     return LONG_FLOAT ( LEFT ) < LONG_FLOAT ( RIGHT ) ;
  2078.   end "<" ;
  2079.  
  2080.   function ">" ( LEFT , RIGHT : REAL ) return BOOLEAN is
  2081.  
  2082.   begin
  2083.     return LONG_FLOAT ( LEFT ) > LONG_FLOAT ( RIGHT ) ;
  2084.   end ">" ;
  2085.  
  2086.   function "<=" ( LEFT , RIGHT : REAL ) return BOOLEAN is
  2087.  
  2088.   begin
  2089.     return LONG_FLOAT ( LEFT ) <= LONG_FLOAT ( RIGHT ) ;
  2090.   end "<=" ;
  2091.  
  2092.   function ">=" ( LEFT , RIGHT : REAL ) return BOOLEAN is
  2093.  
  2094.   begin
  2095.     return LONG_FLOAT ( LEFT ) >= LONG_FLOAT ( RIGHT ) ;
  2096.   end ">=" ;
  2097.  
  2098.   function DIMENSION ( LEFT : LONG_FLOAT ) return REAL is
  2099.  
  2100.   begin
  2101.     return REAL ( LEFT ) ;
  2102.   end DIMENSION ;
  2103.  
  2104.   function UNDIMENSION ( LEFT : REAL ) return LONG_FLOAT is
  2105.  
  2106.   begin
  2107.     return LONG_FLOAT ( LEFT ) ;
  2108.   end UNDIMENSION ;
  2109.  
  2110. end PHYSICAL_REAL ;
  2111.  
  2112. --------------------------------------------------------------------------------
  2113.  
  2114.  
  2115.  
  2116.  
  2117.  
  2118.  
  2119.  
  2120.  
  2121.  
  2122. --------------------------------------------------------------------------------
  2123. with TEXT_IO ; use TEXT_IO ;
  2124. package LONG_FLT_IO is new FLOAT_IO ( LONG_FLOAT ) ;
  2125. --------------------------------------------------------------------------------
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.  
  2134.  
  2135. --------------------------------------------------------------------------------
  2136. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  2137.  
  2138. package PHYSICAL_UNITS_BASIC is
  2139.  
  2140. -- This package specification defines Ada types for physical
  2141. -- quantities. A number of other packages use this package
  2142. -- specification in order to provide a comprehensive dimension
  2143. -- checking and units conversion system.
  2144. --
  2145. --              PHYSICAL QUANTITIES AND THEIR ASSOCIATED DIMENSIONS
  2146. --
  2147. --   Errors can occur in writing equations to solve problems in classical
  2148. --physics. Many of these errors can be prevented by performing a dimensionality
  2149. --check on the equations. All physical quantities have a fundamental dimension
  2150. --that is independent of the units of measurement. The basic physical dimensions
  2151. --are: length, mass, time, electrical charge, temperature and luminous intens-
  2152. --ity.There are a number of systems of units for measuring physical quantities.
  2153. --The MKS system is based on meter, kilogram, second  measurement.
  2154. --The CGS system is based on centimeter, gram, second  measurement.
  2155. --The English system is based on feet, pound, second  measurement.
  2156. --A few physical dimensions and the associated measurement unit in 
  2157. --these three systems are :
  2158. --
  2159. --
  2160. --      Physical Quantity                           Unit System
  2161. --        Dimension                         MKS         CGS          English
  2162. --
  2163. --        length                            meter       centimeter   feet
  2164. --
  2165. --        mass                              kilogram    gram         pound mass
  2166. --
  2167. --        time                              second      second       second
  2168. --
  2169. --        force                             newton      dyne         poundal
  2170. --
  2171. --        energy                            joule       erg          B.t.u.
  2172. --
  2173. --
  2174. --   The checking of a physical equation has two aspects. The first is to check
  2175. --the dimensionality. The dimensionality is independent of the unit system. The
  2176. --second is to check that a consistent system of units is used in the equation.
  2177. --   An example of a dimensionality check is using the basic equation F=ma to
  2178. --determine that force has the dimension  mass x length / time squared, then
  2179. --              2
  2180. --check if  F=mv /r  is dimensionally correct. The check is performed by 
  2181. --expanding the dimensions, e.g.  mass x (length/time) x (length/time) / length.
  2182. --with the dimensions expected for force from the basic equation F=ma. As
  2183. --expected, centripetal force has the same dimensionality as the force from
  2184. --Newton's second law of motion.
  2185. --
  2186. --                    THE ALGEBRA OF DIMENSIONALITY
  2187. --
  2188. --   The dimension of any physical quantity can be written as
  2189. --
  2190. --                  a   b   c   d   e   f
  2191. --                 L   M   T   Q   C   K
  2192. --
  2193. --where a,b,c,d,e and f are integers such as -4, -3, -2 , -1, 0, 1, 2, 3, 4
  2194. --and L is length, M is mass, T is time, Q is charge, C is luminous intensity
  2195. --and K is temperature. An exponent of zero means the dimension does not apply
  2196. --to the physical quantity. The normal rules of algebra for exponents apply
  2197. --for combining dimensions.
  2198. --
  2199. --   In order to add or subtract two physical quantities the quantities must
  2200. --have the same dimension. The resulting physical quantity has the same
  2201. --dimensions. Physical quantities with the same dimension in different
  2202. --systems of units can be added or subtracted by multiplying one of
  2203. --the quantities by a units conversion factor to obtain compatible units.
  2204. --
  2205. --   The multiplication of two physical quantities results in a new physical
  2206. --quantity that has the sum of the exponents of the dimensions of the initial
  2207. --two quantities.
  2208. --
  2209. --   The division of one physical quantity by another results in a new physical
  2210. --quantity that has the dimension of the exponents of the first quantity minus
  2211. --the exponents of the second quantity.
  2212. --
  2213. --   Taking the square root of a physical quantity results in a new physical
  2214. --quantity having a dimension with exponents half of the initial dimension.
  2215. --
  2216. --   Raising a physical quantity to a power results in a new physical quantity
  2217. --having a dimension with the exponents multiplied by the power.
  2218. --
  2219. --                                     2                2  2    2 -2
  2220. --          e.g. v has dimension L/T, v  has dimension L /T or L T
  2221. --
  2222. --   The derivative of a physical quantity with respect to another physical
  2223. --quantity results in a new physical quantity with the exponents of the
  2224. --first dimension minus the exponents of the other dimension.
  2225. --         e.g.  v has dimension L/T, t has dimension T,
  2226. --
  2227. --                                           2
  2228. --               then dv/dt has dimension L/T
  2229. --
  2230. --   The integral of a physical quantity over the range of another physical
  2231. --quantity results in a new physical quantity that has a dimension with the
  2232. --sum of the exponents of the two quantities.
  2233. --        
  2234. --         e.g.  v has dimension L/T, t has dimension T,
  2235. --               then  integral v dt  has dimension  L/T * T or L
  2236. --
  2237. --
  2238. -- The initial thought was to have metric units and English units
  2239. -- in separate package specifications. This proved inpractical
  2240. -- because time in seconds is both metric and English. Many other
  2241. -- units such as watt of power and Farad of capacitance are in
  2242. -- both systems. A further impracticallity arose when considering
  2243. -- the design of a units system conversion package. e.g. A package
  2244. -- that would provide accurate conversion form meters to inches
  2245. -- to micrometers to light years. The one package specification became
  2246. -- so large that it was inefficient, so, in order to keep the size
  2247. -- reasonable, three packages were created. The basic units, the
  2248. -- mechanical units and the electrical units. Then a package
  2249. -- called other units came into existance for pragmatic reasons.
  2250. --
  2251. -- Notice that there is not a type called LENGTH because
  2252. -- adding length in meters to length in feet is not allowed.
  2253. -- Even LENGTH_METRIC and LENGTH_ENGLISH are not acceptable
  2254. -- because meters can not be added to centimeters and inches can
  2255. -- not be added to feet. Further complication arises because of
  2256. -- seconds of time and seconds of arc. There can be ounces of
  2257. -- milk ( liquid measure ) and ounces of sugar ( weight measure ).
  2258. -- There can be quarts of milk and quarts of strawberries ( dry
  2259. -- measure ). Thus the decision was made that every Ada type
  2260. -- would be a dimension name followed by a unit name.
  2261. --
  2262. -- Now, more choices had to be made. Unit names such as 
  2263. --  DENSITY_KILOGRAM_PER_CUBIC_METER or DENSITY_TONS_PER_CUBIC_YARD
  2264. -- start getting long and there are many combinations. The number
  2265. -- of combinations for density are all the units of mass times all
  2266. -- the units of volume. Thus a subset of all possible units was
  2267. -- chosen with the additional short hand notation of _MKS for
  2268. -- the meter, kilogram, second system of units and the _ENGLISH for
  2269. -- the foot, pound, second system. Additional qualifiers are added
  2270. -- to clarify such as VOLUME_QUART_LIQUID and VOLUME_QUART_DRY.
  2271. --
  2272. -- Some other compromises were made:
  2273. --       Only a few units were entered as both singular and plural.
  2274. --       The choice of names is the authors. A committee could expand
  2275. --       the list. For example a meter can be a length or a distance,
  2276. --       length is used as the type and distance is a subtype.
  2277. --       A user may provide additional local subtype names for units 
  2278. --       and thus has the full capability for alternate type names.
  2279. --
  2280. --   The comments below are organized to present the physical quantity name with
  2281. --associated information. The second column is one of the typical symbols used
  2282. --for the physical quantity. The third column is the dimension of the physical
  2283. --quantity expressed in terms of the fundamental dimensions. The fourth column
  2284. --is the name of the unit in the MKS measurement system. The fifth column
  2285. --is the typical MKS unit equation. An independent table presents conversion
  2286. --factors from the MKS measurement system to other measurement systems.
  2287. --   Physics developed over a period of many years by many people from a variety
  2288. --of disciplines. Thus, there is ambiguity and duplication of symbols.
  2289. -- 
  2290. --
  2291. --PHYSICAL QUANTITY         SYMBOL  DIMENSION   MEASUREMENT UNIT  UNIT EQUATION
  2292. --_________________         ______  _________   ________________  ______________
  2293. --
  2294. --
  2295. --                                  BASIC UNITS
  2296. --
  2297. --length                     s       L           meter              m
  2298. --wave length                lambda  "             "                "
  2299. --
  2300.   type LENGTH_MKS is new REAL ;
  2301.   subtype LENGTH_METER is LENGTH_MKS ;
  2302.   subtype LENGTH_METERS is LENGTH_MKS ;  -- This could be done for every type
  2303.   subtype DISTANCE_METER is LENGTH_MKS ;  -- with plurals and alias and
  2304.   subtype DISTANCE_METERS is LENGTH_MKS ;  -- plurals for the alias
  2305.   subtype WAVE_LENGTH_MKS is LENGTH_MKS ;
  2306.   subtype WAVE_LENGTH_METER is LENGTH_MKS ;
  2307.   type LENGTH_ENGLISH is new REAL ;
  2308.   subtype LENGTH_FOOT is LENGTH_ENGLISH ;
  2309.   subtype LENGTH_FEET is LENGTH_ENGLISH ;
  2310.   type LENGTH_PICOMETER is new REAL ;
  2311.   type LENGTH_NANOMETER is new REAL ;
  2312.   type LENGTH_MICROMETER is new REAL ;
  2313.   type LENGTH_MILLIMETER is new REAL ;
  2314.   type LENGTH_CENTIMETER is new REAL ;
  2315.   type LENGTH_DECIMETER is new REAL ;
  2316.   type LENGTH_DECAMETER is new REAL ;
  2317.   type LENGTH_HECTOMETER is new REAL ;
  2318.   type LENGTH_KILOMETER is new REAL ;
  2319.   type LENGTH_MEGAMETER is new REAL ;
  2320.   type LENGTH_GIGAMETER is new REAL ;
  2321.   type LENGTH_ANGSTROM is new REAL ;
  2322.   type LENGTH_MIL is new REAL ;
  2323.   type LENGTH_INCH is new REAL ;
  2324.   type LENGTH_YARD is new REAL ;
  2325.   type LENGTH_FATHOM is new REAL ;
  2326.   type LENGTH_ROD is new REAL ;
  2327.   type LENGTH_CHAIN_SURVEYOR is new REAL ;
  2328.   type LENGTH_CHAIN_ENGINEER is new REAL ;
  2329.   type LENGTH_FURLONG is new REAL ;
  2330.   type LENGTH_MILE is new REAL ;
  2331.   subtype LENGTH_MILE_STATUTE is LENGTH_MILE ;
  2332.   type LENGTH_MILE_NAUTICAL is new REAL ;
  2333.   type LENGTH_LEAGUE_LAND is new REAL ;
  2334.   type LENGTH_LEAGUE_MARINE is new REAL ;
  2335.   type LENGTH_LIGHT_YEAR is new REAL ;
  2336.  
  2337. --
  2338. --mass                       m       M           kilogram           Kg
  2339. --
  2340.   type MASS_MKS is new REAL ;
  2341.   subtype MASS_KILOGRAM is MASS_MKS ;
  2342.   type MASS_ENGLISH is new REAL ;
  2343.   subtype MASS_POUND is MASS_ENGLISH ;
  2344.   subtype MASS_POUND_AVDP is MASS_ENGLISH ;
  2345.   type MASS_POUND_TROY is new REAL ;
  2346.   subtype MASS_POUND_APOTHECARY is MASS_POUND_TROY ;
  2347.   type MASS_MILLIGRAM is new REAL ;
  2348.   type MASS_GRAM is new REAL ;
  2349.   type MASS_GRAIN is new REAL ; -- same inall English systems
  2350.   type MASS_PENNYWEIGHT_TROY is new REAL ;
  2351.   type MASS_CARAT_TROY is new REAL ;
  2352.   type MASS_SCRUPLE is new REAL ;
  2353.   type MASS_DRAM_AVDP is new REAL ;
  2354.   type MASS_OUNCE_AVDP is new REAL ;
  2355.   type MASS_OUNCE_TROY is new REAL ;
  2356.   type MASS_TON_SHORT is new REAL ;
  2357.   type MASS_TON_LONG is new REAL ;
  2358.   type MASS_TON_METRIC is new REAL ;
  2359.  
  2360. --
  2361. --time                       t       T           second             sec
  2362. --
  2363.   type TIME_SECOND is new REAL ;
  2364.   subtype TIME_SECONDS is TIME_SECOND ;
  2365.   type TIME_PICOSECOND is new REAL ;
  2366.   type TIME_NANOSECOND is new REAL ;
  2367.   type TIME_MICROSECOND is new REAL ;
  2368.   type TIME_MILLISECOND is new REAL ;
  2369.   type TIME_CENTISECOND is new REAL ;
  2370.   type TIME_KILOSECOND is new REAL ;
  2371.   type TIME_MEGASECOND is new REAL ;
  2372.   type TIME_GIGASECOND is new REAL ;
  2373.   type TIME_MINUTE is new REAL ;
  2374.   type TIME_HOUR is new REAL ;
  2375.   type TIME_DAY is new REAL ;
  2376.   type TIME_FORTNIGHT is new REAL ;
  2377.   type TIME_MONTH is new REAL ;
  2378.   type TIME_YEAR is new REAL ;
  2379.   type TIME_DECADE is new REAL ;
  2380.   type TIME_CENTURY is new REAL ;
  2381.   type TIME_MILLENNIA is new REAL ;
  2382.  
  2383. --
  2384. --electric charge            q       Q           coulomb            c
  2385. --  electric flux
  2386. --
  2387.   type CHARGE_COULOMB is new REAL ;
  2388.   subtype CHARGE_AMPERE_SECOND is CHARGE_COULOMB ;
  2389.   type CHARGE_AMPERE_HOURS is new REAL ;
  2390.   type CHARGE_ELECTRON is new REAL ;
  2391.   type CHARGE_FARADAY is new REAL ;
  2392.  
  2393. --
  2394. --luminous intensity         I       C           candle             cd
  2395. --
  2396.   type LUMINOUS_INTENSITY_CANDLE is new REAL ;
  2397.  
  2398. --                                                                  o
  2399. --temperature                T       K           degree kelvin       K
  2400. --
  2401.   type TEMPERATURE_KELVIN is new real ;
  2402.   type TEMPERATURE_CENTIGRADE is new REAL ;
  2403.   subtype TEMPERATURE_CELSIUS is TEMPERATURE_CENTIGRADE ;
  2404.   type TEMPERATURE_FARENHEIT is new REAL ;
  2405.  
  2406. --
  2407. --angle                      theta   none        radian             none
  2408. --
  2409.   type ANGLE_RADIAN is new REAL ;
  2410.   subtype ANGLE_RADIANS is ANGLE_RADIAN ;
  2411.   subtype PLANE_ANGLE_RADIANS is ANGLE_RADIAN ;
  2412.   type ANGLE_SECOND is new REAL ;
  2413.   type ANGLE_MINUTE is new REAL ;
  2414.   type ANGLE_DEGREE is new REAL ;
  2415.   type ANGLE_REVOLUTION is new REAL ;
  2416.   type ANGLE_BAM is new REAL ;
  2417.  
  2418. --
  2419. --solid angle                phi     none        steradian          none
  2420. --
  2421.   type SOLID_ANGLE_STERADIAN is new REAL ;
  2422. --
  2423. end PHYSICAL_UNITS_BASIC ;
  2424. --------------------------------------------------------------------------------
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434. --------------------------------------------------------------------------------
  2435. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  2436.  
  2437. package PHYSICAL_UNITS_MECHANICAL is
  2438.  
  2439. -- This package specification defines Ada types for physical
  2440. -- quantities generally in the mechanical context.
  2441. --
  2442. -- This package is the logical continuation of PHYSICAL_UNITS_BASIC
  2443. --
  2444. --
  2445. --                                 DERIVED MECHANICAL UNITS
  2446. --
  2447. --
  2448. --                                    2                              2
  2449. --area                       A       L           square meter       m
  2450. --
  2451.   type AREA_MKS is new REAL ;
  2452.   subtype AREA_SQUARE_METER is AREA_MKS ;
  2453.   subtype AREA_SQUARE_METERS is AREA_MKS ;
  2454.   type AREA_ENGLISH is new REAL ;
  2455.   subtype AREA_SQUARE_FEET is AREA_ENGLISH ;
  2456.   subtype AREA_SQUARE_FOOT is AREA_ENGLISH ;
  2457.   type AREA_SQUARE_CENTIMETER is new REAL ;
  2458.   type AREA_SQUARE_KILOMETER is new REAL ;
  2459.   type AREA_SQUARE_INCH is new REAL ;
  2460.   type AREA_SQUARE_YARD is new REAL ;
  2461.   type AREA_SQUARE_MILE is new REAL ;
  2462.   type AREA_ACRE is new REAL ;
  2463.   type AREA_CIRCULAR_MIL is new REAL ;
  2464.   type AREA_HECTARE is new REAL ;
  2465.   type AREA_TOWNSHIP is new REAL ;
  2466.  
  2467. --
  2468. --                                    3                              3
  2469. --volume                     V       L           stere              m
  2470. --
  2471.   type VOLUME_MKS is new REAL ;
  2472.   subtype VOLUME_STERE is VOLUME_MKS ;
  2473.   subtype VOLUME_CUBIC_METER is VOLUME_MKS ;
  2474.   type VOLUME_ENGLISH is new REAL ;
  2475.   subtype VOLUME_CUBIC_FEET is VOLUME_ENGLISH ;
  2476.   type VOLUME_MILLILITER is new REAL ;
  2477.   type VOLUME_LITER is new REAL ;
  2478.   type VOLUME_KILOLITER is new REAL ;
  2479.   type VOLUME_CUBIC_CENTIMETER is new REAL ;
  2480.   type VOLUME_CUBIC_INCH is new REAL ;
  2481.   type VOLUME_CUBIC_YARD is new REAL ;
  2482.   type VOLUME_CUBIC_MILE is new REAL ;
  2483.   type VOLUME_TEASPOON is new REAL ;
  2484.   type VOLUME_TABLESPOON is new REAL ;
  2485.   type VOLUME_OUNCE_FLUID is new REAL ;
  2486.   type VOLUME_JIGGER is new REAL ;
  2487.   type VOLUME_CUP is new REAL ;
  2488.   type VOLUME_PINT_LIQUID is new REAL ;
  2489.   type VOLUME_QUART_LIQUID is new REAL ;
  2490.   type VOLUME_GALLON is new REAL ;
  2491.   type VOLUME_KEG is new REAL ;
  2492.   type VOLUME_BARREL is new REAL ;
  2493.   type VOLUME_PINT_DRY is new REAL ;
  2494.   type VOLUME_QUART_DRY is new REAL ;
  2495.   type VOLUME_PECK is new REAL ;
  2496.   type VOLUME_BUSHEL is new REAL ;
  2497.   type VOLUME_CORD is new REAL ;
  2498.  
  2499. --
  2500. --velocity                   v       L/T         meter per second   m/sec
  2501. --
  2502.   type VELOCITY_MKS is new REAL ;
  2503.   subtype VELOCITY_METER_PER_SECOND is VELOCITY_MKS ;
  2504.   type VELOCITY_ENGLISH is new REAL ;
  2505.   subtype VELOCITY_FEET_PER_SECOND is VELOCITY_ENGLISH ;
  2506.   type VELOCITY_CENTIMETER_PER_SECOND is new REAL ;
  2507.   type VELOCITY_KILOMETER_PER_HOUR is new REAL ;
  2508.   type VELOCITY_INCHES_PER_SECOND is new REAL ;
  2509.   type VELOCITY_MILE_PER_HOUR is new REAL ;
  2510.   type VELOCITY_MILES_PER_SECOND is new REAL ;
  2511.   type VELOCITY_INCHES_PER_MINUTE is new REAL ;
  2512.   type VELOCITY_FEET_PER_MINUTE is new REAL ;
  2513.   type VELOCITY_MILES_PER_HOUR is new REAL ;
  2514.   type VELOCITY_KNOTS is new REAL ;
  2515.   type VELOCITY_FURLONG_PER_FORTNIGHT is new REAL ;
  2516.  
  2517. --
  2518. --angular velocity           omega   1/T         radians per second 1/sec
  2519. --
  2520.   type ANGULAR_VELOCITY is new REAL ;
  2521.   subtype ANGULAR_VELOCITY_RADIANS_PER_SECOND is ANGULAR_VELOCITY ;
  2522.   type ANGULAR_VELOCITY_DEGREES_PER_SECOND is new REAL ;
  2523.   type ANGULAR_VELOCITY_REVOLUTIONS_PER_MINUTE is new REAL ;
  2524.   type ANGULAR_VELOCITY_REVOLUTIONS_PER_SECOND is new REAL ;
  2525.  
  2526. --
  2527. --                                      2                                2
  2528. --acceleration               a       L/T         meter per second   m/sec
  2529. --                                               squared
  2530. --
  2531.   type ACCELERATION_MKS is new REAL ;
  2532.   subtype ACCELERATION_METER_PER_SECOND_SQUARED is ACCELERATION_MKS ;
  2533.   type ACCELERATION_ENGLISH is new REAL ;
  2534.   subtype ACCELERATION_FEET_PER_SECOND_SQUARED is ACCELERATION_ENGLISH ;
  2535.  
  2536. --
  2537. --                                      2                                2
  2538. --angular acceleration       alpha   1/T         radians per        1/sec
  2539. --                                               square second
  2540. --
  2541.   type ANGULAR_ACCELERATION is new REAL ;
  2542.   subtype ANGULAR_ACCELERATION_RADIANS_PER_SECOND_SQUARED is 
  2543.                  ANGULAR_ACCELERATION ;
  2544.   type ANGULAR_ACCELERATION_REVOLUTIONS_PER_MINUTE_SQUARED is new REAL ;
  2545.  
  2546. --
  2547. --                                       2                                  2
  2548. --force                      F       ML/T        newton             Kg m/sec
  2549. --
  2550.   type FORCE_MKS is new REAL ;
  2551.   subtype FORCE_NEWTON is FORCE_MKS ;
  2552.   subtype FORCE_KILOGRAM_METER_PER_SECOND_SQUARED is FORCE_MKS ;
  2553.   type FORCE_DYNE is new REAL ;
  2554.   type FORCE_ENGLISH is new REAL ;
  2555.   subtype FORCE_POUNDAL is FORCE_ENGLISH ;
  2556.   subtype FORCE_POUND_FOOT_PER_PER_SECOND_SQUARED is FORCE_ENGLISH ;
  2557.  
  2558. --
  2559. --                                     2  2                             2    2
  2560. --energy                     E       ML /T       joule              Kg m /sec
  2561. --work                       W         "           "                   "
  2562. --heat                       Q         "           "                   "
  2563. --torque (moment)            T         "         newton meter          "
  2564. --
  2565.   type ENERGY_MKS is new REAL ;
  2566.   subtype WORK_MKS is ENERGY_MKS ;
  2567.   subtype HEAT_MKS is ENERGY_MKS ;
  2568.   subtype TORQUE_MKS is ENERGY_MKS ;
  2569.   subtype ENERGY_JOULE is ENERGY_MKS ;
  2570.   subtype ENERGY_NEWTON_METER is ENERGY_MKS ;
  2571.   subtype ENERGY_KILOGRAM_METER_SQUARED_PER_SECOND_SQUARED is ENERGY_MKS ;
  2572.   type ENERGY_ERG is new REAL ;
  2573.   type ENERGY_GRAM_CALORIE is new REAL ;
  2574.   type ENERGY_KILOGRAM_CALORIE is new REAL ;
  2575.   type ENERGY_ENGLISH is new REAL ;
  2576.   subtype ENERGY_B_T_U is ENERGY_ENGLISH ;
  2577.   type ENERGY_FOOT_POUND is new REAL ;
  2578.   type ENERGY_KILOWATT_HOUR is new REAL ;
  2579.   type ENERGY_HORSEPOWER_HOUR is new REAL ;
  2580.  
  2581. --
  2582. --                                     2  3                        
  2583. --power                      P       ML /T       watt               joule/sec
  2584. --
  2585.   type POWER_MKS is new REAL ;
  2586.   subtype POWER_WATT is POWER_MKS ;
  2587.   subtype POWER_JOULE_PER_SECOND is POWER_MKS ;
  2588.   subtype POWER_VOLT_AMPERE is POWER_MKS ;
  2589.   type POWER_KILOGRAM_CALORIE_PER_SECOND is new REAL ;
  2590.   type POWER_KILOGRAN_CALORIE_PER_MINUTE is new REAL ;
  2591.   type POWER_HORSEPOWER_MECHANICAL is new REAL ;
  2592.   type POWER_HORSEPOWER_ELECTRICAL is new REAL ;
  2593.   type POWER_HORSEPOWER_METRIC is new REAL ;
  2594.   type POWER_HORSEPOWER_BOILER is new REAL ;
  2595.   type POWER_B_T_U_PER_MINUTE is new REAL ;
  2596.   type POWER_B_T_U_PER_HOUR is new REAL ;
  2597.   type POWER_FOOT_POUND_PER_MINUTE is new REAL ;
  2598.   type POWER_FOOT_POUND_PER_SECOND is new REAL ;
  2599.  
  2600. --
  2601. --                                      3                               3
  2602. --density                    D       M/L         kilogram per       Kg/m
  2603. --                                               cubic meter
  2604. --
  2605.   type DENSITY_MKS is new REAL ;
  2606.   subtype DENSITY_KILOGRAM_PER_CUBIC_METER is DENSITY_MKS ;
  2607.   type DENSITY_ENGLISH is new REAL ;
  2608.   subtype DENSITY_POUND_PER_CUBIC_FOOT is DENSITY_ENGLISH ;
  2609.  
  2610. --
  2611. --                                    3                              3
  2612. --flow rate                  f       L /T        cubic meter per    m /sec
  2613. --                                               second
  2614. --
  2615.   type FLOW_RATE_MKS is new REAL ;
  2616.   subtype FLOW_RATE_CUBIC_METER_PER_SECOND is FLOW_RATE_MKS ;
  2617.   type FLOW_RATE_ENGLISH is new REAL ;
  2618.   subtype FLOW_RATE_CUBIC_FEET_PER_SECOND is FLOW_RATE_ENGLISH ;
  2619.   type FLOW_RATE_GALLON_PER_MINUTE is new REAL ;
  2620.   type FLOW_RATE_CUBIC_FEET_PER_MINUTE is new REAL ;
  2621.  
  2622. --
  2623. --                                       2                                  2
  2624. --pressure                   P       M/LT        pascal             Kg/m sec
  2625. -- stress                                        newton per
  2626. -- energy density                                square meter
  2627. --
  2628.   type PRESSURE_MKS is new REAL ;
  2629.   subtype PRESSURE_PASCAL is PRESSURE_MKS ;
  2630.   subtype PRESSURE_NEWTON_PER_SQUARE_METER is PRESSURE_MKS ;
  2631.   subtype PRESSURE_FORCE_PER_AREA_MKS is PRESSURE_MKS ;
  2632.   subtype PRESSURE_JOULE_PER_CUBIC_METER is PRESSURE_MKS ;
  2633.   subtype PRESSURE_ENERGY_DENSITY_MKS is PRESSURE_MKS ;
  2634.   type PRESSURE_ENGLISH is new REAL ;
  2635.   subtype PRESSURE_POUND_PER_SQUARE_FOOT is PRESSURE_ENGLISH ;
  2636.   type PRESSURE_TON_PER_SQUARE_FOOT is new REAL ;
  2637.   type PRESSURE_ATMOSPHERE_STANDARD is new REAL ;
  2638.   type PRESSURE_FEET_OF_WATER is new REAL ;
  2639.   type PRESSURE_INCHES_OF_MERCURY is new REAL ;
  2640.   type PRESSURE_MILLIMETER_OF_MERCURY is new REAL ;
  2641.   type PRESSURE_BAR is new REAL ;
  2642.   type PRESSURE_MILLIBAR is new REAL ;
  2643.   type PRESSURE_TORR is new REAL ;
  2644.  
  2645. --
  2646. --momentum                   p       ML/T        newton second       Kg m/sec
  2647. --
  2648.   type MOMENTUM_MKS is new REAL ;
  2649.   subtype MOMENTUM_NEWTON_SECOND is MOMENTUM_MKS ;
  2650.   subtype MOMENTUM_KILOGRAM_METER_PER_SECOND is MOMENTUM_MKS ;
  2651.  
  2652. --
  2653. --                                     2                                2
  2654. --inertia                    I       ML /T       joule second       Kg m /sec
  2655. --
  2656.   type INERTIA_MKS is new REAL ;
  2657.   subtype INERTIA_JOULE_SECOND is INERTIA_MKS ;
  2658.   subtype INERTIA_KILOGRAM_METER_SQUARED_PER_SECOND is INERTIA_MKS ;
  2659.  
  2660. --
  2661. --                                     2                                2
  2662. --moment of inertia          M       ML          kilogram           Kg m 
  2663. --                                               meter squared
  2664. --
  2665.   type MOMENT_OF_INERTIA_MKS is new REAL ;
  2666.   subtype MOMENT_OF_INERTIA_KILOGRAM_METER_SQUARED is MOMENT_OF_INERTIA_MKS ;
  2667.  
  2668. --
  2669. --                                    2                                2
  2670. --kinematic viscosity        v       M /T        kilogram squared    Kg /sec 
  2671. --                                               per second
  2672. --
  2673.   type KINEMATIC_VISCOSITY_MKS is new REAL ;
  2674.   subtype KINEMATIC_VISCOSITY_KILOGRAM_SQUARED_PER_SECOND is 
  2675.           KINEMATIC_VISCOSITY_MKS ;
  2676. --
  2677. --dynamic viscosity          d       M/LT        newton second       Kg/m sec 
  2678. --                                               per square meter
  2679. --
  2680.   type DYNAMIC_VISCOSITY_MKS is new REAL ;
  2681.   subtype DYNAMIC_VISCOSITY_NEWTON_PER_SQUARE_METER is DYNAMIC_VISCOSITY_MKS ;
  2682.   subtype DYNAMIC_VISCOSITY_KILOGRAM_PER_METER_SECOND is DYNAMIC_VISCOSITY_MKS ;
  2683. --
  2684. --
  2685. --luminous flux              phi     C           lumen (4Pi candle   cd sr 
  2686. --                                               for point source)
  2687. --
  2688.   type LUMINOUS_FLUX_LUMEN is new REAL ;
  2689.  
  2690. --
  2691. --                                      2                                   2
  2692. --illumination               E       C/L         lumen per           cd sr/m
  2693. --                                               square meter
  2694. --
  2695.   type ILLUMINATION_MKS is new REAL ;
  2696.   subtype ILLUMINATION_LUMEN_PER_SQUARE_METER is ILLUMINATION_MKS ;
  2697.  
  2698. --
  2699. --                                      2                                 2
  2700. --luminance                  l       C/L         lux                  cd/m
  2701. --                                               square meter
  2702. --
  2703.   type LUMINANCE_MKS is new REAL ;
  2704.   subtype LUMINANCE_LUX is LUMINANCE_MKS ;
  2705.   subtype LUMINANCE_CANDLE_PER_SQUARE_METER is LUMINANCE_MKS ;
  2706.  
  2707. --
  2708. --
  2709. --                                     2  2                             2 
  2710. --entropy                    S       ML /T K     joule per degree   Kg m /
  2711. --                                                                      2 o
  2712. --                                                                   sec   K
  2713. --
  2714.   type ENTROPY_MKS is new REAL ;
  2715.   subtype SPECIFIC_HEAT_MKS is ENTROPY_MKS ;
  2716.   subtype SPECIFIC_HEAT_JOULE_PER_DEGREE_KELVIN is ENTROPY_MKS ;
  2717.   type SPECIFIC_HEAT_B_T_U_PER_POUND_DEGREE_FARENHEIT is new REAL ;
  2718.  
  2719. --
  2720. end PHYSICAL_UNITS_MECHANICAL ;
  2721. --------------------------------------------------------------------------------
  2722.  
  2723.  
  2724.  
  2725.  
  2726.  
  2727.  
  2728.  
  2729.  
  2730.  
  2731. --------------------------------------------------------------------------------
  2732. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  2733.  
  2734. package PHYSICAL_UNITS_ELECTRICAL is
  2735.  
  2736. -- This package specification defines Ada types for physical
  2737. -- quantities related to electrical units. It ia a logical
  2738. -- extension of PHYSICAL_UNITS_MECHANICAL .
  2739. --
  2740. --
  2741. --
  2742. --                                  DERIVED ELECTRICAL
  2743. --
  2744. --electric current           I       Q/T         ampere             c/sec
  2745. --  magnetomotive force
  2746.  
  2747.   type CURRENT_AMPERE is new REAL ;
  2748.   type CURRENT_MILLIAMPERE is new REAL ;
  2749.   type CURRENT_MICROAMPERE is new REAL ;
  2750.   type CURRENT_ABAMPERE is new REAL ;
  2751.   type CURRENT_STATAMPERE is new REAL ;
  2752.  
  2753. --
  2754. --                                     2  2                             2    2
  2755. --voltage                    E       ML /T Q     volt               Kg m /sec c
  2756. --  potential difference
  2757. --  electromotive force
  2758.  
  2759.   type VOLTAGE_VOLT is new REAL ;
  2760.   type VOLTAGE_MILLIVOLT is new REAL ;
  2761.   type VOLTAGE_MICROVOLT is new REAL ;
  2762.   type VOLTAGE_KILOVOLT is new REAL ;
  2763.  
  2764. --
  2765. --                                     2   2                            2      2
  2766. --electric resistance        R       ML /TQ      ohm                Kg m /sec c
  2767. --
  2768.   type RESISTANCE_OHM is new REAL ;
  2769.   type RESISTANCE_MILLIOHM is new REAL ;
  2770.   type RESISTANCE_KILOHM is new REAL ;
  2771.   type RESISTANCE_MEGOHM is new REAL ;
  2772.  
  2773. --
  2774. --                                     3   2                            3      2
  2775. --electric resistivity       rho     ML /TQ     ohm meter           Kg m /sec c
  2776. --
  2777.   type RESISTIVITY_OHM_METER is new REAL ;
  2778.  
  2779. --
  2780. --                                     2   2                             2     2
  2781. --electric conductance       G       TQ /ML      mho                sec c /Kg m
  2782. --
  2783.   type CONDUCTANCE_MHO is new REAL ;
  2784.  
  2785. --
  2786. --                                     2   3                             2     3
  2787. --conductivity               sigma   TQ /ML      mho per meter      sec c /Kg m
  2788. --
  2789.   type CONDUCTIVITY_MHO_PER_METER is new REAL ;
  2790.  
  2791. --
  2792. --
  2793. --                                    2 2   2                          2 2     2
  2794. --capacitance                C       T Q /ML     farad              sec c /Kg m
  2795. --
  2796.   type CAPACITANCE_FARAD is new REAL ;
  2797.   type CAPACITANCE_MICROFARAD is new REAL ;
  2798.   type CAPACITANCE_PICOFARAD is new REAL ;
  2799.  
  2800. --
  2801. --
  2802. --                                     2  2                             2  2
  2803. --inductance                 L       ML /Q       henry              Kg m /c
  2804. --                                               weber per ampere
  2805. --                                               volt second per ampere
  2806.  
  2807. --
  2808.   type INDUCTANCE_HENRY is new REAL ;
  2809.   type INDUCTANCE_MILLIHENRY is new REAL ;
  2810.   type INDUCTANCE_MICROHENRY is new REAL ;
  2811.  
  2812. --
  2813. --                                       2                                 2
  2814. --current density            J       Q/TL        ampere per         c/sec m
  2815. --                                               square meter
  2816. --
  2817.   type CURRENT_DENSITY_AMPERE_PER_SQUARE_METER is new REAL ;
  2818.  
  2819. --
  2820. --                                      3                              3
  2821. --charge density             rho     Q/L         coulomb per        c/m
  2822. --                                               cubic meter
  2823. --
  2824.   type CHARGE_DENSITY_COULOMB_PER_CUBIC_METER is new REAL ;
  2825.  
  2826. --                                     2                                2
  2827. --magnetic flux              F       ML /TQ      weber              Kq m /sec c
  2828. --                                               volt second
  2829. --
  2830.   type MAGNETIC_FLUX_WEBER is new REAL ;
  2831.  
  2832. --
  2833. --magnetic flux density,     B       M/TQ        tesla              Kq/sec c
  2834. --   magnetic induction                          weber per square meter
  2835. --
  2836.   type MAGNETIC_FLUX_DENSITY is new REAL ;
  2837.   subtype MAGNETIC_FLUX_DENSITY_TESLA is MAGNETIC_FLUX_DENSITY ;
  2838.   subtype MAGNETIC_FLUX_DENSITY_WEBER_PER_SQUARE_METER is
  2839.           MAGNETIC_FLUX_DENSITY ;
  2840.  
  2841. --
  2842. --magnetic intensity         H       Q/LT        ampere per meter   c/m sec
  2843. --  magnetic field strength
  2844. --
  2845.   type MAGNETIC_INTENSITY is new REAL ;
  2846.   subtype MAGNETIC_INTENSITY_AMPERE_PER_METER is MAGNETIC_INTENSITY ;
  2847.  
  2848. --
  2849. --
  2850. --magnetic vector potential  A       ML/TQ       weber/meter        Kg m/sec c
  2851. --
  2852.   type MAGNETIC_VECTOR_POTENTIAL_WEBER_PER_METER is new REAL ;
  2853.  
  2854. --
  2855. --                                       2                                  2
  2856. --electric field intensity   E       ML/T Q      volt/meter         Kg m/sec c
  2857. --  electric field strength                      newton per coulomb
  2858. --
  2859.   type ELECTRIC_FIELD is new REAL ;
  2860.   subtype ELECTRIC_FIELD_INTENSITY_VOLT_PER_METER is 
  2861.           ELECTRIC_FIELD ;
  2862.  
  2863. --
  2864. --                                      2                              2
  2865. --electric displacement      D       Q/L         coulomb per        c/m
  2866. --                                               square meter
  2867. --
  2868.   type ELECTRIC_DISPLACEMENT is new REAL ;
  2869.   subtype ELECTRIC_DISPLACEMENT_COULOMB_PER_SQUARE_METER is 
  2870.           ELECTRIC_DISPLACEMENT ;
  2871.  
  2872. --
  2873. --                                       2                                2
  2874. --permeability               mu      ML/Q        henry per meter    Kg m/c
  2875. --
  2876.   type PERMEABILITY is new REAL ;
  2877.   subtype PERMEABILITY_HENRY_PER_METER is PERMEABILITY ;
  2878.  
  2879. --
  2880. --                                    2 2   3                          2 2     3
  2881. --permittivity,              epsi    T Q /ML     farad per meter    sec c /Kg m
  2882. --  dielectric constant
  2883. --
  2884.   type PERMITTIVITY is new REAL ;
  2885.   subtype PERMITTIVITY_FARAD_PER_METER is PERMITTIVITY ;
  2886.   subtype DIELECTRIC_CONSTANT is PERMITTIVITY ;
  2887.  
  2888. --
  2889. --                                                                     -1
  2890. --frequency                  f       Pi/T        hertz              sec
  2891. --
  2892.   type FREQUENCY_HERTZ is new REAL ;
  2893.   type FREQUENCY_KILOHERTZ is new REAL ;
  2894.   type FREQUENCY_MEGAHERTZ is new REAL ;
  2895.   type FREQUENCY_GIGAHERTZ is new REAL ;
  2896.  
  2897. --
  2898. --                                                                     -1
  2899. --angular frequency          omega   1/T         radians per second sec
  2900. --
  2901.   type ANGULAR_FREQUENCY_RADIAN_PER_SECOND is new REAL ;
  2902.  
  2903. --
  2904. end PHYSICAL_UNITS_ELECTRICAL ;
  2905. --------------------------------------------------------------------------------
  2906.  
  2907.  
  2908.  
  2909.  
  2910.  
  2911.  
  2912.  
  2913.  
  2914.  
  2915. --------------------------------------------------------------------------------
  2916. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  2917.  
  2918. package PHYSICAL_UNITS_OTHER is
  2919.  
  2920. -- This package specification defines Ada types for physical
  2921. -- units that occur as intermediate results.
  2922. -- A number of other packages use this package.
  2923. --
  2924. --
  2925. --   The comments below are organized to present the physical quantity unit with
  2926. --associated information. The first column is the dimension of the physical
  2927. --quantity expressed in terms of the fundamental dimensions. The second column
  2928. --is the typical MKS unit equation. 
  2929. --
  2930. -- DIMENSION   UNIT EQUATION
  2931. -- _________   _____________
  2932. --
  2933. --                TYPES NEEDED FOR COMPUTATIONS
  2934. --
  2935. --    2            2
  2936. --   T          sec
  2937.   type TIME_SECOND_SQUARED is new REAL ;
  2938.  
  2939. --
  2940. --   2  2        2    2
  2941. --  L /T        m /sec
  2942.   type VELOCITY_SQUARED_MKS is new REAL ;
  2943.   subtype VELOCITY_MKS_SQUARED is VELOCITY_SQUARED_MKS ;
  2944.  
  2945. --    2  2            o
  2946. --  ML /T K     joule/ K 
  2947.   type JOULE_PER_DEGREE_KELVIN is new REAL ;
  2948.  
  2949. --
  2950. --    3  2 2
  2951. --  ML /T Q     m/farad
  2952.   type METER_PER_FARAD is new REAL ;
  2953.  
  2954. --
  2955. --   2 4  4 2       2
  2956. --  M L /T Q    volt
  2957.   type VOLT_SQUARED  is new REAL ;
  2958.  
  2959. --
  2960. --   2  2             2
  2961. --  Q /T        ampere
  2962.   type AMPERE_SQUARED is new REAL ;
  2963.  
  2964. --
  2965. --     2
  2966. --  Q/T         ampere/sec
  2967.   type AMPERE_PER_SECOND is new REAL ;
  2968.  
  2969. -- 
  2970. --    2  3
  2971. --  ML /T Q     volt/sec
  2972.   type VOLT_PER_SECOND is new REAL ;
  2973.  
  2974. --
  2975. --   2   2
  2976. --  L /MT
  2977.   type ACCELERATION_PER_KILOGRAM is new REAL ;
  2978.  
  2979. --
  2980. end PHYSICAL_UNITS_OTHER ;
  2981. --------------------------------------------------------------------------------
  2982.  
  2983.  
  2984.  
  2985.  
  2986.  
  2987.  
  2988.  
  2989.  
  2990.  
  2991. --------------------------------------------------------------------------------
  2992. with PHYSICAL_UNITS_BASIC ; use PHYSICAL_UNITS_BASIC ;
  2993.  
  2994. package PHYSICAL_UNITS_OUTPUT_BASIC is
  2995.  
  2996. -- This package specification defines a simple PUT for Ada types for physical
  2997. -- quantities. The initial thought was to have metric units and English units
  2998. -- in separate package specifications. This proved inpractical
  2999. -- because time in seconds is both metric and English. Many other
  3000. -- units such as watt of power and Farad of capacitance are in
  3001. -- both systems. Thus, in order to keep the packages reasonable sizes,
  3002. -- the packages are basic units, mechanical units and electrical units.
  3003. --
  3004. -- Notice that there is not a procedure PUT defined for LENGTH_METER
  3005. -- or for that matter, any " subtype " defined in the package PHYSICAL_UNITS.
  3006. -- It is unnecessary and happens to be illegal ada.
  3007.  
  3008.   procedure PUT ( ITEM : LENGTH_MKS ) ;
  3009.  
  3010.   procedure PUT ( ITEM : LENGTH_ENGLISH ) ;
  3011.  
  3012.   procedure PUT ( ITEM : LENGTH_PICOMETER ) ;
  3013.  
  3014.   procedure PUT ( ITEM : LENGTH_NANOMETER ) ;
  3015.  
  3016.   procedure PUT ( ITEM : LENGTH_MICROMETER ) ;
  3017.  
  3018.   procedure PUT ( ITEM : LENGTH_MILLIMETER ) ;
  3019.  
  3020.   procedure PUT ( ITEM : LENGTH_CENTIMETER ) ;
  3021.  
  3022.   procedure PUT ( ITEM : LENGTH_DECIMETER ) ;
  3023.  
  3024.   procedure PUT ( ITEM : LENGTH_DECAMETER ) ;
  3025.  
  3026.   procedure PUT ( ITEM : LENGTH_HECTOMETER ) ;
  3027.  
  3028.   procedure PUT ( ITEM : LENGTH_KILOMETER ) ;
  3029.  
  3030.   procedure PUT ( ITEM : LENGTH_MEGAMETER ) ;
  3031.  
  3032.   procedure PUT ( ITEM : LENGTH_GIGAMETER ) ;
  3033.  
  3034.   procedure PUT ( ITEM : LENGTH_ANGSTROM ) ;
  3035.  
  3036.   procedure PUT ( ITEM : LENGTH_MIL ) ;
  3037.  
  3038.   procedure PUT ( ITEM : LENGTH_INCH ) ;
  3039.  
  3040.   procedure PUT ( ITEM : LENGTH_YARD ) ;
  3041.  
  3042.   procedure PUT ( ITEM : LENGTH_FATHOM ) ;
  3043.  
  3044.   procedure PUT ( ITEM : LENGTH_ROD ) ;
  3045.  
  3046.   procedure PUT ( ITEM : LENGTH_CHAIN_SURVEYOR ) ;
  3047.  
  3048.   procedure PUT ( ITEM : LENGTH_CHAIN_ENGINEER ) ;
  3049.  
  3050.   procedure PUT ( ITEM : LENGTH_FURLONG ) ;
  3051.  
  3052.   procedure PUT ( ITEM : LENGTH_MILE ) ;
  3053.  
  3054.   procedure PUT ( ITEM : LENGTH_MILE_NAUTICAL ) ;
  3055.  
  3056.   procedure PUT ( ITEM : LENGTH_LEAGUE_LAND ) ;
  3057.  
  3058.   procedure PUT ( ITEM : LENGTH_LEAGUE_MARINE ) ;
  3059.  
  3060.   procedure PUT ( ITEM : LENGTH_LIGHT_YEAR ) ;
  3061.  
  3062.   procedure PUT ( ITEM : MASS_MKS ) ;
  3063.  
  3064.   procedure PUT ( ITEM : MASS_ENGLISH ) ;
  3065.  
  3066.   procedure PUT ( ITEM : MASS_POUND_TROY ) ;
  3067.  
  3068.   procedure PUT ( ITEM : MASS_MILLIGRAM ) ;
  3069.  
  3070.   procedure PUT ( ITEM : MASS_GRAM ) ;
  3071.  
  3072.   procedure PUT ( ITEM : MASS_GRAIN ) ;
  3073.  
  3074.   procedure PUT ( ITEM : MASS_PENNYWEIGHT_TROY ) ;
  3075.  
  3076.   procedure PUT ( ITEM : MASS_CARAT_TROY ) ;
  3077.  
  3078.   procedure PUT ( ITEM : MASS_SCRUPLE ) ;
  3079.  
  3080.   procedure PUT ( ITEM : MASS_DRAM_AVDP ) ;
  3081.  
  3082.   procedure PUT ( ITEM : MASS_OUNCE_AVDP ) ;
  3083.  
  3084.   procedure PUT ( ITEM : MASS_OUNCE_TROY ) ;
  3085.  
  3086.   procedure PUT ( ITEM : MASS_TON_SHORT ) ;
  3087.  
  3088.   procedure PUT ( ITEM : MASS_TON_LONG ) ;
  3089.  
  3090.   procedure PUT ( ITEM : MASS_TON_METRIC ) ;
  3091.  
  3092.   procedure PUT ( ITEM : TIME_SECOND ) ;
  3093.  
  3094.   procedure PUT ( ITEM : TIME_PICOSECOND ) ;
  3095.  
  3096.   procedure PUT ( ITEM : TIME_NANOSECOND ) ;
  3097.  
  3098.   procedure PUT ( ITEM : TIME_MICROSECOND ) ;
  3099.  
  3100.   procedure PUT ( ITEM : TIME_MILLISECOND ) ;
  3101.  
  3102.   procedure PUT ( ITEM : TIME_CENTISECOND ) ;
  3103.  
  3104.   procedure PUT ( ITEM : TIME_KILOSECOND ) ;
  3105.  
  3106.   procedure PUT ( ITEM : TIME_MEGASECOND ) ;
  3107.  
  3108.   procedure PUT ( ITEM : TIME_GIGASECOND ) ;
  3109.  
  3110.   procedure PUT ( ITEM : TIME_MINUTE ) ;
  3111.  
  3112.   procedure PUT ( ITEM : TIME_HOUR ) ;
  3113.  
  3114.   procedure PUT ( ITEM : TIME_DAY ) ;
  3115.  
  3116.   procedure PUT ( ITEM : TIME_FORTNIGHT ) ;
  3117.  
  3118.   procedure PUT ( ITEM : TIME_MONTH ) ;
  3119.  
  3120.   procedure PUT ( ITEM : TIME_YEAR ) ;
  3121.  
  3122.   procedure PUT ( ITEM : TIME_DECADE ) ;
  3123.  
  3124.   procedure PUT ( ITEM : TIME_CENTURY ) ;
  3125.  
  3126.   procedure PUT ( ITEM : TIME_MILLENNIA ) ;
  3127.  
  3128.   procedure PUT ( ITEM : CHARGE_COULOMB ) ;
  3129.  
  3130.   procedure PUT ( ITEM : CHARGE_ELECTRON ) ;
  3131.  
  3132.   procedure PUT ( ITEM : CHARGE_FARADAY ) ;
  3133.  
  3134.   procedure PUT ( ITEM : CHARGE_AMPERE_HOURS ) ;
  3135.  
  3136.   procedure PUT ( ITEM : LUMINOUS_INTENSITY_CANDLE ) ;
  3137.  
  3138.   procedure PUT ( ITEM : TEMPERATURE_KELVIN ) ;
  3139.  
  3140.   procedure PUT ( ITEM : TEMPERATURE_CENTIGRADE ) ;
  3141.  
  3142.   procedure PUT ( ITEM : TEMPERATURE_FARENHEIT ) ;
  3143.  
  3144.   procedure PUT ( ITEM : ANGLE_RADIAN ) ;
  3145.  
  3146.   procedure PUT ( ITEM : ANGLE_SECOND ) ;
  3147.  
  3148.   procedure PUT ( ITEM : ANGLE_MINUTE ) ;
  3149.  
  3150.   procedure PUT ( ITEM : ANGLE_DEGREE ) ;
  3151.  
  3152.   procedure PUT ( ITEM : ANGLE_REVOLUTION ) ;
  3153.  
  3154.   procedure PUT ( ITEM : ANGLE_BAM ) ;
  3155.  
  3156.   procedure PUT ( ITEM : SOLID_ANGLE_STERADIAN ) ;
  3157.  
  3158. end PHYSICAL_UNITS_OUTPUT_BASIC ;
  3159. --------------------------------------------------------------------------------
  3160.  
  3161.  
  3162.  
  3163.  
  3164.  
  3165.  
  3166.  
  3167.  
  3168.  
  3169. --------------------------------------------------------------------------------
  3170. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  3171. with TEXT_IO ; use TEXT_IO ;
  3172. with LONG_FLT_IO ; use LONG_FLT_IO ;
  3173.  
  3174. package body PHYSICAL_UNITS_OUTPUT_BASIC is
  3175.  
  3176.   procedure PUT ( ITEM : LENGTH_MKS ) is
  3177.  
  3178.   begin
  3179.     PUT ( UNDIMENSION( ITEM )) ;
  3180.     PUT ( " meter " ) ;
  3181.   end PUT ;
  3182.  
  3183.   procedure PUT ( ITEM : LENGTH_ENGLISH ) is
  3184.  
  3185.   begin
  3186.     PUT ( UNDIMENSION( ITEM )) ;
  3187.     PUT ( " feet " ) ;
  3188.   end PUT ;
  3189.  
  3190.   procedure PUT ( ITEM : LENGTH_PICOMETER ) is
  3191.  
  3192.   begin
  3193.     PUT ( UNDIMENSION( ITEM )) ;
  3194.     PUT ( " picometer " ) ;
  3195.   end PUT ;
  3196.  
  3197.   procedure PUT ( ITEM : LENGTH_NANOMETER ) is
  3198.  
  3199.   begin
  3200.     PUT ( UNDIMENSION( ITEM )) ;
  3201.     PUT ( " nanometer " ) ;
  3202.   end PUT ;
  3203.  
  3204.   procedure PUT ( ITEM : LENGTH_MICROMETER ) is
  3205.  
  3206.   begin
  3207.     PUT ( UNDIMENSION( ITEM )) ;
  3208.     PUT ( " micrometer " ) ;
  3209.   end PUT ;
  3210.  
  3211.   procedure PUT ( ITEM : LENGTH_MILLIMETER ) is
  3212.  
  3213.   begin
  3214.     PUT ( UNDIMENSION( ITEM )) ;
  3215.     PUT ( " millimeter " ) ;
  3216.   end PUT ;
  3217.  
  3218.   procedure PUT ( ITEM : LENGTH_CENTIMETER ) is
  3219.  
  3220.   begin
  3221.     PUT ( UNDIMENSION( ITEM )) ;
  3222.     PUT ( " centimeter " ) ;
  3223.   end PUT ;
  3224.  
  3225.   procedure PUT ( ITEM : LENGTH_DECIMETER ) is
  3226.  
  3227.   begin
  3228.     PUT ( UNDIMENSION( ITEM )) ;
  3229.     PUT ( " decimeter " ) ;
  3230.   end PUT ;
  3231.  
  3232.   procedure PUT ( ITEM : LENGTH_DECAMETER ) is
  3233.  
  3234.   begin
  3235.     PUT ( UNDIMENSION( ITEM )) ;
  3236.     PUT ( " decameter " ) ;
  3237.   end PUT ;
  3238.  
  3239.   procedure PUT ( ITEM : LENGTH_HECTOMETER ) is
  3240.  
  3241.   begin
  3242.     PUT ( UNDIMENSION( ITEM )) ;
  3243.     PUT ( " hectometer " ) ;
  3244.   end PUT ;
  3245.  
  3246.   procedure PUT ( ITEM : LENGTH_KILOMETER ) is
  3247.  
  3248.   begin
  3249.     PUT ( UNDIMENSION( ITEM )) ;
  3250.     PUT ( " kilometer " ) ;
  3251.   end PUT ;
  3252.  
  3253.   procedure PUT ( ITEM : LENGTH_MEGAMETER ) is
  3254.  
  3255.   begin
  3256.     PUT ( UNDIMENSION( ITEM )) ;
  3257.     PUT ( " megameter " ) ;
  3258.   end PUT ;
  3259.  
  3260.   procedure PUT ( ITEM : LENGTH_GIGAMETER ) is
  3261.  
  3262.   begin
  3263.     PUT ( UNDIMENSION( ITEM )) ;
  3264.     PUT ( " gigameter " ) ;
  3265.   end PUT ;
  3266.  
  3267.   procedure PUT ( ITEM : LENGTH_ANGSTROM ) is
  3268.  
  3269.   begin
  3270.     PUT ( UNDIMENSION( ITEM )) ;
  3271.     PUT ( " angstrom " ) ;
  3272.   end PUT ;
  3273.  
  3274.   procedure PUT ( ITEM : LENGTH_MIL ) is
  3275.  
  3276.   begin
  3277.     PUT ( UNDIMENSION( ITEM )) ;
  3278.     PUT ( " mil " ) ;
  3279.   end PUT ;
  3280.  
  3281.   procedure PUT ( ITEM : LENGTH_INCH ) is
  3282.  
  3283.   begin
  3284.     PUT ( UNDIMENSION( ITEM )) ;
  3285.     PUT ( " inch " ) ;
  3286.   end PUT ;
  3287.  
  3288.   procedure PUT ( ITEM : LENGTH_YARD ) is
  3289.  
  3290.   begin
  3291.     PUT ( UNDIMENSION( ITEM )) ;
  3292.     PUT ( " yard " ) ;
  3293.   end PUT ;
  3294.  
  3295.   procedure PUT ( ITEM : LENGTH_FATHOM ) is
  3296.  
  3297.   begin
  3298.     PUT ( UNDIMENSION( ITEM )) ;
  3299.     PUT ( " fathom " ) ;
  3300.   end PUT ;
  3301.  
  3302.   procedure PUT ( ITEM : LENGTH_ROD ) is
  3303.  
  3304.   begin
  3305.     PUT ( UNDIMENSION( ITEM )) ;
  3306.     PUT ( " rod " ) ;
  3307.   end PUT ;
  3308.  
  3309.   procedure PUT ( ITEM : LENGTH_CHAIN_SURVEYOR ) is
  3310.  
  3311.   begin
  3312.     PUT ( UNDIMENSION( ITEM )) ;
  3313.     PUT ( " chain (surveyor) " ) ;
  3314.   end PUT ;
  3315.  
  3316.   procedure PUT ( ITEM : LENGTH_CHAIN_ENGINEER ) is
  3317.  
  3318.   begin
  3319.     PUT ( UNDIMENSION( ITEM )) ;
  3320.     PUT ( " chain (engineer) " ) ;
  3321.   end PUT ;
  3322.  
  3323.   procedure PUT ( ITEM : LENGTH_FURLONG ) is
  3324.  
  3325.   begin
  3326.     PUT ( UNDIMENSION( ITEM )) ;
  3327.     PUT ( " furlong " ) ;
  3328.   end PUT ;
  3329.  
  3330.   procedure PUT ( ITEM : LENGTH_MILE ) is
  3331.  
  3332.   begin
  3333.     PUT ( UNDIMENSION( ITEM )) ;
  3334.     PUT ( " mile " ) ;
  3335.   end PUT ;
  3336.  
  3337.   procedure PUT ( ITEM : LENGTH_MILE_NAUTICAL ) is
  3338.  
  3339.   begin
  3340.     PUT ( UNDIMENSION( ITEM )) ;
  3341.     PUT ( " mile (nautical) " ) ;
  3342.   end PUT ;
  3343.  
  3344.   procedure PUT ( ITEM : LENGTH_LEAGUE_LAND ) is
  3345.  
  3346.   begin
  3347.     PUT ( UNDIMENSION( ITEM )) ;
  3348.     PUT ( " league (land) " ) ;
  3349.   end PUT ;
  3350.  
  3351.   procedure PUT ( ITEM : LENGTH_LEAGUE_MARINE ) is
  3352.  
  3353.   begin
  3354.     PUT ( UNDIMENSION( ITEM )) ;
  3355.     PUT ( " league (marine) " ) ;
  3356.   end PUT ;
  3357.  
  3358.   procedure PUT ( ITEM : LENGTH_LIGHT_YEAR ) is
  3359.  
  3360.   begin
  3361.     PUT ( UNDIMENSION( ITEM )) ;
  3362.     PUT ( " light year " ) ;
  3363.   end PUT ;
  3364.  
  3365.   procedure PUT ( ITEM : MASS_MKS ) is
  3366.  
  3367.   begin
  3368.     PUT ( UNDIMENSION( ITEM )) ;
  3369.     PUT ( " kilogram " ) ;
  3370.   end PUT ;
  3371.  
  3372.   procedure PUT ( ITEM : MASS_ENGLISH ) is
  3373.  
  3374.   begin
  3375.     PUT ( UNDIMENSION( ITEM )) ;
  3376.     PUT ( " pound " ) ;
  3377.   end PUT ;
  3378.  
  3379.   procedure PUT ( ITEM : MASS_POUND_TROY ) is
  3380.  
  3381.   begin
  3382.     PUT ( UNDIMENSION( ITEM )) ;
  3383.     PUT ( " pound (troy) " ) ;
  3384.   end PUT ;
  3385.  
  3386.   procedure PUT ( ITEM : MASS_MILLIGRAM ) is
  3387.  
  3388.   begin
  3389.     PUT ( UNDIMENSION( ITEM )) ;
  3390.     PUT ( " milligram " ) ;
  3391.   end PUT ;
  3392.  
  3393.   procedure PUT ( ITEM : MASS_GRAM ) is
  3394.  
  3395.   begin
  3396.     PUT ( UNDIMENSION( ITEM )) ;
  3397.     PUT ( " gram " ) ;
  3398.   end PUT ;
  3399.  
  3400.   procedure PUT ( ITEM : MASS_GRAIN ) is
  3401.  
  3402.   begin
  3403.     PUT ( UNDIMENSION( ITEM )) ;
  3404.     PUT ( " grain " ) ;
  3405.   end PUT ;
  3406.  
  3407.   procedure PUT ( ITEM : MASS_PENNYWEIGHT_TROY ) is
  3408.  
  3409.   begin
  3410.     PUT ( UNDIMENSION( ITEM )) ;
  3411.     PUT ( " pennyweight (troy) " ) ;
  3412.   end PUT ;
  3413.  
  3414.   procedure PUT ( ITEM : MASS_CARAT_TROY ) is
  3415.  
  3416.   begin
  3417.     PUT ( UNDIMENSION( ITEM )) ;
  3418.     PUT ( " carat (troy) " ) ;
  3419.   end PUT ;
  3420.  
  3421.   procedure PUT ( ITEM : MASS_SCRUPLE ) is
  3422.  
  3423.   begin
  3424.     PUT ( UNDIMENSION( ITEM )) ;
  3425.     PUT ( " scruple " ) ;
  3426.   end PUT ;
  3427.  
  3428.   procedure PUT ( ITEM : MASS_DRAM_AVDP ) is
  3429.  
  3430.   begin
  3431.     PUT ( UNDIMENSION( ITEM )) ;
  3432.     PUT ( " dram (avdp.) " ) ;
  3433.   end PUT ;
  3434.  
  3435.   procedure PUT ( ITEM : MASS_OUNCE_AVDP ) is
  3436.  
  3437.   begin
  3438.     PUT ( UNDIMENSION( ITEM )) ;
  3439.     PUT ( " ounce " ) ;
  3440.   end PUT ;
  3441.  
  3442.   procedure PUT ( ITEM : MASS_OUNCE_TROY ) is
  3443.  
  3444.   begin
  3445.     PUT ( UNDIMENSION( ITEM )) ;
  3446.     PUT ( " ounce (troy) " ) ;
  3447.   end PUT ;
  3448.  
  3449.   procedure PUT ( ITEM : MASS_TON_SHORT ) is
  3450.  
  3451.   begin
  3452.     PUT ( UNDIMENSION( ITEM )) ;
  3453.     PUT ( " ton (short) " ) ;
  3454.   end PUT ;
  3455.  
  3456.   procedure PUT ( ITEM : MASS_TON_LONG ) is
  3457.  
  3458.   begin
  3459.     PUT ( UNDIMENSION( ITEM )) ;
  3460.     PUT ( " ton (long) " ) ;
  3461.   end PUT ;
  3462.  
  3463.   procedure PUT ( ITEM : MASS_TON_METRIC ) is
  3464.  
  3465.   begin
  3466.     PUT ( UNDIMENSION( ITEM )) ;
  3467.     PUT ( " ton (metric) " ) ;
  3468.   end PUT ;
  3469.  
  3470.   procedure PUT ( ITEM : TIME_SECOND ) is
  3471.  
  3472.   begin
  3473.     PUT ( UNDIMENSION( ITEM )) ;
  3474.     PUT ( " second " ) ;
  3475.   end PUT ;
  3476.  
  3477.   procedure PUT ( ITEM : TIME_PICOSECOND ) is
  3478.  
  3479.   begin
  3480.     PUT ( UNDIMENSION( ITEM )) ;
  3481.     PUT ( " picosecond " ) ;
  3482.   end PUT ;
  3483.  
  3484.   procedure PUT ( ITEM : TIME_NANOSECOND ) is
  3485.  
  3486.   begin
  3487.     PUT ( UNDIMENSION( ITEM )) ;
  3488.     PUT ( " nanosecond " ) ;
  3489.   end PUT ;
  3490.  
  3491.   procedure PUT ( ITEM : TIME_MICROSECOND ) is
  3492.  
  3493.   begin
  3494.     PUT ( UNDIMENSION( ITEM )) ;
  3495.     PUT ( " microsecond " ) ;
  3496.   end PUT ;
  3497.  
  3498.   procedure PUT ( ITEM : TIME_MILLISECOND ) is
  3499.  
  3500.   begin
  3501.     PUT ( UNDIMENSION( ITEM )) ;
  3502.     PUT ( " millisecond " ) ;
  3503.   end PUT ;
  3504.  
  3505.   procedure PUT ( ITEM : TIME_CENTISECOND ) is
  3506.  
  3507.   begin
  3508.     PUT ( UNDIMENSION( ITEM )) ;
  3509.     PUT ( " centisecond " ) ;
  3510.   end PUT ;
  3511.  
  3512.   procedure PUT ( ITEM : TIME_KILOSECOND ) is
  3513.  
  3514.   begin
  3515.     PUT ( UNDIMENSION( ITEM )) ;
  3516.     PUT ( " kilosecond " ) ;
  3517.   end PUT ;
  3518.  
  3519.   procedure PUT ( ITEM : TIME_MEGASECOND ) is
  3520.  
  3521.   begin
  3522.     PUT ( UNDIMENSION( ITEM )) ;
  3523.     PUT ( " megasecond " ) ;
  3524.   end PUT ;
  3525.  
  3526.   procedure PUT ( ITEM : TIME_GIGASECOND ) is
  3527.  
  3528.   begin
  3529.     PUT ( UNDIMENSION( ITEM )) ;
  3530.     PUT ( " gigasecond " ) ;
  3531.   end PUT ;
  3532.  
  3533.   procedure PUT ( ITEM : TIME_MINUTE ) is
  3534.  
  3535.   begin
  3536.     PUT ( UNDIMENSION( ITEM )) ;
  3537.     PUT ( " minute " ) ;
  3538.   end PUT ;
  3539.  
  3540.   procedure PUT ( ITEM : TIME_HOUR ) is
  3541.  
  3542.   begin
  3543.     PUT ( UNDIMENSION( ITEM )) ;
  3544.     PUT ( " hour " ) ;
  3545.   end PUT ;
  3546.  
  3547.   procedure PUT ( ITEM : TIME_DAY ) is
  3548.  
  3549.   begin
  3550.     PUT ( UNDIMENSION( ITEM )) ;
  3551.     PUT ( " day " ) ;
  3552.   end PUT ;
  3553.  
  3554.   procedure PUT ( ITEM : TIME_FORTNIGHT ) is
  3555.  
  3556.   begin
  3557.     PUT ( UNDIMENSION( ITEM )) ;
  3558.     PUT ( " fortnight " ) ;
  3559.   end PUT ;
  3560.  
  3561.   procedure PUT ( ITEM : TIME_MONTH ) is
  3562.  
  3563.   begin
  3564.     PUT ( UNDIMENSION( ITEM )) ;
  3565.     PUT ( " month " ) ;
  3566.   end PUT ;
  3567.  
  3568.   procedure PUT ( ITEM : TIME_YEAR ) is
  3569.  
  3570.   begin
  3571.     PUT ( UNDIMENSION( ITEM )) ;
  3572.     PUT ( " year " ) ;
  3573.   end PUT ;
  3574.  
  3575.   procedure PUT ( ITEM : TIME_DECADE ) is
  3576.  
  3577.   begin
  3578.     PUT ( UNDIMENSION( ITEM )) ;
  3579.     PUT ( " decade " ) ;
  3580.   end PUT ;
  3581.  
  3582.   procedure PUT ( ITEM : TIME_CENTURY ) is
  3583.  
  3584.   begin
  3585.     PUT ( UNDIMENSION( ITEM )) ;
  3586.     PUT ( " century " ) ;
  3587.   end PUT ;
  3588.  
  3589.   procedure PUT ( ITEM : TIME_MILLENNIA ) is
  3590.  
  3591.   begin
  3592.     PUT ( UNDIMENSION( ITEM )) ;
  3593.     PUT ( " millennia " ) ;
  3594.   end PUT ;
  3595.  
  3596.   procedure PUT ( ITEM : CHARGE_COULOMB ) is
  3597.  
  3598.   begin
  3599.     PUT ( UNDIMENSION( ITEM )) ;
  3600.     PUT ( " coulomb " ) ;
  3601.   end PUT ;
  3602.  
  3603.   procedure PUT ( ITEM : CHARGE_ELECTRON ) is
  3604.  
  3605.   begin
  3606.     PUT ( UNDIMENSION( ITEM )) ;
  3607.     PUT ( " charge (electron) " ) ;
  3608.   end PUT ;
  3609.  
  3610.   procedure PUT ( ITEM : CHARGE_FARADAY ) is
  3611.  
  3612.   begin
  3613.     PUT ( UNDIMENSION( ITEM )) ;
  3614.     PUT ( " faraday " ) ;
  3615.   end PUT ;
  3616.  
  3617.   procedure PUT ( ITEM : CHARGE_AMPERE_HOURS ) is
  3618.  
  3619.   begin
  3620.     PUT ( UNDIMENSION( ITEM )) ;
  3621.     PUT ( " ampere hour " ) ;
  3622.  
  3623.  
  3624.   end PUT ;
  3625.  
  3626.   procedure PUT ( ITEM : LUMINOUS_INTENSITY_CANDLE ) is
  3627.  
  3628.   begin
  3629.     PUT ( UNDIMENSION( ITEM )) ;
  3630.     PUT ( " candel " ) ;
  3631.   end PUT ;
  3632.  
  3633.   procedure PUT ( ITEM : TEMPERATURE_KELVIN ) is
  3634.  
  3635.   begin
  3636.     PUT ( UNDIMENSION( ITEM )) ;
  3637.     PUT ( " degree kelvin " ) ;
  3638.   end PUT ;
  3639.  
  3640.   procedure PUT ( ITEM : TEMPERATURE_CENTIGRADE ) is
  3641.  
  3642.   begin
  3643.     PUT ( UNDIMENSION( ITEM )) ;
  3644.     PUT ( " degree centigrade " ) ;
  3645.   end PUT ;
  3646.  
  3647.   procedure PUT ( ITEM : TEMPERATURE_FARENHEIT ) is
  3648.  
  3649.   begin
  3650.     PUT ( UNDIMENSION( ITEM )) ;
  3651.     PUT ( " degree farenheit " ) ;
  3652.   end PUT ;
  3653.  
  3654.   procedure PUT ( ITEM : ANGLE_RADIAN ) is
  3655.  
  3656.   begin
  3657.     PUT ( UNDIMENSION( ITEM )) ;
  3658.     PUT ( " radian " ) ;
  3659.   end PUT ;
  3660.  
  3661.   procedure PUT ( ITEM : ANGLE_SECOND ) is
  3662.  
  3663.   begin
  3664.     PUT ( UNDIMENSION( ITEM )) ;
  3665.     PUT ( " second (angle) " ) ;
  3666.   end PUT ;
  3667.  
  3668.   procedure PUT ( ITEM : ANGLE_MINUTE ) is
  3669.  
  3670.   begin
  3671.     PUT ( UNDIMENSION( ITEM )) ;
  3672.     PUT ( " minute ( angle) " ) ;
  3673.   end PUT ;
  3674.  
  3675.   procedure PUT ( ITEM : ANGLE_DEGREE ) is
  3676.  
  3677.   begin
  3678.     PUT ( UNDIMENSION( ITEM )) ;
  3679.     PUT ( " degree (angle) " ) ;
  3680.   end PUT ;
  3681.  
  3682.   procedure PUT ( ITEM : ANGLE_REVOLUTION ) is
  3683.  
  3684.   begin
  3685.     PUT ( UNDIMENSION( ITEM )) ;
  3686.     PUT ( " revolution " ) ;
  3687.   end PUT ;
  3688.  
  3689.   procedure PUT ( ITEM : ANGLE_BAM ) is
  3690.  
  3691.   begin
  3692.     PUT ( UNDIMENSION( ITEM )) ;
  3693.     PUT ( " bam " ) ;
  3694.   end PUT ;
  3695.  
  3696.   procedure PUT ( ITEM : SOLID_ANGLE_STERADIAN ) is
  3697.  
  3698.   begin
  3699.     PUT ( UNDIMENSION( ITEM )) ;
  3700.     PUT ( " steradian " ) ;
  3701.   end PUT ;
  3702.  
  3703. end PHYSICAL_UNITS_OUTPUT_BASIC ;
  3704. --------------------------------------------------------------------------------
  3705.  
  3706.  
  3707.  
  3708.  
  3709.  
  3710.  
  3711.  
  3712.  
  3713.  
  3714. --------------------------------------------------------------------------------
  3715. with PHYSICAL_UNITS_MECHANICAL ; use PHYSICAL_UNITS_MECHANICAL ;
  3716.  
  3717. package PHYSICAL_UNITS_OUTPUT_MECHANICAL is
  3718.  
  3719. -- This package specification defines a simple PUT for Ada types for physical
  3720. -- quantities generally mechanical in nature.
  3721. --
  3722. -- Notice that there is not a procedure PUT defined for LENGTH_METER
  3723. -- or for that matter, any " subtype " defined in the package PHYSICAL_UNITS.
  3724. -- It is unnecessary and happens to be illegal ada.
  3725.  
  3726.   procedure PUT ( ITEM : AREA_MKS ) ;
  3727.  
  3728.   procedure PUT ( ITEM : AREA_ENGLISH ) ;
  3729.  
  3730.   procedure PUT ( ITEM : AREA_SQUARE_CENTIMETER ) ;
  3731.  
  3732.   procedure PUT ( ITEM : AREA_SQUARE_KILOMETER ) ;
  3733.  
  3734.   procedure PUT ( ITEM : AREA_SQUARE_INCH ) ;
  3735.  
  3736.   procedure PUT ( ITEM : AREA_SQUARE_YARD ) ;
  3737.  
  3738.   procedure PUT ( ITEM : AREA_SQUARE_MILE ) ;
  3739.  
  3740.   procedure PUT ( ITEM : AREA_ACRE ) ;
  3741.  
  3742.   procedure PUT ( ITEM : AREA_CIRCULAR_MIL ) ;
  3743.  
  3744.   procedure PUT ( ITEM : AREA_HECTARE ) ;
  3745.  
  3746.   procedure PUT ( ITEM : AREA_TOWNSHIP ) ;
  3747.  
  3748.   procedure PUT ( ITEM : VOLUME_MKS ) ;
  3749.  
  3750.   procedure PUT ( ITEM : VOLUME_ENGLISH ) ;
  3751.  
  3752.   procedure PUT ( ITEM : VOLUME_MILLILITER ) ;
  3753.  
  3754.   procedure PUT ( ITEM : VOLUME_LITER ) ;
  3755.  
  3756.   procedure PUT ( ITEM : VOLUME_KILOLITER ) ;
  3757.  
  3758.   procedure PUT ( ITEM : VOLUME_CUBIC_CENTIMETER ) ;
  3759.  
  3760.   procedure PUT ( ITEM : VOLUME_CUBIC_INCH ) ;
  3761.  
  3762.   procedure PUT ( ITEM : VOLUME_CUBIC_YARD ) ;
  3763.  
  3764.   procedure PUT ( ITEM : VOLUME_CUBIC_MILE ) ;
  3765.  
  3766.   procedure PUT ( ITEM : VOLUME_TEASPOON ) ;
  3767.  
  3768.   procedure PUT ( ITEM : VOLUME_TABLESPOON ) ;
  3769.  
  3770.   procedure PUT ( ITEM : VOLUME_OUNCE_FLUID ) ;
  3771.  
  3772.   procedure PUT ( ITEM : VOLUME_JIGGER ) ;
  3773.  
  3774.   procedure PUT ( ITEM : VOLUME_CUP ) ;
  3775.  
  3776.   procedure PUT ( ITEM : VOLUME_PINT_LIQUID ) ;
  3777.  
  3778.   procedure PUT ( ITEM : VOLUME_QUART_LIQUID ) ;
  3779.  
  3780.   procedure PUT ( ITEM : VOLUME_GALLON ) ;
  3781.  
  3782.   procedure PUT ( ITEM : VOLUME_KEG ) ;
  3783.  
  3784.   procedure PUT ( ITEM : VOLUME_BARREL ) ;
  3785.  
  3786.   procedure PUT ( ITEM : VOLUME_PINT_DRY ) ;
  3787.  
  3788.   procedure PUT ( ITEM : VOLUME_QUART_DRY ) ;
  3789.  
  3790.   procedure PUT ( ITEM : VOLUME_PECK ) ;
  3791.  
  3792.   procedure PUT ( ITEM : VOLUME_BUSHEL ) ;
  3793.  
  3794.   procedure PUT ( ITEM : VOLUME_CORD ) ;
  3795.  
  3796.   procedure PUT ( ITEM : VELOCITY_MKS ) ;
  3797.  
  3798.   procedure PUT ( ITEM : VELOCITY_ENGLISH ) ;
  3799.  
  3800.   procedure PUT ( ITEM : VELOCITY_CENTIMETER_PER_SECOND ) ;
  3801.  
  3802.   procedure PUT ( ITEM : VELOCITY_KILOMETER_PER_HOUR ) ;
  3803.  
  3804.   procedure PUT ( ITEM : VELOCITY_INCHES_PER_SECOND ) ;
  3805.  
  3806.   procedure PUT ( ITEM : VELOCITY_MILE_PER_HOUR ) ;
  3807.  
  3808.   procedure PUT ( ITEM : VELOCITY_MILES_PER_SECOND ) ;
  3809.  
  3810.   procedure PUT ( ITEM : VELOCITY_INCHES_PER_MINUTE ) ;
  3811.  
  3812.   procedure PUT ( ITEM : VELOCITY_FEET_PER_MINUTE ) ;
  3813.  
  3814.   procedure PUT ( ITEM : VELOCITY_MILES_PER_HOUR ) ;
  3815.  
  3816.   procedure PUT ( ITEM : VELOCITY_KNOTS ) ;
  3817.  
  3818.   procedure PUT ( ITEM : VELOCITY_FURLONG_PER_FORTNIGHT ) ;
  3819.  
  3820.   procedure PUT ( ITEM : ANGULAR_VELOCITY ) ;
  3821.  
  3822.   procedure PUT ( ITEM : ANGULAR_VELOCITY_DEGREES_PER_SECOND ) ;
  3823.  
  3824.   procedure PUT ( ITEM : ANGULAR_VELOCITY_REVOLUTIONS_PER_MINUTE ) ;
  3825.  
  3826.   procedure PUT ( ITEM : ANGULAR_VELOCITY_REVOLUTIONS_PER_SECOND ) ;
  3827.  
  3828.   procedure PUT ( ITEM : ACCELERATION_MKS ) ;
  3829.  
  3830.   procedure PUT ( ITEM : ACCELERATION_ENGLISH ) ;
  3831.  
  3832.   procedure PUT ( ITEM : ANGULAR_ACCELERATION ) ;
  3833.  
  3834.   procedure PUT ( ITEM : ANGULAR_ACCELERATION_REVOLUTIONS_PER_MINUTE_SQUARED )
  3835.       ;
  3836.  
  3837.   procedure PUT ( ITEM : FORCE_MKS ) ;
  3838.  
  3839.   procedure PUT ( ITEM : FORCE_DYNE ) ;
  3840.  
  3841.   procedure PUT ( ITEM : FORCE_ENGLISH ) ;
  3842.  
  3843.   procedure PUT ( ITEM : ENERGY_MKS ) ;
  3844.  
  3845.   procedure PUT ( ITEM : ENERGY_ERG ) ;
  3846.  
  3847.   procedure PUT ( ITEM : ENERGY_GRAM_CALORIE ) ;
  3848.  
  3849.   procedure PUT ( ITEM : ENERGY_KILOGRAM_CALORIE ) ;
  3850.  
  3851.   procedure PUT ( ITEM : ENERGY_B_T_U ) ;
  3852.  
  3853.   procedure PUT ( ITEM : ENERGY_FOOT_POUND ) ;
  3854.  
  3855.   procedure PUT ( ITEM : ENERGY_KILOWATT_HOUR ) ;
  3856.  
  3857.   procedure PUT ( ITEM : ENERGY_HORSEPOWER_HOUR ) ;
  3858.  
  3859.   procedure PUT ( ITEM : POWER_MKS ) ;
  3860.  
  3861.   procedure PUT ( ITEM : POWER_KILOGRAM_CALORIE_PER_SECOND ) ;
  3862.  
  3863.   procedure PUT ( ITEM : POWER_KILOGRAN_CALORIE_PER_MINUTE ) ;
  3864.  
  3865.   procedure PUT ( ITEM : POWER_HORSEPOWER_MECHANICAL ) ;
  3866.  
  3867.   procedure PUT ( ITEM : POWER_HORSEPOWER_ELECTRICAL ) ;
  3868.  
  3869.   procedure PUT ( ITEM : POWER_HORSEPOWER_METRIC ) ;
  3870.  
  3871.   procedure PUT ( ITEM : POWER_HORSEPOWER_BOILER ) ;
  3872.  
  3873.   procedure PUT ( ITEM : POWER_B_T_U_PER_MINUTE ) ;
  3874.  
  3875.   procedure PUT ( ITEM : POWER_B_T_U_PER_HOUR ) ;
  3876.  
  3877.   procedure PUT ( ITEM : POWER_FOOT_POUND_PER_MINUTE ) ;
  3878.  
  3879.   procedure PUT ( ITEM : POWER_FOOT_POUND_PER_SECOND ) ;
  3880.  
  3881.   procedure PUT ( ITEM : DENSITY_MKS ) ;
  3882.  
  3883.   procedure PUT ( ITEM : DENSITY_ENGLISH ) ;
  3884.  
  3885.   procedure PUT ( ITEM : FLOW_RATE_MKS ) ;
  3886.  
  3887.   procedure PUT ( ITEM : FLOW_RATE_GALLON_PER_MINUTE ) ;
  3888.  
  3889.   procedure PUT ( ITEM : FLOW_RATE_ENGLISH ) ;
  3890.  
  3891.   procedure PUT ( ITEM : FLOW_RATE_CUBIC_FEET_PER_MINUTE ) ;
  3892.  
  3893.   procedure PUT ( ITEM : PRESSURE_MKS ) ;
  3894.  
  3895.   procedure PUT ( ITEM : PRESSURE_ENGLISH ) ;
  3896.  
  3897.   procedure PUT ( ITEM : PRESSURE_TON_PER_SQUARE_FOOT ) ;
  3898.  
  3899.   procedure PUT ( ITEM : PRESSURE_ATMOSPHERE_STANDARD ) ;
  3900.  
  3901.   procedure PUT ( ITEM : PRESSURE_FEET_OF_WATER ) ;
  3902.  
  3903.   procedure PUT ( ITEM : PRESSURE_INCHES_OF_MERCURY ) ;
  3904.  
  3905.   procedure PUT ( ITEM : PRESSURE_MILLIMETER_OF_MERCURY ) ;
  3906.  
  3907.   procedure PUT ( ITEM : PRESSURE_BAR ) ;
  3908.  
  3909.   procedure PUT ( ITEM : PRESSURE_MILLIBAR ) ;
  3910.  
  3911.   procedure PUT ( ITEM : PRESSURE_TORR ) ;
  3912.  
  3913.   procedure PUT ( ITEM : MOMENTUM_MKS ) ;
  3914.  
  3915.   procedure PUT ( ITEM : INERTIA_MKS ) ;
  3916.  
  3917.   procedure PUT ( ITEM : MOMENT_OF_INERTIA_MKS ) ;
  3918.  
  3919.   procedure PUT ( ITEM : KINEMATIC_VISCOSITY_MKS ) ;
  3920.  
  3921.   procedure PUT ( ITEM : DYNAMIC_VISCOSITY_MKS ) ;
  3922.  
  3923.   procedure PUT ( ITEM : LUMINOUS_FLUX_LUMEN ) ;
  3924.  
  3925.   procedure PUT ( ITEM : ILLUMINATION_MKS ) ;
  3926.  
  3927.   procedure PUT ( ITEM : LUMINANCE_MKS ) ;
  3928.  
  3929.   procedure PUT ( ITEM : ENTROPY_MKS ) ;
  3930.  
  3931.   procedure PUT ( ITEM : SPECIFIC_HEAT_B_T_U_PER_POUND_DEGREE_FARENHEIT ) ;
  3932.  
  3933. end PHYSICAL_UNITS_OUTPUT_MECHANICAL ;
  3934. --------------------------------------------------------------------------------
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944. --------------------------------------------------------------------------------
  3945. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  3946. with TEXT_IO ; use TEXT_IO ;
  3947. with LONG_FLT_IO ; use LONG_FLT_IO ;
  3948.  
  3949. package body PHYSICAL_UNITS_OUTPUT_MECHANICAL is
  3950.  
  3951.   procedure PUT ( ITEM : AREA_MKS ) is
  3952.  
  3953.   begin
  3954.     PUT ( UNDIMENSION( ITEM )) ;
  3955.     PUT ( " square meter" ) ;
  3956.   end PUT ;
  3957.  
  3958.   procedure PUT ( ITEM : AREA_ENGLISH ) is
  3959.  
  3960.   begin
  3961.     PUT ( UNDIMENSION( ITEM )) ;
  3962.     PUT ( " square foot " ) ;
  3963.   end PUT ;
  3964.  
  3965.   procedure PUT ( ITEM : AREA_SQUARE_CENTIMETER ) is
  3966.  
  3967.   begin
  3968.     PUT ( UNDIMENSION( ITEM )) ;
  3969.     PUT ( " square centimeter " ) ;
  3970.   end PUT ;
  3971.  
  3972.   procedure PUT ( ITEM : AREA_SQUARE_KILOMETER ) is
  3973.  
  3974.   begin
  3975.     PUT ( UNDIMENSION( ITEM )) ;
  3976.     PUT ( " square kilometer " ) ;
  3977.   end PUT ;
  3978.  
  3979.   procedure PUT ( ITEM : AREA_SQUARE_INCH ) is
  3980.  
  3981.   begin
  3982.     PUT ( UNDIMENSION( ITEM )) ;
  3983.     PUT ( " square inch " ) ;
  3984.   end PUT ;
  3985.  
  3986.   procedure PUT ( ITEM : AREA_SQUARE_YARD ) is
  3987.  
  3988.   begin
  3989.     PUT ( UNDIMENSION( ITEM )) ;
  3990.     PUT ( " square yard " ) ;
  3991.   end PUT ;
  3992.  
  3993.   procedure PUT ( ITEM : AREA_SQUARE_MILE ) is
  3994.  
  3995.   begin
  3996.     PUT ( UNDIMENSION( ITEM )) ;
  3997.     PUT ( " square mile " ) ;
  3998.   end PUT ;
  3999.  
  4000.   procedure PUT ( ITEM : AREA_ACRE ) is
  4001.  
  4002.   begin
  4003.     PUT ( UNDIMENSION( ITEM )) ;
  4004.     PUT ( " acre " ) ;
  4005.   end PUT ;
  4006.  
  4007.   procedure PUT ( ITEM : AREA_CIRCULAR_MIL ) is
  4008.  
  4009.   begin
  4010.     PUT ( UNDIMENSION( ITEM )) ;
  4011.     PUT ( " circular mil " ) ;
  4012.   end PUT ;
  4013.  
  4014.   procedure PUT ( ITEM : AREA_HECTARE ) is
  4015.  
  4016.   begin
  4017.     PUT ( UNDIMENSION( ITEM )) ;
  4018.     PUT ( " hectare " ) ;
  4019.   end PUT ;
  4020.  
  4021.   procedure PUT ( ITEM : AREA_TOWNSHIP ) is
  4022.  
  4023.   begin
  4024.     PUT ( UNDIMENSION( ITEM )) ;
  4025.     PUT ( " township " ) ;
  4026.   end PUT ;
  4027.  
  4028.   procedure PUT ( ITEM : VOLUME_MKS ) is
  4029.  
  4030.   begin
  4031.     PUT ( UNDIMENSION( ITEM )) ;
  4032.     PUT ( " cubic meter " ) ;
  4033.   end PUT ;
  4034.  
  4035.   procedure PUT ( ITEM : VOLUME_ENGLISH ) is
  4036.  
  4037.   begin
  4038.     PUT ( UNDIMENSION( ITEM )) ;
  4039.     PUT ( " cubic foot " ) ;
  4040.   end PUT ;
  4041.  
  4042.   procedure PUT ( ITEM : VOLUME_MILLILITER ) is
  4043.  
  4044.   begin
  4045.     PUT ( UNDIMENSION( ITEM )) ;
  4046.     PUT ( " milliliter " ) ;
  4047.   end PUT ;
  4048.  
  4049.   procedure PUT ( ITEM : VOLUME_LITER ) is
  4050.  
  4051.   begin
  4052.     PUT ( UNDIMENSION( ITEM )) ;
  4053.     PUT ( " liter " ) ;
  4054.   end PUT ;
  4055.  
  4056.   procedure PUT ( ITEM : VOLUME_KILOLITER ) is
  4057.  
  4058.   begin
  4059.     PUT ( UNDIMENSION( ITEM )) ;
  4060.     PUT ( " kiloliter " ) ;
  4061.   end PUT ;
  4062.  
  4063.   procedure PUT ( ITEM : VOLUME_CUBIC_CENTIMETER ) is
  4064.  
  4065.   begin
  4066.     PUT ( UNDIMENSION( ITEM )) ;
  4067.     PUT ( " cubic centimeter " ) ;
  4068.   end PUT ;
  4069.  
  4070.   procedure PUT ( ITEM : VOLUME_CUBIC_INCH ) is
  4071.  
  4072.   begin
  4073.     PUT ( UNDIMENSION( ITEM )) ;
  4074.     PUT ( " cubic inch " ) ;
  4075.   end PUT ;
  4076.  
  4077.   procedure PUT ( ITEM : VOLUME_CUBIC_YARD ) is
  4078.  
  4079.   begin
  4080.     PUT ( UNDIMENSION( ITEM )) ;
  4081.     PUT ( " cubic yard " ) ;
  4082.   end PUT ;
  4083.  
  4084.   procedure PUT ( ITEM : VOLUME_CUBIC_MILE ) is
  4085.  
  4086.   begin
  4087.     PUT ( UNDIMENSION( ITEM )) ;
  4088.     PUT ( " cubic mile " ) ;
  4089.   end PUT ;
  4090.  
  4091.   procedure PUT ( ITEM : VOLUME_TEASPOON ) is
  4092.  
  4093.   begin
  4094.     PUT ( UNDIMENSION( ITEM )) ;
  4095.     PUT ( " teaspoon " ) ;
  4096.   end PUT ;
  4097.  
  4098.   procedure PUT ( ITEM : VOLUME_TABLESPOON ) is
  4099.  
  4100.   begin
  4101.     PUT ( UNDIMENSION( ITEM )) ;
  4102.     PUT ( " tablespoon " ) ;
  4103.   end PUT ;
  4104.  
  4105.   procedure PUT ( ITEM : VOLUME_OUNCE_FLUID ) is
  4106.  
  4107.   begin
  4108.     PUT ( UNDIMENSION( ITEM )) ;
  4109.     PUT ( " ounce (fluid) " ) ;
  4110.   end PUT ;
  4111.  
  4112.   procedure PUT ( ITEM : VOLUME_JIGGER ) is
  4113.  
  4114.   begin
  4115.     PUT ( UNDIMENSION( ITEM )) ;
  4116.     PUT ( " jigger " ) ;
  4117.   end PUT ;
  4118.  
  4119.   procedure PUT ( ITEM : VOLUME_CUP ) is
  4120.  
  4121.   begin
  4122.     PUT ( UNDIMENSION( ITEM )) ;
  4123.     PUT ( " cup " ) ;
  4124.   end PUT ;
  4125.  
  4126.   procedure PUT ( ITEM : VOLUME_PINT_LIQUID ) is
  4127.  
  4128.   begin
  4129.     PUT ( UNDIMENSION( ITEM )) ;
  4130.     PUT ( " pint (liquid) " ) ;
  4131.   end PUT ;
  4132.  
  4133.   procedure PUT ( ITEM : VOLUME_QUART_LIQUID ) is
  4134.  
  4135.   begin
  4136.     PUT ( UNDIMENSION( ITEM )) ;
  4137.     PUT ( " quart (liquid) " ) ;
  4138.   end PUT ;
  4139.  
  4140.   procedure PUT ( ITEM : VOLUME_GALLON ) is
  4141.  
  4142.   begin
  4143.     PUT ( UNDIMENSION( ITEM )) ;
  4144.     PUT ( " gallon " ) ;
  4145.   end PUT ;
  4146.  
  4147.   procedure PUT ( ITEM : VOLUME_KEG ) is
  4148.  
  4149.   begin
  4150.     PUT ( UNDIMENSION( ITEM )) ;
  4151.     PUT ( " keg " ) ;
  4152.   end PUT ;
  4153.  
  4154.   procedure PUT ( ITEM : VOLUME_BARREL ) is
  4155.  
  4156.   begin
  4157.     PUT ( UNDIMENSION( ITEM )) ;
  4158.     PUT ( " barrel " ) ;
  4159.   end PUT ;
  4160.  
  4161.   procedure PUT ( ITEM : VOLUME_PINT_DRY ) is
  4162.  
  4163.   begin
  4164.     PUT ( UNDIMENSION( ITEM )) ;
  4165.     PUT ( " pint (dry) " ) ;
  4166.   end PUT ;
  4167.  
  4168.   procedure PUT ( ITEM : VOLUME_QUART_DRY ) is
  4169.  
  4170.   begin
  4171.     PUT ( UNDIMENSION( ITEM )) ;
  4172.     PUT ( " quart (dry) " ) ;
  4173.   end PUT ;
  4174.  
  4175.   procedure PUT ( ITEM : VOLUME_PECK ) is
  4176.  
  4177.   begin
  4178.     PUT ( UNDIMENSION( ITEM )) ;
  4179.     PUT ( " peck " ) ;
  4180.   end PUT ;
  4181.  
  4182.   procedure PUT ( ITEM : VOLUME_BUSHEL ) is
  4183.  
  4184.   begin
  4185.     PUT ( UNDIMENSION( ITEM )) ;
  4186.     PUT ( " bushel " ) ;
  4187.   end PUT ;
  4188.  
  4189.   procedure PUT ( ITEM : VOLUME_CORD ) is
  4190.  
  4191.   begin
  4192.     PUT ( UNDIMENSION( ITEM )) ;
  4193.     PUT ( " cord " ) ;
  4194.   end PUT ;
  4195.  
  4196.   procedure PUT ( ITEM : VELOCITY_MKS ) is
  4197.  
  4198.   begin
  4199.     PUT ( UNDIMENSION( ITEM )) ;
  4200.     PUT ( " meter per second " ) ;
  4201.   end PUT ;
  4202.  
  4203.   procedure PUT ( ITEM : VELOCITY_ENGLISH ) is
  4204.  
  4205.   begin
  4206.     PUT ( UNDIMENSION( ITEM )) ;
  4207.     PUT ( " foot per second " ) ;
  4208.   end PUT ;
  4209.  
  4210.   procedure PUT ( ITEM : VELOCITY_CENTIMETER_PER_SECOND ) is
  4211.  
  4212.   begin
  4213.     PUT ( UNDIMENSION( ITEM )) ;
  4214.     PUT ( " centimeter per second " ) ;
  4215.   end PUT ;
  4216.  
  4217.   procedure PUT ( ITEM : VELOCITY_KILOMETER_PER_HOUR ) is
  4218.  
  4219.   begin
  4220.     PUT ( UNDIMENSION( ITEM )) ;
  4221.     PUT ( " kilometer per hour " ) ;
  4222.   end PUT ;
  4223.  
  4224.   procedure PUT ( ITEM : VELOCITY_INCHES_PER_SECOND ) is
  4225.  
  4226.   begin
  4227.     PUT ( UNDIMENSION( ITEM )) ;
  4228.     PUT ( " inches per second " ) ;
  4229.   end PUT ;
  4230.  
  4231.   procedure PUT ( ITEM : VELOCITY_MILE_PER_HOUR ) is
  4232.  
  4233.   begin
  4234.     PUT ( UNDIMENSION( ITEM )) ;
  4235.     PUT ( " mile per hour " ) ;
  4236.   end PUT ;
  4237.  
  4238.   procedure PUT ( ITEM : VELOCITY_MILES_PER_SECOND ) is
  4239.  
  4240.   begin
  4241.     PUT ( UNDIMENSION( ITEM )) ;
  4242.     PUT ( " miles per second " ) ;
  4243.   end PUT ;
  4244.  
  4245.   procedure PUT ( ITEM : VELOCITY_INCHES_PER_MINUTE ) is
  4246.  
  4247.   begin
  4248.     PUT ( UNDIMENSION( ITEM )) ;
  4249.     PUT ( " inches per minute " ) ;
  4250.   end PUT ;
  4251.  
  4252.   procedure PUT ( ITEM : VELOCITY_FEET_PER_MINUTE ) is
  4253.  
  4254.   begin
  4255.     PUT ( UNDIMENSION( ITEM )) ;
  4256.     PUT ( " feet per minute " ) ;
  4257.   end PUT ;
  4258.  
  4259.   procedure PUT ( ITEM : VELOCITY_MILES_PER_HOUR ) is
  4260.  
  4261.   begin
  4262.     PUT ( UNDIMENSION( ITEM )) ;
  4263.     PUT ( " miles per hour " ) ;
  4264.   end PUT ;
  4265.  
  4266.   procedure PUT ( ITEM : VELOCITY_KNOTS ) is
  4267.  
  4268.   begin
  4269.     PUT ( UNDIMENSION( ITEM )) ;
  4270.     PUT ( " knots " ) ;
  4271.   end PUT ;
  4272.  
  4273.   procedure PUT ( ITEM : VELOCITY_FURLONG_PER_FORTNIGHT ) is
  4274.  
  4275.   begin
  4276.     PUT ( UNDIMENSION( ITEM )) ;
  4277.     PUT ( " furlong per fortnight " ) ;
  4278.   end PUT ;
  4279.  
  4280.   procedure PUT ( ITEM : ANGULAR_VELOCITY ) is
  4281.  
  4282.   begin
  4283.     PUT ( UNDIMENSION( ITEM )) ;
  4284.     PUT ( " radian per second " ) ;
  4285.   end PUT ;
  4286.  
  4287.   procedure PUT ( ITEM : ANGULAR_VELOCITY_DEGREES_PER_SECOND ) is
  4288.  
  4289.   begin
  4290.     PUT ( UNDIMENSION( ITEM )) ;
  4291.     PUT ( " degrees per second " ) ;
  4292.   end PUT ;
  4293.  
  4294.   procedure PUT ( ITEM : ANGULAR_VELOCITY_REVOLUTIONS_PER_MINUTE ) is
  4295.  
  4296.   begin
  4297.     PUT ( UNDIMENSION( ITEM )) ;
  4298.     PUT ( " revolutions per minute " ) ;
  4299.   end PUT ;
  4300.  
  4301.   procedure PUT ( ITEM : ANGULAR_VELOCITY_REVOLUTIONS_PER_SECOND ) is
  4302.  
  4303.   begin
  4304.     PUT ( UNDIMENSION( ITEM )) ;
  4305.     PUT ( " revolutions per second " ) ;
  4306.   end PUT ;
  4307.  
  4308.   procedure PUT ( ITEM : ACCELERATION_MKS ) is
  4309.  
  4310.   begin
  4311.     PUT ( UNDIMENSION( ITEM )) ;
  4312.     PUT ( " meter per second squared " ) ;
  4313.   end PUT ;
  4314.  
  4315.   procedure PUT ( ITEM : ACCELERATION_ENGLISH ) is
  4316.  
  4317.   begin
  4318.     PUT ( UNDIMENSION( ITEM )) ;
  4319.     PUT ( " foot per second squared " ) ;
  4320.   end PUT ;
  4321.  
  4322.   procedure PUT ( ITEM : ANGULAR_ACCELERATION ) is
  4323.  
  4324.   begin
  4325.     PUT ( UNDIMENSION( ITEM )) ;
  4326.     PUT ( " radians per second squared " ) ;
  4327.   end PUT ;
  4328.  
  4329.   procedure PUT ( ITEM : ANGULAR_ACCELERATION_REVOLUTIONS_PER_MINUTE_SQUARED )
  4330.       is
  4331.  
  4332.   begin
  4333.     PUT ( UNDIMENSION( ITEM )) ;
  4334.     PUT ( " revolutions per minute squared " ) ;
  4335.   end PUT ;
  4336.  
  4337.   procedure PUT ( ITEM : FORCE_MKS ) is
  4338.  
  4339.   begin
  4340.     PUT ( UNDIMENSION( ITEM )) ;
  4341.     PUT ( " newton " ) ;
  4342.   end PUT ;
  4343.  
  4344.   procedure PUT ( ITEM : FORCE_DYNE ) is
  4345.  
  4346.   begin
  4347.     PUT ( UNDIMENSION( ITEM )) ;
  4348.     PUT ( " dyne " ) ;
  4349.   end PUT ;
  4350.  
  4351.   procedure PUT ( ITEM : FORCE_ENGLISH ) is
  4352.  
  4353.   begin
  4354.     PUT ( UNDIMENSION( ITEM )) ;
  4355.     PUT ( " poundal " ) ;
  4356.   end PUT ;
  4357.  
  4358.   procedure PUT ( ITEM : ENERGY_MKS ) is
  4359.  
  4360.   begin
  4361.     PUT ( UNDIMENSION( ITEM )) ;
  4362.     PUT ( " joule " ) ;
  4363.   end PUT ;
  4364.  
  4365.   procedure PUT ( ITEM : ENERGY_ERG ) is
  4366.  
  4367.   begin
  4368.     PUT ( UNDIMENSION( ITEM )) ;
  4369.     PUT ( " erg " ) ;
  4370.   end PUT ;
  4371.  
  4372.   procedure PUT ( ITEM : ENERGY_GRAM_CALORIE ) is
  4373.  
  4374.   begin
  4375.     PUT ( UNDIMENSION( ITEM )) ;
  4376.     PUT ( " gram calorie " ) ;
  4377.   end PUT ;
  4378.  
  4379.   procedure PUT ( ITEM : ENERGY_KILOGRAM_CALORIE ) is
  4380.  
  4381.   begin
  4382.     PUT ( UNDIMENSION( ITEM )) ;
  4383.     PUT ( " kilogram calorie " ) ;
  4384.   end PUT ;
  4385.  
  4386.   procedure PUT ( ITEM : ENERGY_B_T_U ) is
  4387.  
  4388.   begin
  4389.     PUT ( UNDIMENSION( ITEM )) ;
  4390.     PUT ( " B.T.U. " ) ;
  4391.   end PUT ;
  4392.  
  4393.   procedure PUT ( ITEM : ENERGY_FOOT_POUND ) is
  4394.  
  4395.   begin
  4396.     PUT ( UNDIMENSION( ITEM )) ;
  4397.     PUT ( " foot pound " ) ;
  4398.   end PUT ;
  4399.  
  4400.   procedure PUT ( ITEM : ENERGY_KILOWATT_HOUR ) is
  4401.  
  4402.   begin
  4403.     PUT ( UNDIMENSION( ITEM )) ;
  4404.     PUT ( " kilowat hour " ) ;
  4405.   end PUT ;
  4406.  
  4407.   procedure PUT ( ITEM : ENERGY_HORSEPOWER_HOUR ) is
  4408.  
  4409.   begin
  4410.     PUT ( UNDIMENSION( ITEM )) ;
  4411.     PUT ( " horsepower hour " ) ;
  4412.   end PUT ;
  4413.  
  4414.   procedure PUT ( ITEM : POWER_MKS ) is
  4415.  
  4416.   begin
  4417.     PUT ( UNDIMENSION( ITEM )) ;
  4418.     PUT ( " watt " ) ;
  4419.   end PUT ;
  4420.  
  4421.   procedure PUT ( ITEM : POWER_KILOGRAM_CALORIE_PER_SECOND ) is
  4422.  
  4423.   begin
  4424.     PUT ( UNDIMENSION( ITEM )) ;
  4425.     PUT ( " kilogram calorie per second " ) ;
  4426.   end PUT ;
  4427.  
  4428.   procedure PUT ( ITEM : POWER_KILOGRAN_CALORIE_PER_MINUTE ) is
  4429.  
  4430.   begin
  4431.     PUT ( UNDIMENSION( ITEM )) ;
  4432.     PUT ( " kilogram calorie per minute " ) ;
  4433.   end PUT ;
  4434.  
  4435.   procedure PUT ( ITEM : POWER_HORSEPOWER_MECHANICAL ) is
  4436.  
  4437.   begin
  4438.     PUT ( UNDIMENSION( ITEM )) ;
  4439.     PUT ( " horsepower (mechanical) " ) ;
  4440.   end PUT ;
  4441.  
  4442.   procedure PUT ( ITEM : POWER_HORSEPOWER_ELECTRICAL ) is
  4443.  
  4444.   begin
  4445.     PUT ( UNDIMENSION( ITEM )) ;
  4446.     PUT ( " horsepower (electrical) " ) ;
  4447.   end PUT ;
  4448.  
  4449.   procedure PUT ( ITEM : POWER_HORSEPOWER_METRIC ) is
  4450.  
  4451.   begin
  4452.     PUT ( UNDIMENSION( ITEM )) ;
  4453.     PUT ( " horsepower ( metric) " ) ;
  4454.   end PUT ;
  4455.  
  4456.   procedure PUT ( ITEM : POWER_HORSEPOWER_BOILER ) is
  4457.  
  4458.   begin
  4459.     PUT ( UNDIMENSION( ITEM )) ;
  4460.     PUT ( " horsepower (boiler) " ) ;
  4461.   end PUT ;
  4462.  
  4463.   procedure PUT ( ITEM : POWER_B_T_U_PER_MINUTE ) is
  4464.  
  4465.   begin
  4466.     PUT ( UNDIMENSION( ITEM )) ;
  4467.     PUT ( " B.T.U. per minute " ) ;
  4468.   end PUT ;
  4469.  
  4470.   procedure PUT ( ITEM : POWER_B_T_U_PER_HOUR ) is
  4471.  
  4472.   begin
  4473.     PUT ( UNDIMENSION( ITEM )) ;
  4474.     PUT ( " B.T.U. per hour " ) ;
  4475.   end PUT ;
  4476.  
  4477.   procedure PUT ( ITEM : POWER_FOOT_POUND_PER_MINUTE ) is
  4478.  
  4479.   begin
  4480.     PUT ( UNDIMENSION( ITEM )) ;
  4481.     PUT ( " foot pound per minute " ) ;
  4482.   end PUT ;
  4483.  
  4484.   procedure PUT ( ITEM : POWER_FOOT_POUND_PER_SECOND ) is
  4485.  
  4486.   begin
  4487.     PUT ( UNDIMENSION( ITEM )) ;
  4488.     PUT ( " foot pound per second " ) ;
  4489.   end PUT ;
  4490.  
  4491.   procedure PUT ( ITEM : DENSITY_MKS ) is
  4492.  
  4493.   begin
  4494.     PUT ( UNDIMENSION( ITEM )) ;
  4495.     PUT ( " kilogram per cubic meter " ) ;
  4496.   end PUT ;
  4497.  
  4498.   procedure PUT ( ITEM : DENSITY_ENGLISH ) is
  4499.  
  4500.   begin
  4501.     PUT ( UNDIMENSION( ITEM )) ;
  4502.     PUT ( " pound per cubic foot " ) ;
  4503.   end PUT ;
  4504.  
  4505.   procedure PUT ( ITEM : FLOW_RATE_MKS ) is
  4506.  
  4507.   begin
  4508.     PUT ( UNDIMENSION( ITEM )) ;
  4509.     PUT ( " cubic meter per second " ) ;
  4510.   end PUT ;
  4511.  
  4512.   procedure PUT ( ITEM : FLOW_RATE_GALLON_PER_MINUTE ) is
  4513.  
  4514.   begin
  4515.     PUT ( UNDIMENSION( ITEM )) ;
  4516.     PUT ( " gallon per minute " ) ;
  4517.   end PUT ;
  4518.  
  4519.   procedure PUT ( ITEM : FLOW_RATE_ENGLISH ) is
  4520.  
  4521.   begin
  4522.     PUT ( UNDIMENSION( ITEM )) ;
  4523.     PUT ( " cubic feet per second " ) ;
  4524.   end PUT ;
  4525.  
  4526.   procedure PUT ( ITEM : FLOW_RATE_CUBIC_FEET_PER_MINUTE ) is
  4527.  
  4528.   begin
  4529.     PUT ( UNDIMENSION( ITEM )) ;
  4530.     PUT ( " cubic feet per minute " ) ;
  4531.   end PUT ;
  4532.  
  4533.   procedure PUT ( ITEM : PRESSURE_MKS ) is
  4534.  
  4535.   begin
  4536.     PUT ( UNDIMENSION( ITEM )) ;
  4537.     PUT ( " pascal " ) ;
  4538.   end PUT ;
  4539.  
  4540.   procedure PUT ( ITEM : PRESSURE_ENGLISH ) is
  4541.  
  4542.   begin
  4543.     PUT ( UNDIMENSION( ITEM )) ;
  4544.     PUT ( " pound per square foot " ) ;
  4545.   end PUT ;
  4546.  
  4547.   procedure PUT ( ITEM : PRESSURE_TON_PER_SQUARE_FOOT ) is
  4548.  
  4549.   begin
  4550.     PUT ( UNDIMENSION( ITEM )) ;
  4551.     PUT ( " ton per square foot " ) ;
  4552.   end PUT ;
  4553.  
  4554.   procedure PUT ( ITEM : PRESSURE_ATMOSPHERE_STANDARD ) is
  4555.  
  4556.   begin
  4557.     PUT ( UNDIMENSION( ITEM )) ;
  4558.     PUT ( " atmosphere " ) ;
  4559.   end PUT ;
  4560.  
  4561.   procedure PUT ( ITEM : PRESSURE_FEET_OF_WATER ) is
  4562.  
  4563.   begin
  4564.     PUT ( UNDIMENSION( ITEM )) ;
  4565.     PUT ( " feet of water " ) ;
  4566.   end PUT ;
  4567.  
  4568.   procedure PUT ( ITEM : PRESSURE_INCHES_OF_MERCURY ) is
  4569.  
  4570.   begin
  4571.     PUT ( UNDIMENSION( ITEM )) ;
  4572.     PUT ( " inches of mercury " ) ;
  4573.   end PUT ;
  4574.  
  4575.   procedure PUT ( ITEM : PRESSURE_MILLIMETER_OF_MERCURY ) is
  4576.  
  4577.   begin
  4578.     PUT ( UNDIMENSION( ITEM )) ;
  4579.     PUT ( " millimeter of mercury " ) ;
  4580.   end PUT ;
  4581.  
  4582.   procedure PUT ( ITEM : PRESSURE_BAR ) is
  4583.  
  4584.   begin
  4585.     PUT ( UNDIMENSION( ITEM )) ;
  4586.     PUT ( " bar " ) ;
  4587.   end PUT ;
  4588.  
  4589.   procedure PUT ( ITEM : PRESSURE_MILLIBAR ) is
  4590.  
  4591.   begin
  4592.     PUT ( UNDIMENSION( ITEM )) ;
  4593.     PUT ( " millibar " ) ;
  4594.   end PUT ;
  4595.  
  4596.   procedure PUT ( ITEM : PRESSURE_TORR ) is
  4597.  
  4598.   begin
  4599.     PUT ( UNDIMENSION( ITEM )) ;
  4600.     PUT ( " torr " ) ;
  4601.   end PUT ;
  4602.  
  4603.   procedure PUT ( ITEM : MOMENTUM_MKS ) is
  4604.  
  4605.   begin
  4606.     PUT ( UNDIMENSION( ITEM )) ;
  4607.     PUT ( " newton per second " ) ;
  4608.   end PUT ;
  4609.  
  4610.   procedure PUT ( ITEM : INERTIA_MKS ) is
  4611.  
  4612.   begin
  4613.     PUT ( UNDIMENSION( ITEM )) ;
  4614.     PUT ( " joule second " ) ;
  4615.   end PUT ;
  4616.  
  4617.   procedure PUT ( ITEM : MOMENT_OF_INERTIA_MKS ) is
  4618.  
  4619.   begin
  4620.     PUT ( UNDIMENSION( ITEM )) ;
  4621.     PUT ( " kilogram meter squared " ) ;
  4622.   end PUT ;
  4623.  
  4624.   procedure PUT ( ITEM : KINEMATIC_VISCOSITY_MKS ) is
  4625.  
  4626.   begin
  4627.     PUT ( UNDIMENSION( ITEM )) ;
  4628.     PUT ( " meter squared per second " ) ;
  4629.   end PUT ;
  4630.  
  4631.   procedure PUT ( ITEM : DYNAMIC_VISCOSITY_MKS ) is
  4632.  
  4633.   begin
  4634.     PUT ( UNDIMENSION( ITEM )) ;
  4635.     PUT ( " newton second per square meter " ) ;
  4636.   end PUT ;
  4637.  
  4638.   procedure PUT ( ITEM : LUMINOUS_FLUX_LUMEN ) is
  4639.  
  4640.   begin
  4641.     PUT ( UNDIMENSION( ITEM )) ;
  4642.     PUT ( " lumen " ) ;
  4643.   end PUT ;
  4644.  
  4645.   procedure PUT ( ITEM : ILLUMINATION_MKS ) is
  4646.  
  4647.   begin
  4648.     PUT ( UNDIMENSION( ITEM )) ;
  4649.     PUT ( " lumen per square meter " ) ;
  4650.   end PUT ;
  4651.  
  4652.   procedure PUT ( ITEM : LUMINANCE_MKS ) is
  4653.  
  4654.   begin
  4655.     PUT ( UNDIMENSION( ITEM )) ;
  4656.     PUT ( " lux " ) ;
  4657.   end PUT ;
  4658.  
  4659.   procedure PUT ( ITEM : ENTROPY_MKS ) is
  4660.  
  4661.   begin
  4662.     PUT ( UNDIMENSION( ITEM )) ;
  4663.     PUT ( " joule per degree centegrade " ) ;
  4664.   end PUT ;
  4665.  
  4666.   procedure PUT ( ITEM : SPECIFIC_HEAT_B_T_U_PER_POUND_DEGREE_FARENHEIT ) is
  4667.  
  4668.   begin
  4669.     PUT ( UNDIMENSION( ITEM )) ;
  4670.     PUT ( " B.T.U. per pound degree farenheit " ) ;
  4671.   end PUT ;
  4672.  
  4673. end PHYSICAL_UNITS_OUTPUT_MECHANICAL ;
  4674. --------------------------------------------------------------------------------
  4675.  
  4676.  
  4677.  
  4678.  
  4679.  
  4680.  
  4681.  
  4682.  
  4683.  
  4684. --------------------------------------------------------------------------------
  4685. with PHYSICAL_UNITS_BASIC ; use PHYSICAL_UNITS_BASIC ;
  4686. with PHYSICAL_UNITS_MECHANICAL ; use PHYSICAL_UNITS_MECHANICAL ;
  4687. with PHYSICAL_UNITS_OTHER ; use PHYSICAL_UNITS_OTHER ;
  4688.  
  4689. -- This package defines operators needed to evaluate equations of
  4690. -- physics using dimensional and units checking. Only MKS units
  4691. -- are used. A conversion package is available to convert from
  4692. -- other metric units and English units to the MKS units.
  4693. --
  4694. -- This package is not complete. Completeness would imply all
  4695. -- possible operators that combine physical dimensions and yeild
  4696. -- other physical dimensions. Users can provide local definitions
  4697. -- or this package can be augmented.
  4698. --
  4699.  
  4700. package MKS_PHYSICS_MECHANICAL is
  4701.  
  4702.   function "*" ( LEFT , RIGHT : LENGTH_MKS ) return AREA_MKS ;
  4703.  
  4704.   function SQRT ( LEFT : AREA_MKS ) return LENGTH_MKS ;
  4705.  
  4706.   function "**" ( LEFT : LENGTH_MKS ;
  4707.                   RIGHT : INTEGER ) return AREA_MKS ;
  4708.  
  4709.   function "**" ( LEFT : LENGTH_MKS ;
  4710.                   RIGHT : INTEGER ) return VOLUME_MKS ;
  4711.  
  4712.   function "*" ( LEFT : AREA_MKS ;
  4713.                  RIGHT : LENGTH_MKS ) return VOLUME_MKS ;
  4714.  
  4715.   function "*" ( LEFT : LENGTH_MKS ;
  4716.                  RIGHT : AREA_MKS ) return VOLUME_MKS ;
  4717.  
  4718.   function CUBE_ROOT ( LEFT : VOLUME_MKS ) return LENGTH_MKS ;
  4719.  
  4720.   function "/" ( LEFT : VOLUME_MKS ;
  4721.                  RIGHT : LENGTH_MKS ) return AREA_MKS ;
  4722.  
  4723.   function "/" ( LEFT : LENGTH_MKS ;
  4724.                  RIGHT : TIME_SECOND ) return VELOCITY_MKS ;
  4725.  
  4726.   function "/" ( LEFT : LENGTH_MKS ;
  4727.                  RIGHT : TIME_SECOND_SQUARED ) return ACCELERATION_MKS ;
  4728.  
  4729.   function "*" ( LEFT , RIGHT : TIME_SECOND ) return TIME_SECOND_SQUARED ;
  4730.  
  4731.   function "**" ( LEFT : TIME_SECOND ;
  4732.                   RIGHT : INTEGER ) return TIME_SECOND_SQUARED ;
  4733.  
  4734.   function "**" ( LEFT : VELOCITY_MKS ;
  4735.                   RIGHT : INTEGER ) return VELOCITY_SQUARED_MKS ;
  4736.  
  4737.   function SQRT ( LEFT : TIME_SECOND_SQUARED ) return TIME_SECOND ;
  4738.  
  4739.   function "*" ( LEFT , RIGHT : VELOCITY_MKS ) return VELOCITY_SQUARED_MKS ;
  4740.  
  4741.   function SQRT ( LEFT : VELOCITY_SQUARED_MKS ) return VELOCITY_MKS ;
  4742.  
  4743.   function "*" ( LEFT : ACCELERATION_MKS ;
  4744.                  RIGHT : TIME_SECOND_SQUARED ) return LENGTH_MKS ;
  4745.  
  4746.   function "/" ( LEFT : LENGTH_MKS ;
  4747.                  RIGHT : ACCELERATION_MKS ) return TIME_SECOND_SQUARED ;
  4748.  
  4749.   function "*" ( LEFT : ACCELERATION_MKS ;
  4750.                  RIGHT : LENGTH_MKS ) return VELOCITY_SQUARED_MKS ;
  4751.  
  4752.   function "*" ( LEFT : LENGTH_MKS ;
  4753.                  RIGHT : ACCELERATION_MKS ) return VELOCITY_SQUARED_MKS ;
  4754.  
  4755.   function "*" ( LEFT : ACCELERATION_MKS ;
  4756.                  RIGHT : TIME_SECOND ) return VELOCITY_MKS ;
  4757.  
  4758.   function "*" ( LEFT : TIME_SECOND ;
  4759.                  RIGHT : ACCELERATION_MKS ) return VELOCITY_MKS ;
  4760.  
  4761.   function "*" ( LEFT : MASS_MKS ;
  4762.                  RIGHT : ACCELERATION_MKS ) return FORCE_MKS ;
  4763.  
  4764.   function "*" ( LEFT : ACCELERATION_MKS ;
  4765.                  RIGHT : MASS_MKS ) return FORCE_MKS ;
  4766.  
  4767.   function "*" ( LEFT : PRESSURE_MKS ;
  4768.                  RIGHT : AREA_MKS ) return FORCE_MKS ;
  4769.  
  4770.   function "*" ( LEFT : AREA_MKS ;
  4771.                  RIGHT : PRESSURE_MKS ) return FORCE_MKS ;
  4772.  
  4773.   function "/" ( LEFT : POWER_MKS ;
  4774.                  RIGHT : VELOCITY_MKS ) return FORCE_MKS ;
  4775.  
  4776.   function "/" ( LEFT : ENERGY_MKS ;
  4777.                  RIGHT : LENGTH_MKS ) return FORCE_MKS ;
  4778.  
  4779.   function "*" ( LEFT : PRESSURE_MKS ;
  4780.                  RIGHT : VOLUME_MKS ) return ENERGY_MKS ;
  4781.  
  4782.   function "*" ( LEFT : VOLUME_MKS ;
  4783.                  RIGHT : PRESSURE_MKS ) return ENERGY_MKS ;
  4784.  
  4785.   function "*" ( LEFT : FORCE_MKS ;
  4786.                  RIGHT : LENGTH_MKS ) return ENERGY_MKS ;
  4787.  
  4788.   function "*" ( LEFT : LENGTH_MKS ;
  4789.                  RIGHT : FORCE_MKS ) return ENERGY_MKS ;
  4790.  
  4791.   function "*" ( LEFT : MASS_MKS ;
  4792.                  RIGHT : VELOCITY_SQUARED_MKS ) return ENERGY_MKS ;
  4793.  
  4794.   function "*" ( LEFT : VELOCITY_SQUARED_MKS ;
  4795.                  RIGHT : MASS_MKS ) return ENERGY_MKS ;
  4796.  
  4797.   function "*" ( LEFT : POWER_MKS ;
  4798.                  RIGHT : TIME_SECOND ) return ENERGY_MKS ;
  4799.  
  4800.   function "*" ( LEFT : TIME_SECOND ;
  4801.                  RIGHT : POWER_MKS ) return ENERGY_MKS ;
  4802.  
  4803.   function "*" ( LEFT : FORCE_MKS ;
  4804.                  RIGHT : VELOCITY_MKS ) return POWER_MKS ;
  4805.  
  4806.   function "*" ( LEFT : VELOCITY_MKS ;
  4807.                  RIGHT : FORCE_MKS ) return POWER_MKS ;
  4808.  
  4809.   function "/" ( LEFT : ENERGY_MKS ;
  4810.                  RIGHT : TIME_SECOND ) return POWER_MKS ;
  4811.  
  4812.  
  4813.   pragma INLINE ( "*", "/" , "**", SQRT ) ;
  4814.  
  4815. end MKS_PHYSICS_MECHANICAL ;
  4816.  
  4817. --------------------------------------------------------------------------------
  4818.  
  4819.  
  4820.  
  4821.  
  4822.  
  4823.  
  4824.  
  4825.  
  4826.  
  4827. --------------------------------------------------------------------------------
  4828. -- with LONG_REFUNCT; use LONG_REFUNCT;                        --Alstad
  4829. with PHYSICAL_REAL ; use PHYSICAL_REAL ;
  4830.  
  4831. package body MKS_PHYSICS_MECHANICAL is
  4832.  
  4833.   function "*" ( LEFT , RIGHT : LENGTH_MKS ) return AREA_MKS is
  4834.  
  4835.   begin
  4836.     return AREA_MKS'  --
  4837.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4838.   end "*" ;
  4839.  
  4840.   function SQRT ( LEFT : AREA_MKS ) return LENGTH_MKS is
  4841.  
  4842.   begin
  4843.     return LENGTH_MKS' ( DIMENSION( SQRT( UNDIMENSION( LEFT )))) ;
  4844.   end SQRT ;
  4845.  
  4846.   function "**" ( LEFT : LENGTH_MKS ;
  4847.                   RIGHT : INTEGER ) return AREA_MKS is
  4848.  
  4849.   begin
  4850.     if RIGHT /= 2 then
  4851.       raise NUMERIC_ERROR ;
  4852.     end if ;
  4853.     return AREA_MKS'  --
  4854.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( LEFT ))) ;
  4855.   end "**" ;
  4856.  
  4857.   function "**" ( LEFT : LENGTH_MKS ;
  4858.                   RIGHT : INTEGER ) return VOLUME_MKS is
  4859.  
  4860.   begin
  4861.     if RIGHT /= 3 then
  4862.       raise NUMERIC_ERROR ;
  4863.     end if ;
  4864.     return VOLUME_MKS'  --
  4865.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( LEFT ) * UNDIMENSION
  4866.         ( LEFT ))) ;
  4867.   end "**" ;
  4868.  
  4869.   function "*" ( LEFT : AREA_MKS ;
  4870.                  RIGHT : LENGTH_MKS ) return VOLUME_MKS is
  4871.  
  4872.   begin
  4873.     return VOLUME_MKS'  --
  4874.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4875.   end "*" ;
  4876.  
  4877.   function "*" ( LEFT : LENGTH_MKS ;
  4878.                  RIGHT : AREA_MKS ) return VOLUME_MKS is
  4879.  
  4880.   begin
  4881.     return VOLUME_MKS'  --
  4882.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4883.   end "*" ;
  4884.  
  4885.   function CUBE_ROOT ( LEFT : VOLUME_MKS ) return LENGTH_MKS is
  4886.  
  4887.   begin
  4888.     return LENGTH_MKS' ( DIMENSION( CUBE_ROOT( UNDIMENSION( LEFT ))));  --Alstad
  4889.   end CUBE_ROOT ;
  4890.  
  4891.   function "/" ( LEFT : VOLUME_MKS ;
  4892.                  RIGHT : LENGTH_MKS ) return AREA_MKS is
  4893.  
  4894.   begin
  4895.     return AREA_MKS'  --
  4896.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  4897.   end "/" ;
  4898.  
  4899.   function "/" ( LEFT : LENGTH_MKS ;
  4900.                  RIGHT : TIME_SECOND ) return VELOCITY_MKS is
  4901.  
  4902.   begin
  4903.     return VELOCITY_MKS'  --
  4904.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  4905.   end "/" ;
  4906.  
  4907.   function "/" ( LEFT : LENGTH_MKS ;
  4908.                  RIGHT : TIME_SECOND_SQUARED ) return ACCELERATION_MKS is
  4909.  
  4910.   begin
  4911.     return ACCELERATION_MKS'  --
  4912.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  4913.   end "/" ;
  4914.  
  4915.   function "*" ( LEFT , RIGHT : TIME_SECOND ) return TIME_SECOND_SQUARED is
  4916.  
  4917.   begin
  4918.     return TIME_SECOND_SQUARED'  --
  4919.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4920.   end "*" ;
  4921.  
  4922.   function "**" ( LEFT : TIME_SECOND ;
  4923.                   RIGHT : INTEGER ) return TIME_SECOND_SQUARED is
  4924.  
  4925.   begin
  4926.     if RIGHT /= 2 then
  4927.       raise NUMERIC_ERROR ;
  4928.     end if ;
  4929.     return TIME_SECOND_SQUARED'  --
  4930.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( LEFT ))) ;
  4931.   end "**" ;
  4932.  
  4933.   function "**" ( LEFT : VELOCITY_MKS ;
  4934.                   RIGHT : INTEGER ) return VELOCITY_SQUARED_MKS is
  4935.  
  4936.   begin
  4937.     if RIGHT /= 2 then
  4938.       raise NUMERIC_ERROR ;
  4939.     end if ;
  4940.     return VELOCITY_SQUARED_MKS'  --
  4941.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( LEFT ))) ;
  4942.   end "**" ;
  4943.  
  4944.   function SQRT ( LEFT : TIME_SECOND_SQUARED ) return TIME_SECOND is
  4945.  
  4946.   begin
  4947.     return TIME_SECOND' ( DIMENSION( SQRT( UNDIMENSION( LEFT )))) ;
  4948.   end SQRT ;
  4949.  
  4950.   function "*" ( LEFT , RIGHT : VELOCITY_MKS ) return VELOCITY_SQUARED_MKS is
  4951.  
  4952.   begin
  4953.     return VELOCITY_SQUARED_MKS'  --
  4954.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4955.   end "*" ;
  4956.  
  4957.   function SQRT ( LEFT : VELOCITY_SQUARED_MKS ) return VELOCITY_MKS is
  4958.  
  4959.   begin
  4960.     return VELOCITY_MKS' ( DIMENSION( SQRT( UNDIMENSION( LEFT )))) ;
  4961.   end SQRT ;
  4962.  
  4963.   function "*" ( LEFT : ACCELERATION_MKS ;
  4964.                  RIGHT : TIME_SECOND_SQUARED ) return LENGTH_MKS is
  4965.  
  4966.   begin
  4967.     return LENGTH_MKS'  --
  4968.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4969.   end "*" ;
  4970.  
  4971.   function "/" ( LEFT : LENGTH_MKS ;
  4972.                  RIGHT : ACCELERATION_MKS ) return TIME_SECOND_SQUARED is
  4973.  
  4974.   begin
  4975.     return TIME_SECOND_SQUARED'  --
  4976.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  4977.   end "/" ;
  4978.  
  4979.   function "*" ( LEFT : ACCELERATION_MKS ;
  4980.                  RIGHT : LENGTH_MKS ) return VELOCITY_SQUARED_MKS is
  4981.  
  4982.   begin
  4983.     return VELOCITY_SQUARED_MKS'  --
  4984.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4985.   end "*" ;
  4986.  
  4987.   function "*" ( LEFT : LENGTH_MKS ;
  4988.                  RIGHT : ACCELERATION_MKS ) return VELOCITY_SQUARED_MKS is
  4989.  
  4990.   begin
  4991.     return VELOCITY_SQUARED_MKS'  --
  4992.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  4993.   end "*" ;
  4994.  
  4995.   function "*" ( LEFT : ACCELERATION_MKS ;
  4996.                  RIGHT : TIME_SECOND ) return VELOCITY_MKS is
  4997.  
  4998.   begin
  4999.     return VELOCITY_MKS'  --
  5000.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5001.   end "*" ;
  5002.  
  5003.   function "*" ( LEFT : TIME_SECOND ;
  5004.                  RIGHT : ACCELERATION_MKS ) return VELOCITY_MKS is
  5005.  
  5006.   begin
  5007.     return VELOCITY_MKS'  --
  5008.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5009.   end "*" ;
  5010.  
  5011.   function "*" ( LEFT : MASS_MKS ;
  5012.                  RIGHT : ACCELERATION_MKS ) return FORCE_MKS is
  5013.  
  5014.   begin
  5015.     return FORCE_MKS'  --
  5016.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5017.   end "*" ;
  5018.  
  5019.   function "*" ( LEFT : ACCELERATION_MKS ;
  5020.                  RIGHT : MASS_MKS ) return FORCE_MKS is
  5021.  
  5022.   begin
  5023.     return FORCE_MKS'  --
  5024.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5025.   end "*" ;
  5026.  
  5027.   function "*" ( LEFT : PRESSURE_MKS ;
  5028.                  RIGHT : AREA_MKS ) return FORCE_MKS is
  5029.  
  5030.   begin
  5031.     return FORCE_MKS'  --
  5032.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5033.   end "*" ;
  5034.  
  5035.   function "*" ( LEFT : AREA_MKS ;
  5036.                  RIGHT : PRESSURE_MKS ) return FORCE_MKS is
  5037.  
  5038.   begin
  5039.     return FORCE_MKS'  --
  5040.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5041.   end "*" ;
  5042.  
  5043.   function "/" ( LEFT : POWER_MKS ;
  5044.                  RIGHT : VELOCITY_MKS ) return FORCE_MKS is
  5045.  
  5046.   begin
  5047.     return FORCE_MKS'  --
  5048.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  5049.   end "/" ;
  5050.  
  5051.   function "/" ( LEFT : ENERGY_MKS ;
  5052.                  RIGHT : LENGTH_MKS ) return FORCE_MKS is
  5053.  
  5054.   begin
  5055.     return FORCE_MKS'  --
  5056.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  5057.   end "/" ;
  5058.  
  5059.   function "*" ( LEFT : PRESSURE_MKS ;
  5060.                  RIGHT : VOLUME_MKS ) return ENERGY_MKS is
  5061.  
  5062.   begin
  5063.     return ENERGY_MKS'  --
  5064.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5065.   end "*" ;
  5066.  
  5067.   function "*" ( LEFT : VOLUME_MKS ;
  5068.                  RIGHT : PRESSURE_MKS ) return ENERGY_MKS is
  5069.  
  5070.   begin
  5071.     return ENERGY_MKS'  --
  5072.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5073.   end "*" ;
  5074.  
  5075.   function "*" ( LEFT : FORCE_MKS ;
  5076.                  RIGHT : LENGTH_MKS ) return ENERGY_MKS is
  5077.  
  5078.   begin
  5079.     return ENERGY_MKS'  --
  5080.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5081.   end "*" ;
  5082.  
  5083.   function "*" ( LEFT : LENGTH_MKS ;
  5084.                  RIGHT : FORCE_MKS ) return ENERGY_MKS is
  5085.  
  5086.   begin
  5087.     return ENERGY_MKS'  --
  5088.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5089.   end "*" ;
  5090.  
  5091.   function "*" ( LEFT : MASS_MKS ;
  5092.                  RIGHT : VELOCITY_SQUARED_MKS ) return ENERGY_MKS is
  5093.  
  5094.   begin
  5095.     return ENERGY_MKS'  --
  5096.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5097.   end "*" ;
  5098.  
  5099.   function "*" ( LEFT : VELOCITY_SQUARED_MKS ;
  5100.                  RIGHT : MASS_MKS ) return ENERGY_MKS is
  5101.  
  5102.   begin
  5103.     return ENERGY_MKS'  --
  5104.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5105.   end "*" ;
  5106.  
  5107.   function "*" ( LEFT : POWER_MKS ;
  5108.                  RIGHT : TIME_SECOND ) return ENERGY_MKS is
  5109.  
  5110.   begin
  5111.     return ENERGY_MKS'  --
  5112.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5113.   end "*" ;
  5114.  
  5115.   function "*" ( LEFT : TIME_SECOND ;
  5116.                  RIGHT : POWER_MKS ) return ENERGY_MKS is
  5117.  
  5118.   begin
  5119.     return ENERGY_MKS'  --
  5120.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5121.   end "*" ;
  5122.  
  5123.   function "*" ( LEFT : FORCE_MKS ;
  5124.                  RIGHT : VELOCITY_MKS ) return POWER_MKS is
  5125.  
  5126.   begin
  5127.     return POWER_MKS'  --
  5128.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5129.   end "*" ;
  5130.  
  5131.   function "*" ( LEFT : VELOCITY_MKS ;
  5132.                  RIGHT : FORCE_MKS ) return POWER_MKS is
  5133.  
  5134.   begin
  5135.     return POWER_MKS'  --
  5136.         ( DIMENSION( UNDIMENSION( LEFT ) * UNDIMENSION ( RIGHT ))) ;
  5137.   end "*" ;
  5138.  
  5139.   function "/" ( LEFT : ENERGY_MKS ;
  5140.                  RIGHT : TIME_SECOND ) return POWER_MKS is
  5141.  
  5142.   begin
  5143.     return POWER_MKS'  --
  5144.         ( DIMENSION( UNDIMENSION( LEFT ) / UNDIMENSION ( RIGHT ))) ;
  5145.   end "/" ;
  5146. end MKS_PHYSICS_MECHANICAL ;
  5147. --------------------------------------------------------------------------------
  5148.  
  5149.  
  5150.  
  5151.  
  5152.  
  5153.  
  5154.  
  5155.  
  5156.  
  5157. --------------------------------------------------------------------------------
  5158.  
  5159. -- This procedure solves a few physics problems involving
  5160. -- time, distance, vecocity and acceleration. All units are 
  5161. -- in the MKS system of units. Note that all "put" calls
  5162. -- on physical quantities are to be printed as the value followed
  5163. -- by the unit.
  5164. --
  5165. -- make available types for physical units
  5166. with PHYSICAL_UNITS_BASIC ; use PHYSICAL_UNITS_BASIC ;
  5167. with PHYSICAL_UNITS_MECHANICAL ; use PHYSICAL_UNITS_MECHANICAL ;
  5168. with PHYSICAL_UNITS_OTHER ; use PHYSICAL_UNITS_OTHER ;
  5169.  
  5170. -- make available operations on MKS types
  5171. with MKS_PHYSICS_MECHANICAL ; use MKS_PHYSICS_MECHANICAL ;
  5172.  
  5173. -- make PUT available for physical units types
  5174. with PHYSICAL_UNITS_OUTPUT_BASIC ; use PHYSICAL_UNITS_OUTPUT_BASIC ;
  5175. with PHYSICAL_UNITS_OUTPUT_MECHANICAL ; use PHYSICAL_UNITS_OUTPUT_MECHANICAL ;
  5176.  
  5177. --
  5178. with TEXT_IO ; use TEXT_IO ;
  5179.  
  5180. procedure PHYSICS_1 is
  5181.  
  5182. --    define acceleration due to gravity
  5183.   G : ACCELERATION_MKS := DIMENSION ( 9.80665 ) ;
  5184.   FALL : DISTANCE_METER ;
  5185.   FALL_TIME : TIME_SECOND ;
  5186.   V_FINAL : VELOCITY_METER_PER_SECOND ;
  5187. begin
  5188.   PUT ( " Test printout and value of acceleration, " ) ;
  5189.   PUT ( G ) ;
  5190.   PUT_LINE ( " = G " ) ;
  5191.  
  5192. -- How far will Ball_1 fall in 1.5 second in earths gravity ?
  5193.   FALL := 0.5 * G * TIME_SECOND' ( DIMENSION( 1.5 )) ** 2 ;
  5194.   PUT ( FALL ) ;
  5195.   NEW_LINE ;
  5196.  
  5197. -- Cross check that the time for the ball to fall is 1.5 seconds.
  5198.   FALL_TIME := SQRT ( 2.0 * FALL / G ) ;
  5199.   PUT ( FALL_TIME ) ;
  5200.   NEW_LINE ;
  5201.  
  5202. -- Now determine the final velocity if the ball falls another 0.2 meter
  5203. -- Method :  square root of initial velocity squared plus twice
  5204. --           the acceleration times the distance
  5205.   V_FINAL := SQRT (( G * FALL_TIME ) ** 2 + 2.0 * G * FALL) ;
  5206.   PUT ( V_FINAL ) ;
  5207.   NEW_LINE ;
  5208. end PHYSICS_1 ;
  5209.  
  5210.  
  5211. ------- End of Forwarded Message
  5212.  
  5213.  
  5214. ------- End of Forwarded Message
  5215.  
  5216.  
  5217.  
  5218. -------------------------------------------------------------------
  5219. ---------------------  Next  Program  -----------------------------
  5220. -------------------------------------------------------------------
  5221.  
  5222.  
  5223.  
  5224. ----------------------------------------------------------------------
  5225. --
  5226. --        PRODUCER / CONSUMER TASKING BENCHMARK
  5227. --
  5228. --        Version: @(#)conprod.ada    1.3    Date: 6/20/84
  5229. --
  5230. --                Gerry Fisher
  5231. --            Computer Sciences Corporation
  5232. --                May 27, 1984
  5233. --
  5234. --  This benchmark tests tasking performance using the buffering task
  5235. --  given as an example in chapter 9.12 of the Ada RM.  The consumer
  5236. --  task is the main program itself; the producer and buffer tasks
  5237. --  are declared as tasks within it.  During execution each "write"
  5238. --  entry call produces a "." on the standard output file, while each
  5239. --  "read" call produces a "*".  When all the produced data has been
  5240. --  consumed a check is made to see that the data has arrived in the
  5241. --  correct order and that no data remains buffered within the buffer
  5242. --  task.
  5243. --
  5244. ----------------------------------------------------------------------
  5245.  
  5246. with text_io; use text_io;
  5247. procedure main is
  5248.  
  5249.   all_there : boolean;
  5250.  
  5251. begin
  5252.   set_line_length(50);
  5253.   put_line("*** Producer/Consumer Task Test");
  5254.  
  5255.   declare
  5256.  
  5257.     x         : array(character) of character := (others => ' ');
  5258.     pool_size : constant integer := 5;
  5259.     pool      : array(1 .. pool_size) of character;
  5260.     count     : integer range 0 .. pool_size := 0;
  5261.  
  5262.     task buffer is
  5263.       entry read (c : out character);
  5264.       entry write(c : in  character);
  5265.     end buffer;
  5266.  
  5267.     task producer;
  5268.  
  5269.     task body producer is
  5270.     begin
  5271.       for c in character loop
  5272.         buffer.write(c);
  5273.       end loop;
  5274.     end producer;
  5275.  
  5276.     task body buffer is
  5277.       in_index, out_index : integer range 1 .. pool_size := 1;
  5278.     begin
  5279.       loop
  5280.         select
  5281.           when count < pool_size =>
  5282.         accept write(c : in character) do
  5283.           pool(in_index) := c;
  5284.         end write;
  5285.         put('.');
  5286.         in_index := in_index mod pool_size + 1;
  5287.         count    := count + 1;
  5288.         or when count > 0 =>
  5289.         accept read(c : out character) do
  5290.           c := pool(out_index);
  5291.         end read;
  5292.         put('*');
  5293.         out_index := out_index mod pool_size + 1;
  5294.         count := count - 1;
  5295.         or
  5296.           terminate;
  5297.         end select;
  5298.       end loop;
  5299.     end buffer;
  5300.  
  5301.     function Is_ok return boolean is
  5302.     begin
  5303.       for i in x'range loop
  5304.         if x(i) /= i then return false; end if;
  5305.       end loop;
  5306.       return true;
  5307.     end Is_ok;
  5308.  
  5309.   begin
  5310.     for i in x'range loop
  5311.       buffer.read(x(i));
  5312.     end loop;
  5313.     all_there := Is_ok;
  5314.   end;
  5315.  
  5316.   new_line;
  5317.   if all_there then
  5318.     put_line("*** PASSED Producer/Consumer Task Test");
  5319.   else
  5320.     put_line("*** FAILED Producer/Consumer Task Test");
  5321.   end if;
  5322. end main;
  5323.  
  5324.  
  5325.  
  5326.  
  5327. -------------------------------------------------------------------
  5328. ---------------------  Next  Program  -----------------------------
  5329. -------------------------------------------------------------------
  5330.  
  5331.  
  5332.  
  5333. --
  5334. -- Version: @(#)derived.ada    1.2        Date: 7/2/84
  5335. --
  5336. -- Author:  Bryce Bardin
  5337. --          Ada Projects Section
  5338. --          Software Engineering Division
  5339. --          Ground Systems Group
  5340. --          Hughes Aircraft Company
  5341. --          Fullerton, CA
  5342. --
  5343. -- This program tests the inter-conversion of derived types with 
  5344. -- different representations.  An approriate message is output to 
  5345. -- indicate "pass" or "fail".
  5346. --
  5347. --
  5348. -- Define the original types:
  5349. with Text_IO; use Text_IO;
  5350. package Originals is
  5351.  
  5352.    type Bit is range 0 .. 1;
  5353.  
  5354.    type Bit_String is array (Positive range <>) of Bit;
  5355.  
  5356.    subtype Word is Bit_String (1 .. 16);
  5357.  
  5358.    type Byte is range 0 .. 255;
  5359.  
  5360.    type Block is
  5361.       record
  5362.      First : Byte;
  5363.      Second : Word;
  5364.      Third : Byte;
  5365.       end record;
  5366.  
  5367.    package Byte_IO is new Integer_IO (Byte);
  5368.    use Byte_IO;
  5369.  
  5370.    procedure Put (B : Block);
  5371.  
  5372. end Originals;
  5373.  
  5374.  
  5375. package body Originals is
  5376.  
  5377.    procedure Put (B : Block) is
  5378.       S : String (1 .. Word'Length);
  5379.    begin
  5380.       Put("First = ");
  5381.       Put(B.First);
  5382.       for N in 1 .. Word'Length loop
  5383.      if B.Second(N) = 0 then
  5384.         S(N) := '0';
  5385.      else
  5386.             S(N) := '1';
  5387.      end if;
  5388.       end loop;
  5389.       Put(", Second = ");
  5390.       Put(S);
  5391.       Put(", Third = ");
  5392.       Put(B.Third);
  5393.       Put_Line(".");
  5394.    end Put;
  5395.  
  5396. end Originals;
  5397.  
  5398.  
  5399. -- Define the derived types:
  5400. with Originals; use Originals;
  5401. with System;
  5402. package Deriveds is
  5403.  
  5404.    type New_Block is new Block;
  5405.  
  5406.  for New_Block use
  5407.     record at mod System.Storage_Unit;
  5408.      First  at 0 range  0 ..  7;
  5409.      Second at 0 range  8 .. 23;
  5410.      Third  at 0 range 24 .. 31;
  5411.     end record;
  5412.  
  5413.  for New_Block'Size use 32;
  5414.  
  5415. end Deriveds;
  5416.  
  5417.  
  5418. -- Test conversion from derived to original types and vice versa.
  5419. with Originals; use Originals;
  5420. with Deriveds; use Deriveds;
  5421. with Text_IO; use Text_IO;
  5422. procedure Change_Representation is
  5423.  
  5424.    Original : Block := (First => 85, 
  5425.                Second => (1 .. 8 => 1, 9 .. 16 => 0),
  5426.                Third => 170);
  5427.  
  5428.    Derived  : New_Block := New_Block(Original);
  5429.  
  5430.    Copy : Block := Block(Derived);
  5431.  
  5432.    package Int_IO is new Integer_IO(Integer);
  5433.    use Int_IO;
  5434.  
  5435. begin
  5436.  
  5437.    Put_Line("Original:");
  5438.    Put(Original);
  5439.    New_Line;
  5440.  
  5441.    Put("Size = ");
  5442.    Put(Original'Size);
  5443.    Put_Line(" bits");
  5444.    New_Line;
  5445.  
  5446.    Put_Line("Derived:");
  5447.    Put(Derived);
  5448.    New_Line;
  5449.  
  5450.    Put("Size = ");
  5451.    Put(Derived'Size);
  5452.    Put_Line(" bits");
  5453.    New_Line;
  5454.  
  5455.    Put_Line("Copy:");
  5456.    Put(Copy);
  5457.    New_Line(2);
  5458.  
  5459.    if Copy = Original and Derived'Size = 32 then
  5460.       Put_Line("TEST PASSED!");
  5461.    else
  5462.       Put_Line("** TEST FAILED! **");
  5463.    end if;
  5464.  
  5465. end Change_Representation;
  5466.  
  5467.  
  5468.  
  5469.  
  5470.  
  5471.  
  5472. -------------------------------------------------------------------
  5473. ---------------------  Next  Program  -----------------------------
  5474. -------------------------------------------------------------------
  5475.  
  5476.  
  5477. --
  5478. -- Version: @(#)floatvec.ada    1.2        Date: 9/21/84
  5479. --
  5480. -- Author:  Edward Colbert
  5481. --        Ada Technology Group
  5482. --        Information Software Systems Lab
  5483. --        Defense Systems Group
  5484. --        TRW
  5485. --        Redondo Beach, CA
  5486. --
  5487. -- This program measures the time required for the adding of the
  5488. -- elements of a large floating point vector
  5489. --
  5490. -- Note:  In order for the measurement to be meaningful, it must be the 
  5491. -- only program executing while the test is run.  
  5492. --
  5493. -- Please set Vector_Size large enough to provide at least two significant 
  5494. -- digits in the average times, i.e., the difference between 
  5495. -- the elapsed time and the loop time must be at least 100 times 
  5496. -- Duration'Small & at least 100 times System.Tick.
  5497. --
  5498.  
  5499. with Text_IO; use Text_IO;
  5500. with Calendar; use Calendar;
  5501. with System; use System;
  5502. procedure Float_Vector_Add_Test is
  5503.  
  5504.    Vector_Size : constant Positive := 1000;
  5505.  
  5506.    type Real_Time is digits Max_Digits;
  5507.  
  5508.    Start_Time : Time;
  5509.    Loop_Time : Duration;
  5510.    Elapsed_Time : Duration;
  5511.    Average_Time : Real_Time;
  5512.  
  5513.    package Duration_IO is new Fixed_IO (Duration);
  5514.    use Duration_IO;
  5515.  
  5516.    package Real_Time_IO is new Float_IO (Real_Time);
  5517.    use Real_Time_IO;
  5518.  
  5519.    package Int_IO is new Integer_IO (Integer);
  5520.    use Int_IO;
  5521.  
  5522.    type vector is array (1..Vector_Size) of Float;
  5523.    
  5524.    v1, v2, vector_result: vector;
  5525.    count:  integer := integer'first;    -- used in timing loop
  5526.  
  5527. begin
  5528.  
  5529.    -- Initialize Vectors
  5530.    for N in vector'range loop
  5531.       v1(N) := float (N);
  5532.       v2(N) := float (vector'last - N + 1);
  5533.    end loop;
  5534.  
  5535.    -- Measure the timing loop overhead.
  5536.    Start_Time := Clock;
  5537.    for N in vector'range loop
  5538.       count := count + 1;        -- prevent optimization
  5539.    end loop;
  5540.    Loop_Time := Clock - Start_Time;
  5541.  
  5542.  
  5543.    -- Measure the time including the adding of vector elements
  5544.    Start_Time := Clock;
  5545.    for N in vector'range loop
  5546.       count := count + 1;        -- prevent optimization
  5547.       vector_result (n) := v1(n) + v2(n);
  5548.    end loop;
  5549.    Elapsed_Time := Clock - Start_Time;
  5550.  
  5551.  
  5552.    Put("Loop time = ");
  5553.    Put(Loop_Time, Fore => 0);
  5554.    Put(" seconds for ");
  5555.    Put(Vector_Size, Width => 0);
  5556.    Put_Line(" iterations");
  5557.  
  5558.  
  5559.    Put("Elapsed time = ");
  5560.    Put(Elapsed_Time, Fore => 0);
  5561.    Put(" seconds for ");
  5562.    Put(Vector_Size, Width => 0);
  5563.    Put_Line(" iterations (1 iteration/element)");
  5564.  
  5565.    Average_Time := Real_Time(Elapsed_Time - Loop_Time)/Real_Time(Vector_Size);
  5566.    Put("Average time for adding each element = ");
  5567.    Put(Average_Time, Fore => 0);
  5568.    Put_Line(" seconds");
  5569.  
  5570.    New_Line;
  5571.    if (Elapsed_Time - Loop_Time < 100 * Duration'Small    or
  5572.        Elapsed_Time - Loop_Time < 100 * System.Tick)    then
  5573.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  5574.    else
  5575.       Put_Line("** TEST PASSED **");
  5576.    end if;
  5577.  
  5578. end Float_Vector_Add_Test;
  5579.  
  5580.  
  5581. -------------------------------------------------------------------
  5582. ---------------------  Next  Program  -----------------------------
  5583. -------------------------------------------------------------------
  5584.  
  5585.  
  5586.  
  5587. --
  5588. -- Version: @(#)friend.ada    1.1        Date: 5/30/84
  5589. --
  5590. -- Author:  Bryce Bardin
  5591. --          Ada Projects Section
  5592. --          Software Engineering Division
  5593. --          Ground Systems Group
  5594. --          Hughes Aircraft Company
  5595. --          Fullerton, CA
  5596. --
  5597. -- The purpose of this program is to determine how "friendly" the Ada
  5598. -- compiler is with regard to warning about the use of uninitialized 
  5599. -- objects, exceptions which will always be raised, and both warning 
  5600. -- about and removal of code that will never be executed.
  5601. -- Compilers may be graded by the number of instances they catch in each 
  5602. -- of the three categories:  set/use errors, 'hard' exceptions, and 
  5603. -- 'dead' code removal.  A perfect score is: 12, 3, and 4, respectively.
  5604. -- Detection of set/use errors encountered during execution will not be
  5605. -- counted in the score even though it may be a useful feature to have.
  5606. -- Appropriate supporting evidence, such as an assembly listing, must be 
  5607. -- supplied if dead code removal is claimed.
  5608. -- N.B.:  It is not expected that any compiler will get a perfect score!
  5609. --
  5610. package Global is
  5611.    G : Integer; -- uninitialized
  5612. end Global;
  5613.  
  5614. with Global;
  5615. package Renamed is
  5616.    R : Integer renames Global.G; -- "A rose by any other name ..."
  5617. end Renamed;
  5618.  
  5619. with Text_IO; use Text_IO;
  5620. procedure Do_It is
  5621. begin
  5622.    Put_Line("Should do it.");
  5623. end Do_It;
  5624.  
  5625. with Text_IO; use Text_IO;
  5626. procedure Dont_Do_It is
  5627. begin
  5628.    Put_Line("Shouldn't have done it.");
  5629. end Dont_Do_It;
  5630.  
  5631. procedure Raise_It is
  5632. begin
  5633.    raise Program_Error;
  5634. end Raise_It;
  5635.  
  5636. with Global; use Global;
  5637. with Renamed; use Renamed;
  5638. with Do_It;
  5639. with Dont_Do_It;
  5640. with Raise_It;
  5641. procedure Friendly is
  5642.    L : Integer; -- uninitialized
  5643.    Use_1 : Integer := L; -- use before set 1
  5644.    Use_2 : Integer := G; -- use before set 2
  5645.    Use_3 : Integer := R; -- use before set 3
  5646.    Use_4 : Integer;
  5647.    Use_5 : Integer;
  5648.    Use_6 : Integer;
  5649.    Static : constant Integer := 8;
  5650.    Named : constant := 8;
  5651.    procedure Embedded (Data : Integer) is separate;
  5652. begin
  5653.    Use_4 := L; -- use before set 4
  5654.    Use_5 := G; -- use before set 5
  5655.    Use_6 := R; -- use before set 6
  5656.    Embedded(L); -- use before set 7
  5657.    Embedded(G); -- use before set 8
  5658.    Embedded(R); -- use before set 9
  5659.    if Static = 8 then
  5660.       Do_It;
  5661.    else
  5662.       Dont_Do_It; -- never executed 1
  5663.    end if;
  5664.    if Static - 4 /= 2**2 then
  5665.       Dont_Do_It; -- never executed 2
  5666.    else
  5667.       Do_It;
  5668.    end if;
  5669.    if Named mod 4 = 0 then
  5670.       Do_It;
  5671.    else
  5672.       Dont_Do_It; -- never executed 3
  5673.    end if;
  5674.    if Named/2 + 2 /= 6 then
  5675.       Dont_Do_It; -- never executed 4
  5676.    else
  5677.       Do_It;
  5678.    end if;
  5679.    Raise_It; -- always raised 1
  5680. end Friendly;
  5681.  
  5682. separate (Friendly)
  5683. procedure Embedded (Data : Integer) is
  5684.    Use_1 : Integer := L; -- use before set 10
  5685.    Use_2 : Integer := G; -- use before set 11
  5686.    Use_3 : Integer := R; -- use before set 12
  5687. begin
  5688.    Use_4 := Data; -- (if Data is uninitialized, causes a use before set)
  5689.    raise Program_Error; -- always raised 2
  5690.    Raise_It; -- always raised 3
  5691. end Embedded;
  5692.  
  5693.  
  5694. -------------------------------------------------------------------
  5695. ---------------------  Next  Program  -----------------------------
  5696. -------------------------------------------------------------------
  5697.  
  5698.  
  5699. --
  5700. -- Version: @(#)int_dir.ada    1.2        Date: 9/21/84
  5701. --
  5702. -- Author:  Edward Colbert
  5703. --        Ada Technology Group
  5704. --        Information Software Systems Lab
  5705. --        Defense Systems Group
  5706. --        TRW
  5707. --        Redondo Beach, CA
  5708. --
  5709. -- This program measures the time required for doing various file
  5710. -- operations using the Direct_IO package with Integer.
  5711. --
  5712. -- Note:  In order for the measurement to be meaningful, it must be the 
  5713. -- only program executing while the test is run.  
  5714. --
  5715. -- Please set Times large enough to provide at least two significant 
  5716. -- digits in the average times, i.e., the difference between 
  5717. -- the elapsed time and the loop time must be at least 100 times 
  5718. -- Duration'Small & at least 100 times System.Tick.
  5719. --
  5720.  
  5721. with Text_IO; use Text_IO;
  5722. with Direct_IO;
  5723. with Calendar; use Calendar;
  5724. with System; use System;
  5725. procedure Integer_Direct_IO_Test is
  5726.  
  5727.    Times : constant Positive := 1000;
  5728.  
  5729.    type Real_Time is digits Max_Digits;
  5730.  
  5731.    Start_Time : Time;
  5732.    Loop_Time : Duration;
  5733.    Average_Time : Real_Time;
  5734.    Create_Time : Duration;
  5735.    Close_Time  : Duration;
  5736.    Open_Time   : Duration;
  5737.    Delete_Time : Duration;
  5738.    Read_Time   : Duration;
  5739.    Write_Time  : Duration;
  5740.  
  5741.    package Duration_IO is new Fixed_IO (Duration);
  5742.    use Duration_IO;
  5743.  
  5744.    package Real_Time_IO is new Float_IO (Real_Time);
  5745.    use Real_Time_IO;
  5746.  
  5747.    package Int_IO is new Integer_IO (Integer);
  5748.    use Int_IO;
  5749.  
  5750.    package Int_Direct_IO is new Direct_IO (Integer);
  5751.    use Int_Direct_IO;
  5752.  
  5753.    file:   Int_Direct_IO.file_type;
  5754.    value:  Integer := 5;
  5755.    count:  Integer := Integer'first;    -- used in timing loop
  5756.  
  5757. begin
  5758.  
  5759.    -- Measure the timing loop overhead.
  5760.    Start_Time := Clock;
  5761.    for N in 1 .. Times loop
  5762.       count := count + 1;        -- prevent optimization
  5763.    end loop;
  5764.    Loop_Time := Clock - Start_Time;
  5765.  
  5766.  
  5767.    -- Create a file
  5768.    Start_Time := Clock;
  5769.    Int_Direct_IO.Create (file, mode => out_file, name => "test_file");
  5770.    Create_Time := Clock - Start_Time;
  5771.  
  5772.    -- Measure the time of Writing of value
  5773.    Start_Time := Clock;
  5774.    for N in 1 .. Times loop
  5775.       count := count + 1;
  5776.       Int_Direct_IO.write (file, value);
  5777.    end loop;
  5778.    Write_Time := Clock - Start_Time;
  5779.  
  5780.    -- Close a file
  5781.    Start_Time := Clock;
  5782.    Int_Direct_IO.Close (file);
  5783.    Close_Time := Clock - Start_Time;
  5784.  
  5785.    -- Open a file
  5786.    Start_Time := Clock;
  5787.    Int_Direct_IO.Open (file, mode => in_file, name => "test_file");
  5788.    Open_Time := Clock - Start_Time;
  5789.  
  5790.    -- Measure the time of Reading of value
  5791.    Start_Time := Clock;
  5792.    for N in 1 .. Times loop
  5793.       count := count + 1;
  5794.       Int_Direct_IO.read (file, value);
  5795.    end loop;
  5796.    Read_Time := Clock - Start_Time;
  5797.  
  5798.    -- Delete a file
  5799.    Start_Time := Clock;
  5800.    Int_Direct_IO.Delete (file);
  5801.    Delete_Time := Clock - Start_Time;
  5802.  
  5803.  
  5804.    Put ("Create File Time = ");
  5805.    Put (Create_Time, Fore => 0);
  5806.    put_line (" seconds ");
  5807.  
  5808.    Put ("Close File Time = ");
  5809.    Put (Close_Time, Fore => 0);
  5810.    put_line (" seconds ");
  5811.  
  5812.    Put ("Open File Time = ");
  5813.    Put (Open_Time, Fore => 0);
  5814.    put_line (" seconds ");
  5815.  
  5816.    Put ("Delete File Time = ");
  5817.    Put (Delete_Time, Fore => 0);
  5818.    put_line (" seconds ");
  5819.  
  5820.    Put("Loop time = ");
  5821.    Put(Loop_Time, Fore => 0);
  5822.    Put(" seconds for ");
  5823.    Put(Times, Width => 0);
  5824.    Put_Line(" iterations");
  5825.  
  5826.  
  5827.    Put("Elapsed time = ");
  5828.    Put(Write_Time, Fore => 0);
  5829.    Put(" seconds for ");
  5830.    Put(Times, Width => 0);
  5831.    Put_Line(" Writes");
  5832.  
  5833.    Average_Time := Real_Time(Write_Time - Loop_Time)/Real_Time(Times);
  5834.    Put("Average time for a Write = ");
  5835.    Put(Average_Time, Fore => 0);
  5836.    Put_Line(" seconds");
  5837.  
  5838.    New_Line;
  5839.  
  5840.  
  5841.  
  5842.    Put("Elapsed time = ");
  5843.    Put(Read_Time, Fore => 0);
  5844.    Put(" seconds for ");
  5845.    Put(Times, Width => 0);
  5846.    Put_Line(" Reads");
  5847.  
  5848.    Average_Time := Real_Time(Read_Time - Loop_Time)/Real_Time(Times);
  5849.    Put("Average time for a Read = ");
  5850.    Put(Average_Time, Fore => 0);
  5851.    Put_Line(" seconds");
  5852.  
  5853.    New_Line;
  5854.  
  5855.    if (Read_Time  - Loop_Time < 100 * Duration'Small)    or
  5856.       (Read_Time  - Loop_Time < 100 * System.Tick)    or
  5857.       (Write_Time - Loop_Time < 100 * Duration'Small)    or
  5858.       (Write_Time - Loop_Time < 100 * System.Tick)    then
  5859.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  5860.    else
  5861.       Put_Line("** TEST PASSED **");
  5862.    end if;
  5863.  
  5864. end Integer_Direct_IO_Test;
  5865.  
  5866.  
  5867. -------------------------------------------------------------------
  5868. ---------------------  Next  Program  -----------------------------
  5869. -------------------------------------------------------------------
  5870.  
  5871.  
  5872. --
  5873. -- Version: @(#)int_text.ada    1.2        Date: 9/21/84
  5874. --
  5875. -- Author:  Edward Colbert
  5876. --        Ada Technology Group
  5877. --        Information Software Systems Lab
  5878. --        Defense Systems Group
  5879. --        TRW
  5880. --        Redondo Beach, CA
  5881. --
  5882. -- This program measures the time required for doing various file
  5883. -- operations using the Text_IO package with Integers.
  5884. --
  5885. -- Note:  In order for the measurement to be meaningful, it must be the 
  5886. -- only program executing while the test is run.  
  5887. --
  5888. -- Please set Times large enough to provide at least two significant 
  5889. -- digits in the average times, i.e., the difference between 
  5890. -- the elapsed time and the loop time must be at least 100 times 
  5891. -- Duration'Small & at least 100 times System.Tick.
  5892. --
  5893.  
  5894. with Text_IO; use Text_IO;
  5895. with Calendar; use Calendar;
  5896. with System; use System;
  5897. procedure Integer_Text_IO_Test is
  5898.  
  5899.    Times : constant Positive := 1000;
  5900.  
  5901.    type Real_Time is digits Max_Digits;
  5902.  
  5903.    Start_Time : Time;
  5904.    Loop_Time : Duration;
  5905.    Average_Time : Real_Time;
  5906.    Create_Time : Duration;
  5907.    Close_Time  : Duration;
  5908.    Open_Time   : Duration;
  5909.    Delete_Time : Duration;
  5910.    Read_Time   : Duration;
  5911.    Write_Time  : Duration;
  5912.  
  5913.    package Duration_IO is new Fixed_IO (Duration);
  5914.    use Duration_IO;
  5915.  
  5916.    package Real_Time_IO is new Float_IO (Real_Time);
  5917.    use Real_Time_IO;
  5918.  
  5919.    package Int_IO is new Integer_IO (Integer);
  5920.    use Int_IO;
  5921.  
  5922.    file:   Text_IO.file_type;
  5923.    value:  Integer := 5;
  5924.    count:  Integer := Integer'first;    -- used in timing loop
  5925.  
  5926. begin
  5927.  
  5928.    -- Measure the timing loop overhead.
  5929.    Start_Time := Clock;
  5930.    for N in 1 .. Times loop
  5931.       count := count + 1;        -- prevent optimization
  5932.    end loop;
  5933.    Loop_Time := Clock - Start_Time;
  5934.  
  5935.  
  5936.    -- Create a file
  5937.    Start_Time := Clock;
  5938.    Text_IO.Create (file, mode => out_file, name => "test_file");
  5939.    Create_Time := Clock - Start_Time;
  5940.  
  5941.    -- Measure the time of Writing of value
  5942.    Start_Time := Clock;
  5943.    for N in 1 .. Times loop
  5944.       count := count + 1;
  5945.       Int_IO.put (file, value);
  5946.    end loop;
  5947.    Write_Time := Clock - Start_Time;
  5948.  
  5949.    -- Close a file
  5950.    Start_Time := Clock;
  5951.    Text_IO.Close (file);
  5952.    Close_Time := Clock - Start_Time;
  5953.  
  5954.    -- Open a file
  5955.    Start_Time := Clock;
  5956.    Text_IO.Open (file, mode => in_file, name => "test_file");
  5957.    Open_Time := Clock - Start_Time;
  5958.  
  5959.    -- Measure the time of Reading of value
  5960.    Start_Time := Clock;
  5961.    for N in 1 .. Times loop
  5962.       count := count + 1;
  5963.       Int_IO.get (file, value);
  5964.    end loop;
  5965.    Read_Time := Clock - Start_Time;
  5966.  
  5967.    -- Delete a file
  5968.    Start_Time := Clock;
  5969.    Text_IO.Delete (file);
  5970.    Delete_Time := Clock - Start_Time;
  5971.  
  5972.  
  5973.    Put ("Create File Time = ");
  5974.    Put (Create_Time, Fore => 0);
  5975.    put_line (" seconds ");
  5976.  
  5977.    Put ("Close File Time = ");
  5978.    Put (Close_Time, Fore => 0);
  5979.    put_line (" seconds ");
  5980.  
  5981.    Put ("Open File Time = ");
  5982.    Put (Open_Time, Fore => 0);
  5983.    put_line (" seconds ");
  5984.  
  5985.    Put ("Delete File Time = ");
  5986.    Put (Delete_Time, Fore => 0);
  5987.    put_line (" seconds ");
  5988.  
  5989.    Put("Loop time = ");
  5990.    Put(Loop_Time, Fore => 0);
  5991.    Put(" seconds for ");
  5992.    Put(Times, Width => 0);
  5993.    Put_Line(" iterations");
  5994.  
  5995.  
  5996.    Put("Elapsed time = ");
  5997.    Put(Write_Time, Fore => 0);
  5998.    Put(" seconds for ");
  5999.    Put(Times, Width => 0);
  6000.    Put_Line(" Writes");
  6001.  
  6002.    Average_Time := Real_Time(Write_Time - Loop_Time)/Real_Time(Times);
  6003.    Put("Average time for a Write = ");
  6004.    Put(Average_Time, Fore => 0);
  6005.    Put_Line(" seconds");
  6006.  
  6007.    New_Line;
  6008.  
  6009.  
  6010.  
  6011.    Put("Elapsed time = ");
  6012.    Put(Read_Time, Fore => 0);
  6013.    Put(" seconds for ");
  6014.    Put(Times, Width => 0);
  6015.    Put_Line(" Reads");
  6016.  
  6017.    Average_Time := Real_Time(Read_Time - Loop_Time)/Real_Time(Times);
  6018.    Put("Average time for a Read = ");
  6019.    Put(Average_Time, Fore => 0);
  6020.    Put_Line(" seconds");
  6021.  
  6022.    New_Line;
  6023.  
  6024.    if (Read_Time  - Loop_Time < 100 * Duration'Small)    or
  6025.       (Read_Time  - Loop_Time < 100 * System.Tick)    or
  6026.       (Write_Time - Loop_Time < 100 * Duration'Small)    or
  6027.       (Write_Time - Loop_Time < 100 * System.Tick)    then
  6028.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  6029.    else
  6030.       Put_Line("** TEST PASSED **");
  6031.    end if;
  6032.  
  6033. end Integer_Text_IO_Test;
  6034.  
  6035.  
  6036. -------------------------------------------------------------------
  6037. ---------------------  Next  Program  -----------------------------
  6038. -------------------------------------------------------------------
  6039.  
  6040.  
  6041. --
  6042. -- Version: @(#)intvec.ada    1.2        Date: 9/21/84
  6043. --
  6044. -- Author:  Edward Colbert
  6045. --        Ada Technology Group
  6046. --        Information Software Systems Lab
  6047. --        Defense Systems Group
  6048. --        TRW
  6049. --        Redondo Beach, CA
  6050. --
  6051. -- This program measures the time required for the adding of the
  6052. -- elements of a large integer vector
  6053. --
  6054. -- Note:  In order for the measurement to be meaningful, it must be the 
  6055. -- only program executing while the test is run.  
  6056. --
  6057. -- Please set Vector_Size large enough to provide at least two significant 
  6058. -- digits in the average times, i.e., the difference between 
  6059. -- the elapsed time and the loop time must be at least 100 times 
  6060. -- Duration'Small & at least 100 times System.Tick.
  6061. --
  6062.  
  6063. with Text_IO; use Text_IO;
  6064. with Calendar; use Calendar;
  6065. with System; use System;
  6066. procedure Integer_Vector_Add_Test is
  6067.  
  6068.    Vector_Size : constant Positive := 1000;
  6069.  
  6070.    type Real_Time is digits Max_Digits;
  6071.  
  6072.    Start_Time : Time;
  6073.    Loop_Time : Duration;
  6074.    Elapsed_Time : Duration;
  6075.    Average_Time : Real_Time;
  6076.  
  6077.    package Duration_IO is new Fixed_IO (Duration);
  6078.    use Duration_IO;
  6079.  
  6080.    package Real_Time_IO is new Float_IO (Real_Time);
  6081.    use Real_Time_IO;
  6082.  
  6083.    package Int_IO is new Integer_IO (Integer);
  6084.    use Int_IO;
  6085.  
  6086.    type vector is array (1..Vector_Size) of integer;
  6087.    
  6088.    v1, v2, vector_result: vector;
  6089.    count:  integer := integer'first;    -- used in timing loop
  6090.  
  6091. begin
  6092.  
  6093.    -- Initialize Vectors
  6094.    for N in vector'range loop
  6095.       v1(N) := N;
  6096.       v2(N) := vector'last - N + 1;
  6097.    end loop;
  6098.  
  6099.    -- Measure the timing loop overhead.
  6100.    Start_Time := Clock;
  6101.    for N in vector'range loop
  6102.       count := count + 1;        -- prevent optimization
  6103.    end loop;
  6104.    Loop_Time := Clock - Start_Time;
  6105.  
  6106.  
  6107.    -- Measure the time including the adding of vector elements
  6108.    Start_Time := Clock;
  6109.    for N in vector'range loop
  6110.       count := count + 1;        -- prevent optimization
  6111.       vector_result (n) := v1(n) + v2(n);
  6112.    end loop;
  6113.    Elapsed_Time := Clock - Start_Time;
  6114.  
  6115.  
  6116.    Put("Loop time = ");
  6117.    Put(Loop_Time, Fore => 0);
  6118.    Put(" seconds for ");
  6119.    Put(Vector_Size, Width => 0);
  6120.    Put_Line(" iterations");
  6121.  
  6122.  
  6123.    Put("Elapsed time = ");
  6124.    Put(Elapsed_Time, Fore => 0);
  6125.    Put(" seconds for ");
  6126.    Put(Vector_Size, Width => 0);
  6127.    Put_Line(" Elements");
  6128.  
  6129.    Average_Time := Real_Time(Elapsed_Time - Loop_Time)/Real_Time(Vector_Size);
  6130.    Put("Average time for adding each element = ");
  6131.    Put(Average_Time, Fore => 0);
  6132.    Put_Line(" seconds");
  6133.  
  6134.    New_Line;
  6135.    if (Elapsed_Time - Loop_Time < 100 * Duration'Small    or
  6136.        Elapsed_Time - Loop_Time < 100 * System.Tick)    then
  6137.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  6138.    else
  6139.       Put_Line("** TEST PASSED **");
  6140.    end if;
  6141.  
  6142. end Integer_Vector_Add_Test;
  6143.  
  6144.  
  6145. -------------------------------------------------------------------
  6146. ---------------------  Next  Program  -----------------------------
  6147. -------------------------------------------------------------------
  6148.  
  6149.  
  6150.  
  6151. --
  6152. -- Version: @(#)lowlev.ada    1.1        Date: 5/30/84
  6153. --
  6154. -- Author:  Bryce Bardin
  6155. --          Ada Projects Section
  6156. --          Software Engineering Division
  6157. --          Ground Systems Group
  6158. --          Hughes Aircraft Company
  6159. --          Fullerton, CA
  6160. --
  6161. -- The following program tests length clauses in conjunction with 
  6162. -- unchecked conversion.
  6163. --
  6164. -- Before running the test, No_Of_Bits must be set to the base 2 logarithm 
  6165. -- of the successor of System.Max_Int, i.e., the total number of bits in 
  6166. -- the largest integer type supported.
  6167. -- Note:  The place where this change is to be made is flagged by a 
  6168. -- comment prefixed by "--!".  
  6169. --
  6170. -- For a compiler to pass this test, it must obey the length clauses 
  6171. -- and instantiate and use the unchecked conversions correctly.
  6172. -- The output will consist of Cases sets of three identical values.
  6173. -- If a conversion fails, the line will be flagged as an error.  A summary
  6174. -- error count and a "pass/fail" message will be output.
  6175. -- Ideally, an assembly listing should be provided which demonstrates 
  6176. -- the efficiency of the compiled code.
  6177. --
  6178.  
  6179.  
  6180. with Text_IO; use Text_IO;
  6181. with Unchecked_Conversion;
  6182. with System;
  6183. procedure Change_Types is
  6184.  
  6185. --! Change this to Log2 (System.Max_Int + 1):
  6186.    No_Of_Bits : constant := 32;
  6187.  
  6188.    Cases : constant := 100;
  6189.  
  6190.    type Int is range 0 .. 2**No_Of_Bits - 1;
  6191.    for Int'Size use No_Of_Bits;
  6192.    
  6193. --! Change this to System.Max_Int/(Cases - 1):
  6194.    Increment : constant Int := System.Max_Int/(Cases - 1);
  6195.  
  6196.    type Bit is (Off, On);
  6197.    for Bit use (Off => 0, On => 1);
  6198.    for Bit'Size use 1;
  6199.  
  6200.    subtype Bits is Positive range 1 .. No_Of_Bits;
  6201.  
  6202.    type Bit_String is array (Bits) of Bit;
  6203.    for Bit_String'Size use No_Of_Bits;
  6204.  
  6205.    I : Int;
  6206.    J : Int;
  6207.    B : Bit_String;
  6208.    Errors : Natural := 0;
  6209.    Column : constant := 16;
  6210.  
  6211.    package Int_IO is new Integer_IO(Int);
  6212.    use Int_IO;
  6213.  
  6214.    package Nat_IO is new Integer_IO(Natural);
  6215.    use Nat_IO;
  6216.  
  6217.    procedure Put (B : Bit_String) is
  6218.    begin
  6219.       Put("2#");
  6220.       for N in Bits loop
  6221.      if B(N) = On then
  6222.         Put("1");
  6223.      else
  6224.         Put("0");
  6225.      end if;
  6226.       end loop;
  6227.       Put("#");
  6228.    end Put;
  6229.  
  6230.    function To_Bit_String is new Unchecked_Conversion (Int, Bit_String);
  6231.  
  6232.    function To_Int is new Unchecked_Conversion (Bit_String, Int);
  6233.  
  6234. begin
  6235.  
  6236.    for N in 1 .. Cases loop
  6237.  
  6238.       I := Int(N-1) * Increment;
  6239.       B := To_Bit_String(I);
  6240.       J := To_Int(B);
  6241.  
  6242.       if J /= I then
  6243.      Errors := Errors + 1;
  6244.      Put("*** ERROR ***");
  6245.       end if;
  6246.  
  6247.       Set_Col(To => Column);
  6248.       Put("I = ");
  6249.       Put(I, Base => 2);
  6250.       Put_Line(",");
  6251.  
  6252.       Set_Col(To => Column);
  6253.       Put("B = ");
  6254.       Put(B);
  6255.       Put_Line(",");
  6256.  
  6257.       Set_Col(To => Column);
  6258.       Put("J = ");
  6259.       Put(J, Base => 2);
  6260.       Put(".");
  6261.       New_Line(2);
  6262.  
  6263.    end loop;
  6264.  
  6265.    New_Line(2);
  6266.  
  6267.    if Errors > 0 then
  6268.       Put_Line("*** TEST FAILED! ***");
  6269.       if Errors = 1 then
  6270.      Put_Line("There was 1 error.");
  6271.       else
  6272.      Put("There were ");
  6273.      Put(Errors, Width => 0);
  6274.      Put_Line(" errors.");
  6275.       end if;
  6276.    else
  6277.       Put_Line("TEST PASSED!");
  6278.       Put_Line("There were no errors.");
  6279.    end if;
  6280.  
  6281. end Change_Types;
  6282.  
  6283.  
  6284. -------------------------------------------------------------------
  6285. ---------------------  Next  Program  -----------------------------
  6286. -------------------------------------------------------------------
  6287.  
  6288.  
  6289. --
  6290. -- Version: @(#)proccal.ada    1.2        Date: 9/21/84
  6291. --
  6292. --
  6293. -- Author:  Bryce Bardin
  6294. --          Ada Projects Section
  6295. --          Software Engineering Division
  6296. --          Ground Systems Group
  6297. --          Hughes Aircraft Company
  6298. --          Fullerton, CA
  6299. --
  6300. -- This program measures the time required for simple procedure calls 
  6301. -- with scalar parameters.
  6302. --
  6303. -- Note:  In order for the measurement to be meaningful, it must be the 
  6304. -- only program executing while the test is run.  
  6305. --
  6306. -- Please set Times large enough to provide at least two significant 
  6307. -- digits in the average calling times, i.e., the differences between 
  6308. -- the elapsed times and the corresponding loop times for each form of
  6309. -- call should be greater than 100 times Duration'Small & greater than
  6310. -- 100 times System.Tick.
  6311.  
  6312. with Text_IO; use Text_IO;
  6313. with Calendar; use Calendar;
  6314. with System; use System;
  6315. procedure Procedure_Call is
  6316.  
  6317.    Times : constant Positive := 1000;
  6318.  
  6319.    type Real_Time is digits Max_Digits;
  6320.  
  6321.    Start_Time : Time;
  6322.    Loop_Time : Duration;
  6323.    Elapsed_Time : Duration;
  6324.    Average_Time : Real_Time;
  6325.  
  6326.    Insufficient_Precision : Boolean := False;
  6327.  
  6328.    package Duration_IO is new Fixed_IO (Duration);
  6329.    use Duration_IO;
  6330.  
  6331.    package Real_Time_IO is new Float_IO (Real_Time);
  6332.    use Real_Time_IO;
  6333.  
  6334.    package Int_IO is new Integer_IO (Integer);
  6335.    use Int_IO;
  6336.  
  6337.    type Cases is range 1 .. 4;
  6338.  
  6339.    Kind : array (Cases) of String (1 .. 22) :=
  6340.       ("No parameter call:    ",
  6341.        "In parameter call:    ",
  6342.        "Out parameter call:   ",
  6343.        "In Out parameter call:");
  6344.  
  6345.    -- This package is used to prevent elimination of a "null" call
  6346.    -- by a smart compiler.
  6347.    package Prevent is
  6348.       Counter : Natural := 0;
  6349.       procedure Prevent_Optimization;
  6350.    end Prevent;
  6351.    use Prevent;
  6352.  
  6353.    procedure Call is
  6354.    begin
  6355.       Prevent_Optimization;
  6356.    end Call;
  6357.  
  6358.    procedure Call_In (N : in Natural) is
  6359.    begin
  6360.       Counter := N;
  6361.    end Call_In;
  6362.  
  6363.    procedure Call_Out (N : out Natural) is
  6364.    begin
  6365.       N := Counter;
  6366.    end Call_Out;
  6367.  
  6368.    procedure Call_In_Out (N : in out Natural) is
  6369.    begin
  6370.       N := Counter;
  6371.    end Call_In_Out;
  6372.  
  6373. -- This procedure determines if Times is large enough to assure adequate 
  6374. -- precision in the timings.
  6375.    procedure Check_Precision is
  6376.    begin
  6377.       if (Elapsed_Time - Loop_Time < 100 * Duration'Small    or
  6378.           Elapsed_Time - Loop_Time < 100 * System.Tick)    then
  6379.      Insufficient_Precision := True;
  6380.       end if;
  6381.    end Check_Precision;
  6382.  
  6383.    package body Prevent is
  6384.       procedure Prevent_Optimization is
  6385.       begin
  6386.      Counter := Counter + 1;
  6387.       end Prevent_Optimization;
  6388.    end Prevent;
  6389.  
  6390. begin
  6391.  
  6392.    for Case_Number in Cases loop
  6393.  
  6394.       -- Measure the timing loop overhead.
  6395.       Start_Time := Clock;
  6396.       for N in 1 .. Times loop
  6397.      case Case_Number is
  6398.         when 1 =>
  6399.            Prevent_Optimization;
  6400.         when 2 =>
  6401.            Counter := N;
  6402.         when 3 =>
  6403.            Counter := N;
  6404.         when 4 =>
  6405.            Counter := N;
  6406.      end case;
  6407.       end loop;
  6408.       Loop_Time := Clock - Start_Time;
  6409.  
  6410.       -- Measure the time including the procedure call.
  6411.       Start_Time := Clock;
  6412.       for N in 1 .. Times loop
  6413.      case Case_Number is
  6414.         when 1 =>
  6415.            Call;
  6416.         when 2 =>
  6417.            Call_In(Counter);
  6418.         when 3 =>
  6419.            Call_Out(Counter);
  6420.         when 4 =>
  6421.            Call_In_Out(Counter);
  6422.      end case;
  6423.       end loop;
  6424.       Elapsed_Time := Clock - Start_Time;
  6425.  
  6426.       Check_Precision;
  6427.  
  6428.       -- Calculate timing and output the result
  6429.  
  6430.       Put(Kind(Case_Number));
  6431.       New_Line(2);
  6432.  
  6433.       Put("Loop time = ");
  6434.       Put(Loop_Time, Fore => 0);
  6435.       Put(" seconds for ");
  6436.       Put(Times, Width => 0);
  6437.       Put_Line(" iterations");
  6438.  
  6439.       Put("Elapsed time = ");
  6440.       Put(Elapsed_Time, Fore => 0);
  6441.       Put(" seconds for ");
  6442.       Put(Times, Width => 0);
  6443.       Put_Line(" iterations");
  6444.  
  6445.       Average_Time := Real_Time(Elapsed_Time - Loop_Time)/Real_Time(Times);
  6446.       New_Line;
  6447.       Put("Average time for a call = ");
  6448.       Put(Average_Time);
  6449.       Put_Line(" seconds");
  6450.       New_Line(3);
  6451.  
  6452.    end loop;
  6453.  
  6454.    if Insufficient_Precision then
  6455.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  6456.    else
  6457.       Put_Line("TEST PASSED");
  6458.    end if;
  6459.  
  6460. end Procedure_Call;
  6461.  
  6462.  
  6463. -------------------------------------------------------------------
  6464. ---------------------  Next  Program  -----------------------------
  6465. -------------------------------------------------------------------
  6466.  
  6467.  
  6468.  
  6469. ----------------------------------------------------------------------
  6470. --
  6471. --             QUICK SORT BENCHMARK
  6472. --
  6473. --          Version: @(#)qsortpar.ada    1.1    Date: 6/5/84
  6474. --
  6475. --                Gerry Fisher
  6476. --            Computer Sciences Corporation
  6477. --
  6478. --                May 26, 1984
  6479. --
  6480. --  This benchmark consists of two versions of the familiar quick
  6481. --  sort algorithm: a parallel version and a sequential version.
  6482. --  A relatively small vector (length 100) is sorted into ascending
  6483. --  sequence.  The number of comparisons and exchanges is counted.
  6484. --  In the parallel version separate tasks are created to sort the
  6485. --  two subvectors created by partitioning the vector.  Each task
  6486. --  invokes the quicksort procedure.  The parallel version is
  6487. --  functionally equivalent to the sequential version and should
  6488. --  require the same number of comparisions and exchanges.  A check
  6489. --  is made to verify that this is so.  Also, the sorted vector is
  6490. --  checked to verify that the sort has been performed correctly.
  6491. --  Control is exercised so that no more than fourteen tasks are
  6492. --  created when sorting the vector.
  6493. --
  6494. --  The sorting is repeated a number of times to obtain a measurable
  6495. --  amount of execution time.
  6496. --
  6497. --  The important measure for this benchmark is the ratio of the
  6498. --  execution time of the parallel version to that of the sequential
  6499. --  version.  This will give some indication of task activation and
  6500. --  scheduling overhead.
  6501. --
  6502. --  One file is used for both versions.  The boolean constant "p"
  6503. --  indicates whether the parallel or serial version of the algorithm
  6504. --  is to be used.  Simply set this constant TRUE for the parallel
  6505. --  test and FALSE for the sequential test.  A difference in code
  6506. --  size between the two tests may indicate that conditional
  6507. --  compilation is supported by the compiler.
  6508. --
  6509. ------------------------------------------------------------------------
  6510.  
  6511. with text_io; use text_io;
  6512. procedure main is
  6513.    failed : exception;
  6514.  
  6515.    type vector is array(integer range <>) of integer;
  6516.    type stats  is record c, e : integer := 0; end record;
  6517.  
  6518.    p : constant boolean := true;    -- true for parallel algorithm
  6519.    n : constant integer := 100;        -- size of vector to be sorted
  6520.    m : constant integer := 100;        -- number of times to sort vector
  6521.  
  6522.    x : vector(1 .. n);
  6523.  
  6524.    y : stats;
  6525.  
  6526.    procedure Quick_sort(A : in out vector; w : out stats) is
  6527.      lb : constant integer := A'first;
  6528.      ub : constant integer := A'last;
  6529.      k    : integer;
  6530.  
  6531.      c, e : integer := 0;
  6532.      u, v : stats;
  6533.  
  6534.      function partition(L, U : integer) return integer is
  6535.        q, r, i, j : integer;
  6536.      begin
  6537.  
  6538.        r := A((U + L)/2);
  6539.        i := L;
  6540.        j := U;
  6541.  
  6542.        while i < j loop
  6543.       while A(i) < r loop
  6544.         c := c + 1;
  6545.         i := i + 1;
  6546.       end loop;
  6547.  
  6548.       while A(j) > r loop
  6549.         c := c + 1;
  6550.         j := j - 1;
  6551.       end loop;
  6552.  
  6553.       c := c + 2;
  6554.  
  6555.       if i <= j then
  6556.         e := e + 1;
  6557.         q := A(i);
  6558.         A(i) := A(j);
  6559.         A(j) := q;
  6560.         i := i + 1;
  6561.         j := j - 1;
  6562.       end if;
  6563.        end loop;
  6564.  
  6565.        if j > L then
  6566.      return j;
  6567.        else
  6568.      return L;
  6569.        end if;
  6570.  
  6571.      end partition;
  6572.  
  6573.    begin
  6574.      if lb < ub then
  6575.  
  6576.       k := partition(lb, ub);
  6577.  
  6578.       if ub > lb + 15 then
  6579.        if p then
  6580.     declare
  6581.       task S1;
  6582.       task body S1 is
  6583.       begin
  6584.         Quick_sort(A(lb .. k), u);
  6585.       end S1;
  6586.  
  6587.       task S2;
  6588.       task body S2 is
  6589.       begin
  6590.         Quick_sort(A(k + 1 .. ub), v);
  6591.       end S2;
  6592.     begin
  6593.       null;
  6594.     end;
  6595.  
  6596.        else
  6597.     Quick_sort(A(lb .. k), u);
  6598.     Quick_sort(A(k + 1 .. ub), v);
  6599.        end if;
  6600.  
  6601.       elsif ub > lb + 1 then
  6602.     Quick_sort(A(lb .. k), u);
  6603.     Quick_sort(A(k + 1 .. ub), v);
  6604.       end if;
  6605.  
  6606.       e := e + u.e + v.e;
  6607.       c := c + u.c + v.c;
  6608.  
  6609.      end if;
  6610.  
  6611.      w := (c, e);
  6612.  
  6613.    end Quick_sort;
  6614.  
  6615. begin
  6616.  
  6617.   set_line_length(count(50));
  6618.   if p then
  6619.     put_line("*** Starting Parallel Quick Sort Benchmark");
  6620.   else
  6621.     put_line("*** Starting Sequential Quick Sort Benchmark");
  6622.   end if;
  6623.  
  6624.   for k in 1 .. m loop
  6625.  
  6626.    for i in x'range loop
  6627.      x(i) := x'last - i + 1;
  6628.    end loop;
  6629.  
  6630.    Quick_sort(x, y);
  6631.  
  6632.    for i in x'first .. x'last - 1 loop
  6633.      if x(i) > x(i + 1) then
  6634.        raise failed;
  6635.      end if;
  6636.   end loop;
  6637.  
  6638.   put(".");
  6639.  
  6640.  end loop;
  6641.  
  6642.  new_line;
  6643.  
  6644.  if y.c /= 782 or else y.e /= 148 then
  6645.    put_line("*** FAILED Wrong number of comparisons or exchanges");
  6646.  else
  6647.    put_line("*** PASSED Sorting test");
  6648.  end if;
  6649.  
  6650. exception
  6651.   when failed => put_line("*** FAILED Vector not sorted");
  6652.  
  6653. end main;
  6654.  
  6655.  
  6656. -------------------------------------------------------------------
  6657. ---------------------  Next  Program  -----------------------------
  6658. -------------------------------------------------------------------
  6659.  
  6660.  
  6661.  
  6662. ----------------------------------------------------------------------
  6663. --
  6664. --             QUICK SORT BENCHMARK
  6665. --
  6666. --        Version: @(#)qsortseq.ada    1.1    Date: 6/5/84
  6667. --
  6668. --                Gerry Fisher
  6669. --            Computer Sciences Corporation
  6670. --                May 27, 1984
  6671. --
  6672. --
  6673. --  This benchmark consists of two versions of the familiar quick
  6674. --  sort algorithm: a parallel version and a sequential version.
  6675. --  A relatively small vector (length 100) is sorted into ascending
  6676. --  sequence.  The number of comparisons and exchanges is counted.
  6677. --  In the parallel version separate tasks are created to sort the
  6678. --  two subvectors created by partitioning the vector.  Each task
  6679. --  invokes the quicksort procedure.  The parallel version is
  6680. --  functionally equivalent to the sequential version and should
  6681. --  require the same number of comparisions and exchanges.  A check
  6682. --  is made to verify that this is so.  Also, the sorted vector is
  6683. --  checked to verify that the sort has been performed correctly.
  6684. --  Control is exercised so that no more than fourteen tasks are
  6685. --  created when sorting the vector.
  6686. --
  6687. --  The sorting is repeated a number of times to obtain a measurable
  6688. --  amount of execution time.
  6689. --
  6690. --  The important measure for this benchmark is the ratio of the
  6691. --  execution time of the parallel version to that of the sequential
  6692. --  version.  This will give some indication of task activation and
  6693. --  scheduling overhead.
  6694. --
  6695. --  One file is used for both versions.  The boolean constant "p"
  6696. --  indicates whether the parallel or serial version of the algorithm
  6697. --  is to be used.  Simply set this constant TRUE for the parallel
  6698. --  test and FALSE for the sequential test.  A difference in code
  6699. --  size between the two tests may indicate that conditional
  6700. --  compilation is supported by the compiler.
  6701. --
  6702. --------------------------------------------------------------------
  6703.  
  6704. with text_io; use text_io;
  6705. procedure main is
  6706.    failed : exception;
  6707.  
  6708.    type vector is array(integer range <>) of integer;
  6709.    type stats  is record c, e : integer := 0; end record;
  6710.  
  6711.    p : constant boolean := false;    -- true for parallel algorithm
  6712.    n : constant integer := 100;        -- size of vector to be sorted
  6713.    m : constant integer := 100;        -- number of times to sort vector
  6714.  
  6715.    x : vector(1 .. n);
  6716.  
  6717.    y : stats;
  6718.  
  6719.    procedure Quick_sort(A : in out vector; w : out stats) is
  6720.      lb : constant integer := A'first;
  6721.      ub : constant integer := A'last;
  6722.      k    : integer;
  6723.  
  6724.      c, e : integer := 0;
  6725.      u, v : stats;
  6726.  
  6727.      function partition(L, U : integer) return integer is
  6728.        q, r, i, j : integer;
  6729.      begin
  6730.  
  6731.        r := A((U + L)/2);
  6732.        i := L;
  6733.        j := U;
  6734.  
  6735.        while i < j loop
  6736.       while A(i) < r loop
  6737.         c := c + 1;
  6738.         i := i + 1;
  6739.       end loop;
  6740.  
  6741.       while A(j) > r loop
  6742.         c := c + 1;
  6743.         j := j - 1;
  6744.       end loop;
  6745.  
  6746.       c := c + 2;
  6747.  
  6748.       if i <= j then
  6749.         e := e + 1;
  6750.         q := A(i);
  6751.         A(i) := A(j);
  6752.         A(j) := q;
  6753.         i := i + 1;
  6754.         j := j - 1;
  6755.       end if;
  6756.        end loop;
  6757.  
  6758.        if j > L then
  6759.      return j;
  6760.        else
  6761.      return L;
  6762.        end if;
  6763.  
  6764.      end partition;
  6765.  
  6766.    begin
  6767.      if lb < ub then
  6768.  
  6769.       k := partition(lb, ub);
  6770.  
  6771.       if ub > lb + 15 then
  6772.        if p then
  6773.     declare
  6774.       task S1;
  6775.       task body S1 is
  6776.       begin
  6777.         Quick_sort(A(lb .. k), u);
  6778.       end S1;
  6779.  
  6780.       task S2;
  6781.       task body S2 is
  6782.       begin
  6783.         Quick_sort(A(k + 1 .. ub), v);
  6784.       end S2;
  6785.     begin
  6786.       null;
  6787.     end;
  6788.  
  6789.        else
  6790.     Quick_sort(A(lb .. k), u);
  6791.     Quick_sort(A(k + 1 .. ub), v);
  6792.        end if;
  6793.  
  6794.       elsif ub > lb + 1 then
  6795.     Quick_sort(A(lb .. k), u);
  6796.     Quick_sort(A(k + 1 .. ub), v);
  6797.       end if;
  6798.  
  6799.       e := e + u.e + v.e;
  6800.       c := c + u.c + v.c;
  6801.  
  6802.      end if;
  6803.  
  6804.      w := (c, e);
  6805.  
  6806.    end Quick_sort;
  6807.  
  6808. begin
  6809.  
  6810.   set_line_length(count(50));
  6811.   if p then
  6812.     put_line("*** Starting Parallel Quick Sort Benchmark");
  6813.   else
  6814.     put_line("*** Starting Sequential Quick Sort Benchmark");
  6815.   end if;
  6816.  
  6817.   for k in 1 .. m loop
  6818.  
  6819.    for i in x'range loop
  6820.      x(i) := x'last - i + 1;
  6821.    end loop;
  6822.  
  6823.    Quick_sort(x, y);
  6824.  
  6825.    for i in x'first .. x'last - 1 loop
  6826.      if x(i) > x(i + 1) then
  6827.        raise failed;
  6828.      end if;
  6829.   end loop;
  6830.  
  6831.   put(".");
  6832.  
  6833.  end loop;
  6834.  
  6835.  new_line;
  6836.  
  6837.  if y.c /= 782 or else y.e /= 148 then
  6838.    put_line("*** FAILED Wrong number of comparisons or exchanges");
  6839.  else
  6840.    put_line("*** PASSED Sorting test");
  6841.  end if;
  6842.  
  6843. exception
  6844.   when failed => put_line("*** FAILED Vector not sorted");
  6845.  
  6846. end main;
  6847.  
  6848.  
  6849.  
  6850.  
  6851. -------------------------------------------------------------------
  6852. ---------------------  Next  Program  -----------------------------
  6853. -------------------------------------------------------------------
  6854.  
  6855.  
  6856.  
  6857. --
  6858. -- Version: @(#)rendez.ada    1.2        Date: 9/21/84
  6859. --
  6860. -- Author:  Bryce Bardin
  6861. --          Ada Projects Section
  6862. --          Software Engineering Division
  6863. --          Ground Systems Group
  6864. --          Hughes Aircraft Company
  6865. --          Fullerton, CA
  6866. --
  6867. -- This program measures the time required for a simple rendezvous.
  6868. --
  6869. -- Note:  In order for the measurement to be meaningful, it must be the 
  6870. -- only program executing while the test is run.  
  6871. --
  6872. -- Please set Times large enough to provide at least two significant 
  6873. -- digits in the average rendezvous times, i.e., the difference between 
  6874. -- the elapsed time and the loop time must be at least 100 times 
  6875. -- Duration'Small & at least 100 times System.Tick.
  6876.  
  6877. with Text_IO; use Text_IO;
  6878. with Calendar; use Calendar;
  6879. with System; use System;
  6880. procedure Rendezvous is
  6881.  
  6882.    Times : constant Positive := 1000;
  6883.  
  6884.    type Real_Time is digits Max_Digits;
  6885.  
  6886.    Start_Time : Time;
  6887.    Loop_Time : Duration;
  6888.    Elapsed_Time : Duration;
  6889.    Average_Time : Real_Time;
  6890.  
  6891.    package Duration_IO is new Fixed_IO (Duration);
  6892.    use Duration_IO;
  6893.  
  6894.    package Real_Time_IO is new Float_IO (Real_Time);
  6895.    use Real_Time_IO;
  6896.  
  6897.    package Int_IO is new Integer_IO (Integer);
  6898.    use Int_IO;
  6899.  
  6900.    task T is
  6901.       entry Call;
  6902.    end T;
  6903.  
  6904.    -- This package is used to prevent elimination of the "null" timing loop 
  6905.    -- by a smart compiler.
  6906.    package Prevent is
  6907.       Count : Natural := 0;
  6908.       procedure Prevent_Optimization;
  6909.    end Prevent;
  6910.    use Prevent;
  6911.  
  6912.    task body T is
  6913.    begin
  6914.       loop
  6915.      select
  6916.         accept Call;
  6917.      or
  6918.         terminate;
  6919.      end select;
  6920.       end loop;
  6921.    end T;
  6922.  
  6923.    package body Prevent is
  6924.       procedure Prevent_Optimization is
  6925.       begin
  6926.      Count := Count + 1;
  6927.       end Prevent_Optimization;
  6928.    end Prevent;
  6929.  
  6930. begin
  6931.  
  6932.    -- Measure the timing loop overhead.
  6933.    Start_Time := Clock;
  6934.    for N in 1 .. Times loop
  6935.       Prevent_Optimization;
  6936.    end loop;
  6937.    Loop_Time := Clock - Start_Time;
  6938.  
  6939.    -- Measure the time including rendezvous.
  6940.    Start_Time := Clock;
  6941.    for N in 1 .. Times loop
  6942.       Prevent_Optimization;
  6943.       T.Call;
  6944.    end loop;
  6945.  
  6946.    Put("Loop time = ");
  6947.    Put(Loop_Time, Fore => 0);
  6948.    Put(" seconds for ");
  6949.    Put(Times, Width => 0);
  6950.    Put_Line(" iterations");
  6951.  
  6952.    Elapsed_Time := Clock - Start_Time;
  6953.    Put("Elapsed time = ");
  6954.    Put(Elapsed_Time, Fore => 0);
  6955.    Put(" seconds for ");
  6956.    Put(Times, Width => 0);
  6957.    Put_Line(" iterations");
  6958.  
  6959.    Average_Time := Real_Time(Elapsed_Time - Loop_Time)/Real_Time(Times);
  6960.    Put("Average time for no-parameter rendezvous = ");
  6961.    Put(Average_Time, Fore => 0);
  6962.    Put_Line(" seconds");
  6963.  
  6964.    New_Line;
  6965.    if (Elapsed_Time - Loop_Time < 100 * Duration'Small    or
  6966.        Elapsed_Time - Loop_Time < 100 * System.Tick)    then
  6967.       Put_Line("** TEST FAILED (due to insufficient precision)! **");
  6968.    else
  6969.       Put_Line("** TEST PASSED **");
  6970.    end if;
  6971.  
  6972. end Rendezvous;
  6973.  
  6974.  
  6975.  
  6976.  
  6977.  
  6978. -------------------------------------------------------------------
  6979. ---------------------  Next  Program  -----------------------------
  6980. -------------------------------------------------------------------
  6981.  
  6982.  
  6983.  
  6984. --
  6985. -- Version: @(#)sets.ada    1.3        Date: 10/19/84
  6986. --
  6987. --
  6988. -- Author:  Bryce Bardin
  6989. --          Ada Projects Section
  6990. --          Software Engineering Division
  6991. --          Ground Systems Group
  6992. --          Hughes Aircraft Company
  6993. --          Fullerton, CA
  6994. --
  6995. -- This is a highly portable implementation of sets in Ada.
  6996. --
  6997. -- N. B.:  Vendors are invited to supply listings which demonstrate 
  6998. -- the quality of the code generated.
  6999. --
  7000. generic
  7001.    type Element is (<>);
  7002.    with function Image (E : Element) return String is Element'Image;
  7003. package Sets is
  7004.  
  7005.    type Set is private;
  7006.    -- A set of elements.
  7007.  
  7008.    Empty_Set : constant Set;
  7009.    -- The set of no elements.
  7010.  
  7011.    Full_Set : constant Set;
  7012.    -- The set of all elements.
  7013.  
  7014.    function "and" (Left, Right : Set) return Set;
  7015.    -- Returns the conjunction (intersection) of two sets.
  7016.    -- Usage:  S1 and S2
  7017.  
  7018.    function "or" (Left, Right : Set) return Set;
  7019.    -- Returns the inclusive disjunction (union) of two sets.
  7020.    -- Usage:  S1 or S2
  7021.  
  7022.    function "xor" (Left, Right : Set) return Set;
  7023.    -- Returns the exclusive disjunction of two sets.
  7024.    -- Usage:  S1 xor S2
  7025.  
  7026.    function "not" (Right : Set) return Set;
  7027.    -- Returns the negation (complement) of a set, i.e., the set of
  7028.    -- all elements not in Right.
  7029.    -- Usage:  not S
  7030.  
  7031.    function "-" (Left, Right : Set) return Set;
  7032.    -- Returns the difference of two sets, i.e., the set of elements
  7033.    -- in Left which are not in Right.
  7034.    -- Usage:  S1 - S2
  7035.  
  7036.    function "+" (Left : Element; Right : Set) return Set;
  7037.    -- Adds an element to a set.
  7038.    -- Returns the union (or) of an element with a set.
  7039.    -- Usage:  E + S
  7040.  
  7041.    function "+" (Left : Set; Right : Element) return Set;
  7042.    -- Adds an element to a set.
  7043.    -- Returns the union (or) of an element with a set.
  7044.    -- Usage:  S + E
  7045.  
  7046.    function "+" (Right : Element) return Set;
  7047.    -- Makes an element into a Set.
  7048.    -- Returns the union of the element with the Empty_Set.
  7049.    -- Usage:  + E
  7050.  
  7051.    function "+" (Left, Right : Element) return Set;
  7052.    -- Combines two elements into a Set.
  7053.    -- Returns the union (or) of two elements with the Empty_Set.
  7054.    -- Usage:  E1 + E2
  7055.  
  7056.    function "-" (Left : Set; Right : Element) return Set;
  7057.    -- Deletes an element from a set, i.e., removes it from the set
  7058.    -- if it is currently a member of the set, otherwise it returns
  7059.    -- the original set.
  7060.    -- Usage:  S - E
  7061.  
  7062. -- This function is predefined:
  7063. -- function "=" (Left, Right : Set) return Boolean;
  7064.    -- Tests whether Left is identical to Right.
  7065.    -- Usage: S1 = S2
  7066.  
  7067.    function "<=" (Left, Right : Set) return Boolean;
  7068.    -- Tests whether Left is contained in Right, i.e., whether Left 
  7069.    -- is a subset of Right.
  7070.    -- Usage:  S1 <= S2
  7071.  
  7072.    function Is_Member (S : Set; E : Element) return Boolean;
  7073.    -- Tests an element for membership in a set.
  7074.    -- Returns true if an element is in a set.
  7075.    -- Usage:  Is_Member (S, E)
  7076.  
  7077.    procedure Put (S : Set);
  7078.    -- Prints a set.
  7079.    -- Usage:  Put (S)
  7080.  
  7081. private
  7082.  
  7083.    type Set is array (Element) of Boolean;
  7084.    -- A set of elements.
  7085.  
  7086.    Empty_Set : constant Set := (Element => False);
  7087.    -- The set of no elements.
  7088.  
  7089.    Full_Set : constant Set := (Element => True);   
  7090.    -- The set of all elements.
  7091.  
  7092.    pragma Inline ("and");
  7093.    pragma Inline ("or");
  7094.    pragma Inline ("xor");
  7095.    pragma Inline ("not");
  7096.    pragma Inline ("-");
  7097.    pragma Inline ("+");
  7098.    pragma Inline ("<=");
  7099.    pragma Inline (Is_Member);
  7100.  
  7101. end Sets;
  7102.  
  7103. with Text_IO; use Text_IO;
  7104. package body Sets is
  7105.  
  7106.    type Bool is array (Element) of Boolean;
  7107.  
  7108.    function "and" (Left, Right : Set) return Set is
  7109.    begin
  7110.       return Set(Bool(Left) and Bool(Right));
  7111.    end "and";
  7112.  
  7113.    function "or" (Left, Right : Set) return Set is
  7114.    begin
  7115.       return Set(Bool(Left) or Bool(Right));
  7116.    end "or";
  7117.  
  7118.    function "xor" (Left, Right : Set) return Set is
  7119.    begin
  7120.       return Set(Bool(Left) xor Bool(Right));
  7121.    end "xor";
  7122.  
  7123.    function "not" (Right : Set) return Set is
  7124.    begin
  7125.       return Set(not Bool(Right));
  7126.    end "not";
  7127.  
  7128.    function "-" (Left, Right : Set) return Set is
  7129.    begin
  7130.       return (Left and not Right);
  7131.    end "-";
  7132.  
  7133.    function "+" (Left : Element; Right : Set) return Set is
  7134.       Temp : Set := Right;
  7135.    begin
  7136.       Temp(Left) := True;
  7137.       return Temp;
  7138.    end "+";
  7139.  
  7140.    function "+" (Left : Set; Right : Element) return Set is
  7141.       Temp : Set := Left;
  7142.    begin
  7143.       Temp(Right) := True;
  7144.       return Temp;
  7145.    end "+";
  7146.  
  7147.    function "+" (Right : Element) return Set is
  7148.    begin
  7149.       return Empty_Set + Right;
  7150.    end "+";
  7151.  
  7152.    function "+" (Left, Right : Element) return Set is
  7153.    begin
  7154.       return Empty_Set + Left + Right;
  7155.    end "+";
  7156.  
  7157.    function "-" (Left : Set; Right : Element) return Set is
  7158.       Temp : Set := Left;
  7159.    begin
  7160.       Temp(Right) := False;
  7161.       return Temp;
  7162.    end "-";
  7163.  
  7164.    function "<=" (Left, Right : Set) return Boolean is
  7165.    begin
  7166.       return ((Left and not Right) = Empty_Set);
  7167.    end "<=";
  7168.  
  7169.    function Is_Member (S : Set; E : Element) return Boolean is
  7170.    begin
  7171.       return (S(E) = True);
  7172.    end Is_Member;
  7173.  
  7174.    procedure Put (S : Set) is
  7175.       Comma_Needed : Boolean := False;
  7176.    begin
  7177.       Text_IO.Put ("{");
  7178.       for E in Element loop
  7179.          if S(E) then
  7180.             if Comma_Needed then
  7181.                Text_IO.Put (",");
  7182.             end if;
  7183.             Text_IO.Put (Image(E));
  7184.             Comma_Needed := True;
  7185.          end if;
  7186.       end loop;
  7187.       Text_IO.Put ("}");
  7188.       New_Line;
  7189.    end Put;
  7190.  
  7191. end Sets;
  7192.  
  7193.  
  7194. -- This procedure tests the set package.
  7195. -- Its output is self-explanatory.
  7196. with Text_IO; use Text_IO;
  7197. with Sets;
  7198. procedure Main is
  7199.  
  7200.    type Color is (Red, Yellow, Green, Blue);
  7201.  
  7202.    package Color_Set is new Sets(Color);
  7203.    use Color_Set;
  7204.  
  7205.    X, Y, Z : Set;
  7206.  
  7207.    procedure Put_Set (Name : String; S : Set) is
  7208.    begin
  7209.       Put (Name);
  7210.       Put (" = ");
  7211.       Put (S);
  7212.    end Put_Set;
  7213.  
  7214.    procedure Compare_Set (S_String : String; S : Set;
  7215.                           T_String : String; T : Set) is
  7216.    begin
  7217.       if S = T then
  7218.          Put (S_String);
  7219.          Put (" is identical to ");
  7220.          Put (T_String);
  7221.          New_Line;
  7222.       end if;
  7223.       if S /= T then
  7224.          Put (S_String);
  7225.          Put (" is not identical to ");
  7226.          Put (T_String);
  7227.          New_Line;
  7228.       end if;
  7229.       if S <= T then
  7230.          Put (S_String);
  7231.          Put (" is a subset of ");
  7232.          Put (T_String);
  7233.          New_Line;
  7234.       end if;
  7235.       if T <= S then
  7236.          Put (T_String);
  7237.          Put (" is a subset of ");
  7238.          Put (S_String);
  7239.          New_Line;
  7240.       end if;
  7241.    end Compare_Set;
  7242.  
  7243.    procedure Test_Membership (C : Color; S_String : String; S : Set) is
  7244.    begin
  7245.       Put (Color'Image(C));
  7246.       if Is_Member(S,C) then
  7247.          Put (" is a member of ");
  7248.       else
  7249.          Put (" is not a member of ");
  7250.       end if;
  7251.       Put (S_String);
  7252.       New_Line;
  7253.    end Test_Membership;
  7254.  
  7255. begin
  7256.  
  7257.    X := Empty_Set;
  7258.    Put_Line ("X := Empty_Set");
  7259.    Put_Set ("X",X);
  7260.  
  7261.    Y := Empty_Set;
  7262.    Put_Line ("Y := Empty_Set");
  7263.    Put_Set ("Y",Y);
  7264.  
  7265.    Compare_Set ("X",X,"Y",Y);
  7266.  
  7267.    Y := Full_Set;
  7268.    Put_Line ("Y := Full_Set");
  7269.    Put_Set ("Y",Y);
  7270.  
  7271.    Compare_Set ("X",X,"Y",Y);
  7272.  
  7273.    X := not X;
  7274.    Put_Line ("X := not X");
  7275.    Put_Set ("X",X);
  7276.  
  7277.    Compare_Set ("X",X,"Y",Y);
  7278.  
  7279.    Y := Empty_Set + Blue;
  7280.    Put_Line ("Y := Empty_Set + Blue");
  7281.    Put_Set ("Y",Y);
  7282.  
  7283.    Y := + Yellow;
  7284.    Put_Line ("Y := + Yellow");
  7285.    Put_Set ("Y",Y);
  7286.  
  7287.    Y := Blue + Y;
  7288.    Put_Line ("Y := Blue + Y");
  7289.    Put_Set ("Y",Y);
  7290.  
  7291.    X := Full_Set - Red;
  7292.    Put_Line ("X := Full_Set - Red");
  7293.    Put_Set ("X",X);
  7294.  
  7295.    Test_Membership (Red,"X",X);
  7296.    Test_Membership (Yellow,"X",X);
  7297.    
  7298.    Compare_Set ("X",X,"Y",Y);
  7299.  
  7300.    Z := X - Y;
  7301.    Put_Line ("Z := X - Y");
  7302.    Put_Set ("Z",Z);
  7303.  
  7304.    Z := Y - X;
  7305.    Put_Line ("Z := Y - X");
  7306.    Put_Set ("Z",Z);
  7307.  
  7308.    X := Green + Blue + Yellow + Red;
  7309.    Put_Line ("X := Green + Blue + Yellow + Red");
  7310.    Put_Set ("X",X);
  7311.  
  7312.    X := Green + Blue;
  7313.    Put_Line ("X := Green + Blue");
  7314.    Put_Set ("X",X);
  7315.  
  7316.    Z := X or Y;
  7317.    Put_Line ("Z := X or Y");
  7318.    Put_Set ("Z",Z);
  7319.  
  7320.    Z := X and Y;   
  7321.    Put_Line ("Z := X and Y");
  7322.    Put_Set ("Z",Z);
  7323.  
  7324.    Z := X xor Y;   
  7325.    Put_Line ("Z := X xor Y");
  7326.    Put_Set ("Z",Z);
  7327.  
  7328. end Main;
  7329.  
  7330.  
  7331. -------------------------------------------------------------------
  7332. ---------------------  Next  Program  -----------------------------
  7333. -------------------------------------------------------------------
  7334.  
  7335.  
  7336.  
  7337. --
  7338. -- Version: @(#)shared.ada    1.1        Date: 5/30/84
  7339. --
  7340. --
  7341. -- Author:  Bryce Bardin
  7342. --          Ada Projects Section
  7343. --          Software Engineering Division
  7344. --          Ground Systems Group
  7345. --          Hughes Aircraft Company
  7346. --          Fullerton, CA
  7347. --
  7348. -- This program illustrates the use of tasking to provide shared access 
  7349. -- to global variables.  N.B.:  The values it outputs may vary from run 
  7350. -- to run depending on how tasking is implemented.
  7351.  
  7352.  
  7353. -- A "FIFO" solution to the READERS/WRITERS problem.
  7354. -- Authors:  Gerald Fisher and Robert Dewar.
  7355. -- (Modified by Bryce Bardin to terminate gracefully.)
  7356. -- May be used to provide shared access to objects by an arbitrary number of 
  7357. -- readers and writers which are serviced in order from a single queue.  
  7358. -- Writers are given uninterrupted access for updates and readers are assured 
  7359. -- that updates are indivisible and therefore complete when read access is 
  7360. -- granted.
  7361. --
  7362. -- If C is a task object of type Control and O is an object which is to be 
  7363. -- shared between readers and writers using C, then:
  7364. --
  7365. --    readers should do:
  7366. --
  7367. --       C.Start(Read);
  7368. --       <read all or part of O>
  7369. --       C.Stop;
  7370. --
  7371. --    and writers should do:
  7372. --
  7373. --       C.Start(Write);
  7374. --       <update all or part of O>
  7375. --       C.Stop;
  7376.  
  7377. package Readers_Writers is
  7378.  
  7379.    type Service is (Read, Write);
  7380.  
  7381.    task type Control is
  7382.       entry Start (Mode : Service);  -- start readers or writers
  7383.       entry Stop;                    -- stop readers or writers
  7384.    end Control;
  7385.  
  7386. end Readers_Writers;
  7387.  
  7388. package body Readers_Writers is
  7389.  
  7390.    task body Control is
  7391.       Read_Count : Natural := 0;
  7392.    begin
  7393.       loop
  7394.          select
  7395.             -- remove the first reader or writer from the queue
  7396.             accept Start (Mode : Service) do
  7397.                if Mode = Read then
  7398.                   Read_Count := Read_Count + 1;
  7399.                else
  7400.                   -- when writer, wait for readers which have already 
  7401.                   -- started to finish before allowing the writer to 
  7402.                   -- perform the update
  7403.                   while Read_Count > 0 loop
  7404.                      -- when a write is pending, readers stop here        
  7405.                      accept Stop;
  7406.                      Read_Count := Read_Count - 1;
  7407.                   end loop;
  7408.                end if;
  7409.             end Start;
  7410.  
  7411.             if Read_Count = 0 then
  7412.                -- when writer, wait for writer to stop before allowing 
  7413.                -- other readers or writers to start
  7414.                accept Stop;
  7415.             end if;
  7416.          or
  7417.             -- when no write is pending, readers stop here
  7418.             accept Stop;
  7419.             Read_Count := Read_Count -1;
  7420.          or
  7421.             -- quit when everyone agrees to do so
  7422.             terminate;
  7423.          end select;
  7424.       end loop;
  7425.    end Control;
  7426.  
  7427. end Readers_Writers;
  7428.  
  7429.  
  7430.  
  7431. -- This package allows any number of concurrent programs to read and/or 
  7432. -- indivisibly write a particular (possibly composite) variable object
  7433. -- without interference and in FIFO order.  Similar packages can be 
  7434. -- constructed to perform partial reads and writes of composite objects.
  7435. -- If service cannot be started before the appropriate time limit expires,
  7436. -- the exception Timed_Out will be raised.  (By default, service must be
  7437. -- started within Duration'Last (24+) hours.  Setting the time limits to 
  7438. -- 0.0 will require immediate service.)
  7439. --
  7440. generic
  7441.  
  7442.    type Object_Type is private;
  7443.    Object : in out Object_Type;
  7444.  
  7445.    Read_Time_Limit : in Duration := Duration'Last;
  7446.    Write_Time_Limit : in Duration := Duration'Last;
  7447.  
  7448.    -- for testing only
  7449.    with procedure Read_Put (Item : in Object_Type) is <>;
  7450.  
  7451.    -- for testing only
  7452.    with procedure Write_Put (Item : in Object_Type) is <>;
  7453.  
  7454.    -- for testing only
  7455.    with procedure Copy (From : in Object_Type; To : in out Object_Type);
  7456.  
  7457. package Shared_Variable is
  7458.  
  7459.    -- for testing only: Item made "in out" instead of "out"
  7460.    procedure Read (Item : in out Object_Type);
  7461.    procedure Write (Item : in Object_Type);
  7462.  
  7463.    Timed_Out : exception;
  7464.  
  7465. end Shared_Variable;
  7466.  
  7467. with Readers_Writers; use Readers_Writers;
  7468. package body Shared_Variable is
  7469.  
  7470.    C : Control;
  7471.  
  7472.    -- for testing only: Item made "in out" instead of "out"
  7473.    procedure Read (Item : in out Object_Type) is
  7474.    begin
  7475.  
  7476.       select
  7477.      C.Start(Read);
  7478.       or
  7479.      delay Read_Time_Limit;
  7480.      raise Timed_Out;
  7481.       end select;
  7482.  
  7483. -- for testing only; this allows the scheduler to screw up!
  7484.       Copy(From => Object, To => Item);
  7485. -- temporarily replaces
  7486. --    Item := Object;
  7487.  
  7488. -- for testing only
  7489.       Read_Put(Item);
  7490.  
  7491.       C.Stop;
  7492.    end Read;
  7493.  
  7494.    procedure Write (Item : in Object_Type) is
  7495.    begin
  7496.  
  7497.       select
  7498.      C.Start(Write);
  7499.       or
  7500.      delay Write_Time_Limit;
  7501.      raise Timed_Out;
  7502.       end select;
  7503.  
  7504. -- for testing only; this allows the scheduler to screw up!
  7505.       Copy(From => Item, To => Object);
  7506. -- temporarily replaces
  7507.       Object := Item;
  7508.  
  7509. -- for testing only
  7510.       Write_Put(Item);
  7511.  
  7512.       C.Stop;
  7513.    end Write;
  7514.  
  7515. end Shared_Variable;
  7516.  
  7517.  
  7518.  
  7519. with Shared_Variable;
  7520. package Encapsulate is
  7521.  
  7522.    Max : constant := 2;
  7523.  
  7524.    subtype Index is Positive range 1 .. Max;
  7525.  
  7526.    type Composite is array (Index) of Integer;
  7527.  
  7528.    procedure Read (C : out Composite);
  7529.  
  7530.    procedure Write (C : in Composite);
  7531.  
  7532. -- This is a help function for testing
  7533.    function Set_To (I : Integer) return Composite;
  7534.  
  7535. -- This is a help function for testing
  7536.    function Value_Of (C : Composite) return Integer;
  7537.  
  7538. -- This entry is used to serialize debug output to Standard_Output
  7539.    task Msg is
  7540.       entry Put (S : String);
  7541.    end Msg;
  7542.  
  7543. end Encapsulate;
  7544.  
  7545.  
  7546. with Text_IO;
  7547. package body Encapsulate is
  7548.  
  7549.    Shared : Composite;
  7550.  
  7551.    function Set_To (I : Integer) return Composite is
  7552.       Temp : Composite;
  7553.    begin
  7554.       for N in Index loop
  7555.      Temp(N) := I;
  7556.       end loop;
  7557.       return Temp;
  7558.    end Set_To;
  7559.  
  7560.    function Value_Of (C : Composite) return Integer is
  7561.    begin
  7562.       return C(Index'First);
  7563.    end Value_Of;
  7564.  
  7565.    -- for testing only; this allows the scheduler to overlap readers and 
  7566.    -- writers and thus screw up if Readers_Writers doesn't do its job.
  7567.    -- it also checks that the copy is consistent.
  7568.    procedure Copy (From : in Composite; To : in out Composite) is
  7569.    begin
  7570.       for I in Index loop
  7571.      To(I) := From(I);
  7572.          -- delay so that another access could be made:
  7573.      delay 0.5;
  7574.       end loop;
  7575.       -- test for consistency:
  7576.       for I in Index range Index'Succ(Index'First) .. Index'Last loop
  7577.      if To(I) /= To(Index'First) then
  7578.         raise Program_Error;
  7579.      end if;
  7580.       end loop;
  7581.    end Copy;
  7582.  
  7583.    procedure Read_Put (Item : Composite) is
  7584.    begin
  7585.       Msg.Put(Integer'Image(Value_Of(Item)) & " read");
  7586.    end Read_Put;
  7587.  
  7588.    procedure Write_Put (Item : Composite) is
  7589.    begin
  7590.       Msg.Put(Integer'Image(Value_Of(Item)) & " written");
  7591.    end Write_Put;
  7592.  
  7593.    task body Msg is
  7594.    begin
  7595.       loop
  7596.      select
  7597.         accept Put (S : String) do
  7598.            Text_IO.Put (S);
  7599.            Text_IO.New_Line;
  7600.         end Put;
  7601.      or
  7602.         terminate;
  7603.      end select;
  7604.       end loop;
  7605.    end Msg;
  7606.  
  7607.    package Share is new Shared_Variable 
  7608.       (Object_Type => Composite, Object => Shared, Read_Put => Read_Put,
  7609.       Write_Put => Write_Put, Copy => Copy);
  7610.    use Share;
  7611.  
  7612.    procedure Read (C : out Composite) is
  7613.       Temp : Composite;
  7614.    begin
  7615.       Share.Read(Temp);
  7616.       C := Temp;
  7617.    end Read;
  7618.  
  7619.    procedure Write (C : in Composite) is
  7620.    begin
  7621.       Share.Write(C);
  7622.    end Write;
  7623.  
  7624. begin
  7625.  
  7626.    Shared := Set_To (0);
  7627.  
  7628. end Encapsulate;
  7629.  
  7630.  
  7631. with Encapsulate; use Encapsulate;
  7632. with Text_IO; use Text_IO;
  7633. procedure Test_Shared is
  7634.  
  7635.    Local : Composite := Set_To (-1);
  7636.  
  7637.    task A;
  7638.    task B;
  7639.    task C;
  7640.  
  7641.    procedure Put(C : Character; I : Integer);
  7642.  
  7643.    task body A is
  7644.    begin
  7645.       Read(Local);
  7646.       Put('A',Value_Of(Local));
  7647.  
  7648.       Write(Set_To(1));
  7649.  
  7650.       Read(Local);
  7651.       Put('A',Value_Of(Local));
  7652.  
  7653.       Write(Set_To(2));
  7654.  
  7655.       Read(Local);
  7656.       Put('A',Value_Of(Local));
  7657.    end A;
  7658.  
  7659.    task body B is
  7660.    begin
  7661.       Read(Local);
  7662.       Put('B',Value_Of(Local));
  7663.  
  7664.       Write(Set_To(3));
  7665.  
  7666.       Read(Local);
  7667.       Put('B',Value_Of(Local));
  7668.    end B;
  7669.  
  7670.    task body C is
  7671.    begin
  7672.       Write(Set_To(4));
  7673.  
  7674.       Read(Local);
  7675.       Put('C',Value_Of(Local));
  7676.  
  7677.       Write(Set_To(5));
  7678.  
  7679.       Read(Local);
  7680.       Put('C',Value_Of(Local));
  7681.    end C;
  7682.  
  7683.    procedure Put(C : Character; I : Integer) is
  7684.    begin
  7685.       Msg.Put("Task " & C & " read the value " & Integer'Image(I));
  7686.    end Put;
  7687.  
  7688. begin
  7689.    null;
  7690. end Test_Shared;
  7691.  
  7692.  
  7693.  
  7694.  
  7695.  
  7696.  
  7697. -------------------------------------------------------------------
  7698. ---------------------  Next  Program  -----------------------------
  7699. -------------------------------------------------------------------
  7700.  
  7701.  
  7702.  
  7703. ------------------------------------------------------------------------
  7704. --
  7705. --
  7706. --
  7707. --  U N I V E R S A L    A R I T H M E T I C    P A C K A G E S
  7708. --
  7709. --        Version: @(#)univ_ar.ada    1.1    Date: 5/30/84
  7710. --
  7711. --              written by
  7712. --
  7713. --             Gerry Fisher
  7714. --         Computer Sciences Corporation
  7715. --              4045 Hancock Street
  7716. --              San Diego, CA 92110
  7717. --
  7718. --
  7719. --
  7720. -- The packages UNIVERSAL_INTEGER_ARITHMETIC and UNIVERSAL_REAL_ARITHMETIC,
  7721. -- implement the arithmetic operations for the Ada* universal_integer and
  7722. -- universal_real types.  Unlimited precision arithmetic is used for the
  7723. -- universal_integer type and rational arithmetic for the universal_real
  7724. -- type.  The implementation is based on the universal arithmetic package
  7725. -- written in SETL by Robert Dewar for the NYU Ada/Ed compiler, and was
  7726. -- coded in part while the author worked at TeleSoft.
  7727. --
  7728. -- The implementation presented here is not the most efficient.  It is,
  7729. -- however, quite general and requires no low level facilities.  With some
  7730. -- tuning these packages could be used within an Ada compiler to evaluate
  7731. -- static expressions.  They also provide an excellent example of the use
  7732. -- of Ada packages to support an abstract data type.
  7733. --
  7734. -- * Ada is a registered trademark of the DoD (Ada Joint Program Office)
  7735. --
  7736. ------------------------------------------------------------------------
  7737.  
  7738.  
  7739.  
  7740. package UNIVERSAL_INTEGER_ARITHMETIC is
  7741.  
  7742. --  This package implements the Ada type Universal_integer.
  7743.  
  7744. --  The operations defined on universal integers are those specified in
  7745. --  chapter 4 of the RM.  Since the equality and inequality operators can
  7746. --  not be overloaded, an equality operation is defined. In addition,
  7747. --  conversions between INTEGER, STRING and Universal_integer are defined.
  7748.  
  7749.   type Universal_integer is private;
  7750.  
  7751.   function "+"    (x, y : Universal_integer) return Universal_integer;
  7752.   function "-"    (x, y : Universal_integer) return Universal_integer;
  7753.   function "*"    (x, y : Universal_integer) return Universal_integer;
  7754.   function "/"    (x, y : Universal_integer) return Universal_integer;
  7755.   function "mod"(x, y : Universal_integer) return Universal_integer;
  7756.   function "rem"(x, y : Universal_integer) return Universal_integer;
  7757.  
  7758.   function "**" (x : Universal_integer; y : INTEGER) return Universal_integer;
  7759.  
  7760.   function "-"    (x : Universal_integer) return Universal_integer;
  7761.   function "abs"(x : Universal_integer) return Universal_integer;
  7762.  
  7763.   function ">=" (x, y : Universal_integer) return boolean;
  7764.   function ">"    (x, y : Universal_integer) return boolean;
  7765.   function "<=" (x, y : Universal_integer) return boolean;
  7766.   function "<"    (x, y : Universal_integer) return boolean;
  7767.   function eql    (x, y : Universal_integer) return boolean;
  7768.  
  7769.   function Int(x : Universal_integer) return INTEGER;
  7770.  
  7771.   -- Converts a universal integer to a integer.  The exception
  7772.   -- NUMERIC_ERROR is raised if the universal integer x has a value
  7773.   -- outside the integer range.
  7774.  
  7775.  
  7776.   function UI(i : INTEGER) return Universal_integer;
  7777.  
  7778.   -- Constructs a universal integer from an integer.
  7779.  
  7780.  
  7781.   function IMAGE(x : Universal_integer) return STRING;
  7782.  
  7783.   -- Converts the universal integer x into its string image, that is, a
  7784.   -- sequence of characters representing the value in display form.  The
  7785.   -- image of a universal integer value is the corresponding decimal
  7786.   -- literal; without underlines, leading zeros, exponent or trailing spaces;
  7787.   -- but with a single leading minus sign or space.  The lower bound of the
  7788.   -- image string is one.
  7789.  
  7790.  
  7791.   function VALUE(s : STRING) return Universal_integer;
  7792.  
  7793.   -- Converts the string s into a universal integer value.  The string must have
  7794.   -- the syntax of an optionally signed decimal integer literal; otherwise, the
  7795.   -- exception CONSTRAINT_ERROR is raised.  The exponent of the decimal literal,
  7796.   -- if present, must not exceed INTEGER'LAST.
  7797.  
  7798.  
  7799. private
  7800.  
  7801.   type VECTOR;
  7802.  
  7803.   type Universal_integer is access VECTOR;
  7804.  
  7805. end UNIVERSAL_INTEGER_ARITHMETIC;
  7806.  
  7807.  
  7808.  
  7809. package body UNIVERSAL_INTEGER_ARITHMETIC is
  7810.  
  7811. --  A universal integer consists of a sign and a magnitude.  The
  7812. --  magnitude is a vector of non-negative integers giving from
  7813. --  most significant to least significant the "digits" of the
  7814. --  number in some convenient base.  There are no leading zero digits,
  7815. --  unless the value is zero.  Universal integers are always normalized.
  7816. --  The lower bound of the universal integer vector is always one.
  7817. --  Thus, the magnitude for the vector V(1 .. k) is given by:
  7818. --
  7819. --    V(1) * BASE**(k - 1) + V(2) * BASE**(k - 2) + ... + V(k)
  7820. --
  7821. --  The maximum number of digits in a universal integer is limited
  7822. --  in this implementation only by the amount of available memory.
  7823. --
  7824. --  The base is 10 ** ((INTEGER'WIDTH - 2) / 2).  The universal digits are
  7825. --  integers in the range 0 .. BASE - 1.  This choice of BASE means that
  7826. --  slightly less than half of the integer range is used.  However, the
  7827. --  choice does ensure that the product of two universal digits is an integer.
  7828. --  Also, the number of universal digits required to represent an integer value
  7829. --  as a universal integer is at most four.
  7830. --
  7831. --  To complete the representation the high order universal digit has the sign
  7832. --  of the universal integer.
  7833.  
  7834.  
  7835.   BASE_D  : constant := (INTEGER'WIDTH - 2) / 2;
  7836.   BASE      : constant :=  10 ** BASE_D;
  7837.   BASE_SQ : constant := BASE * BASE;
  7838.   INT_D   : constant := 4;
  7839.  
  7840.  
  7841.   type VECTOR is array(POSITIVE range <>) of INTEGER;
  7842.  
  7843.  
  7844.   i_zero : constant Universal_integer := new VECTOR'(1 => 0);
  7845.   i_one  : constant Universal_integer := new VECTOR'(1 => 1);
  7846.   i_two  : constant Universal_integer := new VECTOR'(1 => 2);
  7847.   i_ten  : constant Universal_integer := new VECTOR'(1 => 10);
  7848.  
  7849.  
  7850.   function UI(v : VECTOR; s : BOOLEAN := FALSE) return Universal_integer is
  7851.  
  7852.   -- Constructs a universal integer from a vector and a sign; the vector
  7853.   -- need not be normalized.  The boolean s is true if the number is negative.
  7854.  
  7855.      t : Universal_integer;
  7856.  
  7857.   begin
  7858.  
  7859.   --  The representation used in this package requires that all
  7860.   --  Universal_integer values be normalized.  The first digit of any
  7861.   --  value, except zero, must be non-zero.
  7862.  
  7863.      for j in v'range loop
  7864.        if v(j) /= 0 then
  7865.          t := new VECTOR(1 .. v'last - j + 1);  -- ensure lower bound of one
  7866.          t.all := v(j .. v'last);
  7867.      if s then t(1) := - t(1); end if;
  7868.      return t;
  7869.        end if;
  7870.      end loop;
  7871.  
  7872.      return i_zero;
  7873.  
  7874.   end UI;
  7875.  
  7876.  
  7877.   function UI(i : INTEGER) return Universal_integer is
  7878.  
  7879.     y : VECTOR(1 .. INT_D) := (1 .. INT_D => 0);
  7880.     z : INTEGER;
  7881.  
  7882.   begin
  7883.  
  7884.     if i < BASE and then i > - BASE then
  7885.       return new VECTOR'(1 => i);
  7886.     end if;
  7887.  
  7888.     z := i;
  7889.  
  7890.     for j in reverse y'range
  7891.     loop
  7892.       y(j) := abs(z rem BASE);
  7893.       z    := z / BASE;
  7894.     end loop;
  7895.  
  7896.     return UI(y, i < 0);
  7897.  
  7898.   end UI;
  7899.  
  7900.  
  7901.   function Int(x : Universal_integer) return INTEGER is
  7902.     y : INTEGER;
  7903.   begin
  7904.  
  7905.     if    x'length = 1 then
  7906.       return x(1);
  7907.     end if;
  7908.  
  7909.     y := 0;
  7910.  
  7911.     for i in x'range loop        -- convert as a negative integer
  7912.       y := y * BASE - abs x(i);  -- this may raise NUMERIC_ERROR, but
  7913.     end loop;             -- only if the magnitude of x is too large.
  7914.  
  7915.     if x(1) < 0 then
  7916.       return   y;
  7917.     else
  7918.       return - y;         -- this may raise NUMERIC_ERROR if x is
  7919.     end if;                      -- -(integer'first) and range is not symmetric.
  7920.  
  7921.   end Int;
  7922.  
  7923.  
  7924.   function IMAGE(x : Universal_integer) return STRING is
  7925.  
  7926.     m    : integer := x'length * BASE_D + 1;
  7927.     s     : string(1 .. m);
  7928.     y     : Universal_integer;
  7929.     j, d : integer;
  7930.  
  7931.   begin
  7932.  
  7933.     if x(1) = 0 then
  7934.        return " 0";
  7935.     end if;
  7936.  
  7937.     j := m;
  7938.     y := abs x;
  7939.  
  7940.     while y(1) /= 0 loop
  7941.       d := Int(y rem i_ten);
  7942.       y := y / i_ten;
  7943.  
  7944.       s(j) := character'val(character'pos('0') + d);
  7945.       j    := j - 1;
  7946.     end loop;
  7947.  
  7948.     if x(1) < 0 then
  7949.       s(j) := '-';
  7950.     else
  7951.       s(j) := ' ';
  7952.     end if;
  7953.  
  7954.     d := m - j + 1;
  7955.     s(1 .. d) := s(j .. m);
  7956.     return s(1 .. d);
  7957.  
  7958.   end IMAGE;
  7959.  
  7960.  
  7961.   function VALUE(s : STRING) return Universal_integer is
  7962.  
  7963.     num    : Universal_integer := i_zero;
  7964.     exp    : integer := 0;
  7965.     signed : boolean := false;
  7966.     has_exp: boolean := false;
  7967.     c       : character;
  7968.     j       : integer;
  7969.  
  7970.   begin
  7971.  
  7972.     if s'length = 0 then
  7973.       raise CONSTRAINT_ERROR;
  7974.     end if;
  7975.  
  7976.     j := s'first;
  7977.     c := s(j);
  7978.  
  7979.     if c = '-' or else c = '+' then
  7980.  
  7981.       j := j + 1;
  7982.       if s(j) not in '0' .. '9' then    -- index out of range may also raise
  7983.     raise CONSTRAINT_ERROR;     -- constraint_error here
  7984.       end if;
  7985.       signed := c = '-';
  7986.  
  7987.     end if;
  7988.  
  7989.     while j <= s'last loop
  7990.  
  7991.       c := s(j);
  7992.       case c is
  7993.         when '0' .. '9' =>
  7994.  
  7995.       if has_exp then
  7996.             exp := exp * 10 + (character'pos(c) - character'pos('0'));
  7997.       else
  7998.             num := num * i_ten + UI(character'pos(c) - character'pos('0'));
  7999.       end if;
  8000.  
  8001.         when '_' =>
  8002.  
  8003.           if s(j - 1) not in '0' .. '9' or else s(j + 1) not in '0' .. '9' then
  8004.         raise CONSTRAINT_ERROR;
  8005.       end if;
  8006.  
  8007.         when 'E' | 'e' =>
  8008.  
  8009.           if has_exp or else s(j - 1) not in '0' .. '9' then
  8010.         raise CONSTRAINT_ERROR;
  8011.       end if;
  8012.  
  8013.       has_exp := true;
  8014.           if s(j + 1) = '+' then j := j + 1; end if;
  8015.           if s(j + 1) not in '0' .. '9' then
  8016.         raise CONSTRAINT_ERROR;
  8017.       end if;
  8018.  
  8019.     when others =>
  8020.       raise CONSTRAINT_ERROR;
  8021.  
  8022.       end case;
  8023.  
  8024.       j := j + 1;
  8025.  
  8026.     end loop;
  8027.  
  8028.     if has_exp then num := num * i_ten ** exp; end if;
  8029.  
  8030.     if signed  then num := - num; end if;
  8031.  
  8032.     return num;
  8033.  
  8034.   end VALUE;
  8035.  
  8036.  
  8037.   function "-"    (x : Universal_integer) return Universal_integer is
  8038.   begin
  8039.     return new VECTOR'(- x(1) & x(2 .. x'last));
  8040.   end "-";
  8041.  
  8042.   function "abs"  (x : Universal_integer) return Universal_integer is
  8043.   begin
  8044.     return new VECTOR'(abs x(1) & x(2 .. x'last));
  8045.   end "abs";
  8046.  
  8047.  
  8048.   function "+"    (x, y : Universal_integer) return Universal_integer is
  8049.  
  8050.      m        : integer;
  8051.      k, r   : integer;
  8052.      xl, yl : integer;
  8053.      xs, ys : boolean;
  8054.  
  8055.   begin
  8056.  
  8057.     xl := x'length;
  8058.     yl := y'length;
  8059.  
  8060.     if xl = 1 and then yl = 1 then            -- each has one digit
  8061.       return UI(x(1) + y(1));
  8062.  
  8063.     else            -- either or both operands have > 1 digits
  8064.  
  8065.       if xl < yl then
  8066.     m := yl + 1;
  8067.       else
  8068.     m := xl + 1;
  8069.       end if;
  8070.  
  8071.       declare
  8072.  
  8073.     u, v   : VECTOR(1 .. m);
  8074.  
  8075.       begin
  8076.  
  8077.     xs := x(1) < 0;
  8078.     ys := y(1) < 0;
  8079.  
  8080.     u := (1 .. m - xl => 0) & abs x(1) & x(2 .. xl);
  8081.     v := (1 .. m - yl => 0) & abs y(1) & y(2 .. yl);
  8082.  
  8083.     if xs = ys then     -- signs agree so add
  8084.  
  8085.       k := 0;
  8086.       for i in reverse 1 .. m loop
  8087.  
  8088.         r := u(i) + v(i) + k;
  8089.         if r >= BASE then
  8090.           r := r - BASE;
  8091.           k := 1;
  8092.         else
  8093.           k := 0;
  8094.         end if;
  8095.         u(i) := r;
  8096.  
  8097.       end loop;
  8098.  
  8099.       return UI(u, xs);
  8100.  
  8101.     else
  8102.  
  8103.     -- signs different, subtract smaller from larger
  8104.  
  8105.       k := 0;
  8106.       for i in reverse 1 .. m loop
  8107.  
  8108.         r := u(i) - v(i) + k;
  8109.         if r < 0 then
  8110.           r := r + BASE;
  8111.           k := - 1;
  8112.         else
  8113.           k := 0;
  8114.         end if;
  8115.         u(i) := r;
  8116.  
  8117.       end loop;
  8118.  
  8119.       if k = 0 then     -- x has the larger magnitude
  8120.  
  8121.         return UI(u, xs);
  8122.  
  8123.       else            -- y has the larger magnitude, so recomplement
  8124.  
  8125.         k := 1;
  8126.         for i in reverse 1 .. m loop
  8127.  
  8128.           r := BASE - 1 - u(i) + k;
  8129.           if r = BASE then
  8130.         r := 0;
  8131.         k := 1;
  8132.           else
  8133.         k := 0;
  8134.           end if;
  8135.           u(i) := r;
  8136.  
  8137.         end loop;
  8138.  
  8139.         return UI(u, ys);
  8140.  
  8141.       end if;
  8142.  
  8143.     end if;
  8144.  
  8145.       end;
  8146.  
  8147.     end if;
  8148.  
  8149.   end "+";
  8150.  
  8151.  
  8152.   function "-"    (x, y : Universal_integer) return Universal_integer is
  8153.   begin
  8154.     return x + (- y);
  8155.   end "-";
  8156.  
  8157.  
  8158.   function "*"    (x, y : Universal_integer) return Universal_integer is
  8159.  
  8160.   --  This function returns the product of the universal integers x
  8161.   --  and y using essentially the familiar hand algorithm.
  8162.  
  8163.     xl, yl : integer;
  8164.  
  8165.   begin
  8166.  
  8167.     xl := x'length;
  8168.     yl := y'length;
  8169.  
  8170.     if xl = 1 and yl = 1 then            -- both have a single digit
  8171.       return UI(x(1) * y(1));
  8172.     end if;
  8173.  
  8174.     declare
  8175.  
  8176.       w    : VECTOR(1 .. xl + yl) := (1 .. xl + yl => 0);
  8177.       k, r : integer;
  8178.  
  8179.     begin
  8180.  
  8181.       for j in reverse y'range loop
  8182.  
  8183.       --  outer loop through digits of the multiplier, inner loop
  8184.       --  through digits of multiplicand
  8185.  
  8186.     k := 0;
  8187.         for i in reverse x'range loop
  8188.       r       := abs(x(i) * y(j)) + w(i + j) + k;
  8189.       w(i + j) := r rem BASE;
  8190.       k       := r /   BASE;
  8191.     end loop;
  8192.  
  8193.     w(j)       := k;
  8194.  
  8195.       end loop;
  8196.  
  8197.       return UI(w, (x(1) < 0) xor (y(1) < 0));
  8198.  
  8199.     end;
  8200.  
  8201.   end "*";
  8202.  
  8203.  
  8204.   function "/"    (x, y : Universal_integer) return Universal_integer is
  8205.  
  8206.     m        : integer;
  8207.     xl, yl  : integer;
  8208.     e        : integer;
  8209.     d, r, t : integer;
  8210.     qe        : integer;            -- quotient digit estimate
  8211.     v1, v2  : integer;
  8212.  
  8213.   begin
  8214.  
  8215.     xl := x'length;
  8216.     yl := y'length;
  8217.  
  8218.     if      xl = 1 and then yl = 1 then    -- can use simple integer division
  8219.  
  8220.       return UI(x(1) / y(1));        -- integer divide catches zero divisor
  8221.  
  8222.     elsif xl < yl then            -- divisor has more digits
  8223.  
  8224.       return i_zero;
  8225.  
  8226.     elsif yl = 1 then            -- divisor has single digit
  8227.                     -- dividend has more than one digit,
  8228.                     -- important special case for which
  8229.                     -- an efficient algorithm is used
  8230.       r  := 0;
  8231.       v1 := abs y(1);
  8232.       if v1 = 0 then            -- divisor is zero
  8233.     raise NUMERIC_ERROR;
  8234.       end if;
  8235.  
  8236.       declare
  8237.     q : VECTOR(1 .. xl);
  8238.       begin
  8239.  
  8240.         for j in x'range loop
  8241.       t    := r * BASE + abs x(j);
  8242.       q(j) := t /    v1;
  8243.       r    := t rem v1;
  8244.     end loop;
  8245.  
  8246.     return UI(q, (x(1) < 0) xor (y(1) < 0));
  8247.  
  8248.       end;
  8249.  
  8250.     end if;
  8251.  
  8252.     --    At this point the length of the dividend is at least two and
  8253.     --    at least as much as the length of the divisor.    We must do a
  8254.     --    full long division.  The algorithm used here is from Knuth,
  8255.     --    "The Art of Programming", Volume 2, Section 4.3.1, Algorithm D.
  8256.  
  8257.     --    The first step is to multiply both the divisor and dividend
  8258.     --    by a scale factor to ensure that the first digit of the divisor
  8259.     --    is at least BASE / 2.  This condition is required by the
  8260.     --    quotient digit estimation algorithm used in the division loop.
  8261.     --    Note that this may increase the size of the dividend by one digit
  8262.     --    and thus the scaled dividend is placed in u.
  8263.  
  8264.     m := xl - yl + 1;
  8265.  
  8266.     declare
  8267.       u : VECTOR(1 .. xl + 1);        -- the dividend
  8268.       v : VECTOR(1 .. yl);        -- the divisor
  8269.       q : VECTOR(1 .. m);        -- the quotient
  8270.     begin
  8271.  
  8272.       u := 0 & abs x(1) & x(2 .. xl);
  8273.       v := abs y(1) & y(2 .. yl);
  8274.  
  8275.       v1 := v(1);
  8276.  
  8277.       d := BASE / (v1 + 1);        -- scale factor
  8278.  
  8279.       if d > 1 then            -- scale dividend and divisor
  8280.  
  8281.     r := 0;
  8282.         for j in reverse u'range loop
  8283.        t    := u(j) * d + r;
  8284.        u(j) := t rem BASE;
  8285.        r    := t /     BASE;
  8286.     end loop;
  8287.  
  8288.     r := 0;
  8289.         for j in reverse v'range loop
  8290.        t    := v(j) * d + r;
  8291.        v(j) := t rem BASE;
  8292.        r    := t /     BASE;
  8293.     end loop;
  8294.  
  8295.       end if;
  8296.  
  8297.       -- This is the major loop, corresponding to long division steps.
  8298.  
  8299.       v1 := v(1);
  8300.       v2 := v(2);
  8301.  
  8302.       for j in q'range loop
  8303.  
  8304.     -- Guess the next quotient digit, qe, by dividing the first two
  8305.     -- remaining dividend digits by the high order divisor digit.
  8306.     -- This estimate is never low and is at most 2 high.
  8307.  
  8308.     t := u(j) * BASE + u(j + 1);
  8309.     if u(j) /= v1 then
  8310.        qe := t / v1;
  8311.     else
  8312.        qe := BASE - 1;
  8313.     end if;
  8314.  
  8315.     -- Now refine this guess so that it is almost always correct and
  8316.     -- is at worst one too high.
  8317.  
  8318.     while v2 * qe > (t - qe * v1) * BASE + u(j + 2) loop
  8319.        qe := qe - 1;
  8320.     end loop;
  8321.  
  8322.     -- Using qe as the quotient digit, we multiply the divisor by
  8323.     -- qe and subtract from the remaining dividend.
  8324.  
  8325.     r := 0;
  8326.         for k in reverse v'range loop
  8327.        t := u(j + k) - qe * v(k) + r;
  8328.        e := t rem BASE;
  8329.        r := t /   BASE;
  8330.        if e < 0 then
  8331.           e := e + BASE;
  8332.           r := r - 1;
  8333.        end if;
  8334.        u(j + k) := e;
  8335.     end loop;
  8336.  
  8337.     u(j) := u(j) + r;
  8338.  
  8339.     -- If qe was off by one, then u(j) went negative when the last
  8340.     -- carry was added.  So we correct the error by subtracting one
  8341.     -- from the quotient digit and adding back the divisor to the
  8342.     -- relevant portion of the dividend.
  8343.  
  8344.     if u(j) < 0 then
  8345.        qe := qe - 1;
  8346.        r := 0;
  8347.            for k in reverse v'range loop
  8348.           t := u(j + k) + v(k) + r;
  8349.           if t > BASE then
  8350.          t := t - BASE;
  8351.          r := 1;
  8352.           else
  8353.          r := 0;
  8354.           end if;
  8355.           u(j + k) := t;
  8356.        end loop;
  8357.        u(j) := u(j) + r;
  8358.     end if;
  8359.  
  8360.     -- Store the next quotient digit.
  8361.  
  8362.     q(j) := qe;
  8363.  
  8364.       end loop;
  8365.  
  8366.       return UI(q, (x(1) < 0) xor (y(1) < 0));
  8367.  
  8368.     end;
  8369.  
  8370.   end "/";
  8371.  
  8372.  
  8373.   function "rem"(x, y : Universal_integer) return Universal_integer is
  8374.   begin
  8375.     if x'length = 1 and then y'length = 1 then
  8376.       return UI(x(1) rem y(1));
  8377.     else
  8378.       return x - (x / y) * y;
  8379.     end if;
  8380.   end "rem";
  8381.  
  8382.   function "mod"(x, y : Universal_integer) return Universal_integer is
  8383.      r : constant Universal_integer := x rem y;
  8384.   begin
  8385.      if (x(1) < 0) = (y(1) < 0) or else r(1) = 0 then
  8386.     return r;
  8387.      else
  8388.     return y + r;
  8389.      end if;
  8390.   end "mod";
  8391.  
  8392.  
  8393.   function "**"(x : Universal_integer; y : INTEGER) return Universal_integer is
  8394.  
  8395.   --  Raise a universal integer to an integer power using the binary
  8396.   --  representation of the exponent.
  8397.  
  8398.     r : Universal_integer := i_one;
  8399.     v : integer       := y;
  8400.     t : Universal_integer := abs x;
  8401.  
  8402.   begin
  8403.  
  8404.     if      y < 0 then
  8405.       raise CONSTRAINT_ERROR;
  8406.     elsif y = 0 then
  8407.       return i_one;
  8408.     elsif x(1) = 0 then
  8409.       return i_zero;
  8410.     end if;
  8411.  
  8412.     -- Starting the variable r at 1 and t at x loop through the binary
  8413.     -- digits of v, squaring t each time, and multiplying the result r
  8414.     -- by the current value of t each time a 1-bit is found.
  8415.  
  8416.     while v /= 0 loop
  8417.  
  8418.       if v rem 2 = 1 then            -- v is odd
  8419.     r := r * t;
  8420.       end if;
  8421.  
  8422.       t := t * t;
  8423.       v := v / 2;                -- halve v
  8424.  
  8425.     end loop;
  8426.  
  8427.     -- Compute the sign of the result: positive if y is even, the sign of
  8428.     -- x if y is odd.
  8429.  
  8430.     if x(1) < 0 and then y rem 2 = 1 then r(1) := - r(1); end if;
  8431.  
  8432.     return r;
  8433.  
  8434.   end "**";
  8435.  
  8436.  
  8437.  
  8438.   function ">=" (x, y : Universal_integer) return boolean is
  8439.     z : Universal_integer := x - y;
  8440.   begin
  8441.      return z(1) >= 0;
  8442.   end ">=";
  8443.  
  8444.  
  8445.   function "<=" (x, y : Universal_integer) return boolean is
  8446.     z : Universal_integer := x - y;
  8447.   begin
  8448.     return z(1) <= 0;
  8449.   end "<=";
  8450.  
  8451.  
  8452.   function "<"    (x, y : Universal_integer) return boolean is
  8453.     z : Universal_integer := x - y;
  8454.   begin
  8455.      return z(1) < 0;
  8456.   end "<";
  8457.  
  8458.  
  8459.   function ">"    (x, y : Universal_integer) return boolean is
  8460.     z : Universal_integer := x - y;
  8461.   begin
  8462.      return z(1) > 0;
  8463.   end ">";
  8464.  
  8465.  
  8466.   function eql    (x, y : Universal_integer) return boolean is
  8467.   begin
  8468.      return x.all = y.all;
  8469.   end eql;
  8470.  
  8471. end UNIVERSAL_INTEGER_ARITHMETIC;
  8472.  
  8473.  
  8474.  
  8475.  
  8476. with UNIVERSAL_INTEGER_ARITHMETIC;
  8477. use  UNIVERSAL_INTEGER_ARITHMETIC;
  8478. package UNIVERSAL_REAL_ARITHMETIC is
  8479.  
  8480. --  This package implements the Ada type Universal_real.
  8481.  
  8482. --  The operations defined on universal numbers are those specified in
  8483. --  chapter 4 of the RM.  Since the equality and inequality operators can
  8484. --  not be overloaded, an equality function is defined.   A universal real
  8485. --  number corresponds to a unique pair of universal integers that represent
  8486. --  it as a rational number.  A function, UR, is defined that constructs a
  8487. --  universal real number from a pair of universal integers.  Also, the inverse
  8488. --  of this function is provided by two functions, NUMERATOR and DENOMINATOR,
  8489. --  that decompose the rational number representation of their universal real
  8490. --  argument into its numerator and denominator, respectively.    In addition,
  8491. --  conversions between Universal_integer and Universal_real are defined.
  8492.  
  8493.  
  8494.   type Universal_real is private;
  8495.  
  8496.  
  8497.   function "+"    (x, y : Universal_real) return Universal_real;
  8498.   function "-"    (x, y : Universal_real) return Universal_real;
  8499.   function "*"    (x, y : Universal_real) return Universal_real;
  8500.   function "/"    (x, y : Universal_real) return Universal_real;
  8501.  
  8502.   function "**" (x : Universal_real;    y : INTEGER) return Universal_real;
  8503.  
  8504.   function "*"    (x : Universal_integer; y : Universal_real)
  8505.                         return Universal_real;
  8506.   function "*"    (x : Universal_real;    y : Universal_integer)
  8507.                         return Universal_real;
  8508.   function "/"    (x : Universal_real;    y : Universal_integer)
  8509.                         return Universal_real;
  8510.  
  8511.   function "-"    (x : Universal_real) return Universal_real;
  8512.   function "abs"(x : Universal_real) return Universal_real;
  8513.  
  8514.   function ">=" (x, y : Universal_real) return boolean;
  8515.   function ">"    (x, y : Universal_real) return boolean;
  8516.   function "<=" (x, y : Universal_real) return boolean;
  8517.   function "<"    (x, y : Universal_real) return boolean;
  8518.   function eql    (x, y : Universal_real) return boolean;
  8519.  
  8520.  
  8521.   function UI(x : Universal_real) return Universal_integer;
  8522.  
  8523.   -- Converts a universal real to a universal integer by rounding.
  8524.  
  8525.  
  8526.   function UR(x : Universal_integer) return Universal_real;
  8527.  
  8528.   -- Converts a universal integer to a universal real.
  8529.  
  8530.  
  8531.   function UR(n, d : Universal_integer) return Universal_real;
  8532.  
  8533.   -- Constructs a universal real as the ratio of  two universal integers.
  8534.   -- The value of d must not be ZERO; if it is, NUMERIC_ERROR is raised.
  8535.  
  8536.  
  8537.   function NUMERATOR(x : Universal_real) return Universal_integer;
  8538.  
  8539.   -- Returns the numerator of x viewed as a rational number.
  8540.  
  8541.  
  8542.   function DENOMINATOR(x : Universal_real) return Universal_integer;
  8543.  
  8544.   -- Returns the denominator of x viewed as a rational number.
  8545.  
  8546.  
  8547. private
  8548.  
  8549. --  A universal real is represented as a rational number consisting
  8550. --  of a pair of universal integers.  The numerator is the first
  8551. --  member of the pair and the denominator is the second.  The
  8552. --  denominator must not be zero.  Also, the numerator, denominator
  8553. --  pair is always reduced to lowest terms.
  8554.  
  8555.   type Universal_real is
  8556.      record
  8557.        num : Universal_integer;
  8558.        den : Universal_integer;
  8559.      end record;
  8560.  
  8561.  
  8562. end UNIVERSAL_REAL_ARITHMETIC;
  8563.  
  8564.  
  8565. with UNIVERSAL_INTEGER_ARITHMETIC;
  8566. use UNIVERSAL_INTEGER_ARITHMETIC;
  8567. pragma ELABORATE(UNIVERSAL_INTEGER_ARITHMETIC);
  8568. package body UNIVERSAL_REAL_ARITHMETIC is
  8569.  
  8570.   i_zero : constant Universal_integer := UI(0);
  8571.   i_one  : constant Universal_integer := UI(1);
  8572.   i_two  : constant Universal_integer := UI(2);
  8573.   i_ten  : constant Universal_integer := UI(10);
  8574.  
  8575.   r_zero : constant Universal_real := (i_zero, i_one);
  8576.   r_one  : constant Universal_real := (i_one,  i_one);
  8577.  
  8578.  
  8579.   function UR(n, d : Universal_integer) return Universal_real is
  8580.  
  8581.   -- Constructs a universal real as the ratio of two universal integers.
  8582.   -- The value of d must not be ZERO; if it is, NUMERIC_ERROR is raised.
  8583.  
  8584.   -- Every real number produced as a result of an operation defined in
  8585.   -- this package must have a positive denominator and the numerator and
  8586.   -- denominator must be reduced to lowest terms.  This ensures uniqueness
  8587.   -- of the representation.
  8588.  
  8589.     r : Universal_integer;
  8590.     y : Universal_integer;
  8591.     z : Universal_integer;
  8592.  
  8593.   begin
  8594.     if      eql(d, i_zero) then
  8595.       raise NUMERIC_ERROR;
  8596.     elsif eql(n, i_zero) then
  8597.       return r_zero;
  8598.     end if;
  8599.  
  8600.     -- Now reduce to lowest terms; that is, find the gcd of n and d.
  8601.  
  8602.     y := abs n;
  8603.     z := abs d;
  8604.     loop
  8605.       r := y rem z;
  8606.       exit when eql(r, i_zero);
  8607.       y := z;
  8608.       z := r;
  8609.     end loop;
  8610.  
  8611.     if     d >= i_zero then
  8612.       return (n / z, d / z);
  8613.     else
  8614.       return (- n / z, - d / z);
  8615.     end if;
  8616.  
  8617.   end UR;
  8618.  
  8619.  
  8620.   function UI(x : Universal_real) return Universal_integer is
  8621.  
  8622.     i : Universal_integer := x.num / x.den;
  8623.     r : Universal_real      := (i, i_one);
  8624.     h : Universal_real      := (i_two, i_one);
  8625.  
  8626.   begin
  8627.     if      eql(x.num, i_zero) then
  8628.       return i_zero;
  8629.     elsif x.num < i_zero and then x - r <= - h then
  8630.       return i - i_one;
  8631.     elsif x.num > i_zero and then x - r >=   h then
  8632.       return i + i_one;
  8633.     else
  8634.       return i;
  8635.     end if;
  8636.   end UI;
  8637.  
  8638.  
  8639.   function UR(x : Universal_integer) return Universal_real is
  8640.   begin
  8641.     return (x, i_one);
  8642.   end UR;
  8643.  
  8644.  
  8645.   function NUMERATOR(x : Universal_real) return Universal_integer is
  8646.   begin
  8647.     return x.num;
  8648.   end NUMERATOR;
  8649.  
  8650.   function DENOMINATOR(x : Universal_real) return Universal_integer is
  8651.   begin
  8652.     return x.den;
  8653.   end DENOMINATOR;
  8654.  
  8655.  
  8656.   function "-"    (x : Universal_real) return Universal_real is
  8657.   begin
  8658.     return (- x.num, x.den);
  8659.   end "-";
  8660.  
  8661.  
  8662.   function "abs"  (x : Universal_real) return Universal_real is
  8663.   begin
  8664.     return (abs x.num, x.den);
  8665.   end "abs";
  8666.  
  8667.   function "*" (x : Universal_integer; y : Universal_real)
  8668.                         return Universal_real is
  8669.   begin
  8670.     return UR(y.num * x, y.den);
  8671.   end "*";
  8672.  
  8673.  
  8674.   function "*"(x : Universal_real; y : Universal_integer)
  8675.                         return Universal_real is
  8676.   begin
  8677.     return UR(x.num * y, x.den);
  8678.   end "*";
  8679.  
  8680.  
  8681.   function "/"(x : Universal_real; y : Universal_integer)
  8682.                         return Universal_real is
  8683.   begin
  8684.     return UR(x.num, x.den * y);
  8685.   end "/";
  8686.  
  8687.  
  8688.   function "+"    (x, y : Universal_real) return Universal_real is
  8689.   begin
  8690.     return UR(x.num * y.den + y.num * x.den, x.den * y.den);
  8691.   end "+";
  8692.  
  8693.  
  8694.   function "-"    (x, y : Universal_real) return Universal_real is
  8695.   begin
  8696.     return x + (- y);
  8697.   end "-";
  8698.  
  8699.  
  8700.   function "*"    (x, y : Universal_real) return Universal_real is
  8701.   begin
  8702.     return UR(x.num * y.num, x.den * y.den);
  8703.   end "*";
  8704.  
  8705.  
  8706.   function "/"    (x, y : Universal_real) return Universal_real is
  8707.   begin
  8708.     return UR(x.num * y.den, x.den * y.num);
  8709.   end "/";
  8710.  
  8711.   function "**"(x : Universal_real; y : INTEGER) return Universal_real is
  8712.   begin
  8713.     if      y = 0 then
  8714.       return r_one;
  8715.     elsif y > 0 then
  8716.       return UR(x.num ** y, x.den ** y);
  8717.     else
  8718.       return UR(x.den ** (- y), x.num ** (- y));
  8719.     end if;
  8720.   end "**";
  8721.  
  8722.  
  8723.   function ">=" (x, y : Universal_real) return boolean is
  8724.     z : Universal_real := x - y;
  8725.   begin
  8726.      return z.num >= i_zero;
  8727.   end ">=";
  8728.  
  8729.  
  8730.   function "<=" (x, y : Universal_real) return boolean is
  8731.     z : Universal_real := x - y;
  8732.   begin
  8733.      return z.num <= i_zero;
  8734.   end "<=";
  8735.  
  8736.  
  8737.   function "<"    (x, y : Universal_real) return boolean is
  8738.     z : Universal_real := x - y;
  8739.   begin
  8740.      return z.num < i_zero;
  8741.   end "<";
  8742.  
  8743.  
  8744.   function ">"    (x, y : Universal_real) return boolean is
  8745.     z : Universal_real := x - y;
  8746.   begin
  8747.     return z.num > i_zero;
  8748.   end ">";
  8749.  
  8750.  
  8751.   function eql    (x, y : Universal_real) return boolean is
  8752.     z : Universal_real := x - y;
  8753.   begin
  8754.     return eql(z.num, i_zero);
  8755.   end eql;
  8756.  
  8757. end UNIVERSAL_REAL_ARITHMETIC;
  8758.  
  8759.  
  8760.  
  8761.  
  8762. ------- End of Forwarded Message
  8763.  
  8764.  
  8765.