]> matita.cs.unibo.it Git - helm.git/blob - components/cic_disambiguation/disambiguate.ml
1. More localization: interpretation errors are now loosely localized.
[helm.git] / components / 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 (* $Id$ *)
27
28 open Printf
29
30 open DisambiguateTypes
31 open UriManager
32
33 module Ast = CicNotationPt
34
35 (* the integer is an offset to be added to each location *)
36 exception NoWellTypedInterpretation of
37  int *
38  ((Stdpp.location list * string * string) list *
39   (DisambiguateTypes.domain_item * DisambiguateTypes.codomain_item) list *
40   Stdpp.location option * string Lazy.t * bool) list
41 exception PathNotWellFormed
42
43   (** raised when an environment is not enough informative to decide *)
44 exception Try_again of string Lazy.t
45
46 type aliases = bool * DisambiguateTypes.environment
47 type 'a disambiguator_input = string * int * 'a
48
49 type domain = domain_tree list
50 and domain_tree = Node of Stdpp.location list * domain_item * domain
51
52 let rec string_of_domain =
53  function
54     [] -> ""
55   | Node (_,domain_item,l)::tl ->
56      DisambiguateTypes.string_of_domain_item domain_item ^
57       " [ " ^ string_of_domain l ^ " ] " ^ string_of_domain tl
58
59 let rec filter_map_domain f =
60  function
61     [] -> []
62   | Node (locs,domain_item,l)::tl ->
63      match f locs domain_item with
64         None -> filter_map_domain f l @ filter_map_domain f tl
65       | Some res -> res :: filter_map_domain f l @ filter_map_domain f tl
66
67 let rec map_domain f =
68  function
69     [] -> []
70   | Node (locs,domain_item,l)::tl ->
71      f locs domain_item :: map_domain f l @ map_domain f tl
72
73 let uniq_domain dom =
74  let rec aux seen =
75   function
76      [] -> seen,[]
77    | Node (locs,domain_item,l)::tl ->
78       if List.mem domain_item seen then
79        let seen,l = aux seen l in
80        let seen,tl = aux seen tl in
81         seen, l @ tl
82       else
83        let seen,l = aux (domain_item::seen) l in
84        let seen,tl = aux seen tl in
85         seen, Node (locs,domain_item,l)::tl
86  in
87   snd (aux [] dom)
88
89 let debug = false
90 let debug_print s = if debug then prerr_endline (Lazy.force s) else ()
91
92 (*
93   (** print benchmark information *)
94 let benchmark = true
95 let max_refinements = ref 0       (* benchmarking is not thread safe *)
96 let actual_refinements = ref 0
97 let domain_size = ref 0
98 let choices_avg = ref 0.
99 *)
100
101 let descr_of_domain_item = function
102  | Id s -> s
103  | Symbol (s, _) -> s
104  | Num i -> string_of_int i
105
106 type 'a test_result =
107   | Ok of 'a * Cic.metasenv
108   | Ko of Stdpp.location option * string Lazy.t
109   | Uncertain of Stdpp.location option * string Lazy.t
110
111 let refine_term metasenv context uri term ugraph ~localization_tbl =
112 (*   if benchmark then incr actual_refinements; *)
113   assert (uri=None);
114     debug_print (lazy (sprintf "TEST_INTERPRETATION: %s" (CicPp.ppterm term)));
115     try
116       let term', _, metasenv',ugraph1 = 
117         CicRefine.type_of_aux' metasenv context term ugraph ~localization_tbl in
118         (Ok (term', metasenv')),ugraph1
119     with
120      exn ->
121       let rec process_exn loc =
122        function
123           HExtlib.Localized (loc,exn) -> process_exn (Some loc) exn
124         | CicRefine.Uncertain msg ->
125             debug_print (lazy ("UNCERTAIN!!! [" ^ (Lazy.force msg) ^ "] " ^ CicPp.ppterm term)) ;
126             Uncertain (loc,msg),ugraph
127         | CicRefine.RefineFailure msg ->
128             debug_print (lazy (sprintf "PRUNED!!!\nterm%s\nmessage:%s"
129               (CicPp.ppterm term) (Lazy.force msg)));
130             Ko (loc,msg),ugraph
131        | exn -> raise exn
132       in
133        process_exn None exn
134
135 let refine_obj metasenv context uri obj ugraph ~localization_tbl =
136  assert (context = []);
137    debug_print (lazy (sprintf "TEST_INTERPRETATION: %s" (CicPp.ppobj obj))) ;
138    try
139      let obj', metasenv,ugraph =
140       CicRefine.typecheck metasenv uri obj ~localization_tbl
141      in
142        (Ok (obj', metasenv)),ugraph
143    with
144      exn ->
145       let rec process_exn loc =
146        function
147           HExtlib.Localized (loc,exn) -> process_exn (Some loc) exn
148         | CicRefine.Uncertain msg ->
149             debug_print (lazy ("UNCERTAIN!!! [" ^ (Lazy.force msg) ^ "] " ^ CicPp.ppobj obj)) ;
150             Uncertain (loc,msg),ugraph
151         | CicRefine.RefineFailure msg ->
152             debug_print (lazy (sprintf "PRUNED!!!\nterm%s\nmessage:%s"
153               (CicPp.ppobj obj) (Lazy.force msg))) ;
154             Ko (loc,msg),ugraph
155        | exn -> raise exn
156       in
157        process_exn None exn
158
159 let resolve (env: codomain_item Environment.t) (item: domain_item) ?(num = "") ?(args = []) () =
160   try
161     snd (Environment.find item env) env num args
162   with Not_found -> 
163     failwith ("Domain item not found: " ^ 
164       (DisambiguateTypes.string_of_domain_item item))
165
166   (* TODO move it to Cic *)
167 let find_in_context name context =
168   let rec aux acc = function
169     | [] -> raise Not_found
170     | Cic.Name hd :: tl when hd = name -> acc
171     | _ :: tl ->  aux (acc + 1) tl
172   in
173   aux 1 context
174
175 let interpretate_term ?(create_dummy_ids=false) ~(context: Cic.name list) ~env ~uri ~is_path ast
176      ~localization_tbl
177 =
178   (* create_dummy_ids shouldbe used only for interpretating patterns *)
179   assert (uri = None);
180   let rec aux ~localize loc (context: Cic.name list) = function
181     | CicNotationPt.AttributedTerm (`Loc loc, term) ->
182         let res = aux ~localize loc context term in
183          if localize then Cic.CicHash.add localization_tbl res loc;
184          res
185     | CicNotationPt.AttributedTerm (_, term) -> aux ~localize loc context term
186     | CicNotationPt.Appl (CicNotationPt.Symbol (symb, i) :: args) ->
187         let cic_args = List.map (aux ~localize loc context) args in
188         resolve env (Symbol (symb, i)) ~args:cic_args ()
189     | CicNotationPt.Appl terms ->
190        Cic.Appl (List.map (aux ~localize loc context) terms)
191     | CicNotationPt.Binder (binder_kind, (var, typ), body) ->
192         let cic_type = aux_option ~localize loc context (Some `Type) typ in
193         let cic_name = CicNotationUtil.cic_name_of_name var in
194         let cic_body = aux ~localize loc (cic_name :: context) body in
195         (match binder_kind with
196         | `Lambda -> Cic.Lambda (cic_name, cic_type, cic_body)
197         | `Pi
198         | `Forall -> Cic.Prod (cic_name, cic_type, cic_body)
199         | `Exists ->
200             resolve env (Symbol ("exists", 0))
201               ~args:[ cic_type; Cic.Lambda (cic_name, cic_type, cic_body) ] ())
202     | CicNotationPt.Case (term, indty_ident, outtype, branches) ->
203         let cic_term = aux ~localize loc context term in
204         let cic_outtype = aux_option ~localize loc context None outtype in
205         let do_branch ((head, _, args), term) =
206           let rec do_branch' context = function
207             | [] -> aux ~localize loc context term
208             | (name, typ) :: tl ->
209                 let cic_name = CicNotationUtil.cic_name_of_name name in
210                 let cic_body = do_branch' (cic_name :: context) tl in
211                 let typ =
212                   match typ with
213                   | None -> Cic.Implicit (Some `Type)
214                   | Some typ -> aux ~localize loc context typ
215                 in
216                 Cic.Lambda (cic_name, typ, cic_body)
217           in
218           do_branch' context args
219         in
220         let indtype_uri, indtype_no =
221           if create_dummy_ids then
222             (UriManager.uri_of_string "cic:/fake_indty.con", 0)
223           else
224           match indty_ident with
225           | Some (indty_ident, _) ->
226              (match resolve env (Id indty_ident) () with
227               | Cic.MutInd (uri, tyno, _) -> (uri, tyno)
228               | Cic.Implicit _ ->
229                  raise (Try_again (lazy "The type of the term to be matched
230                   is still unknown"))
231               | _ ->
232                 raise (Invalid_choice (Some loc, lazy "The type of the term to be matched is not (co)inductive!")))
233           | None ->
234               let fst_constructor =
235                 match branches with
236                 | ((head, _, _), _) :: _ -> head
237                 | [] -> raise (Invalid_choice (Some loc, lazy "The type of the term to be matched is an inductive type without constructors that cannot be determined"))
238               in
239               (match resolve env (Id fst_constructor) () with
240               | Cic.MutConstruct (indtype_uri, indtype_no, _, _) ->
241                   (indtype_uri, indtype_no)
242               | Cic.Implicit _ ->
243                  raise (Try_again (lazy "The type of the term to be matched
244                   is still unknown"))
245               | _ ->
246                 raise (Invalid_choice (Some loc, lazy "The type of the term to be matched is not (co)inductive!")))
247         in
248         let branches =
249          match fst(CicEnvironment.get_obj CicUniv.empty_ugraph indtype_uri) with
250             Cic.InductiveDefinition (il,_,_,_) ->
251              let _,_,_,cl =
252               try
253                List.nth il indtype_no
254               with _ -> assert false
255              in
256               let rec sort branches cl =
257                match cl with
258                   [] ->
259                    if branches = [] then []
260                    else
261                     raise (Invalid_choice
262                      (Some loc,
263                       lazy
264                        ("Unrecognized constructors: " ^
265                         String.concat " "
266                          (List.map (fun ((head,_,_),_) -> head) branches))))
267                 | (name,_)::cltl ->
268                    let rec find_and_remove =
269                     function
270                        [] ->
271                         raise
272                          (Invalid_choice
273                           (Some loc, lazy ("Missing case: " ^ name)))
274                      | ((name',_,_),_) as branch :: tl when name = name' ->
275                         branch,tl
276                      | branch::tl ->
277                         let found,rest = find_and_remove tl in
278                          found, branch::rest
279                    in
280                     let branch,tl = find_and_remove branches in
281                      branch::sort tl cltl
282               in
283                sort branches cl
284           | _ -> assert false
285         in
286         Cic.MutCase (indtype_uri, indtype_no, cic_outtype, cic_term,
287           (List.map do_branch branches))
288     | CicNotationPt.Cast (t1, t2) ->
289         let cic_t1 = aux ~localize loc context t1 in
290         let cic_t2 = aux ~localize loc context t2 in
291         Cic.Cast (cic_t1, cic_t2)
292     | CicNotationPt.LetIn ((name, typ), def, body) ->
293         let cic_def = aux ~localize loc context def in
294         let cic_name = CicNotationUtil.cic_name_of_name name in
295         let cic_def =
296           match typ with
297           | None -> cic_def
298           | Some t -> Cic.Cast (cic_def, aux ~localize loc context t)
299         in
300         let cic_body = aux ~localize loc (cic_name :: context) body in
301         Cic.LetIn (cic_name, cic_def, cic_body)
302     | CicNotationPt.LetRec (kind, defs, body) ->
303         let context' =
304           List.fold_left
305             (fun acc (_, (name, _), _, _) ->
306               CicNotationUtil.cic_name_of_name name :: acc)
307             context defs
308         in
309         let cic_body =
310          let unlocalized_body = aux ~localize:false loc context' body in
311          match unlocalized_body with
312             Cic.Rel n when n <= List.length defs -> `AvoidLetInNoAppl n
313           | Cic.Appl (Cic.Rel n::l) when n <= List.length defs ->
314              (try
315                let l' =
316                 List.map
317                  (function t ->
318                    let t',subst,metasenv =
319                     CicMetaSubst.delift_rels [] [] (List.length defs) t
320                    in
321                     assert (subst=[]);
322                     assert (metasenv=[]);
323                     t') l
324                in
325                 (* We can avoid the LetIn. But maybe we need to recompute l'
326                    so that it is localized *)
327                 if localize then
328                  match body with
329                     CicNotationPt.AttributedTerm (_,CicNotationPt.Appl(_::l)) ->
330                      let l' = List.map (aux ~localize loc context) l in
331                       `AvoidLetIn (n,l')
332                   | _ -> assert false
333                 else
334                  `AvoidLetIn (n,l')
335               with
336                CicMetaSubst.DeliftingARelWouldCaptureAFreeVariable ->
337                 if localize then
338                  `AddLetIn (aux ~localize loc context' body)
339                 else
340                  `AddLetIn unlocalized_body)
341           | _ ->
342              if localize then
343               `AddLetIn (aux ~localize loc context' body)
344              else
345               `AddLetIn unlocalized_body
346         in
347         let inductiveFuns =
348           List.map
349             (fun (params, (name, typ), body, decr_idx) ->
350               let add_binders kind t =
351                List.fold_right
352                 (fun var t -> CicNotationPt.Binder (kind, var, t)) params t
353               in
354               let cic_body =
355                aux ~localize loc context' (add_binders `Lambda body) in
356               let cic_type =
357                aux_option ~localize loc context (Some `Type)
358                 (HExtlib.map_option (add_binders `Pi) typ) in
359               let name =
360                 match CicNotationUtil.cic_name_of_name name with
361                 | Cic.Anonymous ->
362                     CicNotationPt.fail loc
363                       "Recursive functions cannot be anonymous"
364                 | Cic.Name name -> name
365               in
366               (name, decr_idx, cic_type, cic_body))
367             defs
368         in
369         let fix_or_cofix n =
370          match kind with
371             `Inductive -> Cic.Fix (n,inductiveFuns)
372           | `CoInductive ->
373               let coinductiveFuns =
374                 List.map
375                  (fun (name, _, typ, body) -> name, typ, body)
376                  inductiveFuns
377               in
378                Cic.CoFix (n,coinductiveFuns)
379         in
380          let counter = ref ~-1 in
381          let build_term funs (var,_,_,_) t =
382           incr counter;
383           Cic.LetIn (Cic.Name var, fix_or_cofix !counter, t)
384          in
385           (match cic_body with
386               `AvoidLetInNoAppl n ->
387                 let n' = List.length inductiveFuns - n in
388                  fix_or_cofix n'
389             | `AvoidLetIn (n,l) ->
390                 let n' = List.length inductiveFuns - n in
391                  Cic.Appl (fix_or_cofix n'::l)
392             | `AddLetIn cic_body ->         
393                 List.fold_right (build_term inductiveFuns) inductiveFuns
394                  cic_body)
395     | CicNotationPt.Ident _
396     | CicNotationPt.Uri _ when is_path -> raise PathNotWellFormed
397     | CicNotationPt.Ident (name, subst)
398     | CicNotationPt.Uri (name, subst) as ast ->
399         let is_uri = function CicNotationPt.Uri _ -> true | _ -> false in
400         (try
401           if is_uri ast then raise Not_found;(* don't search the env for URIs *)
402           let index = find_in_context name context in
403           if subst <> None then
404             CicNotationPt.fail loc "Explicit substitutions not allowed here";
405           Cic.Rel index
406         with Not_found ->
407           let cic =
408             if is_uri ast then  (* we have the URI, build the term out of it *)
409               try
410                 CicUtil.term_of_uri (UriManager.uri_of_string name)
411               with UriManager.IllFormedUri _ ->
412                 CicNotationPt.fail loc "Ill formed URI"
413             else
414               resolve env (Id name) ()
415           in
416           let mk_subst uris =
417             let ids_to_uris =
418               List.map (fun uri -> UriManager.name_of_uri uri, uri) uris
419             in
420             (match subst with
421             | Some subst ->
422                 List.map
423                   (fun (s, term) ->
424                     (try
425                       List.assoc s ids_to_uris, aux ~localize loc context term
426                      with Not_found ->
427                        raise (Invalid_choice (Some loc, lazy "The provided explicit named substitution is trying to instantiate a named variable the object is not abstracted on"))))
428                   subst
429             | None -> List.map (fun uri -> uri, Cic.Implicit None) uris)
430           in
431           (try 
432             match cic with
433             | Cic.Const (uri, []) ->
434                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
435                 let uris = CicUtil.params_of_obj o in
436                 Cic.Const (uri, mk_subst uris)
437             | Cic.Var (uri, []) ->
438                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
439                 let uris = CicUtil.params_of_obj o in
440                 Cic.Var (uri, mk_subst uris)
441             | Cic.MutInd (uri, i, []) ->
442                (try
443                  let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
444                  let uris = CicUtil.params_of_obj o in
445                  Cic.MutInd (uri, i, mk_subst uris)
446                 with
447                  CicEnvironment.Object_not_found _ ->
448                   (* if we are here it is probably the case that during the
449                      definition of a mutual inductive type we have met an
450                      occurrence of the type in one of its constructors.
451                      However, the inductive type is not yet in the environment
452                   *)
453                   (*here the explicit_named_substituion is assumed to be of length 0 *)
454                   Cic.MutInd (uri,i,[]))
455             | Cic.MutConstruct (uri, i, j, []) ->
456                 let o,_ = CicEnvironment.get_obj CicUniv.empty_ugraph uri in
457                 let uris = CicUtil.params_of_obj o in
458                 Cic.MutConstruct (uri, i, j, mk_subst uris)
459             | Cic.Meta _ | Cic.Implicit _ as t ->
460 (*
461                 debug_print (lazy (sprintf
462                   "Warning: %s must be instantiated with _[%s] but we do not enforce it"
463                   (CicPp.ppterm t)
464                   (String.concat "; "
465                     (List.map
466                       (fun (s, term) -> s ^ " := " ^ CicNotationPtPp.pp_term term)
467                       subst))));
468 *)
469                 t
470             | _ ->
471               raise (Invalid_choice (Some loc, lazy "??? Can this happen?"))
472            with 
473              CicEnvironment.CircularDependency _ -> 
474                raise (Invalid_choice (None, lazy "Circular dependency in the environment"))))
475     | CicNotationPt.Implicit -> Cic.Implicit None
476     | CicNotationPt.UserInput -> Cic.Implicit (Some `Hole)
477     | CicNotationPt.Num (num, i) -> resolve env (Num i) ~num ()
478     | CicNotationPt.Meta (index, subst) ->
479         let cic_subst =
480           List.map
481             (function
482                 None -> None
483               | Some term -> Some (aux ~localize loc context term))
484             subst
485         in
486         Cic.Meta (index, cic_subst)
487     | CicNotationPt.Sort `Prop -> Cic.Sort Cic.Prop
488     | CicNotationPt.Sort `Set -> Cic.Sort Cic.Set
489     | CicNotationPt.Sort (`Type u) -> Cic.Sort (Cic.Type u)
490     | CicNotationPt.Sort `CProp -> Cic.Sort Cic.CProp
491     | CicNotationPt.Symbol (symbol, instance) ->
492         resolve env (Symbol (symbol, instance)) ()
493     | _ -> assert false (* god bless Bologna *)
494   and aux_option ~localize loc (context: Cic.name list) annotation = function
495     | None -> Cic.Implicit annotation
496     | Some term -> aux ~localize loc context term
497   in
498    aux ~localize:true HExtlib.dummy_floc context ast
499
500 let interpretate_path ~context path =
501  let localization_tbl = Cic.CicHash.create 23 in
502   (* here we are throwing away useful localization informations!!! *)
503   fst (
504    interpretate_term ~create_dummy_ids:true 
505     ~context ~env:Environment.empty ~uri:None ~is_path:true
506     path ~localization_tbl, localization_tbl)
507
508 let interpretate_obj ~context ~env ~uri ~is_path obj ~localization_tbl =
509  assert (context = []);
510  assert (is_path = false);
511  let interpretate_term = interpretate_term ~localization_tbl in
512  match obj with
513   | CicNotationPt.Inductive (params,tyl) ->
514      let uri = match uri with Some uri -> uri | None -> assert false in
515      let context,params =
516       let context,res =
517        List.fold_left
518         (fun (context,res) (name,t) ->
519           let t =
520            match t with
521               None -> CicNotationPt.Implicit
522             | Some t -> t in
523           let name = CicNotationUtil.cic_name_of_name name in
524            name::context,(name, interpretate_term context env None false t)::res
525         ) ([],[]) params
526       in
527        context,List.rev res in
528      let add_params =
529       List.fold_right (fun (name,ty) t -> Cic.Prod (name,ty,t)) params in
530      let name_to_uris =
531       snd (
532        List.fold_left
533         (*here the explicit_named_substituion is assumed to be of length 0 *)
534         (fun (i,res) (name,_,_,_) ->
535           i + 1,(name,name,Cic.MutInd (uri,i,[]))::res
536         ) (0,[]) tyl) in
537      let con_env = DisambiguateTypes.env_of_list name_to_uris env in
538      let tyl =
539       List.map
540        (fun (name,b,ty,cl) ->
541          let ty' = add_params (interpretate_term context env None false ty) in
542          let cl' =
543           List.map
544            (fun (name,ty) ->
545              let ty' =
546               add_params (interpretate_term context con_env None false ty)
547              in
548               name,ty'
549            ) cl
550          in
551           name,b,ty',cl'
552        ) tyl
553      in
554       Cic.InductiveDefinition (tyl,[],List.length params,[])
555   | CicNotationPt.Record (params,name,ty,fields) ->
556      let uri = match uri with Some uri -> uri | None -> assert false in
557      let context,params =
558       let context,res =
559        List.fold_left
560         (fun (context,res) (name,t) ->
561           let t =
562            match t with
563               None -> CicNotationPt.Implicit
564             | Some t -> t in
565           let name = CicNotationUtil.cic_name_of_name name in
566            name::context,(name, interpretate_term context env None false t)::res
567         ) ([],[]) params
568       in
569        context,List.rev res in
570      let add_params =
571       List.fold_right
572        (fun (name,ty) t -> Cic.Prod (name,ty,t)) params in
573      let ty' = add_params (interpretate_term context env None false ty) in
574      let fields' =
575       snd (
576        List.fold_left
577         (fun (context,res) (name,ty,_coercion,arity) ->
578           let context' = Cic.Name name :: context in
579            context',(name,interpretate_term context env None false ty)::res
580         ) (context,[]) fields) in
581      let concl =
582       (*here the explicit_named_substituion is assumed to be of length 0 *)
583       let mutind = Cic.MutInd (uri,0,[]) in
584       if params = [] then mutind
585       else
586        Cic.Appl
587         (mutind::CicUtil.mk_rels (List.length params) (List.length fields)) in
588      let con =
589       List.fold_left
590        (fun t (name,ty) -> Cic.Prod (Cic.Name name,ty,t))
591        concl fields' in
592      let con' = add_params con in
593      let tyl = [name,true,ty',["mk_" ^ name,con']] in
594      let field_names = List.map (fun (x,_,y,z) -> x,y,z) fields in
595       Cic.InductiveDefinition
596        (tyl,[],List.length params,[`Class (`Record field_names)])
597   | CicNotationPt.Theorem (flavour, name, ty, bo) ->
598      let attrs = [`Flavour flavour] in
599      let ty' = interpretate_term [] env None false ty in
600      (match bo,flavour with
601         None,`Axiom ->
602          Cic.Constant (name,None,ty',[],attrs)
603       | Some bo,`Axiom -> assert false
604       | None,_ ->
605          Cic.CurrentProof (name,[],Cic.Implicit None,ty',[],attrs)
606       | Some bo,_ ->
607          let bo' = Some (interpretate_term [] env None false bo) in
608           Cic.Constant (name,bo',ty',[],attrs))
609           
610 let rec domain_of_term ?(loc = HExtlib.dummy_floc) ~context = function
611   | Ast.AttributedTerm (`Loc loc, term) ->
612      domain_of_term ~loc ~context term
613   | Ast.AttributedTerm (_, term) ->
614       domain_of_term ~loc ~context term
615   | Ast.Symbol (symbol, instance) ->
616       [ Node ([loc], Symbol (symbol, instance), []) ]
617       (* to be kept in sync with Ast.Appl (Ast.Symbol ...) *)
618   | Ast.Appl (Ast.Symbol (symbol, instance) as hd :: args)
619   | Ast.Appl (Ast.AttributedTerm (_,Ast.Symbol (symbol, instance)) as hd :: args)
620      ->
621       let args_dom =
622         List.fold_right
623           (fun term acc -> domain_of_term ~loc ~context term @ acc)
624           args [] in
625       let loc =
626        match hd with
627           Ast.AttributedTerm (`Loc loc,_)  -> loc
628         | _ -> loc
629       in
630        [ Node ([loc], Symbol (symbol, instance), args_dom) ]
631   | Ast.Appl (Ast.Ident (name, subst) as hd :: args)
632   | Ast.Appl (Ast.AttributedTerm (_,Ast.Ident (name, subst)) as hd :: args) ->
633       let args_dom =
634         List.fold_right
635           (fun term acc -> domain_of_term ~loc ~context term @ acc)
636           args [] in
637       let loc =
638        match hd with
639           Ast.AttributedTerm (`Loc loc,_)  -> loc
640         | _ -> loc
641       in
642       (try
643         (* the next line can raise Not_found *)
644         ignore(find_in_context name context);
645         if subst <> None then
646           Ast.fail loc "Explicit substitutions not allowed here"
647         else
648           args_dom
649       with Not_found ->
650         (match subst with
651         | None -> [ Node ([loc], Id name, args_dom) ]
652         | Some subst ->
653             let terms =
654               List.fold_left
655                 (fun dom (_, term) ->
656                   let dom' = domain_of_term ~loc ~context term in
657                   dom @ dom')
658                 [] subst in
659             [ Node ([loc], Id name, terms @ args_dom) ]))
660   | Ast.Appl terms ->
661       List.fold_right
662         (fun term acc -> domain_of_term ~loc ~context term @ acc)
663         terms []
664   | Ast.Binder (kind, (var, typ), body) ->
665       let type_dom = domain_of_term_option ~loc ~context typ in
666       let body_dom =
667         domain_of_term ~loc
668           ~context:(CicNotationUtil.cic_name_of_name var :: context) body in
669       (match kind with
670       | `Exists -> [ Node ([loc], Symbol ("exists", 0), (type_dom @ body_dom)) ]
671       | _ -> type_dom @ body_dom)
672   | Ast.Case (term, indty_ident, outtype, branches) ->
673       let term_dom = domain_of_term ~loc ~context term in
674       let outtype_dom = domain_of_term_option ~loc ~context outtype in
675       let get_first_constructor = function
676         | [] -> []
677         | ((head, _, _), _) :: _ -> [ Node ([loc], Id head, []) ] in
678       let do_branch ((head, _, args), term) =
679         let (term_context, args_domain) =
680           List.fold_left
681             (fun (cont, dom) (name, typ) ->
682               (CicNotationUtil.cic_name_of_name name :: cont,
683                (match typ with
684                | None -> dom
685                | Some typ -> dom @ domain_of_term ~loc ~context:cont typ)))
686             (context, []) args
687         in
688         domain_of_term ~loc ~context:term_context term @ args_domain
689       in
690       let branches_dom =
691         List.fold_left (fun dom branch -> dom @ do_branch branch) [] branches in
692       (match indty_ident with
693        | None -> get_first_constructor branches
694        | Some (ident, _) -> [ Node ([loc], Id ident, []) ])
695       @ term_dom @ outtype_dom @ branches_dom
696   | Ast.Cast (term, ty) ->
697       let term_dom = domain_of_term ~loc ~context term in
698       let ty_dom = domain_of_term ~loc ~context ty in
699       term_dom @ ty_dom
700   | Ast.LetIn ((var, typ), body, where) ->
701       let body_dom = domain_of_term ~loc ~context body in
702       let type_dom = domain_of_term_option ~loc ~context typ in
703       let where_dom =
704         domain_of_term ~loc
705           ~context:(CicNotationUtil.cic_name_of_name var :: context) where in
706       body_dom @ type_dom @ where_dom
707   | Ast.LetRec (kind, defs, where) ->
708       let add_defs context =
709         List.fold_left
710           (fun acc (_, (var, _), _, _) ->
711             CicNotationUtil.cic_name_of_name var :: acc
712           ) context defs in
713       let where_dom = domain_of_term ~loc ~context:(add_defs context) where in
714       let defs_dom =
715         List.fold_left
716           (fun dom (params, (_, typ), body, _) ->
717             let context' =
718              add_defs
719               (List.fold_left
720                 (fun acc (var,_) -> CicNotationUtil.cic_name_of_name var :: acc)
721                 context params)
722             in
723             List.rev
724              (snd
725                (List.fold_left
726                 (fun (context,res) (var,ty) ->
727                   CicNotationUtil.cic_name_of_name var :: context,
728                   domain_of_term_option ~loc ~context ty @ res)
729                 (add_defs context,[]) params))
730             @ domain_of_term_option ~loc ~context:context' typ
731             @ domain_of_term ~loc ~context:context' body
732           ) [] defs
733       in
734       defs_dom @ where_dom
735   | Ast.Ident (name, subst) ->
736       (try
737         (* the next line can raise Not_found *)
738         ignore(find_in_context name context);
739         if subst <> None then
740           Ast.fail loc "Explicit substitutions not allowed here"
741         else
742           []
743       with Not_found ->
744         (match subst with
745         | None -> [ Node ([loc], Id name, []) ]
746         | Some subst ->
747             let terms =
748               List.fold_left
749                 (fun dom (_, term) ->
750                   let dom' = domain_of_term ~loc ~context term in
751                   dom @ dom')
752                 [] subst in
753             [ Node ([loc], Id name, terms) ]))
754   | Ast.Uri _ -> []
755   | Ast.Implicit -> []
756   | Ast.Num (num, i) -> [ Node ([loc], Num i, []) ]
757   | Ast.Meta (index, local_context) ->
758       List.fold_left
759        (fun dom term -> dom @ domain_of_term_option ~loc ~context term)
760        [] local_context
761   | Ast.Sort _ -> []
762   | Ast.UserInput
763   | Ast.Literal _
764   | Ast.Layout _
765   | Ast.Magic _
766   | Ast.Variable _ -> assert false
767
768 and domain_of_term_option ~loc ~context = function
769   | None -> []
770   | Some t -> domain_of_term ~loc ~context t
771
772 let domain_of_term ~context term = 
773  uniq_domain (domain_of_term ~context term)
774
775 let domain_of_obj ~context ast =
776  assert (context = []);
777   match ast with
778    | Ast.Theorem (_,_,ty,bo) ->
779       domain_of_term [] ty
780       @ (match bo with
781           None -> []
782         | Some bo -> domain_of_term [] bo)
783    | Ast.Inductive (params,tyl) ->
784       let context, dom = 
785        List.fold_left
786         (fun (context, dom) (var, ty) ->
787           let context' = CicNotationUtil.cic_name_of_name var :: context in
788           match ty with
789              None -> context', dom
790            | Some ty -> context', dom @ domain_of_term context ty
791         ) ([], []) params in
792       let context_w_types =
793         List.rev_map
794           (fun (var, _, _, _) -> Cic.Name var) tyl
795         @ context in
796       dom
797       @ List.flatten (
798          List.map
799           (fun (_,_,ty,cl) ->
800             domain_of_term context ty
801             @ List.flatten (
802                List.map
803                 (fun (_,ty) -> domain_of_term context_w_types ty) cl))
804                 tyl)
805    | CicNotationPt.Record (params,var,ty,fields) ->
806       let context, dom = 
807        List.fold_left
808         (fun (context, dom) (var, ty) ->
809           let context' = CicNotationUtil.cic_name_of_name var :: context in
810           match ty with
811              None -> context', dom
812            | Some ty -> context', dom @ domain_of_term context ty
813         ) ([], []) params in
814       let context_w_types = Cic.Name var :: context in
815       dom
816       @ domain_of_term context ty
817       @ snd
818          (List.fold_left
819           (fun (context,res) (name,ty,_,_) ->
820             Cic.Name name::context, res @ domain_of_term context ty
821           ) (context_w_types,[]) fields)
822
823 let domain_of_obj ~context obj = 
824  uniq_domain (domain_of_obj ~context obj)
825
826   (* dom1 \ dom2 *)
827 let domain_diff dom1 dom2 =
828 (* let domain_diff = Domain.diff *)
829   let is_in_dom2 elt =
830     List.exists
831      (function
832        | Symbol (symb, 0) ->
833           (match elt with
834               Symbol (symb',_) when symb = symb' -> true
835             | _ -> false)
836        | Num i ->
837           (match elt with
838               Num _ -> true
839             | _ -> false)
840        | item -> elt = item
841      ) dom2
842   in
843    let rec aux =
844     function
845        [] -> []
846      | Node (_,elt,l)::tl when is_in_dom2 elt -> aux (l @ tl)
847      | Node (loc,elt,l)::tl -> Node (loc,elt,aux l)::(aux tl)
848    in
849     aux dom1
850
851 module type Disambiguator =
852 sig
853   val disambiguate_term :
854     ?fresh_instances:bool ->
855     dbd:HSql.dbd ->
856     context:Cic.context ->
857     metasenv:Cic.metasenv ->
858     ?initial_ugraph:CicUniv.universe_graph -> 
859     aliases:DisambiguateTypes.environment ->(* previous interpretation status *)
860     universe:DisambiguateTypes.multiple_environment option ->
861     CicNotationPt.term disambiguator_input ->
862     ((DisambiguateTypes.domain_item * DisambiguateTypes.codomain_item) list *
863      Cic.metasenv *                  (* new metasenv *)
864      Cic.term*
865      CicUniv.universe_graph) list *  (* disambiguated term *)
866     bool
867
868   val disambiguate_obj :
869     ?fresh_instances:bool ->
870     dbd:HSql.dbd ->
871     aliases:DisambiguateTypes.environment ->(* previous interpretation status *)
872     universe:DisambiguateTypes.multiple_environment option ->
873     uri:UriManager.uri option ->     (* required only for inductive types *)
874     CicNotationPt.term CicNotationPt.obj disambiguator_input ->
875     ((DisambiguateTypes.domain_item * DisambiguateTypes.codomain_item) list *
876      Cic.metasenv *                  (* new metasenv *)
877      Cic.obj *
878      CicUniv.universe_graph) list *  (* disambiguated obj *)
879     bool
880 end
881
882 module Make (C: Callbacks) =
883   struct
884     let choices_of_id dbd id =
885       let uris = Whelp.locate ~dbd id in
886       let uris =
887        match uris with
888         | [] ->
889            (match 
890              (C.input_or_locate_uri 
891                ~title:("URI matching \"" ^ id ^ "\" unknown.") ~id ()) 
892            with
893            | None -> []
894            | Some uri -> [uri])
895         | [uri] -> [uri]
896         | _ ->
897             C.interactive_user_uri_choice ~selection_mode:`MULTIPLE
898              ~ok:"Try selected." ~enable_button_for_non_vars:true
899              ~title:"Ambiguous input." ~id
900              ~msg: ("Ambiguous input \"" ^ id ^
901                 "\". Please, choose one or more interpretations:")
902              uris
903       in
904       List.map
905         (fun uri ->
906           (UriManager.string_of_uri uri,
907            let term =
908              try
909                CicUtil.term_of_uri uri
910              with exn ->
911                debug_print (lazy (UriManager.string_of_uri uri));
912                debug_print (lazy (Printexc.to_string exn));
913                assert false
914             in
915            fun _ _ _ -> term))
916         uris
917
918 let refine_profiler = HExtlib.profile "disambiguate_thing.refine_thing"
919
920     let disambiguate_thing ~dbd ~context ~metasenv
921       ?(initial_ugraph = CicUniv.empty_ugraph) ~aliases ~universe
922       ~uri ~pp_thing ~domain_of_thing ~interpretate_thing ~refine_thing 
923       (thing_txt,thing_txt_prefix_len,thing)
924     =
925       debug_print (lazy "DISAMBIGUATE INPUT");
926       let disambiguate_context =  (* cic context -> disambiguate context *)
927         List.map
928           (function None -> Cic.Anonymous | Some (name, _) -> name)
929           context
930       in
931       debug_print (lazy ("TERM IS: " ^ (pp_thing thing)));
932       let thing_dom = domain_of_thing ~context:disambiguate_context thing in
933       debug_print
934        (lazy (sprintf "DISAMBIGUATION DOMAIN: %s"(string_of_domain thing_dom)));
935 (*
936       debug_print (lazy (sprintf "DISAMBIGUATION ENVIRONMENT: %s"
937         (DisambiguatePp.pp_environment aliases)));
938       debug_print (lazy (sprintf "DISAMBIGUATION UNIVERSE: %s"
939         (match universe with None -> "None" | Some _ -> "Some _")));
940 *)
941       let current_dom =
942         Environment.fold (fun item _ dom -> item :: dom) aliases [] in
943       let todo_dom = domain_diff thing_dom current_dom in
944       debug_print
945        (lazy (sprintf "DISAMBIGUATION DOMAIN AFTER DIFF: %s"(string_of_domain todo_dom)));
946       (* (2) lookup function for any item (Id/Symbol/Num) *)
947       let lookup_choices =
948         fun item ->
949           let choices =
950             let lookup_in_library () =
951               match item with
952               | Id id -> choices_of_id dbd id
953               | Symbol (symb, _) ->
954                  (try
955                    List.map DisambiguateChoices.mk_choice
956                     (TermAcicContent.lookup_interpretations symb)
957                   with
958                    TermAcicContent.Interpretation_not_found -> [])
959               | Num instance ->
960                   DisambiguateChoices.lookup_num_choices ()
961             in
962             match universe with
963             | None -> lookup_in_library ()
964             | Some e ->
965                 (try
966                   let item =
967                     match item with
968                     | Symbol (symb, _) -> Symbol (symb, 0)
969                     | item -> item
970                   in
971                   Environment.find item e
972                 with Not_found -> lookup_in_library ())
973           in
974           choices
975       in
976 (*
977       (* <benchmark> *)
978       let _ =
979         if benchmark then begin
980           let per_item_choices =
981             List.map
982               (fun dom_item ->
983                 try
984                   let len = List.length (lookup_choices dom_item) in
985                   debug_print (lazy (sprintf "BENCHMARK %s: %d"
986                     (string_of_domain_item dom_item) len));
987                   len
988                 with No_choices _ -> 0)
989               thing_dom
990           in
991           max_refinements := List.fold_left ( * ) 1 per_item_choices;
992           actual_refinements := 0;
993           domain_size := List.length thing_dom;
994           choices_avg :=
995             (float_of_int !max_refinements) ** (1. /. float_of_int !domain_size)
996         end
997       in
998       (* </benchmark> *)
999 *)
1000
1001       (* (3) test an interpretation filling with meta uninterpreted identifiers
1002        *)
1003       let test_env aliases todo_dom ugraph = 
1004         let rec aux env = function
1005           | [] -> env
1006           | Node (_, item, l) :: tl ->
1007               let env =
1008                 Environment.add item
1009                  ("Implicit",
1010                    (match item with
1011                       | Id _ | Num _ ->
1012                           (fun _ _ _ -> Cic.Implicit (Some `Closed))
1013                       | Symbol _ -> (fun _ _ _ -> Cic.Implicit None)))
1014                  env in
1015               aux (aux env l) tl in
1016         let filled_env = aux aliases todo_dom in
1017         try
1018           let localization_tbl = Cic.CicHash.create 503 in
1019           let cic_thing =
1020             interpretate_thing ~context:disambiguate_context ~env:filled_env
1021              ~uri ~is_path:false thing ~localization_tbl
1022           in
1023 let foo () =
1024           let k,ugraph1 =
1025            refine_thing metasenv context uri cic_thing ugraph ~localization_tbl
1026           in
1027             (k , ugraph1 )
1028 in refine_profiler.HExtlib.profile foo ()
1029         with
1030         | Try_again msg -> Uncertain (None,msg), ugraph
1031         | Invalid_choice (loc,msg) -> Ko (loc,msg), ugraph
1032       in
1033       (* (4) build all possible interpretations *)
1034       let (@@) (l1,l2,l3) (l1',l2',l3') = l1@l1', l2@l2', l3@l3' in
1035       (* aux returns triples Ok/Uncertain/Ko *)
1036       (* rem_dom is the concatenation of all the remainin domains *)
1037       let rec aux aliases diff lookup_in_todo_dom todo_dom rem_dom base_univ =
1038         debug_print (lazy ("ZZZ: " ^ string_of_domain todo_dom));
1039         match todo_dom with
1040         | [] ->
1041             assert (lookup_in_todo_dom = None);
1042             (match test_env aliases rem_dom base_univ with
1043             | Ok (thing, metasenv),new_univ -> 
1044                [ aliases, diff, metasenv, thing, new_univ ], [], []
1045             | Ko (loc,msg),_ -> [],[],[aliases,diff,loc,msg,true]
1046             | Uncertain (loc,msg),new_univ ->
1047                [],[aliases,diff,loc,msg,new_univ],[])
1048         | Node (locs,item,inner_dom) :: remaining_dom ->
1049             debug_print (lazy (sprintf "CHOOSED ITEM: %s"
1050              (string_of_domain_item item)));
1051             let choices =
1052              match lookup_in_todo_dom with
1053                 None -> lookup_choices item
1054               | Some choices -> choices in
1055             match choices with
1056                [] ->
1057                 [], [],
1058                  [aliases, diff, Some (List.hd locs),
1059                   lazy ("No choices for " ^ string_of_domain_item item),
1060                   true]
1061 (*
1062              | [codomain_item] ->
1063                  (* just one choice. We perform a one-step look-up and
1064                     if the next set of choices is also a singleton we
1065                     skip this refinement step *)
1066                  debug_print(lazy (sprintf "%s CHOSEN" (fst codomain_item)));
1067                  let new_env = Environment.add item codomain_item aliases in
1068                  let new_diff = (item,codomain_item)::diff in
1069                  let lookup_in_todo_dom,next_choice_is_single =
1070                   match remaining_dom with
1071                      [] -> None,false
1072                    | (_,he)::_ ->
1073                       let choices = lookup_choices he in
1074                        Some choices,List.length choices = 1
1075                  in
1076                   if next_choice_is_single then
1077                    aux new_env new_diff lookup_in_todo_dom remaining_dom
1078                     base_univ
1079                   else
1080                     (match test_env new_env remaining_dom base_univ with
1081                     | Ok (thing, metasenv),new_univ ->
1082                         (match remaining_dom with
1083                         | [] ->
1084                            [ new_env, new_diff, metasenv, thing, new_univ ], []
1085                         | _ ->
1086                            aux new_env new_diff lookup_in_todo_dom
1087                             remaining_dom new_univ)
1088                     | Uncertain (loc,msg),new_univ ->
1089                         (match remaining_dom with
1090                         | [] -> [], [new_env,new_diff,loc,msg,true]
1091                         | _ ->
1092                            aux new_env new_diff lookup_in_todo_dom
1093                             remaining_dom new_univ)
1094                     | Ko (loc,msg),_ -> [], [new_env,new_diff,loc,msg,true])
1095 *)
1096              | _::_ ->
1097                  let mark_not_significant failures =
1098                    List.map
1099                     (fun (env, diff, loc, msg, _b) ->
1100                       env, diff, loc, msg, false)
1101                     failures in
1102                  let classify_errors ((ok_l,uncertain_l,error_l) as outcome) =
1103                   if ok_l <> [] || uncertain_l <> [] then
1104                    ok_l,uncertain_l,mark_not_significant error_l
1105                   else
1106                    outcome in
1107                let rec filter univ = function 
1108                 | [] -> [],[],[]
1109                 | codomain_item :: tl ->
1110                     debug_print(lazy (sprintf "%s CHOSEN" (fst codomain_item)));
1111                     let new_env = Environment.add item codomain_item aliases in
1112                     let new_diff = (item,codomain_item)::diff in
1113                     (match
1114                       test_env new_env (inner_dom@remaining_dom@rem_dom) univ
1115                      with
1116                     | Ok (thing, metasenv),new_univ ->
1117                         let res = 
1118                           (match inner_dom with
1119                           | [] ->
1120                              [new_env,new_diff,metasenv,thing,new_univ], [], []
1121                           | _ ->
1122                              aux new_env new_diff None inner_dom
1123                               (remaining_dom@rem_dom) new_univ
1124                           ) 
1125                         in
1126                          res @@ filter univ tl
1127                     | Uncertain (loc,msg),new_univ ->
1128                         let res =
1129                           (match inner_dom with
1130                           | [] -> [],[new_env,new_diff,loc,msg,new_univ],[]
1131                           | _ ->
1132                              aux new_env new_diff None inner_dom
1133                               (remaining_dom@rem_dom) new_univ
1134                           )
1135                         in
1136                          res @@ filter univ tl
1137                     | Ko (loc,msg),_ ->
1138                         let res = [],[],[new_env,new_diff,loc,msg,true] in
1139                          res @@ filter univ tl)
1140                in
1141                 let ok_l,uncertain_l,error_l =
1142                  classify_errors (filter base_univ choices)
1143                 in
1144                  let res_after_ok_l =
1145                   List.fold_right
1146                    (fun (env,diff,_,_,univ) res ->
1147                      aux env diff None remaining_dom rem_dom univ @@ res
1148                    ) ok_l ([],[],error_l)
1149                 in
1150                  List.fold_right
1151                   (fun (env,diff,_,_,univ) res ->
1152                     aux env diff None remaining_dom rem_dom univ @@ res
1153                   ) uncertain_l res_after_ok_l
1154       in
1155       let aux' aliases diff lookup_in_todo_dom todo_dom base_univ =
1156        match test_env aliases todo_dom base_univ with
1157         | Ok _,_
1158         | Uncertain _,_ ->
1159            aux aliases diff lookup_in_todo_dom todo_dom [] base_univ
1160         | Ko (loc,msg),_ -> [],[],[aliases,diff,loc,msg,true] in
1161       let base_univ = initial_ugraph in
1162       try
1163         let res =
1164          match aux' aliases [] None todo_dom base_univ with
1165          | [],uncertain,errors ->
1166             let errors =
1167              List.map
1168               (fun (env,diff,loc,msg,_) -> (env,diff,loc,msg,true)
1169               ) uncertain @ errors
1170             in
1171             let errors =
1172              List.map
1173               (fun (env,diff,loc,msg,significant) ->
1174                 let env' =
1175                  filter_map_domain
1176                    (fun locs domain_item ->
1177                      try
1178                       let description =
1179                        fst (Environment.find domain_item env)
1180                       in
1181                        Some (locs,descr_of_domain_item domain_item,description)
1182                      with
1183                       Not_found -> None)
1184                    thing_dom
1185                 in
1186                  env',diff,loc,msg,significant
1187               ) errors
1188             in
1189              raise (NoWellTypedInterpretation (0,errors))
1190          | [_,diff,metasenv,t,ugraph],_,_ ->
1191              debug_print (lazy "SINGLE INTERPRETATION");
1192              [diff,metasenv,t,ugraph], false
1193          | l,_,_ ->
1194              debug_print 
1195                (lazy (sprintf "MANY INTERPRETATIONS (%d)" (List.length l)));
1196              let choices =
1197                List.map
1198                  (fun (env, _, _, _, _) ->
1199                    map_domain
1200                      (fun locs domain_item ->
1201                        let description =
1202                          fst (Environment.find domain_item env)
1203                        in
1204                        locs,descr_of_domain_item domain_item, description)
1205                      thing_dom)
1206                  l
1207              in
1208              let choosed = 
1209                C.interactive_interpretation_choice 
1210                  thing_txt thing_txt_prefix_len choices 
1211              in
1212              (List.map (fun n->let _,d,m,t,u= List.nth l n in d,m,t,u) choosed),
1213               true
1214         in
1215          res
1216      with
1217       CicEnvironment.CircularDependency s -> 
1218         failwith "Disambiguate: circular dependency"
1219
1220     let disambiguate_term ?(fresh_instances=false) ~dbd ~context ~metasenv
1221       ?(initial_ugraph = CicUniv.empty_ugraph) ~aliases ~universe 
1222       (text,prefix_len,term)
1223     =
1224       let term =
1225         if fresh_instances then CicNotationUtil.freshen_term term else term
1226       in
1227       disambiguate_thing ~dbd ~context ~metasenv ~initial_ugraph ~aliases
1228         ~universe ~uri:None ~pp_thing:CicNotationPp.pp_term
1229         ~domain_of_thing:domain_of_term
1230         ~interpretate_thing:(interpretate_term (?create_dummy_ids:None))
1231         ~refine_thing:refine_term (text,prefix_len,term)
1232
1233     let disambiguate_obj ?(fresh_instances=false) ~dbd ~aliases ~universe ~uri
1234      (text,prefix_len,obj)
1235     =
1236       let obj =
1237         if fresh_instances then CicNotationUtil.freshen_obj obj else obj
1238       in
1239       disambiguate_thing ~dbd ~context:[] ~metasenv:[] ~aliases ~universe ~uri
1240         ~pp_thing:(CicNotationPp.pp_obj CicNotationPp.pp_term) ~domain_of_thing:domain_of_obj
1241         ~interpretate_thing:interpretate_obj ~refine_thing:refine_obj
1242         (text,prefix_len,obj)
1243   end
1244