Commit c67c36eb authored by bguillaum's avatar bguillaum

[libcaml-grew] more robust corpus mode -> generate an error page and go on...

[libcaml-grew] more robust corpus mode -> generate an error page and go on with next file, include erros in stats

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/semagramme/libcaml-grew/trunk@6393 7838e531-6607-4d57-9587-6c381814729c
parent 59f222b0
......@@ -85,15 +85,15 @@ libgrew.mli : grew_types.mli
libgrew.cma : $(FILES_CMO) parser_byte checker_byte HTMLer_byte libgrew.mli libgrew.ml
rm libgrew.mli
@make libgrew.mli
ocamlc -c $(FILES_CMO) str.cma -I parser $(PARSER_CMO) -I HTMLer HTMLer.cmo -I checker checker.cmo libgrew.mli
ocamlc -a -o libgrew.cma -pp 'camlp4o pa_macro.cmo -DDATA_DIR=\"$(DATA_DIR)\"' -linkall $(FILES_CMO) -I parser $(PARSER_CMO) -I HTMLer HTMLer.cmo -I checker checker.cmo libgrew.ml
ocamlc -c $(BYPE_FLAGS) $(FILES_CMO) str.cma -I parser $(PARSER_CMO) -I HTMLer HTMLer.cmo -I checker checker.cmo libgrew.mli
ocamlc -a -o libgrew.cma $(BYPE_FLAGS) -pp 'camlp4o pa_macro.cmo -DDATA_DIR=\"$(DATA_DIR)\"' -linkall $(FILES_CMO) -I parser $(PARSER_CMO) -I HTMLer HTMLer.cmo -I checker checker.cmo libgrew.ml
libgrew.cmxa : $(FILES_CMX) parser_opt checker_opt HTMLer_opt libgrew.mli libgrew.ml
rm libgrew.mli
@make libgrew.mli
ocamlopt -c $(FILES_CMX) str.cmxa -I parser $(PARSER_CMX) -I HTMLer HTMLer.cmx -I checker checker.cmx libgrew.mli
ocamlopt -a -o libgrew.cmxa -pp 'camlp4o pa_macro.cmo -DDATA_DIR=\"$(DATA_DIR)\"' -linkall $(FILES_CMX) -I parser $(PARSER_CMX) -I HTMLer HTMLer.cmx -I checker checker.cmx libgrew.ml
ocamlopt -c $(OPT_FLAGS) $(FILES_CMX) str.cmxa -I parser $(PARSER_CMX) -I HTMLer HTMLer.cmx -I checker checker.cmx libgrew.mli
ocamlopt -a -o libgrew.cmxa $(OPT_FLAGS) -pp 'camlp4o pa_macro.cmo -DDATA_DIR=\"$(DATA_DIR)\"' -linkall $(FILES_CMX) -I parser $(PARSER_CMX) -I HTMLer HTMLer.cmx -I checker checker.cmx libgrew.ml
DEPENDS_DIR= -I parser -I checker -I HTMLer
......
......@@ -7,30 +7,6 @@ open Command
open Grew_edge
open Graph
module Html = struct
let css = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n<link rel=\"stylesheet\" href=\"style.css\" type=\"text/css\">"
let enter out_ch ?title ?header base_name =
fprintf out_ch "<html>\n";
(match title with
| Some t -> fprintf out_ch "<head>\n%s\n<title>%s</title>\n</head>\n" css t
| None -> fprintf out_ch "<head>\n%s\n</head>\n" css
);
fprintf out_ch "<body>\n";
(match header with None -> () | Some s -> fprintf out_ch "%s\n" s);
(match title with
| Some t -> fprintf out_ch "<h1>%s</h1>\n" t
| None -> ()
)
let leave out_ch =
fprintf out_ch "</body>\n";
fprintf out_ch "</html>\n";
end
module Rewrite_history = struct
......@@ -45,14 +21,14 @@ module Rewrite_history = struct
match t.good_nf with
| [] -> [([], t.instance)]
| l ->
List.flatten
(List_.mapi
(fun i t' ->
List.map
(fun (path,x) -> (i::path,x))
(get_nfs t')
) l
)
List.flatten
(List_.mapi
(fun i t' ->
List.map
(fun (path,x) -> (i::path,x))
(get_nfs t')
) l
)
type html_mode =
| Normal
......@@ -64,33 +40,33 @@ module Rewrite_history = struct
let nfs = ref [] in
let rec loop first (rev_path, rev_rules) t =
let file =
match List.rev rev_path with
| [] -> base_name
| l -> sprintf "%s_%s" base_name (List_.to_string string_of_int "_" l) in
match List.rev rev_path with
| [] -> base_name
| l -> sprintf "%s_%s" base_name (List_.to_string string_of_int "_" l) in
begin
match (first, mode) with
| (_, Full) | (true, Normal)
-> Instance.save_dep_png ?main_feat file t.instance
| _ when t.good_nf = []
-> Instance.save_dep_png ?main_feat file t.instance
| _ -> ()
match (first, mode) with
| (_, Full) | (true, Normal)
-> Instance.save_dep_png ?main_feat file t.instance
| _ when t.good_nf = []
-> Instance.save_dep_png ?main_feat file t.instance
| _ -> ()
end;
match t.good_nf with
| [] -> nfs := (rev_path,List.rev rev_rules,file) :: !nfs
| l ->
List_.iteri
(fun i t' ->
loop false (i::rev_path,(t.module_name, t'.instance.Instance.rules)::rev_rules) t'
) l in
List_.iteri
(fun i t' ->
loop false (i::rev_path,(t.module_name, t'.instance.Instance.rules)::rev_rules) t'
) l in
loop true ([],[]) t;
List.rev !nfs
let save_html ?main_feat ?(mode=Normal) ?title ?header prefix t =
let stats = ref [] in
(* remove files from previous runs *)
let _ = Unix.system (sprintf "rm -f %s*.html" prefix) in
let _ = Unix.system (sprintf "rm -f %s*.dep" prefix) in
......@@ -107,8 +83,8 @@ module Rewrite_history = struct
if mode <> Only_nfs
then
begin
fprintf html_ch "<h6>Initial graph</h6>\n";
fprintf html_ch "<div width=100%% style=\"overflow-x:auto\"><IMG SRC=\"%s.png\"></div>\n" local
fprintf html_ch "<h6>Initial graph</h6>\n";
fprintf html_ch "<div width=100%% style=\"overflow-x:auto\"><IMG SRC=\"%s.png\"></div>\n" local
end;
......@@ -116,20 +92,20 @@ module Rewrite_history = struct
List.iter
(fun (_,rules_list,file_name) ->
fprintf html_ch "<h6>Solution %d</h6>\n" !sol_counter;
incr sol_counter;
let local_name = Filename.basename file_name in
fprintf html_ch "<b>Modules applied</b>: %d<br/>\n" (List.length rules_list);
List.iter
(fun (mod_name,rules) ->
fprintf html_ch "<p><b><font color=\"red\">%s: </font></b><font color=\"green\">%s</font></p>\n"
mod_name
(List_.to_string (fun x -> x) ", " rules);
stats := (mod_name,rules)::(!stats)
)
rules_list;
if mode = Full then fprintf html_ch "<p><a href=\"%s.html\">Show history</a></p>\n" local_name;
fprintf html_ch "<div width=100%% style=\"overflow-x:auto\"><IMG SRC=\"%s.png\"></div>\n" local_name;
fprintf html_ch "<h6>Solution %d</h6>\n" !sol_counter;
incr sol_counter;
let local_name = Filename.basename file_name in
fprintf html_ch "<b>Modules applied</b>: %d<br/>\n" (List.length rules_list);
List.iter
(fun (mod_name,rules) ->
fprintf html_ch "<p><b><font color=\"red\">%s: </font></b><font color=\"green\">%s</font></p>\n"
mod_name
(List_.to_string (fun x -> x) ", " rules);
stats := (mod_name,rules)::(!stats)
)
rules_list;
if mode = Full then fprintf html_ch "<p><a href=\"%s.html\">Show history</a></p>\n" local_name;
fprintf html_ch "<div width=100%% style=\"overflow-x:auto\"><IMG SRC=\"%s.png\"></div>\n" local_name;
) nf_files;
Html.leave html_ch;
close_out html_ch;
......@@ -138,28 +114,28 @@ module Rewrite_history = struct
then
(* All derivation view *)
List.iter
(fun (rev_path, _, file) ->
let html_ch = open_out (sprintf "%s.html" file) in
let () = Html.enter html_ch ?header file in
fprintf html_ch "<h1>Rewriting history for normal form: %s</h1>\n" file;
let rec loop = function
| [] ->
fprintf html_ch "<h6>Initial form: %s</h6>\n" local;
fprintf html_ch "<p><IMG SRC=\"%s.png\"></p>\n" local;
""
| x::t ->
let string = loop t in
let new_string = Printf.sprintf "%s_%d" string x in
let file = Printf.sprintf "%s%s" local new_string in
fprintf html_ch "<h6>Graph: %s</h6>\n" file;
fprintf html_ch "<p><IMG SRC=\"%s.png\"></p>\n" file;
new_string
in ignore (loop rev_path);
Html.leave html_ch;
close_out html_ch
) nf_files;
List.rev !stats
(fun (rev_path, _, file) ->
let html_ch = open_out (sprintf "%s.html" file) in
let () = Html.enter html_ch ?header file in
fprintf html_ch "<h1>Rewriting history for normal form: %s</h1>\n" file;
let rec loop = function
| [] ->
fprintf html_ch "<h6>Initial form: %s</h6>\n" local;
fprintf html_ch "<p><IMG SRC=\"%s.png\"></p>\n" local;
""
| x::t ->
let string = loop t in
let new_string = Printf.sprintf "%s_%d" string x in
let file = Printf.sprintf "%s%s" local new_string in
fprintf html_ch "<h6>Graph: %s</h6>\n" file;
fprintf html_ch "<p><IMG SRC=\"%s.png\"></p>\n" file;
new_string
in ignore (loop rev_path);
Html.leave html_ch;
close_out html_ch
) nf_files;
List.rev !stats
end
......@@ -175,29 +151,29 @@ module Modul = struct
}
let build ?domain ast_module =
let locals = Array.of_list ast_module.Ast.local_labels in
Array.sort compare locals;
{
name = ast_module.Ast.module_id;
local_labels = locals;
bad_labels = List.map Label.from_string ast_module.Ast.bad_labels;
rules = List.map (Rule.build ?domain ~locals) ast_module.Ast.rules;
confluent = ast_module.Ast.confluent;
}
let build ?domain ast_module =
let locals = Array.of_list ast_module.Ast.local_labels in
Array.sort compare locals;
{
name = ast_module.Ast.module_id;
local_labels = locals;
bad_labels = List.map Label.from_string ast_module.Ast.bad_labels;
rules = List.map (Rule.build ?domain ~locals) ast_module.Ast.rules;
confluent = ast_module.Ast.confluent;
}
end
module Grs = struct
type sequence = string * string list (* (name of the seq, list of modules) *)
type t = {
labels: Label.t list; (* the list of global edge labels *)
modules: Modul.t list; (* the ordered list of modules used from rewriting *)
sequences: sequence list;
}
let sequences t = t.sequences
let empty = {labels=[]; modules=[]; sequences=[];}
let build ast_grs =
......@@ -215,30 +191,30 @@ module Grs = struct
let modules_to_apply =
List.map
(fun name ->
try List.find (fun m -> m.Modul.name=name) grs.modules
with Not_found -> Log.fcritical "No sequence or module named '%s'" name
)
module_names_to_apply in
(fun name ->
try List.find (fun m -> m.Modul.name=name) grs.modules
with Not_found -> Log.fcritical "No sequence or module named '%s'" name
)
module_names_to_apply in
let rec loop instance = function
| [] -> (* no more modules to apply *)
{Rewrite_history.instance = instance; module_name = ""; good_nf = []; bad_nf = []; }
{Rewrite_history.instance = instance; module_name = ""; good_nf = []; bad_nf = []; }
| next::tail ->
let (good_set, bad_set) =
Rule.normalize
~confluent: next.Modul.confluent
next.Modul.rules
(fun x -> true) (* FIXME *)
(Instance.clear instance) in
let good_list = Instance_set.elements good_set
and bad_list = Instance_set.elements bad_set in
{
Rewrite_history.instance = instance;
module_name = next.Modul.name;
good_nf = List.map (fun i -> loop i tail) good_list;
bad_nf = bad_list;
}
let (good_set, bad_set) =
Rule.normalize
~confluent: next.Modul.confluent
next.Modul.rules
(fun x -> true) (* FIXME *)
(Instance.clear instance) in
let good_list = Instance_set.elements good_set
and bad_list = Instance_set.elements bad_set in
{
Rewrite_history.instance = instance;
module_name = next.Modul.name;
good_nf = List.map (fun i -> loop i tail) good_list;
bad_nf = bad_list;
}
in loop instance modules_to_apply
let build_rew_display grs sequence instance =
......@@ -248,38 +224,38 @@ module Grs = struct
let modules_to_apply =
List.map
(fun name ->
try List.find (fun m -> m.Modul.name=name) grs.modules
with Not_found -> Log.fcritical "No sequence or module named '%s'" name
)
module_names_to_apply in
(fun name ->
try List.find (fun m -> m.Modul.name=name) grs.modules
with Not_found -> Log.fcritical "No sequence or module named '%s'" name
)
module_names_to_apply in
let rec loop instance = function
| [] -> Grew_types.Leaf instance.Instance.graph
| next :: tail ->
let (good_set, bad_set) =
Rule.normalize
~confluent: next.Modul.confluent
next.Modul.rules
(fun x -> true) (* FIXME: filtering in module outputs *)
(Instance.clear instance) in
let inst_list = Instance_set.elements good_set
(* and bad_list = Instance_set.elements bad_set *) in
let (good_set, bad_set) =
Rule.normalize
~confluent: next.Modul.confluent
next.Modul.rules
(fun x -> true) (* FIXME: filtering in module outputs *)
(Instance.clear instance) in
let inst_list = Instance_set.elements good_set
(* and bad_list = Instance_set.elements bad_set *) in
match inst_list with
| [{Instance.big_step = None}] ->
Grew_types.Local_normal_form (instance.Instance.graph, next.Modul.name, loop instance tail)
| _ -> Grew_types.Node
(
instance.Instance.graph,
next.Modul.name,
List.map
(fun inst ->
match inst.Instance.big_step with
| None -> Error.bug "Cannot have no big_steps and more than one reducts at the same time"
| Some bs -> (bs, loop inst tail)
) inst_list
)
match inst_list with
| [{Instance.big_step = None}] ->
Grew_types.Local_normal_form (instance.Instance.graph, next.Modul.name, loop instance tail)
| _ -> Grew_types.Node
(
instance.Instance.graph,
next.Modul.name,
List.map
(fun inst ->
match inst.Instance.big_step with
| None -> Error.bug "Cannot have no big_steps and more than one reducts at the same time"
| Some bs -> (bs, loop inst tail)
) inst_list
)
in loop instance modules_to_apply
end
include Grew_types
open Printf
open Log
open Utils
open Grew_parser
open Checker
open Grs
......@@ -10,7 +12,7 @@ open Rule
open HTMLer
exception Parsing_err of string
exception File_dont_exists of string
......@@ -24,42 +26,42 @@ type gr = Instance.t
let empty_grs = Grs.empty
let grs file doc_output_dir =
if (Sys.file_exists file) then (
try
let ast = Grew_parser.parse_file_to_grs file in
(* Checker.check_grs ast;*)
let grs = Grs.build ast in
HTMLer.proceed doc_output_dir ast;
grs
with
| Grew_parser.Parse_error msg -> raise (Parsing_err msg)
| Utils.Build (msg,loc) -> raise (Build (msg,loc))
| Utils.Bug (msg, loc) -> raise (Bug (msg,loc))
| exc -> raise (Bug (Printf.sprintf "UNCATCHED EXCEPTION: %s" (Printexc.to_string exc), None))
) else (
raise (File_dont_exists file)
)
if (Sys.file_exists file) then (
try
let ast = Grew_parser.parse_file_to_grs file in
(* Checker.check_grs ast; *)
let grs = Grs.build ast in
HTMLer.proceed doc_output_dir ast;
grs
with
| Grew_parser.Parse_error msg -> raise (Parsing_err msg)
| Utils.Build (msg,loc) -> raise (Build (msg,loc))
| Utils.Bug (msg, loc) -> raise (Bug (msg,loc))
| exc -> raise (Bug (Printf.sprintf "UNCATCHED EXCEPTION: %s" (Printexc.to_string exc), None))
) else (
raise (File_dont_exists file)
)
let get_available_seq grs = Grs.sequences grs
let empty_gr = Instance.empty
let gr file =
if (Sys.file_exists file) then (
try
let ast = Grew_parser.parse_file_to_gr file in
(* Checker.check_gr ast;*)
Instance.build ast
with
| Grew_parser.Parse_error msg -> raise (Parsing_err msg)
| Utils.Build (msg,loc) -> raise (Build (msg,loc))
| Utils.Bug (msg, loc) -> raise (Bug (msg,loc))
| exc -> raise (Bug (Printf.sprintf "UNCATCHED EXCEPTION: %s" (Printexc.to_string exc), None))
) else (
raise (File_dont_exists file)
)
if (Sys.file_exists file) then (
try
let ast = Grew_parser.parse_file_to_gr file in
(* Checker.check_gr ast;*)
Instance.build ast
with
| Grew_parser.Parse_error msg -> raise (Parsing_err msg)
| Utils.Build (msg,loc) -> raise (Build (msg,loc))
| Utils.Bug (msg, loc) -> raise (Bug (msg,loc))
| exc -> raise (Bug (Printf.sprintf "UNCATCHED EXCEPTION: %s" (Printexc.to_string exc), None))
) else (
raise (File_dont_exists file)
)
let rewrite ~gr ~grs ~seq =
try
......@@ -68,17 +70,17 @@ let rewrite ~gr ~grs ~seq =
| Utils.Run (msg,loc) -> raise (Run (msg,loc))
| Utils.Bug (msg, loc) -> raise (Bug (msg,loc))
| exc -> raise (Bug (Printf.sprintf "UNCATCHED EXCEPTION: %s" (Printexc.to_string exc), None))
let rewrite_to_html ?main_feat input_dir grs output_dir no_init current_grs_file current_grs seq title =
try
let rewrite_to_html_intern ?(no_init=false) grs_file grs seq input output nb_sentence previous next =
let buff = Buffer.create 16 in
let head = Printf.sprintf "
<div class=\"navbar\">%s<a href=\"index.html\">Up</a>%s</div><br/>"
(if previous <> "" then (Printf.sprintf "<a href=\"%s.html\">Sentence %d</a> -- " previous (nb_sentence-1)) else "")
(if next <> "" then (Printf.sprintf " -- <a href=\"%s.html\">Sentence %d</a>" next (nb_sentence+1)) else "") in
<div class=\"navbar\">%s<a href=\"index.html\">Up</a>%s</div><br/>"
(if previous <> "" then (Printf.sprintf "<a href=\"%s.html\">Sentence %d</a> -- " previous (nb_sentence-1)) else "")
(if next <> "" then (Printf.sprintf " -- <a href=\"%s.html\">Sentence %d</a>" next (nb_sentence+1)) else "") in
let title = "Sentence "^(string_of_int nb_sentence) in
......@@ -87,114 +89,163 @@ let rewrite_to_html ?main_feat input_dir grs output_dir no_init current_grs_file
Printf.bprintf buff "<b>Input file</b>: <a href=\"file:///%s\">%s</a></h2>\n" (Filename.concat (Filename.dirname output) (Filename.basename input)) (Filename.basename input);
ignore(Sys.command(Printf.sprintf "cp %s %s" input (Filename.concat (Filename.dirname output) (Filename.basename input))));
let init =
let ast_gr =
Grew_parser.parse_file_to_gr input in
(* Checker.check_gr ast_gr; *)
Instance.build ast_gr
in
let rew_hist = Grs.rewrite grs seq init in
(* let _ = Grs.build_rew_display grs seq init in *)
let stats =
if no_init
then Rewrite_history.save_html ?main_feat ~mode:Rewrite_history.Only_nfs ~header:(Buffer.contents buff) ~title output rew_hist
else Rewrite_history.save_html ?main_feat ~mode:Rewrite_history.Normal ~header:(Buffer.contents buff) ~title output rew_hist in
stats in
(* get ALL gr files *)
let gr_files = Array.to_list (Sys.readdir input_dir) in
let gr_files = (List.sort (fun a b -> compare a b) (List.filter (fun file -> Filename.check_suffix file ".gr") gr_files)) in
(* create html files *)
ignore(Sys.command(Printf.sprintf "cp %s %s" grs (Filename.concat output_dir (Filename.basename grs))));
let sentence_counter = ref 1 in
let stats = ref Utils.StringMap.empty in
List.iter (fun input ->
Log.fmessage "Computing %s" input;
let rules = rewrite_to_html_intern
~no_init
current_grs_file
current_grs
seq
(Filename.concat input_dir input)
(Filename.concat output_dir (Filename.chop_extension input))
!sentence_counter
(if !sentence_counter>1 then (Filename.chop_extension (List.nth gr_files (!sentence_counter-2))) else "")
(if !sentence_counter<(List.length gr_files) then (Filename.chop_extension (List.nth gr_files (!sentence_counter))) else "")
let init = Instance.build (Grew_parser.parse_file_to_gr input) in
try
let rew_hist = Grs.rewrite grs seq init in
(* let _ = Grs.build_rew_display grs seq init in *)
let stats =
if no_init
then Some (Rewrite_history.save_html ?main_feat ~mode:Rewrite_history.Only_nfs ~header:(Buffer.contents buff) ~title output rew_hist)
else Some (Rewrite_history.save_html ?main_feat ~mode:Rewrite_history.Normal ~header:(Buffer.contents buff) ~title output rew_hist) in
stats
with
| Utils.Run (msg, Some (loc_file,loc_line)) ->
let html_ch = open_out (sprintf "%s.html" output) in
let () = Html.enter html_ch ~title ~header:(Buffer.contents buff) output in
fprintf html_ch "<h6>Initial graph</h6>\n";
Instance.save_dep_png ?main_feat output init;
fprintf html_ch "<div width=100%% style=\"overflow-x:auto\"><IMG SRC=\"%s.png\"></div>\n" (Filename.basename output);
fprintf html_ch "<h2>ERROR during rewriting:</h2>\n";
fprintf html_ch "<p>Message: %s</p>\n" msg;
fprintf html_ch "<p>File: %s</p>\n" loc_file;
fprintf html_ch "<p>Line: %d</p>\n" loc_line;
Html.leave html_ch;
close_out html_ch;
None
| exc ->
let html_ch = open_out (sprintf "%s.html" output) in
let () = Html.enter html_ch ~title ~header:(Buffer.contents buff) output in
fprintf html_ch "<h1>UNEXPECTED EXCEPTION: %s</h1>" (Printexc.to_string exc);
Html.leave html_ch;
close_out html_ch;
None
in
incr sentence_counter;
List.iter (fun rules ->
let ruls = try ref (Utils.StringMap.find (fst rules) !stats) with Not_found -> ref Utils.StringMap.empty in
List.iter (fun r ->
let old = try Utils.StringMap.find r !ruls with Not_found -> [] in
ruls := Utils.StringMap.add r (input::old) !ruls
) (snd rules);
stats := Utils.StringMap.add (fst rules) !ruls !stats
) rules;
) gr_files;
let out_ch = open_out (Filename.concat output_dir "index.html") in
let css = "<link rel=\"stylesheet\" href=\"style.css\" type=\"text/css\">" in
ignore(Sys.command("cp "^(Filename.concat DATA_DIR "style.css")^" "^(Filename.concat output_dir "style.css")));
Printf.fprintf out_ch "<head>\n%s\n<title>%s</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>\n" css title;
Printf.fprintf out_ch "<h1>%s</h1>\n" title;
Printf.fprintf out_ch "<b>Grs file</b>:%s\n<br/>\n" (Filename.basename current_grs_file);
Printf.fprintf out_ch "<b>%d Sentences</b><br/>\n<br/>\n" (List.length gr_files);
Printf.fprintf out_ch "<center><table cellpadding=10 cellspacing=0 width=90%%>\n";
Utils.StringMap.iter (fun modul rules ->
Printf.fprintf out_ch "<tr><td colspan=5><h6>Module %s</h6></td>\n" modul;
Printf.fprintf out_ch "<tr><th class=\"first\" width=10>Rule</th><th width=10>#occ</th><th width=10>#files</th><th width=10>Ratio</th><th width=10>Files</th></tr>\n";
Utils.StringMap.iter (fun rule files ->
let tmp = ref "" in
let counter = ref 0 in
let rec compute list = match list with
| [] -> ()
| h::[] ->
if (!counter = 10) then (
tmp := Printf.sprintf "%s<div id=\"%s_%s\" style=\"display:none;\">\n" !tmp modul rule
);
incr counter;
tmp := Printf.sprintf "%s<a href=\"%s\">%s</a>" !tmp ((Filename