]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/cic_disambiguation/disambiguate.ml
merged changes from the svn fork by me and Enrico
[helm.git] / helm / ocaml / cic_disambiguation / disambiguate.ml
1 (* Copyright (C) 2004, 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://helm.cs.unibo.it/
24  *)
25
26 open Printf
27
28 open DisambiguateTypes
29 open UriManager
30
31 exception No_choices of domain_item
32 exception NoWellTypedInterpretation
33
34   (** raised when an environment is not enough informative to decide *)
35 exception Try_again
36
37 let debug = false
38 let debug_print = if debug then prerr_endline else ignore
39
40 (*
41   (** print benchmark information *)
42 let benchmark = true
43 let max_refinements = ref 0       (* benchmarking is not thread safe *)
44 let actual_refinements = ref 0
45 let domain_size = ref 0
46 let choices_avg = ref 0.
47 *)
48
49 let descr_of_domain_item = function
50  | Id s -> s
51  | Symbol (s, _) -> s
52  | Num i -> string_of_int i
53
54 type test_result =
55   | Ok of Cic.term * Cic.metasenv
56   | Ko
57   | Uncertain
58
59 let refine metasenv context term ugraph =
60 (*   if benchmark then incr actual_refinements; *)
61   let metasenv, term = 
62     CicMkImplicit.expand_implicits metasenv [] context term in
63     debug_print (sprintf "TEST_INTERPRETATION: %s" (CicPp.ppterm term));
64     try
65       let term', _, metasenv',ugraph1 = 
66         CicRefine.type_of_aux' metasenv context term ugraph in
67         (Ok (term', metasenv')),ugraph1
68     with
69       | CicRefine.Uncertain _ ->
70           debug_print ("UNCERTAIN!!! " ^ CicPp.ppterm term) ;
71           Uncertain,ugraph
72       | CicRefine.RefineFailure msg ->
73           debug_print (sprintf "PRUNED!!!\nterm%s\nmessage:%s"
74             (CicPp.ppterm term) msg);
75           Ko,ugraph
76       | CicUnification.UnificationFailure s -> 
77          prerr_endline ("PASSADI QUI: " ^ s);
78            raise ( CicUnification.UnificationFailure s )
79
80 let resolve (env: environment) (item: domain_item) ?(num = "") ?(args = []) () =
81   try
82     snd (Environment.find item env) env num args
83   with Not_found -> 
84     failwith ("Domain item not found: " ^ 
85       (DisambiguateTypes.string_of_domain_item item))
86
87   (* TODO move it to Cic *)
88 let find_in_environment name context =
89   let rec aux acc = function
90     | [] -> raise Not_found
91     | Cic.Name hd :: tl when hd = name -> acc
92     | _ :: tl ->  aux (acc + 1) tl
93   in
94   aux 1 context
95
96 let interpretate ~context ~env ast =
97   let rec aux loc context = function
98     | CicAst.AttributedTerm (`Loc loc, term) ->
99         aux loc context term
100     | CicAst.AttributedTerm (_, term) -> aux loc context term
101     | CicAst.Appl (CicAst.Symbol (symb, i) :: args) ->
102         let cic_args = List.map (aux loc context) args in
103         resolve env (Symbol (symb, i)) ~args:cic_args ()
104     | CicAst.Appl terms -> Cic.Appl (List.map (aux loc context) terms)
105     | CicAst.Binder (binder_kind, (var, typ), body) ->
106         let cic_type = aux_option loc context typ in
107         let cic_body = aux loc (var :: context) body in
108         (match binder_kind with
109         | `Lambda -> Cic.Lambda (var, cic_type, cic_body)
110         | `Pi | `Forall -> Cic.Prod (var, cic_type, cic_body)
111         | `Exists ->
112             resolve env (Symbol ("exists", 0))
113               ~args:[ cic_type; Cic.Lambda (var, cic_type, cic_body) ] ())
114     | CicAst.Case (term, indty_ident, outtype, branches) ->
115         let cic_term = aux loc context term in
116         let cic_outtype = aux_option loc context outtype in
117         let do_branch ((head, args), term) =
118           let rec do_branch' context = function
119             | [] -> aux loc context term
120             | (name, typ) :: tl ->
121                 let cic_body = do_branch' (name :: context) tl in
122                 let typ =
123                   match typ with
124                   | None -> Cic.Implicit (Some `Type)
125                   | Some typ -> aux loc context typ
126                 in
127                 Cic.Lambda (name, typ, cic_body)
128           in
129           do_branch' context args
130         in
131         let (indtype_uri, indtype_no) =
132           match indty_ident with
133           | Some indty_ident ->
134               (match resolve env (Id indty_ident) () with
135               | Cic.MutInd (uri, tyno, _) -> (uri, tyno)
136               | Cic.Implicit _ -> raise Try_again
137               | _ -> raise DisambiguateChoices.Invalid_choice)
138           | None ->
139               let fst_constructor =
140                 match branches with
141                 | ((head, _), _) :: _ -> head
142                 | [] -> raise DisambiguateChoices.Invalid_choice
143               in
144               (match resolve env (Id fst_constructor) () with
145               | Cic.MutConstruct (indtype_uri, indtype_no, _, _) ->
146                   (indtype_uri, indtype_no)
147               | Cic.Implicit _ -> raise Try_again
148               | _ -> raise DisambiguateChoices.Invalid_choice)
149         in
150         Cic.MutCase (indtype_uri, indtype_no, cic_outtype, cic_term,
151           (List.map do_branch branches))
152     | CicAst.LetIn ((name, typ), def, body) ->
153         let cic_def = aux loc context def in
154         let cic_def =
155           match typ with
156           | None -> cic_def
157           | Some t -> Cic.Cast (cic_def, aux loc context t)
158         in
159         let cic_body = aux loc (name :: context) body in
160         Cic.LetIn (name, cic_def, cic_body)
161     | CicAst.LetRec (kind, defs, body) ->
162         let context' =
163           List.fold_left (fun acc ((name, _), _, _) -> name :: acc)
164             context defs
165         in
166         let cic_body = aux loc context' body in
167         let inductiveFuns =
168           List.map
169             (fun ((name, typ), body, decr_idx) ->
170               let cic_body = aux loc context' body in
171               let cic_type = aux_option loc context typ in
172               let name =
173                 match name with
174                 | Cic.Anonymous ->
175                     CicTextualParser2.fail loc
176                       "Recursive functions cannot be anonymous"
177                 | Cic.Name name -> name
178               in
179               (name, decr_idx, cic_type, cic_body))
180             defs
181         in
182         let counter = ref ~-1 in
183         let build_term funs =
184           (* this is the body of the fold_right function below. Rationale: Fix
185            * and CoFix cases differs only in an additional index in the
186            * inductiveFun list, see Cic.term *)
187           match kind with
188           | `Inductive ->
189               (fun (var, _, _, _) cic ->
190                 incr counter;
191                 Cic.LetIn (Cic.Name var, Cic.Fix (!counter, funs), cic))
192           | `CoInductive ->
193               let funs =
194                 List.map (fun (name, _, typ, body) -> (name, typ, body)) funs
195               in
196               (fun (var, _, _, _) cic ->
197                 incr counter;
198                 Cic.LetIn (Cic.Name var, Cic.CoFix (!counter, funs), cic))
199         in
200         List.fold_right (build_term inductiveFuns) inductiveFuns cic_body
201     | CicAst.Ident (name, subst)
202     | CicAst.Uri (name, subst) as ast ->
203         let is_uri = function CicAst.Uri _ -> true | _ -> false in
204         (try
205           if is_uri ast then raise Not_found;(* don't search the env for URIs *)
206           let index = find_in_environment name context in
207           if subst <> None then
208             CicTextualParser2.fail loc
209               "Explicit substitutions not allowed here";
210           Cic.Rel index
211         with Not_found ->
212           let cic =
213             if is_uri ast then  (* we have the URI, build the term out of it *)
214               try
215                 CicUtil.term_of_uri name
216               with UriManager.IllFormedUri _ ->
217                 CicTextualParser2.fail loc "Ill formed URI"
218             else
219               resolve env (Id name) ()
220           in
221           let mk_subst uris =
222             let ids_to_uris =
223               List.map (fun uri -> UriManager.name_of_uri uri, uri) uris
224             in
225             (match subst with
226             | Some subst ->
227                 List.map
228                   (fun (s, term) ->
229                     (try
230                       List.assoc s ids_to_uris, aux loc context term
231                      with Not_found ->
232                        raise DisambiguateChoices.Invalid_choice))
233                   subst
234             | None -> List.map (fun uri -> uri, Cic.Implicit None) uris)
235           in
236           (try 
237             match cic with
238             | Cic.Const (uri, []) ->
239                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
240                 let uris = CicUtil.params_of_obj o in
241                 Cic.Const (uri, mk_subst uris)
242             | Cic.Var (uri, []) ->
243                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
244                 let uris = CicUtil.params_of_obj o in
245                 Cic.Var (uri, mk_subst uris)
246             | Cic.MutInd (uri, i, []) ->
247                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
248                 let uris = CicUtil.params_of_obj o in
249                 Cic.MutInd (uri, i, mk_subst uris)
250             | Cic.MutConstruct (uri, i, j, []) ->
251                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
252                 let uris = CicUtil.params_of_obj o in
253                 Cic.MutConstruct (uri, i, j, mk_subst uris)
254             | Cic.Meta _ | Cic.Implicit _ as t ->
255 (*
256                 prerr_endline (sprintf
257                   "Warning: %s must be instantiated with _[%s] but we do not enforce it"
258                   (CicPp.ppterm t)
259                   (String.concat "; "
260                     (List.map
261                       (fun (s, term) -> s ^ " := " ^ CicAstPp.pp_term term)
262                       subst)));
263 *)
264                 t
265             | _ ->
266               raise DisambiguateChoices.Invalid_choice
267            with 
268              CicEnvironment.CircularDependency _ -> 
269                raise DisambiguateChoices.Invalid_choice))
270     | CicAst.Implicit -> Cic.Implicit None
271     | CicAst.Num (num, i) -> resolve env (Num i) ~num ()
272     | CicAst.Meta (index, subst) ->
273         let cic_subst =
274           List.map
275             (function None -> None | Some term -> Some (aux loc context term))
276             subst
277         in
278         Cic.Meta (index, cic_subst)
279     | CicAst.Sort `Prop -> Cic.Sort Cic.Prop
280     | CicAst.Sort `Set -> Cic.Sort Cic.Set
281     | CicAst.Sort `Type -> Cic.Sort (Cic.Type (CicUniv.fresh())) (* TASSI *)
282     | CicAst.Sort `CProp -> Cic.Sort Cic.CProp
283     | CicAst.Symbol (symbol, instance) ->
284         resolve env (Symbol (symbol, instance)) ()
285     | CicAst.UserInput -> assert false
286   and aux_option loc context = function
287     | None -> Cic.Implicit (Some `Type)
288     | Some term -> aux loc context term
289   in
290   match ast with
291   | CicAst.AttributedTerm (`Loc loc, term) -> aux loc context term
292   | term -> aux CicAst.dummy_floc context term
293
294 let domain_of_term ~context ast =
295     (* "aux" keeps domain in reverse order and doesn't care about duplicates.
296      * Domain item more in deep in the list will be processed first.
297      *)
298   let rec aux loc context = function
299     | CicAst.AttributedTerm (`Loc loc, term) -> aux loc context term
300     | CicAst.AttributedTerm (_, term) -> aux loc context term
301     | CicAst.Appl terms ->
302         List.fold_left (fun dom term -> aux loc context term @ dom) [] terms
303     | CicAst.Binder (kind, (var, typ), body) ->
304         let kind_dom =
305           match kind with
306           | `Exists -> [ Symbol ("exists", 0) ]
307           | _ -> []
308         in
309         let type_dom = aux_option loc context typ in
310         let body_dom = aux loc (var :: context) body in
311         body_dom @ type_dom @ kind_dom
312     | CicAst.Case (term, indty_ident, outtype, branches) ->
313         let term_dom = aux loc context term in
314         let outtype_dom = aux_option loc context outtype in
315         let do_branch ((head, args), term) =
316           let (term_context, args_domain) =
317             List.fold_left
318               (fun (cont, dom) (name, typ) ->
319                 (name :: cont,
320                  (match typ with
321                  | None -> dom
322                  | Some typ -> aux loc cont typ @ dom)))
323               (context, []) args
324           in
325           args_domain @ aux loc term_context term
326         in
327         let branches_dom =
328           List.fold_left (fun dom branch -> do_branch branch @ dom) [] branches
329         in
330         branches_dom @ outtype_dom @ term_dom @
331         (match indty_ident with None -> [] | Some ident -> [ Id ident ])
332     | CicAst.LetIn ((var, typ), body, where) ->
333         let body_dom = aux loc context body in
334         let type_dom = aux_option loc context typ in
335         let where_dom = aux loc (var :: context) where in
336         where_dom @ type_dom @ body_dom
337     | CicAst.LetRec (kind, defs, where) ->
338         let context' =
339           List.fold_left (fun acc ((var, typ), _, _) -> var :: acc)
340             context defs
341         in
342         let where_dom = aux loc context' where in
343         let defs_dom =
344           List.fold_left
345             (fun dom ((_, typ), body, _) ->
346               aux loc context' body @ aux_option loc context typ)
347             [] defs
348         in
349         where_dom @ defs_dom
350     | CicAst.Ident (name, subst) ->
351         (try
352           let index = find_in_environment name context in
353           if subst <> None then
354             CicTextualParser2.fail loc
355               "Explicit substitutions not allowed here"
356           else
357             []
358         with Not_found ->
359           (match subst with
360           | None -> [Id name]
361           | Some subst ->
362               List.fold_left
363                 (fun dom (_, term) ->
364                   let dom' = aux loc context term in
365                   dom' @ dom)
366                 [Id name] subst))
367     | CicAst.Uri _ -> []
368     | CicAst.Implicit -> []
369     | CicAst.Num (num, i) -> [ Num i ]
370     | CicAst.Meta (index, local_context) ->
371         List.fold_left (fun dom term -> aux_option loc context term @ dom) []
372           local_context
373     | CicAst.Sort _ -> []
374     | CicAst.Symbol (symbol, instance) -> [ Symbol (symbol, instance) ]
375     | CicAst.UserInput -> assert false
376
377   and aux_option loc context = function
378     | None -> []
379     | Some t -> aux loc context t
380   in
381
382     (* e.g. [5;1;1;1;2;3;4;1;2] -> [2;1;4;3;5] *)
383   let rev_uniq =
384     let module SortedItem =
385       struct
386         type t = DisambiguateTypes.domain_item
387         let compare = Pervasives.compare
388       end
389     in
390     let module Set = Set.Make (SortedItem) in
391     fun l ->
392       let rev_l = List.rev l in
393       let (_, uniq_rev_l) =
394         List.fold_left
395           (fun (members, rev_l) elt ->
396             if Set.mem elt members then
397               (members, rev_l)
398             else
399               Set.add elt members, elt :: rev_l)
400           (Set.empty, []) rev_l
401       in
402       List.rev uniq_rev_l
403   in
404             
405   rev_uniq
406     (match ast with
407     | CicAst.AttributedTerm (`Loc loc, term) -> aux loc context term
408     | term -> aux CicAst.dummy_floc context term)
409
410
411   (* dom1 \ dom2 *)
412 let domain_diff dom1 dom2 =
413 (* let domain_diff = Domain.diff *)
414   let is_in_dom2 =
415     List.fold_left (fun pred elt -> (fun elt' -> elt' = elt || pred elt'))
416       (fun _ -> false) dom2
417   in
418   List.filter (fun elt -> not (is_in_dom2 elt)) dom1
419
420 module type Disambiguator =
421 sig
422   val disambiguate_term :
423     dbd:Mysql.dbd ->
424     context:Cic.context ->
425     metasenv:Cic.metasenv ->
426     ?initial_ugraph:CicUniv.universe_graph -> 
427     aliases:environment ->  (* previous interpretation status *)
428     CicAst.term ->
429     (environment *                   (* new interpretation status *)
430      Cic.metasenv *                  (* new metasenv *)
431      Cic.term*
432      CicUniv.universe_graph) list    (* disambiguated term *)
433 end
434
435 module Make (C: Callbacks) =
436   struct
437     let choices_of_id dbd id =
438       let uris = MetadataQuery.locate ~dbd id in
439       let uris =
440        match uris with
441         | [] ->
442            [UriManager.string_of_uri (C.input_or_locate_uri
443             ~title:("URI matching \"" ^ id ^ "\" unknown.") ~id ())]
444         | [uri] -> [uri]
445         | _ ->
446             C.interactive_user_uri_choice ~selection_mode:`MULTIPLE
447              ~ok:"Try selected." ~enable_button_for_non_vars:true
448              ~title:"Ambiguous input." ~id
449              ~msg: ("Ambiguous input \"" ^ id ^
450                 "\". Please, choose one or more interpretations:")
451              uris
452       in
453       List.map
454         (fun uri ->
455           (uri,
456            let term =
457              try
458                CicUtil.term_of_uri uri
459              with exn ->
460                prerr_endline uri;
461                prerr_endline (Printexc.to_string exn);
462                assert false
463             in
464            fun _ _ _ -> term))
465         uris
466
467     let disambiguate_term ~(dbd:Mysql.dbd) ~context ~metasenv
468       ?(initial_ugraph = CicUniv.empty_ugraph) ~aliases:current_env
469       term
470     =
471       debug_print "NEW DISAMBIGUATE INPUT";
472       let disambiguate_context =  (* cic context -> disambiguate context *)
473         List.map
474           (function None -> Cic.Anonymous | Some (name, _) -> name)
475           context
476       in
477       let term_dom = domain_of_term ~context:disambiguate_context term in
478       debug_print (sprintf "DISAMBIGUATION DOMAIN: %s"
479         (string_of_domain term_dom));
480       let current_dom =
481         Environment.fold (fun item _ dom -> item :: dom) current_env []
482       in
483       let todo_dom = domain_diff term_dom current_dom in
484       (* (2) lookup function for any item (Id/Symbol/Num) *)
485       let lookup_choices =
486         let id_choices = Hashtbl.create 1023 in
487         fun item ->
488         let choices =
489           match item with
490           | Id id ->
491               (try
492                 Hashtbl.find id_choices id
493               with Not_found ->
494                 let choices = choices_of_id dbd id in
495                 Hashtbl.add id_choices id choices;
496                 choices)
497           | Symbol (symb, _) -> DisambiguateChoices.lookup_symbol_choices symb
498           | Num instance -> DisambiguateChoices.lookup_num_choices ()
499         in
500         if choices = [] then raise (No_choices item);
501         choices
502       in
503
504 (*
505       (* <benchmark> *)
506       let _ =
507         if benchmark then begin
508           let per_item_choices =
509             List.map
510               (fun dom_item ->
511                 try
512                   let len = List.length (lookup_choices dom_item) in
513                   prerr_endline (sprintf "BENCHMARK %s: %d"
514                     (string_of_domain_item dom_item) len);
515                   len
516                 with No_choices _ -> 0)
517               term_dom
518           in
519           max_refinements := List.fold_left ( * ) 1 per_item_choices;
520           actual_refinements := 0;
521           domain_size := List.length term_dom;
522           choices_avg :=
523             (float_of_int !max_refinements) ** (1. /. float_of_int !domain_size)
524         end
525       in
526       (* </benchmark> *)
527 *)
528
529       (* (3) test an interpretation filling with meta uninterpreted identifiers
530        *)
531       let test_env current_env todo_dom ugraph = 
532         let filled_env =
533           List.fold_left
534             (fun env item ->
535                Environment.add item
536                ("Implicit",
537                  (match item with
538                     | Id _ | Num _ -> (fun _ _ _ -> Cic.Implicit (Some `Closed))
539                     | Symbol _ -> (fun _ _ _ -> Cic.Implicit None))) env)
540             current_env todo_dom 
541         in
542         try
543           let cic_term =
544             interpretate ~context:disambiguate_context ~env:filled_env term
545           in
546           let k,ugraph1 = refine metasenv context cic_term ugraph in
547             (k , ugraph1 )
548         with
549         | Try_again -> Uncertain,ugraph
550         | DisambiguateChoices.Invalid_choice -> Ko,ugraph
551       in
552       (* (4) build all possible interpretations *)
553       let rec aux current_env todo_dom base_univ =
554         match todo_dom with
555         | [] ->
556             (match test_env current_env [] base_univ with
557             | Ok (term, metasenv),new_univ -> 
558                                [ current_env, metasenv, term, new_univ ]
559             | Ko,_ | Uncertain,_ -> [])
560         | item :: remaining_dom ->
561             debug_print (sprintf "CHOOSED ITEM: %s"
562              (string_of_domain_item item));
563             let choices = lookup_choices item in
564             let rec filter univ = function 
565               | [] -> []
566               | codomain_item :: tl ->
567                   debug_print (sprintf "%s CHOSEN" (fst codomain_item)) ;
568                   let new_env =
569                     Environment.add item codomain_item current_env
570                   in
571                   (match test_env new_env remaining_dom univ with
572                   | Ok (term, metasenv),new_univ ->
573                       (match remaining_dom with
574                       | [] -> [ new_env, metasenv, term, new_univ ]
575                       | _ -> aux new_env remaining_dom new_univ )@ 
576                         filter univ tl
577                   | Uncertain,new_univ ->
578                       (match remaining_dom with
579                       | [] -> []
580                       | _ -> aux new_env remaining_dom new_univ )@ 
581                         filter univ tl
582                   | Ko,_ -> filter univ tl)
583             in
584             filter base_univ choices 
585       in
586       let base_univ = initial_ugraph in
587       try
588         let res =
589          match aux current_env todo_dom base_univ with
590          | [] -> raise NoWellTypedInterpretation
591          | [ e,me,t,u ] as l ->
592              debug_print "UNA SOLA SCELTA";
593              [ e,me,t,u]
594          | l ->
595              debug_print (sprintf "PIU' SCELTE (%d)" (List.length l));
596              let choices =
597                List.map
598                  (fun (env, _, _, _) ->
599                    List.map
600                      (fun domain_item ->
601                        let description =
602                          fst (Environment.find domain_item env)
603                        in
604                        (descr_of_domain_item domain_item, description))
605                      term_dom)
606                  l
607              in
608              let choosed = C.interactive_interpretation_choice choices in
609              List.map (List.nth l) choosed
610         in
611 (*
612         (if benchmark then
613           let res_size = List.length res in
614           prerr_endline (sprintf
615             ("BENCHMARK: %d/%d refinements performed, domain size %d, interps %d, k %.2f\n" ^^
616             "BENCHMARK:   estimated %.2f")
617             !actual_refinements !max_refinements !domain_size res_size
618             !choices_avg
619             (float_of_int (!domain_size - 1) *. !choices_avg *. (float_of_int res_size) +. !choices_avg)));
620 *)
621         res
622      with
623       CicEnvironment.CircularDependency s -> 
624         failwith "Disambiguate: circular dependency"
625   end
626
627 module Trivial =
628 struct
629   exception Ambiguous_term of string
630   exception Exit
631   module Callbacks =
632   struct
633     let interactive_user_uri_choice ~selection_mode ?ok
634           ?(enable_button_for_non_vars = true) ~title ~msg ~id uris =
635               raise Exit
636     let interactive_interpretation_choice interp = raise Exit
637     let input_or_locate_uri ~(title:string) ?id = raise Exit
638   end
639   module Disambiguator = Make (Callbacks)
640   let disambiguate_string ~dbd ?(context=[]) ?(metasenv=[]) ?initial_ugraph
641         ?(aliases=DisambiguateTypes.Environment.empty) term =
642     let ast = CicTextualParser2.parse_term (Stream.of_string term) in
643     try
644       Disambiguator.disambiguate_term ~dbd ~context ~metasenv ast
645         ?initial_ugraph ~aliases
646     with Exit -> raise (Ambiguous_term term)
647 end
648