]> matita.cs.unibo.it Git - helm.git/blob - helm/searchEngine/searchEngine.ml
New: the user can now refine the proposed constraints once that they are
[helm.git] / helm / searchEngine / searchEngine.ml
1 (* Copyright (C) 2002, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 open Http_types ;;
27
28 let debug = true;;
29 let debug_print s = if debug then prerr_endline s;;
30 Http_common.debug := true;;
31 (* Http_common.debug := true;; *)
32
33   (** accepted HTTP servers for ask_uwobo method forwarding *)
34 let valid_servers = [ "mowgli.cs.unibo.it:58080" ; "mowgli.cs.unibo.it" ; "localhost:58080" ] ;;
35
36 let mqi_flags = [] (* default MathQL interpreter options *)
37
38 open Printf;;
39
40 let daemon_name = "Search Engine";;
41 let default_port = 58085;;
42 let port_env_var = "SEARCH_ENGINE_PORT";;
43
44 let pages_dir =
45   try
46     Sys.getenv "SEARCH_ENGINE_HTML_DIR"
47   with Not_found -> "html"  (* relative to searchEngine's document root *)
48 ;;
49 let interactive_user_uri_choice_TPL = pages_dir ^ "/templateambigpdq1.html";;
50 let interactive_interpretation_choice_TPL =
51   pages_dir ^ "/templateambigpdq2.html";;
52 let constraints_choice_TPL = pages_dir ^ "/constraints_choice_template.html";;
53 let final_results_TPL = pages_dir ^ "/templateambigpdq3.html";;
54
55 exception Chat_unfinished
56
57   (* build a bool from a 1-character-string *)
58 let bool_of_string' = function
59   | "0" -> false
60   | "1" -> true
61   | s -> failwith ("Can't parse a boolean from string: " ^ s)
62 ;;
63
64   (* build an int option from a string *)
65 let int_of_string' = function
66   | "_" -> None
67   | s ->
68       try
69         Some (int_of_string s)
70       with Failure "int_of_string" ->
71         failwith ("Can't parse an int option from string: " ^ s)
72 ;;
73
74 let is_concl_pos pos =
75   pos = "http://www.cs.unibo.it/helm/schemas/schema-helm#MainConclusion"
76   or
77   pos = "http://www.cs.unibo.it/helm/schemas/schema-helm#InConclusion"
78 ;;
79
80 let is_main_pos pos =
81   pos = "http://www.cs.unibo.it/helm/schemas/schema-helm#MainConclusion"
82   or
83   pos = "http://www.cs.unibo.it/helm/schemas/schema-helm#MainHypothesis"
84 ;;
85
86   (* HTML pretty printers for mquery_generator types *)
87
88 let html_of_r_obj (uri, pos, depth) =
89   sprintf
90     "<tr><td><input type='checkbox' name='constr_obj' checked='on'/></td><td>%s</td><td>%s</td><td>%s</td></tr>"
91     uri (Str.string_after pos ((String.rindex pos '#') + 1))
92     (if is_main_pos pos then
93       sprintf "<input name='obj_depth' size='2' type='text' value='%s' />"
94         (match depth with Some i -> string_of_int i | None -> "")
95     else
96       "<input type=\"hidden\" name=\"obj_depth\" />")
97 ;;
98
99 let html_of_r_rel (pos, depth) =
100   sprintf
101     "<tr><td><input type='checkbox' name='constr_rel' checked='on'/></td><td>%s</td><td><input name='rel_depth' size='2' type='text' value='%s' /></td></tr>"
102     pos (match depth with Some i -> string_of_int i | None -> "")
103 ;;
104
105 let html_of_r_sort (pos, depth, sort) =
106   sprintf
107     "<tr><td><input type='checkbox' name='constr_sort' checked='on'/></td><td>%s</td><td>%s</td><td><input name='sort_depth' size='2' type='text' value='%s'/></td></tr>"
108     sort pos (match depth with Some i -> string_of_int i | None -> "")
109 ;;
110
111   (** pretty print a MathQL query result to an HELM theory file *)
112 let theory_of_result result =
113  let results_no = List.length result in
114   if results_no > 0 then
115    let mode = if results_no > 10 then "linkonly" else "typeonly" in
116    let results =
117     let idx = ref (results_no + 1) in
118      List.fold_right
119       (fun (uri,attrs) i ->
120         decr idx ;
121         "<tr><td valign=\"top\">" ^ string_of_int !idx ^ ".</td><td><ht:OBJECT uri=\"" ^ uri ^ "\" mode=\"" ^ mode ^ "\"/></td></tr>" ^  i
122       ) result ""
123    in
124     "<h1>Query Results:</h1><table xmlns:ht=\"http://www.cs.unibo.it/helm/namespaces/helm-theory\">" ^ results ^ "</table>"
125   else
126     "<h1>Query Results:</h1><p>No results found!</p>"
127 ;;
128
129 let pp_result result =
130  "<html xmlns:ht=\"http://www.cs.unibo.it/helm/namespaces/helm-theory\">\n<head><title>Query Results</title><style> A { text-decoration: none } </style></head>\n<body>" ^ theory_of_result result ^ "</body></html>"
131 ;;
132
133   (** chain application of Pcre substitutions *)
134 let rec apply_substs substs line =
135   match substs with
136   | [] -> line
137   | (rex, templ) :: rest -> apply_substs rest (Pcre.replace ~rex ~templ line)
138   (** fold like function on files *)
139 let fold_file f init fname =
140   let inchan = open_in fname in
141   let rec fold_lines' value =
142     try 
143       let line = input_line inchan in 
144       fold_lines' (f value line)
145     with End_of_file -> value
146   in
147   let res = (try fold_lines' init with e -> (close_in inchan; raise e)) in
148   close_in inchan;
149   res
150   (** iter like function on files *)
151 let iter_file f = fold_file (fun _ line -> f line) ()
152
153 let (title_tag_RE, choices_tag_RE, msg_tag_RE, id_to_uris_RE, id_RE,
154     interpretations_RE, interpretations_labels_RE, results_RE, new_aliases_RE,
155     form_RE, variables_initialization_RE)
156   =
157   (Pcre.regexp "@TITLE@", Pcre.regexp "@CHOICES@", Pcre.regexp "@MSG@",
158   Pcre.regexp "@ID_TO_URIS@", Pcre.regexp "@ID@",
159   Pcre.regexp "@INTERPRETATIONS@", Pcre.regexp "@INTERPRETATIONS_LABELS@",
160   Pcre.regexp "@RESULTS@", Pcre.regexp "@NEW_ALIASES@", Pcre.regexp "@FORM@",
161   Pcre.regexp "@VARIABLES_INITIALIZATION@")
162 let server_and_port_url_RE = Pcre.regexp "^http://([^/]+)/.*$"
163
164 exception NotAnInductiveDefinition
165
166 let port =
167   try
168     int_of_string (Sys.getenv port_env_var)
169   with
170   | Not_found -> default_port
171   | Failure "int_of_string" ->
172       prerr_endline "Warning: invalid port, reverting to default";
173       default_port
174 in
175 let pp_error = sprintf "<html><body><h1>Error: %s</h1></body></html>" in
176 let bad_request body outchan =
177   Http_daemon.respond_error ~status:(`Client_error `Bad_request) ~body outchan
178 in
179 let contype = "Content-Type", "text/html" in
180
181 (* SEARCH ENGINE functions *)
182
183 let refine_constraints (constr_obj, constr_rel, constr_sort) =
184  function
185     "/searchPattern" ->
186       (constr_obj, constr_rel, constr_sort),
187        (Some constr_obj, Some constr_rel, Some constr_sort)
188   | "/matchConclusion" ->
189       let constr_obj' =
190        List.map
191         (function (uri,pos,_) -> (uri,pos,None))
192         (List.filter
193           (function (uri,pos,depth) as constr -> is_concl_pos pos)
194           constr_obj)
195       in
196        (*CSC: we must select the must constraints here!!! *)
197        (constr_obj',[],[]),(Some constr_obj', None, None)
198   | _ -> assert false
199 in
200
201 let get_constraints term =
202  function
203     "/locateInductivePrinciple" ->
204       let uri = 
205        match term with
206           Cic.MutInd (uri,t,_) -> MQueryUtil.string_of_uriref (uri,[t])
207         | _ -> raise NotAnInductiveDefinition
208       in
209       let constr_obj =
210        [uri,"http://www.cs.unibo.it/helm/schemas/schema-helm#InHypothesis",
211          None ;
212         uri,"http://www.cs.unibo.it/helm/schemas/schema-helm#MainHypothesis",
213          Some 0
214        ]
215       in
216       let constr_rel =
217        ["http://www.cs.unibo.it/helm/schemas/schema-helm#MainConclusion",
218         None] in
219       let constr_sort =
220        ["http://www.cs.unibo.it/helm/schemas/schema-helm#MainHypothesis",
221         Some 1, "http://www.cs.unibo.it/helm/schemas/schema-helm#Prop"]
222       in
223        (constr_obj, constr_rel, constr_sort), (None,None,None)
224   | req_path ->
225      let must = MQueryLevels2.get_constraints term in
226       refine_constraints must req_path
227 in
228
229 (*
230   format:
231     <must_obj> ':' <must_rel> ':' <must_sort> ':' <only_obj> ':' <only_rel> ':' <only_sort>
232
233     <must_*> ::= ('0'|'1') ('_'|<int>) (',' ('0'|'1') ('_'|<int>))*
234     <only> ::= '0'|'1'
235 *)
236 let add_user_constraints ~constraints
237  ((obj, rel, sort), (only_obj, only_rel, only_sort))
238 =
239   let parse_must s =
240     let l = Pcre.split ~pat:"," s in
241     (try
242       List.map
243         (fun s ->
244           let subs = Pcre.extract ~pat:"^(.)(\\d+|_)$" s in
245           (bool_of_string' subs.(1), int_of_string' subs.(2)))
246         l
247      with
248       Not_found -> failwith ("Can't parse constraint string: " ^ constraints)
249     )
250   in
251     (* to be used on "obj" *)
252   let add_user_must33 user_must must =
253     List.map2
254       (fun (b, i) (p1, p2, p3) -> if b then (p1, p2, i) else (p1, p2, None))
255       user_must must
256   in
257     (* to be used on "rel" *)
258   let add_user_must22 user_must must =
259     List.map2
260       (fun (b, i) (p1, p2) -> if b then (p1, i) else (p1, None))
261       user_must must
262   in
263     (* to be used on "sort" *)
264   let add_user_must32 user_must must =
265     List.map2
266       (fun (b, i) (p1, p2, p3) -> if b then (p1, i, p3) else (p1, None, p3))
267       user_must must
268   in
269   match Pcre.split ~pat:":" constraints with
270   | [user_obj;user_rel;user_sort;user_only_obj;user_only_rel;user_only_sort] ->
271       let
272        (user_obj,user_rel,user_sort,user_only_obj,user_only_rel,user_only_sort)
273       =
274         (parse_must user_obj,
275         parse_must user_rel,
276         parse_must user_sort,
277         bool_of_string' user_only_obj,
278         bool_of_string' user_only_rel,
279         bool_of_string' user_only_sort)
280       in
281       let only' =
282        (if user_only_obj  then only_obj else None),
283        (if user_only_rel  then only_rel else None),
284        (if user_only_sort then only_sort else None)
285       in
286       let must' =
287         add_user_must33 user_obj obj,
288         add_user_must22 user_rel rel,
289         add_user_must32 user_sort sort
290       in
291       (must', only')
292   | _ -> failwith ("Can't parse constraint string: " ^ constraints)
293 in
294
295 (* HTTP DAEMON CALLBACK *)
296
297 let callback (req: Http_types.request) outchan =
298   try
299     debug_print (sprintf "Received request: %s" req#path);
300     (match req#path with
301     | "/execute" ->
302         let mqi_handle = MQIConn.init mqi_flags debug_print in 
303         let query_string = req#param "query" in
304         let lexbuf = Lexing.from_string query_string in
305         let query = MQueryUtil.query_of_text lexbuf in
306         let result = MQueryGenerator.execute_query mqi_handle query in
307         let result_string = pp_result result in
308               MQIConn.close mqi_handle;
309         Http_daemon.respond ~body:result_string ~headers:[contype] outchan
310     | "/locate" ->
311         let mqi_handle = MQIConn.init mqi_flags debug_print in
312         let id = req#param "id" in
313         let result = MQueryGenerator.locate mqi_handle id in
314               MQIConn.close mqi_handle;
315         Http_daemon.respond ~headers:[contype] ~body:(pp_result result) outchan
316     | "/getpage" ->
317         (* TODO implement "is_permitted" *)
318         (let is_permitted _ = true in
319         let remove_fragment uri = Pcre.replace ~pat:"#.*" uri in
320         let page = remove_fragment (req#param "url") in
321         let preprocess =
322           (try
323             bool_of_string (req#param "preprocess")
324           with Invalid_argument _ | Http_types.Param_not_found _ -> false)
325         in
326         (match page with
327         | page when is_permitted page ->
328             (let fname = sprintf "%s/%s" pages_dir (remove_fragment page) in
329             Http_daemon.send_basic_headers ~code:200 outchan;
330             Http_daemon.send_header "Content-Type" "text/html" outchan;
331             Http_daemon.send_CRLF outchan;
332             if preprocess then begin
333               iter_file
334                 (fun line ->
335                   output_string outchan
336                     ((apply_substs
337                        (List.map
338                          (function (key,value) ->
339                            let key' =
340                             (Pcre.extract ~pat:"param\\.(.*)" key).(1)
341                            in
342                             Pcre.regexp ("@" ^ key' ^ "@"), value
343                          )
344                          (List.filter
345                            (fun (key,_) as p-> Pcre.pmatch ~pat:"^param\\." key)
346                            req#params)
347                        )
348                        line) ^
349                     "\n"))
350                 fname
351             end else
352               Http_daemon.send_file ~src:(FileSrc fname) outchan)
353         | page -> Http_daemon.respond_forbidden ~url:page outchan))
354     | "/ask_uwobo" ->
355       let url = req#param "url" in
356       let server_and_port =
357         (Pcre.extract ~rex:server_and_port_url_RE url).(1)
358       in
359       if List.mem server_and_port valid_servers then
360         Http_daemon.respond
361           ~headers:["Content-Type", "text/html"]
362           ~body:(Http_client.Convenience.http_get url)
363           outchan
364       else
365         Http_daemon.respond
366           ~body:(pp_error ("Untrusted UWOBO server: " ^ server_and_port))
367           outchan
368     | "/searchPattern"
369     | "/matchConclusion"
370     | "/locateInductivePrinciple" ->
371         let mqi_handle = MQIConn.init mqi_flags debug_print in
372         let term_string = req#param "term" in
373         let lexbuf = Lexing.from_string term_string in
374         let (context, metasenv) = ([], []) in
375         let (dom, mk_metasenv_and_expr) =
376           CicTextualParserContext.main
377             ~context ~metasenv CicTextualLexer.token lexbuf
378         in
379         let id_to_uris_raw = req#param "aliases" in
380         let tokens = Pcre.split ~pat:"\\s" id_to_uris_raw in
381         let rec parse_tokens keys lookup = function (* TODO spostarla fuori *)
382           | [] -> keys, lookup
383           | "alias" :: key :: value :: rest ->
384               let key' = CicTextualParser0.Id key in
385                parse_tokens
386                  (key'::keys)
387                  (fun id ->
388                    if id = key' then
389                      Some
390                       (CicTextualParser0.Uri (MQueryMisc.cic_textual_parser_uri_of_string value))
391                    else lookup id)
392                  rest
393           | _ -> failwith "Can't parse aliases"
394         in
395         let parse_choices choices_raw =
396           let choices = Pcre.split ~pat:";" choices_raw in
397           List.fold_left
398             (fun f x ->
399               match Pcre.split ~pat:"\\s" x with
400               | ""::id::tail
401               | id::tail when id<>"" ->
402                   (fun id' ->
403 prerr_endline ("#### " ^ id ^ " :=");
404 List.iter (fun u -> prerr_endline ("<" ^ Netencoding.Url.decode u ^ ">")) tail;
405                     if id = id' then
406                       Some (List.map (fun u -> Netencoding.Url.decode u) tail)
407                     else
408                       f id')
409               | _ -> failwith "Can't parse choices")
410             (fun _ -> None)
411             choices
412         in
413         let (id_to_uris : Disambiguate.domain_and_interpretation) =
414          parse_tokens [] (fun _ -> None) tokens in
415         let id_to_choices =
416           try
417             let choices_raw = req#param "choices" in
418             parse_choices choices_raw
419           with Http_types.Param_not_found _ -> (fun _ -> None)
420         in
421         let module Chat: Disambiguate.Callbacks =
422           struct
423
424             let get_metasenv () =
425              !CicTextualParser0.metasenv
426
427             let set_metasenv metasenv =
428               CicTextualParser0.metasenv := metasenv
429
430             let output_html = prerr_endline
431
432             let interactive_user_uri_choice
433               ~selection_mode ?ok
434               ?enable_button_for_non_vars ~(title: string) ~(msg: string)
435               ~(id: string) (choices: string list)
436               =
437                 (match id_to_choices id with
438                 | Some choices -> choices
439                 | None ->
440                   let msg = Pcre.replace ~pat:"\'" ~templ:"\\\'" msg in
441                   (match selection_mode with
442                   | `SINGLE -> assert false
443                   | `EXTENDED ->
444                       Http_daemon.send_basic_headers ~code:200 outchan ;
445                       Http_daemon.send_CRLF outchan ;
446                       iter_file
447                         (fun line ->
448                           let formatted_choices =
449                             String.concat ","
450                               (List.map (fun uri -> sprintf "\'%s\'" uri) choices)
451                           in
452                           let processed_line =
453                             apply_substs
454                               [title_tag_RE, title;
455                                choices_tag_RE, formatted_choices;
456                                msg_tag_RE, msg;
457                                id_to_uris_RE, id_to_uris_raw;
458                                id_RE, id]
459                               line
460                           in
461                           output_string outchan (processed_line ^ "\n"))
462                         interactive_user_uri_choice_TPL;
463                       raise Chat_unfinished))
464
465             let interactive_interpretation_choice interpretations =
466               let html_interpretations_labels =
467                 String.concat ", "
468                   (List.map
469                     (fun l ->
470                       "\'" ^
471                       (String.concat "<br />"
472                         (List.map
473                           (fun (id, value) ->
474                             (sprintf "alias %s %s" id value))
475                           l)) ^
476                       "\'")
477                   interpretations)
478               in
479               let html_interpretations =
480                 String.concat ", "
481                   (List.map
482                     (fun l ->
483                       "\'" ^
484                       (String.concat " "
485                         (List.map
486                           (fun (id, value) ->
487                             (sprintf "alias %s %s"
488                               id
489                               (MQueryMisc.wrong_xpointer_format_from_wrong_xpointer_format'
490                                 value)))
491                           l)) ^
492                       "\'")
493                     interpretations)
494               in
495               Http_daemon.send_basic_headers ~code:200 outchan ;
496               Http_daemon.send_CRLF outchan ;
497               iter_file
498                 (fun line ->
499                   let processed_line =
500                     apply_substs
501                       [interpretations_RE, html_interpretations;
502                        interpretations_labels_RE, html_interpretations_labels]
503                       line
504                   in
505                   output_string outchan (processed_line ^ "\n"))
506                 interactive_interpretation_choice_TPL;
507               raise Chat_unfinished
508
509             let input_or_locate_uri ~title =
510               UriManager.uri_of_string "cic:/Coq/Init/DataTypes/nat_ind.con"
511
512           end
513         in
514         let module Disambiguate' = Disambiguate.Make (Chat) in
515         let (id_to_uris', metasenv', term') =
516           Disambiguate'.disambiguate_input mqi_handle
517             context metasenv dom mk_metasenv_and_expr id_to_uris
518         in
519         (match metasenv' with
520         | [] ->
521             let ((must_obj, must_rel, must_sort) as must'),
522                 ((only_obj, only_rel, only_sort) as only) =
523               get_constraints term' req#path
524             in
525             let must'', only' =
526               (try
527                 add_user_constraints
528                   ~constraints:(req#param "constraints")
529                   (must', only)
530               with Http_types.Param_not_found _ ->
531                 let variables =
532                  "var aliases = '" ^ id_to_uris_raw ^ "';\n" ^
533                  "var constr_obj_len = " ^
534                   string_of_int (List.length must_obj) ^ ";\n" ^
535                  "var constr_rel_len = " ^
536                   string_of_int (List.length must_rel) ^ ";\n" ^
537                  "var constr_sort_len = " ^
538                   string_of_int (List.length must_sort) ^ ";\n" in
539                 let form =
540                   (if must_obj = [] then "" else
541                     "<h4>Obj constraints</h4>" ^
542                     "<table>" ^
543                     (String.concat "\n" (List.map html_of_r_obj must_obj)) ^
544                     "</table>" ^
545                     (* The following three lines to make Javascript create *)
546                     (* the constr_obj[] and obj_depth[] arrays even if we  *)
547                     (* have only one real entry.                           *)
548                     "<input type=\"hidden\" name=\"constr_obj\" />" ^
549                     "<input type=\"hidden\" name=\"obj_depth\" />") ^
550                   (if must_rel = [] then "" else
551                    "<h4>Rel constraints</h4>" ^
552                    "<table>" ^
553                    (String.concat "\n" (List.map html_of_r_rel must_rel)) ^
554                    "</table>" ^
555                     (* The following two lines to make Javascript create *)
556                     (* the constr_rel[] and rel_depth[] arrays even if   *)
557                     (* we have only one real entry.                      *)
558                     "<input type=\"hidden\" name=\"constr_rel\" />" ^
559                     "<input type=\"hidden\" name=\"rel_depth\" />") ^
560                   (if must_sort = [] then "" else
561                     "<h4>Sort constraints</h4>" ^
562                     "<table>" ^
563                     (String.concat "\n" (List.map html_of_r_sort must_sort)) ^
564                     "</table>" ^
565                     (* The following two lines to make Javascript create *)
566                     (* the constr_sort[] and sort_depth[] arrays even if *)
567                     (* we have only one real entry.                      *)
568                     "<input type=\"hidden\" name=\"constr_sort\" />" ^
569                     "<input type=\"hidden\" name=\"sort_depth\" />") ^
570                     "<h4>Only constraints</h4>" ^
571                     "Enforce Only constraints for objects: " ^
572                       "<input type='checkbox' name='only_obj'" ^
573                       (if only_obj = None then "" else " checked='yes'") ^ " /><br />" ^
574                     "Enforce Rel constraints for objects: " ^
575                       "<input type='checkbox' name='only_rel'" ^
576                       (if only_rel = None then "" else " checked='yes'") ^ " /><br />" ^
577                     "Enforce Sort constraints for objects: " ^
578                       "<input type='checkbox' name='only_sort'" ^
579                       (if only_sort = None then "" else " checked='yes'") ^ " /><br />"
580                 in
581                 Http_daemon.send_basic_headers ~code:200 outchan ;
582                 Http_daemon.send_CRLF outchan ;
583                 iter_file
584                   (fun line ->
585                     let processed_line =
586                       apply_substs
587                        [form_RE, form ;
588                         variables_initialization_RE, variables] line
589                     in
590                     output_string outchan (processed_line ^ "\n"))
591                   constraints_choice_TPL;
592                   raise Chat_unfinished)
593             in
594             let results =
595              MQueryGenerator.searchPattern mqi_handle must'' only' in 
596             Http_daemon.send_basic_headers ~code:200 outchan ;
597             Http_daemon.send_CRLF outchan ;
598             iter_file
599               (fun line ->
600                 let new_aliases =
601                   match id_to_uris' with
602                   | (domain, f) ->
603                       String.concat ", "
604                         (List.map
605                           (fun name ->
606                             sprintf "\'alias %s cic:%s\'"
607                               (match name with
608                                   CicTextualParser0.Id name -> name
609                                 | _ -> assert false (*CSC: completare *))
610                               (match f name with
611                               | None -> assert false
612                               | Some (CicTextualParser0.Uri t) ->
613                                   MQueryMisc.string_of_cic_textual_parser_uri
614                                     t
615                               | _ -> assert false (*CSC: completare *)))
616                           domain)
617                 in
618                 let processed_line =
619                   apply_substs
620                     [results_RE, theory_of_result results ;
621                      new_aliases_RE, new_aliases]
622                     line
623                 in
624                 output_string outchan (processed_line ^ "\n"))
625               final_results_TPL
626         | _ -> (* unable to instantiate some implicit variable *)
627             Http_daemon.respond
628               ~headers:[contype]
629               ~body:"some implicit variables are still unistantiated :-("
630               outchan);
631             MQIConn.close mqi_handle
632     | invalid_request ->
633         Http_daemon.respond_error ~status:(`Client_error `Bad_request) outchan);
634     debug_print (sprintf "%s done!" req#path)
635   with
636   | Chat_unfinished -> prerr_endline "Chat unfinished, Try again!"
637   | Http_types.Param_not_found attr_name ->
638       bad_request (sprintf "Parameter '%s' is missing" attr_name) outchan
639   | exc ->
640       Http_daemon.respond
641         ~body:(pp_error ("Uncaught exception: " ^ (Printexc.to_string exc)))
642         outchan
643 in
644 printf "%s started and listening on port %d\n" daemon_name port;
645 printf "Current directory is %s\n" (Sys.getcwd ());
646 printf "HTML directory is %s\n" pages_dir;
647 flush stdout;
648 Unix.putenv "http_proxy" "";
649 Http_daemon.start' ~port callback;
650 printf "%s is terminating, bye!\n" daemon_name
651