Release coccinelle-0.2.4rc5
[bpt/coccinelle.git] / ctl / ctl_engine.ml
index a739d05..4577176 100644 (file)
@@ -1,23 +1,25 @@
 (*
-* Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
-* Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller
-* This file is part of Coccinelle.
-* 
-* Coccinelle is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, according to version 2 of the License.
-* 
-* Coccinelle is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-* GNU General Public License for more details.
-* 
-* You should have received a copy of the GNU General Public License
-* along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
-* 
-* The authors reserve the right to distribute this or future versions of
-* Coccinelle under other licenses.
-*)
+ * Copyright 2010, INRIA, University of Copenhagen
+ * Julia Lawall, Rene Rydhof Hansen, Gilles Muller, Nicolas Palix
+ * Copyright 2005-2009, Ecole des Mines de Nantes, University of Copenhagen
+ * Yoann Padioleau, Julia Lawall, Rene Rydhof Hansen, Henrik Stuart, Gilles Muller, Nicolas Palix
+ * This file is part of Coccinelle.
+ *
+ * Coccinelle is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, according to version 2 of the License.
+ *
+ * Coccinelle is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Coccinelle.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The authors reserve the right to distribute this or future versions of
+ * Coccinelle under other licenses.
+ *)
 
 
 (*external c_counter : unit -> int = "c_counter"*)
@@ -95,8 +97,8 @@ let new_let _ =
 
 (* **********************************************************************
  *
- * Implementation of a Witness Tree model checking engine for CTL-FVex 
- * 
+ * Implementation of a Witness Tree model checking engine for CTL-FVex
+ *
  *
  * **********************************************************************)
 
@@ -134,7 +136,7 @@ module type GRAPH =
   end
 ;;
 
-module OGRAPHEXT_GRAPH = 
+module OGRAPHEXT_GRAPH =
   struct
     type node = int;;
     type cfg = (string,unit) Ograph_extended.ograph_mutable;;
@@ -165,7 +167,7 @@ let get_graph_comp_files outfile = Hashtbl.find_all graph_hash outfile
 
 let head = List.hd
 
-let tail l = 
+let tail l =
   match l with
     [] -> []
   | (x::xs) -> xs
@@ -203,13 +205,13 @@ let rec some_tolist opts =
   match opts with
     | []             -> []
     | (Some x)::rest -> x::(some_tolist rest)
-    | _::rest        -> some_tolist rest 
+    | _::rest        -> some_tolist rest
 ;;
 
 let rec groupBy eq l =
     match l with
       [] -> []
-    | (x::xs) -> 
+    | (x::xs) ->
        let (xs1,xs2) = partition (fun x' -> eq x x') xs in
        (x::xs1)::(groupBy eq xs2)
 ;;
@@ -282,7 +284,7 @@ let get_states l = nub (List.map (function (s,_,_) -> s) l)
 (* ********************************************************************** *)
 
 module CTL_ENGINE =
-  functor (SUB : SUBST) -> 
+  functor (SUB : SUBST) ->
     functor (G : GRAPH) ->
       functor (P : PREDICATE) ->
 struct
@@ -307,7 +309,7 @@ let (print_generic_substitution : substitution -> unit) = fun substxs ->
   let print_generic_subst = function
       A.Subst (mvar, v) ->
        SUB.print_mvar mvar; Format.print_string " --> "; SUB.print_value v
-    | A.NegSubst (mvar, v) -> 
+    | A.NegSubst (mvar, v) ->
        SUB.print_mvar mvar; Format.print_string " -/-> "; SUB.print_value v in
   Format.print_string "[";
   Common.print_between (fun () -> Format.print_string ";" )
@@ -316,16 +318,16 @@ let (print_generic_substitution : substitution -> unit) = fun substxs ->
 
 let rec (print_generic_witness: ('pred, 'anno) witness -> unit) =
   function
-  | A.Wit (state, subst, anno, childrens) -> 
+  | A.Wit (state, subst, anno, childrens) ->
       Format.print_string "wit ";
       G.print_node state;
       print_generic_substitution subst;
       (match childrens with
        [] -> Format.print_string "{}"
-      |        _ -> 
+      |        _ ->
          Format.force_newline(); Format.print_string "   "; Format.open_box 0;
          print_generic_witnesstree childrens; Format.close_box())
-  | A.NegWit(wit) -> 
+  | A.NegWit(wit) ->
       Format.print_string "!";
       print_generic_witness wit
 
@@ -334,17 +336,17 @@ and (print_generic_witnesstree: ('pred,'anno) witness list -> unit) =
     Format.open_box 1;
     Format.print_string "{";
     Common.print_between
-      (fun () -> Format.print_string ";"; Format.force_newline() ) 
+      (fun () -> Format.print_string ";"; Format.force_newline() )
       print_generic_witness witnesstree;
     Format.print_string "}";
     Format.close_box()
-      
+
 and print_generic_triple (node,subst,tree) =
   G.print_node node;
   print_generic_substitution subst;
   print_generic_witnesstree tree
 
-and (print_generic_algo : ('pred,'anno) triples -> unit) = fun xs -> 
+and (print_generic_algo : ('pred,'anno) triples -> unit) = fun xs ->
   Format.print_string "<";
   Common.print_between
     (fun () -> Format.print_string ";"; Format.force_newline())
@@ -358,7 +360,7 @@ let print_state (str : string) (l : ('pred,'anno) triples) =
     print_generic_triple x; Format.print_newline(); flush stdout)
     (List.sort compare l);
   Printf.printf "\n"
-    
+
 let print_required_states = function
     None -> Printf.printf "no required states\n"
   | Some states ->
@@ -396,8 +398,8 @@ let print_graph grp required_states res str = function
                  ) in
              (if not (List.mem file !graph_stack) then
                graph_stack := file :: !graph_stack);
-           let filename = Filename.temp_file (file^":") ".dot" in         
-           Hashtbl.add graph_hash file filename;  
+           let filename = Filename.temp_file (file^":") ".dot" in      
+           Hashtbl.add graph_hash file filename;
            G.print_graph grp
              (if !Flag_ctl.gt_without_label then None else (Some label))
              (match required_states with
@@ -413,26 +415,26 @@ let print_graph_c grp required_states res ctr phi =
 (* ---------------------------------------------------------------------- *)
 (*                                                                        *)
 (* ---------------------------------------------------------------------- *)
-    
-    
+
+
 (* ************************* *)
 (* Substitutions             *)
 (* ************************* *)
-    
+
 let dom_sub sub =
   match sub with
   | A.Subst(x,_)    -> x
   | A.NegSubst(x,_) -> x
 ;;
-       
+
 let ran_sub sub =
   match sub with
   | A.Subst(_,x)    -> x
   | A.NegSubst(_,x) -> x
 ;;
-       
+
 let eq_subBy eqx eqv sub sub' =
-  match (sub,sub') with 
+  match (sub,sub') with
     | (A.Subst(x,v),A.Subst(x',v'))       -> (eqx x x') && (eqv v v')
     | (A.NegSubst(x,v),A.NegSubst(x',v')) -> (eqx x x') && (eqv v v')
     | _                               -> false
@@ -446,7 +448,7 @@ let eq_subst th th' = setequalBy eq_sub th th';;
 let merge_subBy eqx (===) (>+<) sub sub' =
   (* variable part is guaranteed to be the same *)
   match (sub,sub') with
-    (A.Subst (x,v),A.Subst (x',v')) -> 
+    (A.Subst (x,v),A.Subst (x',v')) ->
       if (v === v')
       then Some [A.Subst(x, v >+< v')]
       else None
@@ -471,17 +473,18 @@ let merge_subBy eqx (===) (>+<) sub sub' =
 ;;
 
 (* NOTE: functor *)
-let merge_sub sub sub' = 
+(* How could we accomadate subterm constraints here??? *)
+let merge_sub sub sub' =
   merge_subBy SUB.eq_mvar SUB.eq_val SUB.merge_val sub sub'
 
 let clean_substBy eq cmp theta = List.sort cmp (nubBy eq theta);;
 
 (* NOTE: we sort by using the generic "compare" on (meta-)variable
- *   names; we could also require a definition of compare for meta-variables 
+ *   names; we could also require a definition of compare for meta-variables
  *   or substitutions but that seems like overkill for sorting
  *)
-let clean_subst theta = 
-  let res = 
+let clean_subst theta =
+  let res =
     clean_substBy eq_sub
       (fun s s' ->
        let res = compare (dom_sub s) (dom_sub s') in
@@ -504,7 +507,7 @@ let top_subst = [];;                        (* Always TRUE subst. *)
 
 (* Split a theta in two parts: one with (only) "x" and one without *)
 (* NOTE: functor *)
-let split_subst theta x = 
+let split_subst theta x =
   partition (fun sub -> SUB.eq_mvar (dom_sub sub) x) theta;;
 
 exception SUBST_MISMATCH
@@ -652,7 +655,7 @@ let normalize trips =
   List.map
     (function (st,th,wit) -> (st,List.sort compare th,List.sort compare wit))
     trips
-       
+
 
 (* conj opt doesn't work ((1,[],{{x=3}}) v (1,[],{{x=4}})) & (1,[],{{x=4}}) =
 (1,[],{{x=3},{x=4}}), not (1,[],{{x=4}}) *)
@@ -751,11 +754,11 @@ type ('a) state =
 ;;
 
 let compatible_states = function
-    (PosState s1, PosState s2) -> 
+    (PosState s1, PosState s2) ->
       if s1 = s2 then Some (PosState s1) else None
-  | (PosState s1, NegState s2) -> 
+  | (PosState s1, NegState s2) ->
       if List.mem s1 s2 then None else Some (PosState s1)
-  | (NegState s1, PosState s2) -> 
+  | (NegState s1, PosState s2) ->
       if List.mem s2 s1 then None else Some (PosState s2)
   | (NegState s1, NegState s2) -> Some (NegState (s1 @ s2))
 ;;
@@ -789,7 +792,7 @@ let triples_state_conj trips trips' =
     shared trips
 ;;
 
-let triple_negate (s,th,wits) = 
+let triple_negate (s,th,wits) =
   let negstates = (NegState [s],top_subst,top_wit) in
   let negths = map (fun th -> (PosState s,th,top_wit)) (negate_subst th) in
   let negwits = map (fun nwit -> (PosState s,th,nwit)) (negate_wits wits) in
@@ -841,7 +844,7 @@ let triples_complement states (trips : ('pred, 'anno) triples) =
             (negstates x @ negths x @ negwits x) xs)
 ;;
 
-let triple_negate (s,th,wits) = 
+let triple_negate (s,th,wits) =
   let negths = map (fun th -> (s,th,top_wit)) (negate_subst th) in
   let negwits = map (fun nwit -> (s,th,nwit)) (negate_wits wits) in
   ([s], negths @ negwits) (* all different *)
@@ -943,7 +946,7 @@ let triples_witness x unchecked not_keep trips =
     List.for_all (function A.NegWit _ -> true | A.Wit _ -> false) in
   let negtopos =
     List.map (function A.NegWit w -> w | A.Wit _ -> failwith "bad wit")in
-  let res = 
+  let res =
     List.fold_left
       (function prev ->
        function (s,th,wit) as t ->
@@ -1050,7 +1053,7 @@ let pre_forall dir (grp,_,states) y all reqst =
   | _ ->
       (*normalize*)
         (foldl1 (@) (List.map (foldl1 triples_conj) neighbor_triples))
-       
+
 let pre_forall_AW dir (grp,_,states) y all reqst =
   let check s =
     match reqst with
@@ -1088,16 +1091,17 @@ let pre_forall_AW dir (grp,_,states) y all reqst =
   match neighbor_triples with
     [] -> []
   | _ -> foldl1 (@) (List.map (foldl1 triples_conj_AW) neighbor_triples)
-       
+
 (* drop_negwits will call setify *)
 let satEX dir m s reqst = pre_exist dir m s reqst;;
-    
+
 let satAX dir m s reqst = pre_forall dir m s s reqst
 ;;
 
 (* E[phi1 U phi2] == phi2 \/ (phi1 /\ EXE[phi1 U phi2]) *)
-let satEU dir ((_,_,states) as m) s1 s2 reqst print_graph = 
-  let ctr = ref 0 in
+let satEU dir ((_,_,states) as m) s1 s2 reqst print_graph =
+  (*Printf.printf "EU\n";
+  let ctr = ref 0 in*)
   inc satEU_calls;
   if s1 = []
   then s2
@@ -1110,28 +1114,30 @@ let satEU dir ((_,_,states) as m) s1 s2 reqst print_graph =
        match new_info with
          [] -> y
        | new_info ->
-           ctr := !ctr + 1;
-           print_graph y ctr;
+           (*ctr := !ctr + 1;
+           print_graph y ctr;*)
            let first = triples_conj s1 (pre_exist dir m new_info reqst) in
            let res = triples_union first y in
            let new_info = setdiff res y in
            (*Printf.printf "iter %d res %d new_info %d\n"
            !ctr (List.length res) (List.length new_info);
+           print_state "res" res;
+           print_state "new_info" new_info;
            flush stdout;*)
            f res new_info in
       f s2 s2
     else
       let f y =
        inc_step();
-       ctr := !ctr + 1;
-       print_graph y ctr;
+       (*ctr := !ctr + 1;
+       print_graph y ctr;*)
        let pre = pre_exist dir m y reqst in
        triples_union s2 (triples_conj s1 pre) in
       setfix f s2
 ;;
 
 (* EF phi == E[true U phi] *)
-let satEF dir m s2 reqst = 
+let satEF dir m s2 reqst =
   inc satEF_calls;
   (*let ctr = ref 0 in*)
   if !pNEW_INFO_OPT
@@ -1278,12 +1284,19 @@ let satAW dir ((grp,_,states) as m) s1 s2 reqst =
        print_state "y" y;
        flush stdout;*)
        let pre = pre_forall dir m y y reqst in
+       (*print_state "pre" pre;*)
        let conj = triples_conj s1 pre in (* or triples_conj_AW *)
        triples_union s2 conj in
-      setgfix f (triples_union s1 s2)
+      let drop_wits = List.map (function (s,e,_) -> (s,e,[])) in
+      (* drop wits on s1 represents that we don't want any witnesses from
+        the case that infinitely loops, only from the case that gets
+        out of the loop. s1 is like a guard. To see the problem, consider
+        an example where both s1 and s2 match some code after the loop.
+        we only want the witness from s2. *)
+      setgfix f (triples_union (nub(drop_wits s1)) s2)
 ;;
 
-let satAF dir m s reqst = 
+let satAF dir m s reqst =
   inc satAF_calls;
   if !pNEW_INFO_OPT
   then
@@ -1325,8 +1338,11 @@ let satEG dir ((_,_,states) as m) s reqst =
 (* **************************************************************** *)
 (* applied to the result of matching a node.  collect witnesses when the
 states and environments are the same *)
+(* not a good idea, poses problem for unparsing, because don't realize that
+adjacent things come from different matches, leading to loss of newlines etc.
+exple struct I { ... - int x; + int y; ...} *)
 
-let inner_and trips =
+let inner_and trips = trips (*
   let rec loop = function
       [] -> ([],[])
     | (s,th,w)::trips ->
@@ -1343,7 +1359,7 @@ let inner_and trips =
        | _ -> ([(s,th,w)],cur@acc)) in
   let (cur,acc) =
     loop (List.sort state_compare trips) (* is this sort needed? *) in
-  cur@acc
+  cur@acc *)
 
 (* *************** *)
 (* Partial matches *)
@@ -1383,7 +1399,7 @@ let left_strict_triples_conj strict states trips trips' =
     triples_union res fail_left
   else res
 
-let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states = 
+let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states =
   let res = op dir m trips required_states in
   if !Flag_ctl.partial_match && strict = A.STRICT
   then
@@ -1393,7 +1409,7 @@ let strict_A1 strict op failop dir ((_,_,states) as m) trips required_states =
   else res
 
 let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
-    required_states = 
+    required_states =
   let res = op dir m trips trips' required_states in
   if !Flag_ctl.partial_match && strict = A.STRICT
   then
@@ -1401,9 +1417,9 @@ let strict_A2 strict op failop dir ((_,_,states) as m) trips trips'
     let fail = filter_conj states res (failop dir m trips' required_states) in
     triples_union res fail
   else res
-      
+
 let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
-    required_states print_graph = 
+    required_states print_graph =
   match op dir m trips trips' required_states print_graph with
     AUok res ->
       if !Flag_ctl.partial_match && strict = A.STRICT
@@ -1414,7 +1430,7 @@ let strict_A2au strict op failop dir ((_,_,states) as m) trips trips'
        AUok (triples_union res fail)
       else AUok res
   | AUfailed res -> AUfailed res
-      
+
 (* ********************* *)
 (* Environment functions *)
 (* ********************* *)
@@ -1801,7 +1817,8 @@ let rec satloop unchecked required required_states
                       (* no graph, for the moment *)
                       (fun y str -> ()))
                    s1 in
-               strict_A2 strict satAW satEF dir m s1 s2 new_required_states)
+               strict_A2 strict satAW satEF dir m s1 s2 new_required_states
+               )
     | A.Implies(phi1,phi2) ->
        loop unchecked required required_states (A.Or(A.Not phi1,phi2))
     | A.Exists (keep,v,phi)     ->
@@ -1832,9 +1849,9 @@ let rec satloop unchecked required required_states
     let res = drop_wits required_states res phi (* ) *) in
     print_graph grp required_states res "" phi;
     res in
-  
+
   loop unchecked required required_states phi
-;;    
+;;
 
 
 (* SAT with tracking *)
@@ -1859,19 +1876,19 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
        let (child1,res1) = satv unchecked required required_states phi1 env in
        Printf.printf "uncheck\n"; flush stdout;
        anno res1 [child1]
-    | A.Not(phi1)          -> 
+    | A.Not(phi1)          ->
        let (child,res) =
          satv unchecked required required_states phi1 env in
        Printf.printf "not\n"; flush stdout;
        anno (triples_complement (mkstates states required_states) res) [child]
-    | A.Or(phi1,phi2)      -> 
+    | A.Or(phi1,phi2)      ->
        let (child1,res1) =
          satv unchecked required required_states phi1 env in
        let (child2,res2) =
          satv unchecked required required_states phi2 env in
        Printf.printf "or\n"; flush stdout;
        anno (triples_union res1 res2) [child1; child2]
-    | A.SeqOr(phi1,phi2)      -> 
+    | A.SeqOr(phi1,phi2)      ->
        let (child1,res1) =
          satv unchecked required required_states phi1 env in
        let (child2,res2) =
@@ -1885,7 +1902,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
                      res1neg)
                   res2))
          [child1; child2]
-    | A.And(strict,phi1,phi2)     -> 
+    | A.And(strict,phi1,phi2)     ->
        let pm = !Flag_ctl.partial_match in
        (match (pm,satv unchecked required required_states phi1 env) with
          (false,(child1,[])) ->
@@ -1905,7 +1922,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
                    res1 res2 in
                anno res [child1; child2]))
     | A.AndAny(dir,strict,phi1,phi2)     ->
-       let pm = !Flag_ctl.partial_match in 
+       let pm = !Flag_ctl.partial_match in
        (match (pm,satv unchecked required required_states phi1 env) with
          (false,(child1,[])) ->
            Printf.printf "and\n"; flush stdout; anno [] [child1]
@@ -1924,7 +1941,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
                  [] -> (* !Flag_ctl.partial_match must be true *)
                    if res2 = []
                    then anno [] [child1; child2]
-                   else 
+                   else
                      let res =
                        let s = mkstates states required_states in
                        List.fold_left
@@ -1947,7 +1964,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
                    failwith
                      "only one result allowed for the left arg of AndAny")))
     | A.HackForStmt(dir,strict,phi1,phi2)     ->
-       let pm = !Flag_ctl.partial_match in 
+       let pm = !Flag_ctl.partial_match in
        (match (pm,satv unchecked required required_states phi1 env) with
          (false,(child1,[])) ->
            Printf.printf "and\n"; flush stdout; anno [] [child1]
@@ -1977,14 +1994,14 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
        let (child1,res1) = satv unchecked required required_states phi1 env in
        Printf.printf "uncheck\n"; flush stdout;
        anno (inner_and res1) [child1]
-    | A.EX(dir,phi1)       -> 
+    | A.EX(dir,phi1)       ->
        let new_required_states =
          get_children_required_states dir m required_states in
        let (child,res) =
          satv unchecked required new_required_states phi1 env in
        Printf.printf "EX\n"; flush stdout;
        anno (satEX dir m res required_states) [child]
-    | A.AX(dir,strict,phi1)       -> 
+    | A.AX(dir,strict,phi1)       ->
        let new_required_states =
          get_children_required_states dir m required_states in
        let (child,res) =
@@ -1992,13 +2009,13 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
        Printf.printf "AX\n"; flush stdout;
        let res = strict_A1 strict satAX satEX dir m res required_states in
        anno res [child]
-    | A.EF(dir,phi1)       -> 
+    | A.EF(dir,phi1)       ->
        let new_required_states = get_reachable dir m required_states in
        let (child,res) =
          satv unchecked required new_required_states phi1 env in
        Printf.printf "EF\n"; flush stdout;
        anno (satEF dir m res new_required_states) [child]
-    | A.AF(dir,strict,phi1) -> 
+    | A.AF(dir,strict,phi1) ->
        if !Flag_ctl.loop_in_src_code
        then
          satv unchecked required required_states
@@ -2012,21 +2029,21 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
          let res =
            strict_A1 strict satAF satEF dir m res new_required_states in
          anno res [child])
-    | A.EG(dir,phi1)       -> 
+    | A.EG(dir,phi1)       ->
        let new_required_states = get_reachable dir m required_states in
        let (child,res) =
          satv unchecked required new_required_states phi1 env in
        Printf.printf "EG\n"; flush stdout;
        anno (satEG dir m res new_required_states) [child]
-    | A.AG(dir,strict,phi1)       -> 
+    | A.AG(dir,strict,phi1)       ->
        let new_required_states = get_reachable dir m required_states in
        let (child,res) =
          satv unchecked required new_required_states phi1 env in
        Printf.printf "AG\n"; flush stdout;
        let res = strict_A1 strict satAG satEF dir m res new_required_states in
        anno res [child]
-         
-    | A.EU(dir,phi1,phi2)  -> 
+
+    | A.EU(dir,phi1,phi2)  ->
        let new_required_states = get_reachable dir m required_states in
        (match satv unchecked required new_required_states phi2 env with
          (child2,[]) ->
@@ -2039,7 +2056,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
            Printf.printf "EU\n"; flush stdout;
            anno (satEU dir m res1 res2 new_required_states (fun y str -> ()))
              [child1; child2])
-    | A.AW(dir,strict,phi1,phi2)      -> 
+    | A.AW(dir,strict,phi1,phi2)      ->
        failwith "should not be used" (*
          let new_required_states = get_reachable dir m required_states in
          (match satv unchecked required new_required_states phi2 env with
@@ -2054,7 +2071,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
                strict_A2 strict satAW satEF dir m res1 res2
                  new_required_states in
              anno res [child1; child2]) *)
-    | A.AU(dir,strict,phi1,phi2)      -> 
+    | A.AU(dir,strict,phi1,phi2)      ->
        let new_required_states = get_reachable dir m required_states in
        (match satv unchecked required new_required_states phi2 env with
          (child2,[]) ->
@@ -2086,11 +2103,11 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
              let res =
                strict_A2 strict satAW satEF dir m s1 s2 new_required_states in
              anno res [child1; child2]))
-    | A.Implies(phi1,phi2) -> 
+    | A.Implies(phi1,phi2) ->
        satv unchecked required required_states
          (A.Or(A.Not phi1,phi2))
          env
-    | A.Exists (keep,v,phi1)    -> 
+    | A.Exists (keep,v,phi1)    ->
        let new_required = drop_required v required in
        let (child,res) =
          satv unchecked new_required required_states phi1 env in
@@ -2125,7 +2142,7 @@ let rec sat_verbose_loop unchecked required required_states annot maxlvl lvl
        print_required_states required_states;
       print_state "after drop_wits" res1 end;
     (child,res1)
-       
+
 ;;
 
 let sat_verbose annotate maxlvl lvl m phi =
@@ -2145,8 +2162,8 @@ let sat m phi = satloop m phi []
 *)
 
 let simpleanno l phi res =
-  let pp s = 
-    Format.print_string ("\n" ^ s ^ "\n------------------------------\n"); 
+  let pp s =
+    Format.print_string ("\n" ^ s ^ "\n------------------------------\n");
     print_generic_algo (List.sort compare res);
     Format.print_string "\n------------------------------\n\n" in
   let pp_dir = function
@@ -2184,11 +2201,11 @@ let simpleanno l phi res =
 
 (* pad: Rene, you can now use the module pretty_print_ctl.ml to
    print a ctl formula more accurately if you want.
-   Use the print_xxx provided in the different module to call 
+   Use the print_xxx provided in the different module to call
    Pretty_print_ctl.pp_ctl.
  *)
 
-let simpleanno2 l phi res = 
+let simpleanno2 l phi res =
   begin
     Pretty_print_ctl.pp_ctl (P.print_predicate, SUB.print_mvar) false phi;
     Format.print_newline ();
@@ -2365,7 +2382,7 @@ let bench_sat (_,_,states) fn =
        (List.iter (print_state "a state") answers;
         Printf.printf "something doesn't work\n");
       res)
-      
+
 let print_bench _ =
   let iterct = !Flag_ctl.bench in
   if iterct > 0
@@ -2471,7 +2488,7 @@ let sat m phi reqopt =
       Printf.printf "triples: %d\n" !triples;
       print_state "final result" res;
       *)
-      res)
+      List.sort compare res)
     else
       (if !Flag_ctl.verbose_ctl_engine
       then Common.pr2 "missing something required";
@@ -2484,4 +2501,3 @@ let sat m phi reqopt =
 (* ********************************************************************** *)
 end
 ;;
-