#include "fsm.h"
#include "converter.h"
/*==========================================================================
Function: ControlCheck()
Comments: This function ensures that uncontrollable transitions from a state
	  with (x, y) and y!="dump" do not lead to a bad state.  If it 
	  leads to a bad state then it is also declared bad. This function 
	  runs through the whole fsm declaring states as bad if it fails 
	  the control check.
Input:	  fsm_ptr - pointer to the fsm on which a control check is to
	  be made.
	  fp = file pointer, list of uncontrollable events

Returns True if FSM is controllable, False otherwise
===========================================================================*/
int ControlCheck(FSM *fsm_ptr, FILE *fp)
{
	ST_LIST *current_state;
	TR_LIST *curr_trans;
	NAME_LIST *list, *name_ptr;	
	int num_states=0,new_no_bad=MAX_LENGTH,old_no_bad=0,i=0,flag = TRUE;
	char *uncontlist[MAX_LENGTH];	

	if(!fp)
		prog_abort("ControlCheck: Invalid file pointer");
	if(fsm_ptr==NULL)
		prog_abort("ControlCheck:Invalid FSM pointer");

	po_read_cont_file2(fp, uncontlist);
	
	/*mark dump state as bad*/
	current_state = fsm_ptr->states;
	while(current_state) {
      
          if(strstr(current_state->name, "dump")!=NULL)
	          MarkBadState(fsm_ptr,current_state);
		
       current_state = current_state->next;
	}
			
	new_no_bad = BadStates(fsm_ptr);
	while(new_no_bad !=old_no_bad) { 
	    old_no_bad = new_no_bad;
	    current_state = fsm_ptr->states;
	    while(current_state) {
	       /* (x,y) where y != "dump" or has been marked bad with "@$" */
	       curr_trans=current_state->trans;
		   if(strstr(current_state->name, "@$")==NULL) {
			while(curr_trans) {
			  if(FindLabel(uncontlist, curr_trans->input)){ /*check uncontrollable transitions*/
				if(strstr(curr_trans->next_state->name,"@$")!=NULL) {
				  /* this is a bad transition as it leads to a bad
				  state..so mark it bad */
				  flag = FALSE;
				  MarkBadState(fsm_ptr,current_state);
				}
			  } /* if strcmp ends */
		    curr_trans = curr_trans->next;		
			} /* while curr_trans ends */
		   } /* if strstr ends */	
		current_state = current_state->next;
		} /* while current ends */
	   new_no_bad = BadStates(fsm_ptr);
	}  /* while no_bad ends */

	po_del_uncontlist(uncontlist);
	
	rewind(fp);
	return(flag);

}
