Commit 9de1c09a authored by POTTIER Francois's avatar POTTIER Francois

Modified [LRijkstra] to store and sort the data.

parent 9ef1b9d8
...@@ -1111,20 +1111,44 @@ end) ...@@ -1111,20 +1111,44 @@ end)
let explored = let explored =
ref 0 ref 0
(* [data] can be viewed as a set of triples [nt, s', w], meaning that an error (* We wish to store a set of triples [nt, w, s'], meaning that an error can be
can be triggered in state [s'] by beginning in the initial state that triggered in state [s'] by beginning in the initial state that corresponds
corresponds to [nt] and by reading the sequence of terminal symbols [w]. We to [nt] and by reading the sequence of terminal symbols [w]. We wish to
store at most one such triple for every state [s'], so we organize [data] store at most one such triple for every state [s'], so we organize the data
as a mapping of [s'] to the pair [s, w]. *) as a set [domain] of states [s'] and a list [data] of triples [nt, w, s']. *)
(* We could print this data as we go, which would naturally result in sorting
the output by increasing word sizes. However, it seems preferable to sort
the sentences lexicographically, so that similar sentences end up close to
one another. This is why we store a list of triples and sort it before
printing it out. *)
let domain =
ref Lr1.NodeSet.empty
let data : (Nonterminal.t * W.word) Lr1.NodeMap.t ref = let data : (Nonterminal.t * W.word * Lr1.node) list ref =
ref Lr1.NodeMap.empty ref []
(* [reachable] is a set of all reachable states. *) (* The set [reachable] stores every reachable state (regardless of whether an
error can be triggered in that state). *)
let reachable = let reachable =
ref Lr1.NodeSet.empty ref Lr1.NodeSet.empty
(* [display] displays one data item. *)
let display (nt, w, s') =
Printf.printf
"An error in state %d can be obtained as follows.\n\
Start symbol: %s\n\
Input length: %d\n\
Input sentence:\n\
%s\n\n%!"
(Lr1.number s')
(Nonterminal.print false nt)
(W.length w)
(W.print w)
(* Perform the forward search. *) (* Perform the forward search. *)
let _, _ = let _, _ =
...@@ -1133,7 +1157,7 @@ let _, _ = ...@@ -1133,7 +1157,7 @@ let _, _ =
reachable := Lr1.NodeSet.add s' !reachable; reachable := Lr1.NodeSet.add s' !reachable;
(* If [z] causes an error in state [s'] and this is the first time (* If [z] causes an error in state [s'] and this is the first time
we are able to trigger an error in this state, ... *) we are able to trigger an error in this state, ... *)
if causes_an_error s' z && not (Lr1.NodeMap.mem s' !data) then begin if causes_an_error s' z && not (Lr1.NodeSet.mem s' !domain) then begin
(* Reconstruct the initial state [s] and the word [w] that lead (* Reconstruct the initial state [s] and the word [w] that lead
to this error. *) to this error. *)
let (s, _), ws = A.reverse path in let (s, _), ws = A.reverse path in
...@@ -1142,25 +1166,24 @@ let _, _ = ...@@ -1142,25 +1166,24 @@ let _, _ =
assert (validate s s' w); assert (validate s s' w);
(* Store this new data. *) (* Store this new data. *)
let nt = Lr1.nt_of_entry s in let nt = Lr1.nt_of_entry s in
data := Lr1.NodeMap.add s' (nt, w) !data; domain := Lr1.NodeSet.add s' !domain;
(* As we go, display the data. This leads to sorting the output data := (nt, w, s') :: !data
by increasing word sizes. *)
Printf.printf
"An error in state %d can be obtained as follows.\n\
Start symbol: %s\n\
Input length: %d\n\
Input sentence:\n\
%s\n\n%!"
(Lr1.number s')
(Nonterminal.print false nt)
(W.length w)
(W.print w)
(* TEMPORARY print a concrete version of the input sentence, too *)
(* this requires a mechanism for printing a terminal symbol under a
concrete form *)
end end
) )
(* Sort and output the data. *)
let () =
let compare (nt1, w1, _) (nt2, w2, _) =
let c = Nonterminal.compare nt1 nt2 in
if c <> 0 then c else W.compare w2 w1
in
List.iter display (List.fast_sort compare !data)
(* ------------------------------------------------------------------------ *)
(* Verbosity. *)
let max_heap_size = let max_heap_size =
if X.verbose || X.statistics <> None then if X.verbose || X.statistics <> None then
let stat = Gc.quick_stat() in let stat = Gc.quick_stat() in
...@@ -1178,13 +1201,13 @@ let () = ...@@ -1178,13 +1201,13 @@ let () =
Maximum size reached by the major heap: %dM\n%!" Maximum size reached by the major heap: %dM\n%!"
!explored !explored
(Lr1.NodeSet.cardinal !reachable) Lr1.n (Lr1.NodeSet.cardinal !reachable) Lr1.n
(Lr1.NodeMap.cardinal !data) (Lr1.NodeSet.cardinal !domain)
max_heap_size max_heap_size
end end
(* ------------------------------------------------------------------------ *) (* ------------------------------------------------------------------------ *)
(* If requested by the client, produce one line of statistics. *) (* If requested by the client, write one line of statistics to a .csv file. *)
let stop = let stop =
now() now()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment