with Text_Io ; --| Identification procedure State_Transition --| Filename State_Transition.ada --| History --| 10/02/88 PLT Created Unit --| 12/12/88 PLT Final Test Begun --| Summary This package body contains all packages necessary --| for the State Transition Executor to operate --| Description --| This package body contains the following software hierarchy --| Build_Transition_Actions_Package Procedure --| Build_Transition_Events_Package Procedure --| Build_State_Transition_Executor Procedure --| Get_Threads Procedure --| Requirements --| Use Ward-Mellor Methodology --| Keywords --| Real-Time, Recursion --| Developed_By --| P.L. Treadway --| GTE Government Systems Corporation --| 1 Research Drive --| Mail Stop #54 --| Westborough, Massachusetts 01581 --| (508) 870-4482 --| As_Part_Of --| Structured Development for Real Time Systems --| Under_Contract --| 5-9 (After Hours) package body State_Transition is ----- -- Declare Persistent Data visible throught entire package ----- Num_Valid_Threads : NATURAL := 0 ; Not_First_Thread : Boolean := False ; Any_String : STRING ( 1..1 ) ; Length : NATURAL ; package int_io is new text_io.integer_io (integer); use int_io; Simulation_Report_File : Text_Io.File_Type ; ---------------------------------------------------------------------- -- -- -- B u i l d _ T r a n s i t i o n _ A c t i o n s -- -- -- -- This procedure builds the Ada package Transition_Actions. -- -- The package Transaction_Actions consists of two Ada files, -- -- one for the specification and the other for the body. The -- -- files are named as follows: -- -- -- -- Package Specification: Transaction_Actions_Spec.Ada -- -- Package Body: Transaction_Actions_Body.Ada -- -- -- -- With Mealy State Transition Diagrams, an event at some state -- -- may cause the system to transition to another state and -- -- optionally cause some action to occur. The State Transition -- -- Executor simulates the events which in turn, will cause -- -- "Action" procedures in the Transaction_Action package during -- -- run-time. The action that occurs is displayed on the screen -- -- and optionally written to a file as well. -- -- -- ---------------------------------------------------------------------- procedure Build_Transition_Actions_Package ( TA_Table : Three_D_25_Char_String ) is Num_Unique_Actions : Natural ; Found : Boolean ; Unique_TA_Table : array ( 1..50 ) of String ( 1..Max_String ) ; TA : String ( 1..Max_String ) ; OS_Data_File : Text_Io.File_Type ; Debug : Boolean := false ; OS_State_Transition_Action_File : Text_Io.File_Type ; begin ----- -- Find all unique State Actions ----- Num_Unique_Actions := 0 ; for i in 1..Num_States loop for j in 1..Num_Events loop for k in 1..Max_Actions_Per_Event loop TA := TA_Table ( i , j , k ) ; Found := False ; for l in 1..Num_Unique_Actions loop if TA = "NULL" or TA = " " or TA ( 1 ) = ' ' then Found := true ; end if ; if TA = Unique_TA_Table ( l ) then Found := True ; end if ; end loop ; -- for l in 1..Num_Unique_Actions loop if not Found then Num_Unique_Actions := Num_Unique_Actions + 1 ; Unique_TA_Table ( Num_Unique_Actions ) := TA ; end if ; end loop ; -- for k in 1..Max_Actions_Per_Event loop end loop ; -- for j in 1..Num_Events loop end loop ; -- for i in 1..Num_States loop ----- -- Create State Transition Action Package Specification ----- Text_Io.Create (File => OS_State_Transition_Action_File , Mode => Text_Io.Out_File , Name => "Transition_Actions_Spec.Ada" , Form => "" ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , "package Transition_Actions is " ) ; Text_Io.New_Line ( OS_State_Transition_Action_File ) ; for i in 1..Num_Unique_Actions loop if Unique_TA_Table ( i ) /= "NULL " then Text_Io.Put_Line ( OS_State_Transition_Action_File , " procedure " & Unique_TA_Table ( i ) & " ; " ) ; end if ; end loop ; Text_Io.New_Line ( OS_State_Transition_Action_File ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , "end Transition_Actions ;" ) ; Text_Io.Close ( File => OS_State_Transition_Action_File ) ; ----- -- Build Transition Actions Package Body ----- Text_Io.Create (File => OS_State_Transition_Action_File , Mode => Text_Io.Out_File , Name => "Transition_Actions_Body.Ada" , Form => "" ) ; Text_Io.Put ( OS_State_Transition_Action_File , "with Text_Io " ) ; if Save_Run_Time_Output then -- with in Global Data at run time Text_Io.Put_Line ( OS_State_Transition_Action_File , "," ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " Transition_Global_Data ; " ) ; Num_Write_Passes := 2 ; -- Used for how many times to write output else Text_Io.Put_Line ( OS_State_Transition_Action_File , "; " ) ; Num_Write_Passes := 1 ; end if ; Text_Io.New_Line ( OS_State_Transition_Action_File ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , "package body Transition_Actions is " ) ; Text_Io.New_Line ( OS_State_Transition_Action_File ) ; for i in 1..Num_Unique_Actions loop if Unique_TA_Table ( i ) /= "NULL " then Text_Io.Put_Line ( OS_State_Transition_Action_File , " procedure " & Unique_TA_Table ( i ) & " is" ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " begin" ) ; for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Action_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Action_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " Text_Io.Put ( " & """" & " | " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " text_io.Put ( " & """" & Unique_TA_Table ( i ) & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " Text_Io.Set_Col ( " & "84" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " Text_Io.Put_Line ( " & """" & "|" & """" & " ) ; " ) ; end loop ; Text_Io.Put_Line ( OS_State_Transition_Action_File , " end " & Unique_TA_Table ( i ) & " ; " ) ; Text_Io.New_Line ( OS_State_Transition_Action_File ) ; end if ; end loop ; Text_Io.Put_Line ( OS_State_Transition_Action_File , "end Transition_Actions ;" ) ; Text_Io.Close ( File => OS_State_Transition_Action_File ) ; end Build_Transition_Actions_Package ; ---------------------------------------------------------------------- -- -- -- B u i l d _ T r a n s i t i o n _ E v e n t s -- -- -- -- This procedure builds the Ada package Transition_Events. -- -- The package Transaction_Events consists of two Ada files, -- -- one for the specification and the other for the body. The -- -- files are named as follows: -- -- -- -- Package Specification: Transaction_Events_Spec.Ada -- -- Package Body: Transaction_Events_Body.Ada -- -- -- -- With Mealy State Transition Diagrams, an event at some state -- -- may cause the system to transition to another state and -- -- optionally cause some action to occur. The State Transition -- -- Executor simulates all the valid threads of execution in the -- -- State Transition Diagram by placing calls to the various -- -- "Event" procedures in the Transition_Events Package. The -- -- events simulated are displayed on the screen and optionally -- -- written to a file. -- -- -- ---------------------------------------------------------------------- procedure Build_Transition_Events_Package ( States : One_D_25_Char_String ; Transition_Events : One_D_25_Char_String ; TC_Table : Two_D_25_Char_String ; TA_Table : Three_D_25_Char_String ; Start_State : Natural ; Stop_State : Natural ) is OS_State_Transition_Event_File : Text_Io.File_Type ; Action_Counter : Natural ; Action_NULL : Boolean ; begin ----- -- Create State Transition Events Package Specification ----- Text_Io.Create (File => OS_State_Transition_Event_File , Mode => Text_Io.Out_File , Name => "Transition_Events_Spec.Ada" , Form => "" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , "package Transition_Events is " ) ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; for i in 1..Num_Events loop Text_Io.Put_Line ( OS_State_Transition_Event_File , " procedure " & Transition_Events ( i ) & " ; " ) ; end loop ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , "end Transition_Events ;" ) ; Text_Io.Close ( File => OS_State_Transition_Event_File ) ; ----- -- Build Transition Events Package Body ----- Text_Io.Create (File => OS_State_Transition_Event_File , Mode => Text_Io.Out_File , Name => "Transition_Events_Body.Ada" , Form => "" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , "with Text_Io , " ) ; Text_Io.Put ( OS_State_Transition_Event_File , " Transition_Actions " ) ; if Save_Run_Time_Output then -- with in Global Data at run time Text_Io.Put_Line ( OS_State_Transition_Event_File , "," ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Transition_Global_Data ; " ) ; Num_Write_Passes := 2 ; -- Used for how many times to write output else Text_Io.Put_Line ( OS_State_Transition_Event_File , " ; " ) ; Num_Write_Passes := 1 ; end if ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , "use Transition_Actions ; " ) ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , "package body Transition_Events is " ) ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " type States is ( " & States ( 1 ) & " , " ) ; for i in 2..Num_States-1 loop Text_Io.Put_Line ( OS_State_Transition_Event_File , " " & States ( i ) & " , " ) ; end loop ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " " & States ( Num_States ) & " ) ; " ) ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " State : States := " & States ( Start_State ) & " ; " ) ; Text_Io.New_Line ( OS_State_Transition_Event_File , 2 ) ; for Event in 1..Num_Events loop Text_Io.Put_Line ( OS_State_Transition_Event_File , " procedure " & Transition_Events ( Event ) & " is" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " begin" ) ; if Event = 1 then -- gives improved readability Text_Io.New_Line ( OS_State_Transition_Event_File ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " case STATE is" ) ; ----- -- Find all states where this Transition Event may occur ----- for State in 1..Num_States loop if TC_Table ( State , Event ) /= "NULL " then Text_Io.Put_Line ( OS_State_Transition_Event_File , " when " & States ( State ) & " => " ) ; -- Output the Transition Actions that are triggered Action_Counter := 0; Action_Null := TRUE ; for Action in 1..Max_Actions_Per_Event loop if TA_Table ( State, Event, Action ) /= "NULL " then Action_NULL := FALSE ; if States ( Start_State ) /= States ( State ) or Action > 1 then Action_Counter := Action_Counter + 1 ; -- Finish chart and start new page if Action_Counter >= 2 or States ( State ) = States ( Start_State ) then -- special print for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & "| | "& """" & " ) ; " ) ; end loop ; else for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & " | " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & Transition_Events ( Event ) & """" & " ) ; " ) ; end loop ; end if ; -- If Action_Counter >= 2 ... else Not_First_Thread := True ; for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.New_Page ;" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "====================================================================================" & """" & " ) ;" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "| S T A T E | E V E N T | A C T I O N ( S ) |" & """" & " ) ;" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "====================================================================================" & """" & " ) ;" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & "| " & """" & " ) ;" ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & States ( Start_State ) & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & " | " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & Transition_Events ( Event ) & """" & " ) ; " ) ; end loop ; end if ; -- If Not_First_Thread then ----- -- Output the Transition Action ----- Text_Io.Put_Line ( OS_State_Transition_Event_File , "Transition_Actions." & TA_Table ( State , Event , Action ) & " ; " ) ; end if ; -- If Action /= NULL end loop ; -- for Action in 1..Max_Actions_Per_Event loop ----- -- Check and handle a State Transition with no Action ----- if Action_NULL then for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & " | " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & Transition_Events ( Event ) & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & " | " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Col ( " & "84" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "| " & """" & " ) ; " ) ; end loop ; end if ; for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "+---------------------------+---------------------------+--------------------------+"& """" & " ) ; " ) ; -- Update the Current State and Print the Change in report file Text_Io.Put_Line ( OS_State_Transition_Event_File , " State := " & TC_Table ( State , Event ) & " ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & "| " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put ( " & """" & TC_Table ( State , Event ) & """" & " ) ; " ) ; end loop ; end if ; -- If TC_Table ... ----- -- Check If at End OF Thread. If so, finish table ----- if TC_Table ( State , Event ) = States ( Stop_State ) then for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Col ( " & "29" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "| | |"& """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & "+---------------------------+---------------------------+--------------------------+"& """" & " ) ; " ) ; end loop ; end if ; end loop ; -- for z in 1..Num_States loop Text_Io.Put_Line ( OS_State_Transition_Event_File , " when OTHERS =>" ) ; for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- redirect output to Run-Time File Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " Text_Io.Put_Line ( " & """" & --|* Should be more descriptive "WARNING - Unexpected State Transition Detected." & """" & " ) ; " ) ; end loop ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " end case ;" ) ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; Text_Io.Put_Line ( OS_State_Transition_Event_File , " end " & Transition_Events ( Event ) & " ; " ) ; Text_Io.New_Line ( OS_State_Transition_Event_File ) ; end loop ; Text_Io.Put_Line ( OS_State_Transition_Event_File , "end Transition_Events ;" ) ; Text_Io.Close ( File => OS_State_Transition_Event_File ) ; end Build_Transition_Events_Package ; ------------------------------------------------------------------------ -- -- -- B u i l d _ S t a t e _ T r a n s i t i o n _ E x e c u t o r -- -- -- -- This procedure builds the Ada procedure State_Transition_Executor -- -- The file name for this procedure is as follows: -- -- -- -- Procedure: State_Transition_Executor.Ada -- -- -- -- This procedure finds all valid threads of execution from a -- -- a specified SOURCE state to a specified SINK state. -- -- Thus, this procedure can find all valid flows from the SOURCE to -- -- SINK state, and find all transitions from any state to any other -- -- state through the "Ad-Hoc" query feature in the MMI. -- -- -- -- -- -- The algorithm makes full use of recursion to fnd all valid -- -- transitions between the specified SOURCE and SINK states. -- -- The events are simulated by making calls to the Transition_Events - -- package. -- ------------------------------------------------------------------------ procedure Build_State_Transition_Executor ( States : One_D_25_Char_String ; Events : One_D_25_Char_String ; TC_Table : Two_D_25_Char_String ; TA_Table : Three_D_25_Char_String ; The_Source : Natural ; The_Sink : Natural ; Simulate : Boolean ) is One : CONSTANT := 1 ; Two : CONSTANT := 2 ; Num_Transitions : NATURAL ; The_First_State : NATURAL ; Num_Output_Passes : NATURAL ; Debug : BOOLEAN := FALSE; OS_State_Transition_Executor_File : Text_Io.File_Type ; Transitions : Two_D_25_Char_String ; ---------------------------------------------------------------------- -- -- -- F i n d _ T r a n s i t i o n s -- -- -- -- This procedure finds all valid threads for a given state. -- -- Each possible transition is explored from this state, and if -- -- necessary, it will recursively call itself to resolve looping -- -- and explore further transitions to the SINK state. -- -- -- ---------------------------------------------------------------------- procedure Find_Transitions ( State : in NATURAL ; Event : in NATURAL ; Transitions : in out Two_D_25_Char_String ; Num_Transitions : in out NATURAL ) is New_State : NATURAL ; function Loop_Found ( Transitions : Two_D_25_Char_String ; Num_Transitions : NATURAL ; Next_State : Twenty_Five_Char_String ) return BOOLEAN is begin for A_State in 1 .. Num_Transitions loop if Transitions ( A_State , 1 ) = Next_State then return TRUE ; -- loop detected end if ; end loop ; return FALSE ; -- no loop detected end Loop_Found ; procedure Record_Thread ( Transitions : in out Two_D_25_Char_String ; Num_Transitions : NATURAL ) is Action_Index : NATURAL ; A_State : NATURAL ; An_Event : NATURAL ; begin Action_Index := 0 ; Num_Valid_Threads := Num_Valid_Threads + 1 ; if ( Simulate ) then -- User wants FASTER Simulation for Iteration in 1 .. Num_Output_Passes loop if Iteration = 1 then -- Direct Output to the Terminal Text_Io.Set_Output ( Text_Io.Standard_Output ) ; Text_Io.Put ( ASCII.ESC & "[?3h" ) ; -- 132 Column mode Text_Io.Put ( ASCII.ESC & "[1;1H" ) ; -- Home Cursor else Text_Io.Set_Output ( Simulation_Report_File ) ; If Num_Valid_Threads > 1 then -- Start on a fresh page Text_Io.New_Page ; end if ; end if ; Text_Io.Put_Line ( "====================================================================================" ) ; Text_Io.Put_Line ( "| S T A T E | E V E N T | A C T I O N ( S ) |" ) ; Text_Io.Put_Line ( "====================================================================================" ) ; for i in 1 .. Num_Transitions loop Text_Io.Put ( "| " ) ; Text_Io.Put ( Transitions ( i , One ) ) ; Text_Io.Put ( " | " ) ; Text_Io.Put ( Transitions ( i , Two ) ) ; Text_Io.Put ( " | " ) ; ----- -- Find correct STATE index into the ACTION table ----- for v in 1 .. Num_States loop if States ( v ) = Transitions ( i , one ) then A_State := v ; -- the Correct state index exit ; end if ; end loop ; ----- -- Find the correct EVENT index into the ACTION table ----- for v in 1 .. Num_Events loop if Events ( v ) = Transitions ( i , two ) then An_Event := v ; -- the Correct event index exit ; end if ; end loop ; If TA_Table ( A_State , An_Event , 1 ) /= "NULL " then Action_Index := 1 ; While TA_Table( A_State , An_Event , Action_Index ) /= "NULL " loop if Action_Index = 1 then Text_Io.Put ( TA_Table ( A_State , An_Event , Action_Index ) ) ; else Text_Io.Put ( "| " ) ; Text_Io.Set_Col ( 29 ) ; Text_Io.Put ( "| " ) ; Text_Io.Set_Col ( 57 ) ; Text_Io.Put ( "| " ) ; Text_Io.Put ( TA_Table ( A_State , An_Event , Action_Index ) ) ; end if ; Text_Io.Set_Col ( 84 ) ; Text_Io.Put_Line ( "|" ) ; Action_Index := Action_Index + 1 ; end loop ; -- end While TA_Table else -- No actions associated with this State/Event index if ( Action_Index <= 0 ) then -- Balance Chart Text_Io.Set_Col ( 84 ) ; Text_Io.Put_Line ( "|" ) ; else Text_Io.New_Line ; end if ; end if ; Text_Io.Put_Line ( "+---------------------------+---------------------------+--------------------------+"); end loop ; -- for i in 1 .. Num_Transitions loop ----- -- Print/Display the Sink State to show final state has been reached ----- Text_Io.Put ( "| " ) ; Text_Io.Put ( States ( The_Sink ) ) ; Text_Io.Set_Col ( 29 ) ; Text_Io.Put ( "| " ) ; Text_Io.Set_Col ( 57 ) ; Text_Io.Put ( "| " ) ; Text_Io.Set_Col ( 84 ) ; Text_Io.Put_Line ( "|" ) ; Text_Io.Put_Line ( "+---------------------------+---------------------------+--------------------------+"); Text_Io.New_Line ( 2 ) ; Text_Io.Put ( " State Transition Path #" ) ; Int_Io.Put ( Num_Valid_Threads , width => 2 , base => 10 ) ; end loop ; -- for Iteration in 1 .. Num_Output_Passes loop ... ----- -- Pause screen before returning to Menu ----- for Iteration in 1 .. Num_Output_Passes loop if Iteration = 1 then -- Pause on screen display Text_Io.Set_Output ( Text_Io.Standard_Output ) ; Text_Io.New_Line ( 2 ) ; Text_Io.Set_Col ( 10 ) ; Text_Io.Put ( "Hit RETURN to continue. " ) ; Text_Io.Get_Line ( Any_String , Length ) ; Text_Io.Put ( ASCII.ESC & "[2J" ) ; -- Clear Screen Text_Io.Put ( ASCII.ESC & "[1;1H" ) ; -- Home Cursor end if ; end loop ; else ----- -- User has choosen the Generate Ada Source Code Option in the MMI --- for i in 1 .. Num_Transitions loop Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Transition_Events." & Transitions ( i , Two ) & " ; " ) ; end loop ; Text_Io.New_Line ( OS_State_Transition_Executor_File ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Num_Valid_Threads := Num_Valid_Threads + 1 ;" ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.New_Line ( 3 ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put ( " & """" & " State Transition Path #" & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Int_Io.Put ( " & "Num_Valid_Threads , width => 2 , base => 10 ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.New_Line ; " ) ; end if ; -- end if Simulate then end Record_Thread ; procedure Record_Transition ( State : Twenty_Five_Char_String ; Event : Twenty_Five_Char_String ; Transitions : in out Two_D_25_Char_String ; Num_Transitions : in out NATURAL ) is begin Num_Transitions := Num_Transitions + 1 ; Transitions ( Num_Transitions , One ) := State ; Transitions ( Num_Transitions , Two ) := Event ; end Record_Transition ; procedure Pop_Stack ( Transitions : in out Two_D_25_Char_String ; Num_Transitions : in out NATURAL ) is begin Transitions ( Num_Transitions , One ) := " " ; Transitions ( Num_Transitions , Two ) := " " ; Num_Transitions := Num_Transitions - 1 ; end Pop_Stack ; begin for An_Event in Event .. Num_Events loop if TC_Table ( State , An_Event ) /= "NULL " then if TC_Table ( State , An_Event ) = States ( The_Sink ) then Record_Transition ( States ( State ) , Events ( An_Event ) , Transitions , Num_Transitions ) ; Record_Thread ( Transitions , Num_Transitions ) ; Pop_Stack ( Transitions , Num_Transitions ) ; elsif not Loop_Found ( Transitions , Num_Transitions , TC_Table ( State , An_Event ) ) then Record_Transition ( States ( State ) , Events ( An_Event ) , Transitions , Num_Transitions ) ; for v in 1 .. Num_States loop -- get new state index if States ( v ) = TC_Table ( State , An_Event ) then New_State := v ; -- the state we're transitioning to exit ; end if ; end loop ; Find_Transitions ( New_State , State_Transition.Source , Transitions , Num_Transitions ) ; Pop_Stack ( Transitions , Num_Transitions ) ; end if ; -- if TC_Table ... = Sink end if ; -- if TC_Table ... /= NULL end loop ; end Find_Transitions ; begin Num_Valid_Threads := 0 ; -- Assume no Threads if ( Simulate ) then -- Check if output file specified if Save_Simulation_Output then -- Open File at Run-Time Num_Output_Passes := 2 ; -- Used in Find_Transitions & below Text_Io.Create (File => Simulation_Report_File , Mode => Text_Io.Out_File , Name => State_Transition.Simulation_File , Form => "" ) ; else Num_Output_Passes := 1 ; -- Display Only end if ; else ----- -- Build State Transition Executor Procedure Sub-Program ----- Text_Io.Create (File => OS_State_Transition_Executor_File , Mode => Text_Io.Out_File , Name => "State_Transition_Executor.Ada" , Form => "" ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , "with Text_Io ," ) ; Text_Io.Put ( OS_State_Transition_Executor_File , " Transition_Events " ) ; if Save_Run_Time_Output then -- with in Global Data at run time Text_Io.Put_Line ( OS_State_Transition_Executor_File , ", " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Transition_Global_Data ; " ) ; Num_Write_Passes := 2 ; -- Used for how many times to write output else Text_Io.Put_Line ( OS_State_Transition_Executor_File , " ; " ) ; Num_Write_Passes := 1 ; end if ; Text_Io.New_Line ( OS_State_Transition_Executor_File ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , "procedure State_Transition_Executor is " ) ; Text_Io.New_Line ( OS_State_Transition_Executor_File ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , "package int_io is new text_io.integer_io (integer) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , "use int_io ; " ) ; Text_Io.New_Line ( OS_State_Transition_Executor_File ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , "Num_Valid_Threads : NATURAL := 0 ;" ) ; Text_Io.New_Line ( OS_State_Transition_Executor_File ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " begin" ) ; if Save_Run_Time_Output then -- Open File at Run-Time Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Create ( Transition_Global_Data.State_Transition_Report_File , "); Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Out_File , " & """" & Run_Time_Report_file & """" & " ) ; " ) ; end if ; end if ; -- if not Simulate Num_Transitions := 0 ; ----- -- Find a valid thread of execution ----- Find_Transitions ( The_Source , State_Transition.Source , Transitions , Num_Transitions ) ; ----- -- Indicate the end of the State Transition Executor Procedure -- and finish bottom line of report ----- if ( Simulate ) then -- Output Final Totals for Iteration in 1 .. Num_Output_Passes loop if Iteration = 1 then -- Direct Output to the Terminal Text_Io.Set_Output ( Text_Io.Standard_Output ) ; else Text_Io.Set_Output ( Simulation_Report_File ) ; end if ; Text_Io.New_Line ( 2 ) ; Text_Io.Put_Line ( " State Transition Execution Completed. " ) ; Text_Io.New_Line ( 2 ) ; if Num_Valid_Threads <= 0 then Text_Io.Put_Line ( " There are no Transition Paths between: " ) ; Text_Io.New_Line ; Text_Io.Set_Col ( 16 ) ; Text_Io.Put_Line ( States ( The_Source ) ) ; Text_Io.Set_Col ( 12 ) ; Text_Io.Put_Line ( "and ... " ) ; Text_Io.Set_Col ( 16 ) ; Text_Io.Put_Line ( States ( The_Sink ) ) ; else -- At least one transition path was found If Num_Valid_Threads >= 2 then Text_Io.Put ( " There are " ) ; else Text_Io.Put ( " There is " ) ; end if ; Int_Io.Put ( Num_Valid_Threads , width => 1 , base => 10 ) ; If Num_Valid_Threads >= 2 then Text_Io.Put_Line ( " Transition Paths, " ) ; else Text_Io.Put_Line ( " Transition Path, " ) ; end if ; Text_Io.Put_Line ( " from Source State: " & States ( The_Source ) ) ; Text_Io.Put_Line ( " to Sink State: " & States ( The_Sink ) ) ; end if ; -- end is Num_Valid_Threads <= 0 ----- -- If Output is being directed to the screen; display pause msg ----- if Iteration = 1 then Text_Io.New_Line ( 2 ) ; Text_Io.Set_Col ( 10 ) ; Text_Io.Put ( "Hit RETURN to continue. " ) ; Text_Io.Get_Line ( Any_String , Length ) ; Text_Io.Put ( ASCII.ESC & "[?3l" ) ; -- Return to 80 Column mode end if ; end loop ; -- for Iteration in 1 ... ----- -- Close Simulation file if open ----- if Save_Simulation_Output then -- CloseFile at Run-Time Text_Io.Close ( Simulation_Report_File ) ; Text_Io.Set_Output ( Text_Io.Standard_Output ) ; end if ; else -- Generate Ada Code Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.New_Line ( 2 ) ; " ) ; if Num_Valid_Threads >= 0 then for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- direct output to report file Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.New_Line ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " State Transition Execution Completed. "& """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.New_Line ( 2 ) ; " ) ; If Num_Valid_Threads >= 2 then Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put ( " & """" & " There are " & """" & " ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put ( " & """" & " There is " & """" & " ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Int_Io.Put ( " & "Num_Valid_Threads , width => 1 , base => 10 ) ; " ) ; If Num_Valid_Threads >= 2 then Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " Transition Paths, " & """" & " ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " Transition Path, " & """" & " ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " from Source State: " & States ( The_Source ) & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " to Sink State: " & States ( The_Sink ) & """" & " ) ; " ) ; end loop ; else -- No valid thread between specified start and stop state for Iteration in 1 .. Num_Write_Passes loop if Iteration = 1 then -- direct output to report file Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Set_Output ( Text_Io.Standard_Output ) ; " ) ; else Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Set_Output ( Transition_Global_Data.State_Transition_Report_File ) ; " ) ; end if ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " There were no Transitions Found, " & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " from Source State: " & States ( The_Source ) & """" & " ) ; " ) ; Text_Io.Put_Line ( OS_State_Transition_Executor_File , " Text_Io.Put_Line ( " & """" & " to Sink State: " & States ( The_Sink ) & """" & " ) ; " ) ; end loop ; end if ; Text_Io.New_Line ( OS_State_Transition_Executor_File ) ; Text_Io.Put ( OS_State_Transition_Executor_File , "end State_Transition_Executor ; " ) ; Text_Io.Close ( File => OS_State_Transition_Executor_File ) ; end if ; -- if ( Not Simulate ) then end Build_State_Transition_Executor ; ---- -- Main Processing Loop for Package "State_Transition" ---- begin null ; end State_Transition ;