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 ;
