+module Formlistlist =
+struct
+ include Hlist.Make(Formlist)
+ let print ppf fll =
+ iter (fun fl -> Formlist.print ppf fl; Format.pp_print_newline ppf ())fll
+end
+
+type 'a t = {
+ id : int;
+ mutable states : Ptset.Int.t;
+ init : Ptset.Int.t;
+ starstate : Ptset.Int.t option;
+ (* Transitions of the Alternating automaton *)
+ trans : (State.t,(TagSet.t*Transition.t) list) Hashtbl.t;
+ query_string: string;
+ }
+
+
+let dump ppf a =
+ Format.fprintf ppf "Automaton (%i) :\n" a.id;
+ Format.fprintf ppf "States : "; StateSet.print ppf a.states;
+ Format.fprintf ppf "\nInitial states : "; StateSet.print ppf a.init;
+ Format.fprintf ppf "\nAlternating transitions :\n";
+ let l = Hashtbl.fold (fun k t acc ->
+ (List.map (fun (ts,tr) -> (ts,k),Transition.node tr) t) @ acc) a.trans [] in
+ let l = List.sort (fun ((tsx,x),_) ((tsy,y),_) ->
+ if y-x == 0 then TagSet.compare tsy tsx else y-x) l in
+ let maxh,maxt,l_print =
+ List.fold_left (
+ fun (maxh,maxt,l) ((ts,q),(_,b,f,_)) ->
+ let s =
+ if TagSet.is_finite ts
+ then "{" ^ (TagSet.fold (fun t a -> a ^ " '" ^ (Tag.to_string t)^"'") ts "") ^" }"
+ else let cts = TagSet.neg ts in
+ if TagSet.is_empty cts then "*" else
+ (TagSet.fold (fun t a -> a ^ " " ^ (Tag.to_string t)) cts "*\\{"
+ )^ "}"
+ in
+ let s = Printf.sprintf "(%s,%i)" s q in
+ let s_frm =
+ Formula.print Format.str_formatter f;
+ Format.flush_str_formatter()
+ in
+ (max (String.length s) maxh, max (String.length s_frm) maxt,
+ (s,(if b then "⇒" else "→"),s_frm)::l)) (0,0,[]) l
+ in
+ Format.fprintf ppf "%s\n%!" (String.make (maxt+maxh+3) '_');
+ List.iter (fun (s,m,f) -> let s = s ^ (String.make (maxh-(String.length s)) ' ') in
+ Format.fprintf ppf "%s %s %s\n" s m f) l_print;
+ Format.fprintf ppf "%s\n%!" (String.make (maxt+maxh+3) '_')
+
+
+module FormTable = Hashtbl.Make(struct
+ type t = Formula.t*StateSet.t*StateSet.t
+ let equal (f1,s1,t1) (f2,s2,t2) =
+ f1 == f2 && s1 == s2 && t1 == t2
+ let hash (f,s,t) =
+ HASHINT3(Formula.uid f ,StateSet.uid s,StateSet.uid t)
+ end)
+module F = Formula
+
+let eval_form_bool =
+ let h_f = FormTable.create BIG_H_SIZE in
+ fun f s1 s2 ->
+ let rec loop f =
+ match F.expr f with
+ | F.True -> true,true,true
+ | F.False -> false,false,false
+ | F.Atom((`Left|`LLeft),b,q) ->
+ if b == (StateSet.mem q s1)
+ then (true,true,false)
+ else false,false,false
+ | F.Atom(_,b,q) ->
+ if b == (StateSet.mem q s2)
+ then (true,false,true)
+ else false,false,false
+ | f' ->
+ try FormTable.find h_f (f,s1,s2)
+ with Not_found -> let r =
+ match f' with
+ | F.Or(f1,f2) ->
+ let b1,rl1,rr1 = loop f1
+ in
+ if b1 && rl1 && rr1 then (true,true,true) else
+ let b2,rl2,rr2 = loop f2 in
+ let rl1,rr1 = if b1 then rl1,rr1 else false,false
+ and rl2,rr2 = if b2 then rl2,rr2 else false,false
+ in (b1 || b2, rl1||rl2,rr1||rr2)
+
+ | F.And(f1,f2) ->
+ let b1,rl1,rr1 = loop f1 in
+ if b1 && rl1 && rr1 then (true,true,true) else
+ if b1 then
+ let b2,rl2,rr2 = loop f2 in
+ if b2 then (true,rl1||rl2,rr1||rr2) else (false,false,false)
+ else (false,false,false)
+ | _ -> assert false
+ in FormTable.add h_f (f,s1,s2) r;r
+ in loop f
+
+
+module FTable = Hashtbl.Make( struct
+ type t = Formlist.t*StateSet.t*StateSet.t
+ let equal (f1,s1,t1) (f2,s2,t2) =
+ f1 == f2 && s1 == s2 && t1 == t2;;
+ let hash (f,s,t) = HASHINT3(Formlist.uid f ,StateSet.uid s,StateSet.uid t);;
+ end)
+
+
+let h_f = FTable.create BIG_H_SIZE
+
+let eval_formlist s1 s2 fl =
+ let rec loop fl =
+ try
+ FTable.find h_f (fl,s1,s2)
+ with
+ | Not_found ->
+ match Formlist.node fl with
+ | Formlist.Cons(f,fll) ->
+ let q,mark,f,_ = Transition.node f in
+ let b,b1,b2 = eval_form_bool f s1 s2 in
+ let (s,(b',b1',b2',amark)) as res = loop fll in
+ let r = if b then (StateSet.add q s, (b, b1'||b1,b2'||b2,mark||amark))
+ else res
+ in FTable.add h_f (fl,s1,s2) r;r
+ | Formlist.Nil -> StateSet.empty,(false,false,false,false)
+ in loop fl
+
+let tags_of_state a q =
+ Hashtbl.fold
+ (fun p l acc ->
+ if p == q then List.fold_left
+ (fun acc (ts,t) ->
+ let _,_,_,aux = Transition.node t in
+ if aux then acc else
+ TagSet.cup ts acc) acc l
+
+ else acc) a.trans TagSet.empty