ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Ada Safety-Critical Error Handling with Exceptions

Ada

Goal -- WPM

Ready
Exercise Algorithm Area
1with Ada.Text_IO;
2use Ada.Text_IO;
3with Ada.Numerics.Float_Random;
4use Ada.Numerics.Float_Random;
5with Ada.Exceptions;
6use Ada.Exceptions;
7
8package Safety_Critical_Pkg is
9
10-- Define custom exception types for specific error conditions
11type Sensor_Error is new Ada.Exceptions.Exception_Occurrence;
12type Processing_Error is new Ada.Exceptions.Exception_Occurrence;
13
14-- Define a type for sensor readings
15subtype Sensor_Reading_Type is Float;
16
17-- Procedure to simulate reading sensor data
18function Read_Sensor return Sensor_Reading_Type;
19
20-- Procedure to process sensor data, potentially raising exceptions
21procedure Process_Sensor_Data (Raw_Data : Sensor_Reading_Type);
22
23-- Procedure to handle detected errors
24procedure Handle_Error (Error_Message : String);
25
26-- Procedure to finalize the operation, always called
27procedure Finalize_Operation;
28
29private
30
31-- Internal state for random number generation
32Gen : Generator;
33
34-- Helper function to simulate a range error
35function Simulate_Range_Error (Value : Sensor_Reading_Type) return Sensor_Reading_Type;
36
37-- Helper function to simulate an overflow error
38function Simulate_Overflow_Error (Value : Sensor_Reading_Type) return Sensor_Reading_Type;
39
40-- Helper function to simulate division by zero
41function Simulate_Division_By_Zero (Value : Sensor_Reading_Type) return Sensor_Reading_Type;
42
43end Safety_Critical_Pkg;
44
45package body Safety_Critical_Pkg is
46
47-- Initialize the random number generator
48procedure Initialize_Generator is
49begin
50Ada.Numerics.Float_Random.Reset(Gen);
51end Initialize_Generator;
52
53-- Simulate reading sensor data
54function Read_Sensor return Sensor_Reading_Type is
55begin
56-- In a real system, this would interface with hardware.
57-- Here, we generate a random float.
58if Gen.Is_Null then
59Initialize_Generator;
60end if;
61return Random(Gen) * 100.0; -- Simulate readings between 0 and 100
62end Read_Sensor;
63
64-- Procedure to process sensor data
65procedure Process_Sensor_Data (Raw_Data : Sensor_Reading_Type) is
66Processed_Value : Sensor_Reading_Type;
67Intermediate_Value : Sensor_Reading_Type;
68begin
69Put_Line ("Processing raw data: " & Float'Image(Raw_Data));
70
71-- Simulate potential errors during processing
72Intermediate_Value := Simulate_Range_Error(Raw_Data);
73Intermediate_Value := Simulate_Overflow_Error(Intermediate_Value);
74Processed_Value := Simulate_Division_By_Zero(Intermediate_Value);
75
76-- If no exceptions were raised, perform final processing
77Put_Line ("Data processed successfully. Final value: " & Float'Image(Processed_Value));
78
79exception
80when Sensor_Error =>
81Handle_Error ("Sensor data out of expected range.");
82when Ada.Exceptions.Overflow_Error =>
83Handle_Error ("Arithmetic overflow during processing.");
84when Ada.Exceptions.Division_By_Zero =>
85Handle_Error ("Division by zero encountered.");
86when Processing_Error =>
87Handle_Error ("An unexpected processing error occurred.");
88when others =>
89Handle_Error ("An unhandled exception occurred.");
90end Process_Sensor_Data;
91
92-- Procedure to handle errors
93procedure Handle_Error (Error_Message : String) is
94begin
95Put_Line ("!!! ERROR DETECTED: " & Error_Message);
96-- In a safety-critical system, this would involve logging,
97-- safe shutdown, or fallback mechanisms.
98end Handle_Error;
99
100-- Procedure to finalize the operation
101procedure Finalize_Operation is
102begin
103Put_Line ("Operation finalized. Cleanup complete.");
104-- This procedure should always be called, regardless of exceptions.
105end Finalize_Operation;
106
107-- Helper function to simulate a range error
108function Simulate_Range_Error (Value : Sensor_Reading_Type) return Sensor_Reading_Type is
109begin
110-- Simulate a range error if the value is too high or too low
111if Value > 95.0 or Value < 5.0 then
112raise Sensor_Error;
113end if;
114return Value * 1.1; -- Simulate some processing
115end Simulate_Range_Error;
116
117-- Helper function to simulate an overflow error
118function Simulate_Overflow_Error (Value : Sensor_Reading_Type) return Sensor_Reading_Type is
119begin
120-- Simulate overflow by multiplying a large number
121declare
122Large_Number : constant Sensor_Reading_Type := 1.0E30;
123begin
124if Value > Large_Number / 2.0 then -- Check for potential overflow before multiplication
125raise Ada.Exceptions.Overflow_Error;
126end if;
127return Value * Large_Number;
128end;
129end Simulate_Overflow_Error;
130
131-- Helper function to simulate division by zero
132function Simulate_Division_By_Zero (Value : Sensor_Reading_Type) return Sensor_Reading_Type is
133begin
134-- Simulate division by zero if the value is very close to zero
135if abs(Value) < 1.0E-10 then
136return Value / 0.0;
137end if;
138return Value / 2.0; -- Simulate some processing
139end Simulate_Division_By_Zero;
140
141end Safety_Critical_Pkg;
Algorithm description viewbox

Ada Safety-Critical Error Handling with Exceptions

Algorithm description:

This Ada code implements robust error handling for safety-critical applications. It defines custom exceptions (`Sensor_Error`, `Processing_Error`) and uses standard Ada exceptions (`Overflow_Error`, `Division_By_Zero`). The `Process_Sensor_Data` procedure simulates reading and processing sensor data, incorporating checks that can raise exceptions. A dedicated `Handle_Error` procedure logs issues, and `Finalize_Operation` ensures cleanup code always runs. This is vital in systems like medical devices or automotive control, where failure to handle errors correctly can have severe consequences.

Algorithm explanation:

The `Safety_Critical_Pkg` demonstrates advanced exception handling in Ada. It defines custom exceptions `Sensor_Error` and `Processing_Error` alongside standard ones like `Overflow_Error` and `Division_By_Zero`. The `Read_Sensor` function simulates data acquisition. `Process_Sensor_Data` is the core procedure where simulated error conditions (`Simulate_Range_Error`, `Simulate_Overflow_Error`, `Simulate_Division_By_Zero`) are triggered. The `exception` block in `Process_Sensor_Data` catches these specific exceptions and calls `Handle_Error` with a descriptive message. The `others` clause catches any unhandled exceptions. Crucially, `Finalize_Operation` is designed to be called regardless of whether an exception occurred, typically via a `raise` statement within the `exception` block or by ensuring it's called after the `exception` block completes normally. The time complexity of `Process_Sensor_Data` is O(1) in the normal execution path. In the presence of exceptions, the cost includes the exception propagation and handling, which is typically efficient but can be higher than normal execution. Space complexity is O(1). The correctness argument relies on the Ada runtime's guaranteed exception propagation and handling mechanism, ensuring that `Handle_Error` is invoked for specific errors and `Finalize_Operation` is always executed.

Pseudocode:

PACKAGE Safety_Critical_Pkg IS
   TYPE Sensor_Error IS new Ada.Exceptions.Exception_Occurrence;
   TYPE Processing_Error IS new Ada.Exceptions.Exception_Occurrence;
   TYPE Sensor_Reading_Type IS Float;

   FUNCTION Read_Sensor RETURN Sensor_Reading_Type;
   PROCEDURE Process_Sensor_Data(Raw_Data : Sensor_Reading_Type);
   PROCEDURE Handle_Error(Error_Message : String);
   PROCEDURE Finalize_Operation;
PRIVATE
   Gen : Generator;
   FUNCTION Simulate_Range_Error(Value : Sensor_Reading_Type) RETURN Sensor_Reading_Type;
   FUNCTION Simulate_Overflow_Error(Value : Sensor_Reading_Type) RETURN Sensor_Reading_Type;
   FUNCTION Simulate_Division_By_Zero(Value : Sensor_Reading_Type) RETURN Sensor_Reading_Type;
END Safety_Critical_Pkg;

PACKAGE BODY Safety_Critical_Pkg IS
   FUNCTION Read_Sensor RETURN Sensor_Reading_Type IS
   BEGIN
      RETURN Random(Gen) * 100.0;
   END Read_Sensor;

   PROCEDURE Process_Sensor_Data(Raw_Data : Sensor_Reading_Type) IS
      Processed_Value : Sensor_Reading_Type;
      Intermediate_Value : Sensor_Reading_Type;
   BEGIN
      Intermediate_Value := Simulate_Range_Error(Raw_Data);
      Intermediate_Value := Simulate_Overflow_Error(Intermediate_Value);
      Processed_Value := Simulate_Division_By_Zero(Intermediate_Value);

   EXCEPTION
      WHEN Sensor_Error => Handle_Error("Sensor data out of expected range.");
      WHEN Ada.Exceptions.Overflow_Error => Handle_Error("Arithmetic overflow during processing.");
      WHEN Ada.Exceptions.Division_By_Zero => Handle_Error("Division by zero encountered.");
      WHEN Processing_Error => Handle_Error("An unexpected processing error occurred.");
      WHEN others => Handle_Error("An unhandled exception occurred.");
   END Process_Sensor_Data;

   PROCEDURE Handle_Error(Error_Message : String) IS
   BEGIN
      -- Log error, take corrective action
   END Handle_Error;

   PROCEDURE Finalize_Operation IS
   BEGIN
      -- Cleanup operations
   END Finalize_Operation;

   FUNCTION Simulate_Range_Error(Value : Sensor_Reading_Type) RETURN Sensor_Reading_Type IS
   BEGIN
      IF Value > 95.0 OR Value < 5.0 THEN RAISE Sensor_Error; END IF;
      RETURN Value * 1.1;
   END Simulate_Range_Error;

   FUNCTION Simulate_Overflow_Error(Value : Sensor_Reading_Type) RETURN Sensor_Reading_Type IS
   BEGIN
      IF Value > 1.0E30 / 2.0 THEN RAISE Ada.Exceptions.Overflow_Error; END IF;
      RETURN Value * 1.0E30;
   END Simulate_Overflow_Error;

   FUNCTION Simulate_Division_By_Zero(Value : Sensor_Reading_Type) RETURN Sensor_Reading_Type IS
   BEGIN
      IF abs(Value) < 1.0E-10 THEN RETURN Value / 0.0; END IF;
      RETURN Value / 2.0;
   END Simulate_Division_By_Zero;
END Safety_Critical_Pkg;