Shortened method to reduce statements in an Ada pr

2019-07-30 14:01发布

问题:

I am creating a procedure that uses an if statement to perform a decision.

I have four variables: Altitude, Velocity, Angle and Temperature.

The procedure is as follows:

procedure Test3 is
begin
   if (Integer(Status_System.Altitude_Measured)) >= Critical_Altitude 
      and  (Integer(Status_System.Velocity_Measured)) >= Critical_Velocity
      and  (Integer(Status_System.Angle_Measured)) >= Critical_Angle
      and  (Integer(Status_System.Temperature_Measured)) >= Critical_Temperature 
   then 
      DT_Put ("message 1");       
   else
      null;
   end if;
end Test3;

This procedure is bassicaly taking the idea that if all the critcal values for the variables are met for each and every variable then it will print a message.

I want to be able to have a shorter way of paring up the statements so I can do the following:

If I have 4 variables: Altitude, velocity, angle and temperature and I want to have a statement that says, If atleast 3 of these varibles (doesnt matter which three) are all exceeding their critical values then display a message.

Is it even possible to do this?

I would hate to think that I would have to write each and every possible combination for the if statements.

In short, I want an if statement that says at least 3 of the variables shown are at their criticle value so print a message.

The same would be good for atleast 2 of these variables as well.

回答1:

First, you should try to use specific types for altitude, velocity, angle and temperature. By using different types you'll leverage strong typing provided by Ada and avoid mistakes such as mixing or comparing altitudes and temperatures. Your example suggests that all of them are Integer. One possible definition could be (there are many others):

type Temperature is digits 5 range -273.15 .. 300.0;
type Angle is digits 5 range -180.0 .. 180.0;

The advantage of such definition is that you define both the range of values and the precision (captors all have a finite precision).

Counting the number of errors is one way do that. In Ada 2012, you could write:

EDIT

Errors : Natural := 0;
...
Errors := Errors + (if Altitude_Measured > Critical_Altitude then 1 else 0);
Errors := Errors + (if Velocity_Measured > Critical_Velocity then 1 else 0);
Errors := Errors + (if Angle_Measured > Critical_Angle then 1 else 0);
Errors := Errors + (if Temperature_Measured > Critical_Temperature then 1 else 0);
if Errors >= 2 then
  ...
end if;


回答2:

Boolean is an enumeration type with values (False, True). As with any enumeration type, the 'Pos attribute can be used to get the position of a value in the list of enumeration literals. Thus, Boolean'Pos(B) equals 0 if B is false, 1 if B is true.

Thus you could say

True_Count := Boolean'Pos(Integer(Status_System.Altitude_Measured) >= Critical_Altitude)
    + Boolean'Pos(Integer(Status_System.Velocity_Measured) >= Critical_Velocity)
    + Boolean'Pos(Integer(Status_System.Angle_Measured) >= Critical_Angle)
    + Boolean'Pos(Integer(Status_System.Temperature_Measured)) >= Critical_Temperature);