From: Kim Nguyễn Date: Fri, 21 Dec 2012 13:17:02 +0000 (+0100) Subject: Add automata data structure. X-Git-Tag: v0.1~193 X-Git-Url: http://git.nguyen.vg/gitweb/?p=tatoo.git;a=commitdiff_plain;h=d2f5764e9f0e89f485d6237d07cbe9b04b7426ae Add automata data structure. --- diff --git a/src/ata.ml b/src/ata.ml new file mode 100644 index 0000000..681ce69 --- /dev/null +++ b/src/ata.ml @@ -0,0 +1,77 @@ +open Format + +type t = { + id : Uid.t; + mutable states : StateSet.t; + mutable top_states : StateSet.t; + mutable bottom_states: StateSet.t; + mutable selection_states: StateSet.t; + transitions: (State.t, (QNameSet.t*Formula.t) list) Hashtbl.t; +} + +let next = Uid.make_maker () + +let create () = { id = next (); + states = StateSet.empty; + top_states = StateSet.empty; + bottom_states = StateSet.empty; + selection_states = StateSet.empty; + transitions = Hashtbl.create 17; + } + +let add_trans a q s f = + let trs = try Hashtbl.find a.transitions q with Not_found -> [] in + let rem, ntrs = + List.fold_left (fun (rem, atrs) ((labs, phi) as tr) -> + let nlabs = QNameSet.inter labs rem in + if QNameSet.is_empty nlabs then + (rem, tr :: atrs) + else + let nrem = QNameSet.diff rem labs in + nrem, (nlabs, Formula.or_ phi f)::atrs + ) (s, []) trs + in + let ntrs = if QNameSet.is_empty rem then ntrs + else (rem, f) :: ntrs + in + Hashtbl.replace a.transitions q ntrs + + +let print fmt a = + fprintf fmt + "Unique ID: %i@\n\ + States %a@\n\ + Top states: %a@\n\ + Bottom states: %a@\n\ + Selection states: %a@\n\ + Alternating transitions:@\n" + (a.id :> int) + StateSet.print a.states + StateSet.print a.top_states + StateSet.print a.bottom_states + StateSet.print a.selection_states; + let trs = + Hashtbl.fold + (fun q t acc -> List.fold_left (fun acc (s , f) -> (q,s,f)::acc) acc t) + a.transitions + [] + in + let sorted_trs = List.stable_sort (fun (q1, s1, phi1) (q2, s2, phi2) -> + let c = State.compare q1 q2 in - (if c == 0 then QNameSet.compare s1 s2 else c)) + trs + in + let sfmt = str_formatter in + let _ = flush_str_formatter () in + let strs_strings, maxs = List.fold_left (fun (accl, accm) (q, s, f) -> + let s1 = State.print sfmt q; flush_str_formatter () in + let s2 = QNameSet.print sfmt s; flush_str_formatter () in + let s3 = Formula.print sfmt f; flush_str_formatter () in + ( (s1, s2, s3) :: accl, + max + accm (2 + String.length s1 + String.length s2)) + ) ([], 0) sorted_trs + in + List.iter (fun (s1, s2, s3) -> + fprintf fmt "%s, %s" s1 s2; + fprintf fmt "%s" (Pretty.padding (maxs - String.length s1 - String.length s2 - 2)); + fprintf fmt "%s %s@\n" Pretty.right_arrow s3) strs_strings