let removeUnusedTransitionsAndStates () = 
(* Step 1 : computation of reached states and crossed transitions *)
  let crossedTransitions = ref (Array.make(getNumberOfTransitions()) falsein
  let reachedStates = ref (Array.make(getNumberOfStates()) falsein
  let addHash htbl = 
    Hashtbl.iter 
      (fun _ (_,tr) -> 
         crossedTransitions:= bool_array_or !crossedTransitions tr;
      )
      htbl
  in

  let addHash_bycase htbl_bc = 
    let htbl = Hashtbl.create (Hashtbl.length htbl_bc) in
    Hashtbl.iter 
      (fun key dbaa -> 
         Hashtbl.add htbl key (Spec_tools.pre_flattening dbaa)
      )
      htbl_bc;
    addHash htbl
  in

  addHash pre_status;
(*   addHash post_status; *)
  addHash_bycase post_status_bycase;

  addHash_bycase loop_ext_pre_bycase;
  addHash_bycase loop_int_pre_bycase;
(*   addHash_bycase loop_ext_post_bycase;  Always empty*) 
 addHash_bycase loop_int_post_bycase;

  List.iter
    (fun tr -> 
       if !crossedTransitions.(tr.numt) then
         begin
           !reachedStates.(tr.start.nums)<-true;
           !reachedStates.(tr.stop.nums)<-true
         end
    )
    (snd !automata);

(* Verification pass because of a plugin limitation *)
(*  List.iter
    (fun tr ->  
       if not !reachedStates.(tr.start.nums) && !crossedTransitions.(tr.numt) then 
         begin 
           Format.printf "Ltl_to_acsl plugin internal error. Status : States/Transitions simplification try to remove an unreachable state wich is the starting point for a crossable transition. \n";
           assert false
         end 
    )
    (snd !automata);
*)



(* DEBUG : Displaying information *)
(*  Format.printf "\n\n Used states and transitions:\n";
  debug_display_stmt_all_pre (!reachedStates,!crossedTransitions) ;
  Format.printf "\n\n" ;*)


(* Step 2 : computation of translation tables *)
  let newNbTrans = Array.fold_left (fun nb tr -> if tr then nb+1 else nb ) 0 !crossedTransitions in
  let newNbStates = Array.fold_left (fun nb st -> if st then nb+1 else nb ) 0 !reachedStates in

  let replaceTransitions = ref (Array.make(getNumberOfTransitions()) 0) in  
  let replaceStates = ref (Array.make(getNumberOfStates()) 0) in
  let nextTr = ref 0 in
  let nextSt = ref 0 in
  Array.iteri 
    (fun i _ -> if !crossedTransitions.(i) then 
       begin
         !replaceTransitions.(i) <- !nextTr;
         nextTr:=!nextTr+1
       end
     else
       !replaceTransitions.(i) <- (-1)
    )
    !replaceTransitions;
  Array.iteri 
    (fun i _ -> if !reachedStates.(i) then 
       begin
         !replaceStates.(i) <- !nextSt;
         nextSt:=!nextSt+1
       end
     else
       !replaceStates.(i) <- (-1)
    )
    !replaceStates ;


(* DEBUG : Displaying information *)
(*   Format.printf "\n\n New nb trans :%d \n New nb states :%d  \n" newNbTrans newNbStates; *)
(*   Format.printf "\n\n Transitions replacement:\n"; *)
(*   Array.iteri  *)
(*     (fun i v -> *)
(*        Format.printf "   tr%s ~> tr%s\n" (string_of_int i) (string_of_int v)  *)
(*     )  *)
(*     !replaceTransitions; *)
(*   Format.printf "\n\n States replacement:\n";  *)
(*   Array.iteri *)
(*     (fun i v ->  *)
(*        Format.printf "   st%s ~> st%s\n" (string_of_int i) (string_of_int v) *)
(*     )  *)
(*     !replaceStates;  *)
(*   Format.printf "\n\n"; *)
    

(* Step 3 : rewritting stored information *)
  (* Rewritting automata *)
  let sts = List.rev (List.fold_left 
                        (fun newl st -> 
                           let newn= !replaceStates.(st.nums) in 
                           if newn= -1 then newl 
                           else begin st.nums<-newn;st::newl end
                        ) [] (fst !automata)) 
  in
  let trs = List.rev (List.fold_left 
                        (fun newl tr -> 
                           let newn= !replaceTransitions.(tr.numt) in 
                           if newn= -1 then newl 
                           else begin tr.numt<-newn;tr::newl end
                        )
                        [] (snd !automata)) in
  automata:=(sts,trs);
  
  (* Rewritting size of automata cached in Spec_tools *)
  setNumberOfStates newNbStates;
  setNumberOfTransitions newNbTrans;
 

  (* Rewritting pre/post conditions and loops specification *)
  let rewriteHashtblSpec htbl =
    Hashtbl.iter 
      (fun key (ost,otr) -> 
         let nst,ntr=mk_empty_pre_or_post () in
         Array.iteri (fun i b -> if b then nst.(!replaceStates.(i))<-true) ost;
         Array.iteri (fun i b -> if b then ntr.(!replaceTransitions.(i))<-true) otr;
         Hashtbl.replace htbl key (nst,ntr)
      )
      htbl
  in
  let rewriteHashtblSpec_bycase htbl =
    Hashtbl.iter 
      (fun key (ost,otr) -> 
         let nst,ntr=mk_empty_pre_or_post_bycase () in
         Array.iteri 
           (fun iniSt sp ->
              let newIniSt = !replaceStates.(iniSt) in
              if newIniSt <> -1 then 
                Array.iteri 
                  (fun i b -> if b then nst.(newIniSt).(!replaceStates.(i))<-true
                  sp
           )
           ost;
         Array.iteri 
           (fun iniSt sp ->
              let newIniSt = !replaceStates.(iniSt) in
              if newIniSt <> -1 then 
                Array.iteri 
                  (fun i b -> if b then ntr.(newIniSt).(!replaceTransitions.(i))<-true
                  sp
           )
           otr;
         Hashtbl.replace htbl key (nst,ntr)
      )
      htbl
  in

  rewriteHashtblSpec pre_status;
(*   rewriteHashtblSpec post_status; *)
  rewriteHashtblSpec_bycase post_status_bycase;

(*   rewriteHashtblSpec loop_ext_pre; *)
(*   rewriteHashtblSpec loop_int_pre; *)
(*   rewriteHashtblSpec loop_ext_post; *)
(*   rewriteHashtblSpec loop_int_post; *)

  rewriteHashtblSpec_bycase loop_ext_pre_bycase;
  rewriteHashtblSpec_bycase loop_int_pre_bycase;
(*   rewriteHashtblSpec_bycase loop_ext_post_bycase; *)
  rewriteHashtblSpec_bycase loop_int_post_bycase