1 (* Copyright (C) 2004, HELM Team.
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.
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.
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.
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,
22 * For details, see the HELM World-Wide-Web page,
23 * http://helm.cs.unibo.it/
30 open DisambiguateTypes
32 module Ast = NotationPt
34 exception NoWellTypedInterpretation of
36 ((Stdpp.location list * string * string) list *
37 (DisambiguateTypes.domain_item * string) list *
38 (Stdpp.location * string) Lazy.t * bool) list
39 exception PathNotWellFormed
41 (** raised when an environment is not enough informative to decide *)
42 exception Try_again of string Lazy.t
44 type ('alias,'term) aliases =
45 bool * 'term DisambiguateTypes.codomain_item DisambiguateTypes.Environment.t
46 type 'a disambiguator_input = string * int * 'a
48 type domain = domain_tree list
49 and domain_tree = Node of Stdpp.location list * domain_item * domain
52 let mono_uris_callback ~selection_mode ?ok
53 ?(enable_button_for_non_vars = true) ~title ~msg ~id =
54 if Helm_registry.get_opt_default Helm_registry.get_bool ~default:true
55 "matita.auto_disambiguation"
61 let mono_interp_callback _ _ _ = assert false
62 let mono_disamb_callback _ = assert false
64 let _choose_uris_callback = ref mono_uris_callback
65 let _choose_interp_callback = ref mono_interp_callback
66 let _choose_disamb_callback = ref mono_disamb_callback
67 let set_choose_uris_callback f = _choose_uris_callback := f
68 let set_choose_interp_callback f = _choose_interp_callback := f
69 let set_choose_disamb_callback f = _choose_disamb_callback := f
71 let interactive_user_uri_choice = !_choose_uris_callback
72 let interactive_interpretation_choice interp = !_choose_interp_callback interp
73 let interactive_ast_choice interp = !_choose_disamb_callback interp
76 let input_or_locate_uri ~(title:string) ?id () = None
77 (* Zack: I try to avoid using this callback. I therefore assume that
78 * the presence of an identifier that can't be resolved via "locate"
79 * query is a syntax error *)
82 let rec string_of_domain =
85 | Node (_,domain_item,l)::tl ->
86 DisambiguateTypes.string_of_domain_item domain_item ^
87 " [ " ^ string_of_domain l ^ " ] " ^ string_of_domain tl
89 let rec filter_map_domain f =
92 | Node (locs,domain_item,l)::tl ->
93 match f locs domain_item with
94 None -> filter_map_domain f l @ filter_map_domain f tl
95 | Some res -> res :: filter_map_domain f l @ filter_map_domain f tl
97 let rec map_domain f =
100 | Node (locs,domain_item,l)::tl ->
101 f locs domain_item :: map_domain f l @ map_domain f tl
103 let uniq_domain dom =
107 | Node (locs,domain_item,l)::tl ->
108 if List.mem domain_item seen then
109 let seen,l = aux seen l in
110 let seen,tl = aux seen tl in
113 let seen,l = aux (domain_item::seen) l in
114 let seen,tl = aux seen tl in
115 seen, Node (locs,domain_item,l)::tl
120 let debug_print s = if debug then prerr_endline (Lazy.force s) else ()
123 (** print benchmark information *)
125 let max_refinements = ref 0 (* benchmarking is not thread safe *)
126 let actual_refinements = ref 0
127 let domain_size = ref 0
128 let choices_avg = ref 0.
131 type ('term,'metasenv,'subst,'graph) test_result =
132 | Ok of 'term * 'metasenv * 'subst * 'graph
133 | Ko of (Stdpp.location * string) Lazy.t
134 | Uncertain of (Stdpp.location * string) Lazy.t
136 let resolve ~env ~universe ~mk_choice item interpr arg =
137 (* let _ = (mk_choice : (GrafiteAst.alias_spec -> 'b
138 DisambiguateTypes.codomain_item)) in *)
142 | None -> InterprEnv.find item env
145 (* one, and only one interpretation is returned (or Not_found) *)
146 (*if (List.length interpr <> 1)
147 then (let strinterpr =
148 String.concat ", " (List.map GrafiteAst.description_of_alias interpr) in
149 prerr_endline (Printf.sprintf "choices for %s: %s"
150 (DisambiguateTypes.string_of_domain_item item) strinterpr);
153 let interpr = List.hd interpr in*)
154 match snd (mk_choice interpr), arg with
155 `Num_interp f, `Num_arg n -> f n
156 | `Sym_interp f, `Args l -> f l
157 | `Sym_interp f, `Num_arg n -> (* Implicit number! *) f []
158 | _,_ -> assert false
160 failwith (": InterprEnv.find failed")
162 (* TODO move it to Cic *)
163 let find_in_context name context =
164 let rec aux acc = function
165 | [] -> raise Not_found
166 | Some hd :: tl when hd = name -> acc
167 | _ :: tl -> aux (acc + 1) tl
173 | Ast.Ident (n, _) -> Some n
177 (* XXX: assuming the domain is composed of uninterpreted items only *)
178 let rec domain_of_term ?(loc = HExtlib.dummy_floc) ~context = function
179 | Ast.AttributedTerm (`Loc loc, term) ->
180 domain_of_term ~loc ~context term
181 | Ast.AttributedTerm (_, term) ->
182 domain_of_term ~loc ~context term
183 | Ast.Symbol (name, attr) ->
185 | None -> [ Node ([loc], Symbol name, []) ]
187 (* to be kept in sync with Ast.Appl (Ast.Symbol ...) *)
188 | Ast.Appl (Ast.Symbol (name, None) as hd :: args)
189 | Ast.Appl (Ast.AttributedTerm (_,Ast.Symbol (name,None)) as hd :: args)
193 (fun term acc -> domain_of_term ~loc ~context term @ acc)
197 Ast.AttributedTerm (`Loc loc,_) -> loc
200 [ Node ([loc], Symbol name, args_dom) ]
201 | Ast.Appl (Ast.Ident (id,`Ambiguous) as hd :: args)
202 | Ast.Appl (Ast.AttributedTerm (_,Ast.Ident (id,`Ambiguous)) as hd :: args) ->
205 (fun term acc -> domain_of_term ~loc ~context term @ acc)
209 Ast.AttributedTerm (`Loc loc,_) -> loc
213 (* the next line can raise Not_found *)
214 ignore(find_in_context id context);
217 [ Node ([loc], Id id, args_dom) ] )
220 (fun term acc -> domain_of_term ~loc ~context term @ acc)
222 | Ast.Binder (kind, (var, typ), body) ->
223 let type_dom = domain_of_term_option ~loc ~context typ in
226 ~context:(string_of_name var :: context) body in
228 | `Exists -> [ Node ([loc], Symbol "exists", (type_dom @ body_dom)) ]
229 | _ -> type_dom @ body_dom)
230 | Ast.Case (term, indty_ident, outtype, branches) ->
231 let term_dom = domain_of_term ~loc ~context term in
232 let outtype_dom = domain_of_term_option ~loc ~context outtype in
233 let rec get_first_constructor = function
235 | (Ast.Pattern (head, Some r, _), _) :: _ -> []
236 (* [ Node ([loc], Id (head,Some (NReference.string_of_reference r)), []) ] *)
237 | (Ast.Pattern (head, None, _), _) :: _ ->
238 [ Node ([loc], Id head, []) ]
239 | _ :: tl -> get_first_constructor tl in
242 Ast.Pattern (head, _, args), term ->
243 let (term_context, args_domain) =
245 (fun (cont, dom) (name, typ) ->
246 (string_of_name name :: cont,
249 | Some typ -> dom @ domain_of_term ~loc ~context:cont typ)))
252 domain_of_term ~loc ~context:term_context term @ args_domain
253 | Ast.Wildcard, term ->
254 domain_of_term ~loc ~context term
257 List.fold_left (fun dom branch -> dom @ do_branch branch) [] branches in
258 (match indty_ident with
259 | None -> get_first_constructor branches
260 | Some (ident, None) -> [ Node ([loc], Id ident , []) ]
261 | Some (ident, Some r) -> [])
262 (* [ Node ([loc], Id (ident,Some (NReference.string_of_reference r)), []) ]) *)
263 @ term_dom @ outtype_dom @ branches_dom
264 | Ast.Cast (term, ty) ->
265 let term_dom = domain_of_term ~loc ~context term in
266 let ty_dom = domain_of_term ~loc ~context ty in
268 | Ast.LetIn ((var, typ), body, where) ->
269 let body_dom = domain_of_term ~loc ~context body in
270 let type_dom = domain_of_term_option ~loc ~context typ in
272 domain_of_term ~loc ~context:(string_of_name var :: context) where in
273 body_dom @ type_dom @ where_dom
274 | Ast.LetRec (kind, defs, where) ->
275 let add_defs context =
277 (fun acc (_, (var, _), _, _) -> string_of_name var :: acc
279 let where_dom = domain_of_term ~loc ~context:(add_defs context) where in
282 (fun dom (params, (_, typ), body, _) ->
286 (fun acc (var,_) -> string_of_name var :: acc)
292 (fun (context,res) (var,ty) ->
293 string_of_name var :: context,
294 domain_of_term_option ~loc ~context ty @ res)
295 (add_defs context,[]) params))
297 @ domain_of_term_option ~loc ~context:context' typ
298 @ domain_of_term ~loc ~context:context' body
302 | Ast.Ident (name, x) ->
308 (* the next line can raise Not_found *)
309 ignore(find_in_context name context); []
313 | None -> [ Node ([loc], Id name, []) ]
317 (fun dom (_, term) ->
318 let dom' = domain_of_term ~loc ~context term in
321 [ Node ([loc], Id name, terms) ]))*)
322 [ Node ([loc], Id name, []) ])
325 | Ast.Implicit _ -> []
326 | Ast.Num (num, i) -> [ Node ([loc], Num, []) ]
327 | Ast.Meta (index, local_context) ->
329 (fun dom term -> dom @ domain_of_term_option ~loc ~context term)
336 | Ast.Variable _ -> assert false
338 and domain_of_term_option ~loc ~context = function
340 | Some t -> domain_of_term ~loc ~context t
342 let domain_of_term ~context term =
343 uniq_domain (domain_of_term ~context term)
345 let domain_of_obj ~context ast =
346 assert (context = []);
348 | Ast.Theorem (_,_,ty,bo,_) ->
352 | Some bo -> domain_of_term [] bo)
353 | Ast.Inductive (params,tyl) ->
356 (fun (context, dom) (var, ty) ->
357 let context' = string_of_name var :: context in
359 None -> context', dom
360 | Some ty -> context', dom @ domain_of_term context ty
362 let context_w_types =
363 List.rev_map (fun (var, _, _, _) -> Some var) tyl @ context in
368 domain_of_term context ty
371 (fun (_,ty) -> domain_of_term context_w_types ty) cl))
373 | Ast.Record (params,var,ty,fields) ->
376 (fun (context, dom) (var, ty) ->
377 let context' = string_of_name var :: context in
379 None -> context', dom
380 | Some ty -> context', dom @ domain_of_term context ty
382 let context_w_types = Some var :: context in
384 @ domain_of_term context ty
387 (fun (context,res) (name,ty,_,_) ->
388 Some name::context, res @ domain_of_term context ty
389 ) (context_w_types,[]) fields)
391 let domain_of_obj ~context obj =
392 uniq_domain (domain_of_obj ~context obj)
395 (* XXX: possibly should take into account locs? *)
396 let domain_diff dom1 dom2 =
397 (* let domain_diff = Domain.diff *)
403 Symbol symb' when symb = symb' -> true
415 | Node (_,elt,l)::tl when is_in_dom2 elt -> aux (l @ tl)
416 | Node (loc,elt,l)::tl -> Node (loc,elt,aux l)::(aux tl)
420 let refine_profiler = HExtlib.profile "disambiguate_thing.refine_thing"
422 (* generic function lifting splitting from type T to type (T list) *)
423 let rec list_split item_split ctx pre post =
427 (item_split (fun v1 -> ctx (pre@v1::post')) x)@
428 list_split item_split ctx (pre@[x]) post'
431 (* splits a 'term capture_variable *)
432 let var_split ctx = function
434 | (v,Some ty) -> [(fun x -> ctx (v,Some x)),ty]
437 let ity_split ctx (n,isind,ty,cl) =
438 [(fun x -> ctx (n,isind,x,cl)),ty]@
439 list_split (fun ctx0 (v,ty) -> [(fun x -> ctx0 (v,x)),ty])
440 (fun x -> ctx (n,isind,ty,x)) [] cl
443 let field_split ctx (n,ty,b,m) =
444 [(fun x -> ctx (n,x,b,m)),ty]
447 (* splits a defn. in a mutual LetRec block *)
448 let letrecaux_split ctx (args,f,bo,n) =
449 list_split var_split (fun x -> ctx (x,f,bo,n)) [] args@
450 var_split (fun x -> ctx (args,x,bo,n)) f@
451 [(fun x -> ctx (args,f,x,n)),bo]
454 let mk_ident s = function
455 | None -> Ast.Ident (s,`Ambiguous)
456 | Some u -> Ast.Ident (s,`Uri (NReference.string_of_reference u))
459 (* splits a pattern (for case analysis) *)
460 let pattern_split ctx = function
462 | Ast.Pattern (s,href,pl) ->
463 let rec auxpatt pre = function
465 | (x,Some y as x')::post' ->
466 ((fun v -> ctx (Ast.Pattern (s,href,pre@(x,Some v)::post'))),y)
467 ::auxpatt (pre@[x']) post'
468 | (x,None as x')::post' -> auxpatt (pre@[x']) post'
473 | Ast.Ident (id,`Ambiguous) -> id, None
474 | Ast.Ident (id,`Uri u) -> id, Some u
477 let href0 = HExtlib.map_option NReference.reference_of_string href0
478 in ctx (Ast.Pattern (id0,href0,pl))),
479 mk_ident s href)::auxpatt [] pl
482 (* this function is used to get the children of a given node, together with
484 * contexts are expressed in the form of functions Ast -> Ast *)
485 (* split : ('term -> 'a) -> 'term -> (('term -> 'a) * 'term) list *)
486 let rec split ctx = function
487 | Ast.AttributedTerm (attr,t) ->
488 [(fun x -> ctx (Ast.AttributedTerm(attr,x))),t]
489 | Ast.Appl tl -> list_split (*split*) (fun ctx0 t0 -> [ctx0,t0]) (fun x -> ctx (Ast.Appl x)) [] tl
490 | Ast.Binder (k,((n,None) as n'),body) ->
491 [ (fun v -> ctx (Ast.Binder (k,n',v))),body]
492 | Ast.Binder (k,((n,Some ty) as n'),body) ->
493 [(fun v -> ctx (Ast.Binder (k,(n,Some v),body))), ty
494 ;(fun v -> ctx (Ast.Binder (k,n',v))),body]
495 | Ast.Case (t,ity,outty,pl) ->
496 let outty_split = match outty with
498 | Some u -> [(fun x -> ctx (Ast.Case (t,ity,Some x,pl))),u]
500 ((fun x -> ctx (Ast.Case (x,ity,outty,pl))),t)::
501 outty_split@list_split
503 ((fun y -> ctx0 (p,y)),x)::pattern_split
504 (fun y -> ctx0 (y,x)) p) (fun x -> ctx (Ast.Case(t,ity,outty,x)))
506 | Ast.Cast (u,v) -> [ (fun x -> ctx (Ast.Cast (x,v))),u
507 ; (fun x -> ctx (Ast.Cast (u,x))),v ]
508 | Ast.LetIn ((n,None) as n',u,v) ->
509 [ (fun x -> ctx (Ast.LetIn (n',x,v))), u
510 ; (fun x -> ctx (Ast.LetIn (n',u,x))), v ]
511 | Ast.LetIn ((n,Some t) as n',u,v) ->
512 [ (fun x -> ctx (Ast.LetIn ((n,Some x),u,v))), t
513 ; (fun x -> ctx (Ast.LetIn (n',x,v))), u
514 ; (fun x -> ctx (Ast.LetIn (n',u,x))), v ]
515 | Ast.LetRec (k,funs,where) -> (* we do not use where any more?? *)
516 list_split letrecaux_split (fun x -> ctx (Ast.LetRec(k,x,where))) [] funs
517 | _ -> [] (* leaves *)
521 (* top_split : 'a -> ((term -> 'a) * term) list
522 * returns all the possible top-level (ctx,t) for its input *)
523 let bfvisit ~pp_term top_split test t =
524 let rec aux = function
526 | (ctx0,t0 as hd)::tl ->
527 (* prerr_endline ("ok! length tl = " ^ string_of_int (List.length tl)); *)
528 debug_print (lazy ("visiting t0 = " ^ pp_term t0));
529 if test t0 then (debug_print (lazy "t0 is ambiguous"); Some hd)
532 (prerr_endline ("splitting not ambiguous t0:");
533 let t0' = split ctx0 t0 in
534 List.iter (fun (ctx',t') -> prerr_endline ("-- subnode " ^
537 let t0' = split ctx0 t0 in
539 (* in aux [(fun x -> x),t] *)
543 let obj_split (o:Ast.term Ast.obj) = match o with
544 | Ast.Inductive (ls,itl) ->
545 list_split var_split (fun x -> Ast.Inductive (x,itl)) [] ls@
546 list_split ity_split (fun x -> Ast.Inductive (ls,x)) [] itl
547 | Ast.Theorem (flav,n,ty,None,p) ->
548 [(fun x -> Ast.Theorem (flav,n,x,None,p)), ty]
549 | Ast.Theorem (flav,n,ty,(Some bo as bo'),p) ->
550 [(fun x -> Ast.Theorem (flav,n,x,bo',p)), ty
551 ;(fun x -> Ast.Theorem (flav,n,ty,Some x,p)), bo]
552 | Ast.Record (ls,n,ty,fl) ->
553 list_split var_split (fun x -> Ast.Record (x,n,ty,fl)) [] ls@
554 [(fun x -> Ast.Record (ls,n,x,fl)),ty]@
555 list_split field_split (fun x -> Ast.Record (ls,n,ty,x)) [] fl
558 let bfvisit_obj = bfvisit obj_split;;
560 let bfvisit = bfvisit (fun t -> [(fun x -> x),t]) ;;
562 let domain_item_of_ast = function
563 | Ast.Ident (id,_) -> DisambiguateTypes.Id id
564 | Ast.Symbol (sym,_) -> DisambiguateTypes.Symbol sym
565 | Ast.Num (n,_) -> DisambiguateTypes.Num
566 | Ast.Case(_,Some (ityname,_),_,_) -> DisambiguateTypes.Id ityname
570 let ast_of_alias_spec t alias = match (t,alias) with
571 | Ast.Ident _, GrafiteAst.Ident_alias (id,uri) -> Ast.Ident(id,`Uri uri)
572 | Ast.Case (t,_,oty,pl), GrafiteAst.Ident_alias (id,uri) ->
573 Ast.Case (t,Some (id,Some (NReference.reference_of_string uri)),oty,pl)
574 | _, GrafiteAst.Symbol_alias (sym,uri,desc) -> Ast.Symbol (sym,Some (uri,desc))
575 | Ast.Num(m,_), GrafiteAst.Number_alias (uri,desc) -> Ast.Num(m,Some (uri,desc))
579 let test_interpr ~context ~metasenv ~subst ~use_coercions ~expty ~env ~universe ~uri
580 ~interpretate_thing ~refine_thing ~ugraph ~mk_localization_tbl t =
582 let localization_tbl = mk_localization_tbl 503 in
584 interpretate_thing ~context ~env ~universe
585 ~uri ~is_path:false t ~localization_tbl
588 refine_thing metasenv subst context uri
589 ~use_coercions cic_thing expty ugraph ~localization_tbl
590 in match (refine_profiler.HExtlib.profile foo ()) with
592 let _,err = Lazy.force x in
593 debug_print (lazy ("test_interpr error: " ^ err));
597 (*| Try_again msg -> Uncertain (lazy (Stdpp.dummy_loc,Lazy.force msg))
598 | Invalid_choice loc_msg -> Ko loc_msg*)
599 | Invalid_choice _ -> false
603 let rec disambiguate_list
604 ~context ~metasenv ~subst ~use_coercions ~expty ~env ~uri ~interpretate_thing
605 ~refine_thing ~ugraph ~visit ~universe ~mk_localization_tbl ~pp_thing ~pp_term ts =
606 let disambiguate_list =
607 disambiguate_list ~context ~metasenv ~subst ~use_coercions ~expty ~env ~uri
608 ~interpretate_thing ~refine_thing ~ugraph ~visit ~universe
609 ~mk_localization_tbl ~pp_thing ~pp_term
611 let test_interpr = test_interpr ~context ~metasenv ~subst ~use_coercions ~expty
612 ~env ~universe ~uri ~interpretate_thing ~refine_thing ~ugraph ~mk_localization_tbl
614 let find_choices item =
616 | GrafiteAst.Ident_alias (_id,uri) -> uri
617 | GrafiteAst.Symbol_alias (_id,_,desc) -> desc
618 | GrafiteAst.Number_alias (_,desc) -> desc
626 Environment.find item universe
628 debug_print (lazy (Printf.sprintf "choices for %s :\n%s"
629 (d2s item) (String.concat ", " (List.map a2s res))));
633 let get_instances ctx t =
635 let choices = find_choices (domain_item_of_ast t) in
636 List.map (fun t0 -> ctx (ast_of_alias_spec t t0)) choices
644 debug_print (lazy ("disambiguate_list: t0 = " ^ pp_thing t0));
645 let is_ambiguous = function
646 | Ast.Ident (_,`Ambiguous)
648 | Ast.Symbol (_,None) -> true
649 | Ast.Case (_,Some (ity,None),_,_) -> true
653 | Ast.Ident (id,_) -> "ID " ^ id
655 | Ast.Symbol (sym,_) -> "SYM " ^ sym
658 (* get first ambiguous subterm (or return disambiguated term) *)
659 match visit ~pp_term is_ambiguous t0 with
661 debug_print (lazy ("visit -- not ambiguous node:\n" ^ pp_thing t0));
664 debug_print (lazy ("visit -- found ambiguous node: " ^ astpp t ^
665 "\nin " ^ pp_thing (ctx t)));
666 (* get possible instantiations of t *)
667 let instances = get_instances ctx t in
668 debug_print (lazy "-- possible instances:");
670 (fun u0 -> debug_print (lazy ("-- instance: " ^ (pp_thing u0)))) instances;
671 (* perforate ambiguous subterms and test refinement *)
672 debug_print (lazy "-- survivors:");
673 let survivors = List.filter test_interpr instances in
675 (fun u0 -> debug_print (lazy ("-- survivor: " ^ (pp_thing u0)))) survivors;
676 disambiguate_list (survivors@tl)
679 let disambiguate_thing
680 ~context ~metasenv ~subst ~use_coercions
681 ~string_context_of_context
682 ~initial_ugraph:base_univ ~expty
683 ~mk_implicit ~description_of_alias ~fix_instance
684 ~aliases ~universe ~lookup_in_library
685 ~uri ~pp_thing ~pp_term ~domain_of_thing ~interpretate_thing ~refine_thing
686 ~visit ~mk_localization_tbl
687 (thing_txt,thing_txt_prefix_len,thing)
691 let test_interpr = test_interpr ~context ~metasenv ~subst ~use_coercions ~expty
692 ~env ~universe ~uri ~interpretate_thing ~refine_thing ~ugraph:base_univ ~mk_localization_tbl
696 match disambiguate_list ~mk_localization_tbl ~context ~metasenv ~subst
697 ~interpretate_thing ~refine_thing ~ugraph:base_univ ~visit
698 ~use_coercions ~expty ~uri ~env ~universe ~pp_thing
701 | Some (t,tl') -> t::aux tl'
705 let localization_tbl = mk_localization_tbl 503 in
706 debug_print (lazy "before interpretate_thing");
708 interpretate_thing ~context ~env ~universe ~uri ~is_path:false t ~localization_tbl
710 debug_print (lazy "after interpretate_thing");
711 match refine_thing metasenv subst context uri ~use_coercions t' expty
712 base_univ ~localization_tbl with
713 | Ok (t',m',s',u') -> t,m',s',t',u'
715 let _,err = Lazy.force x in
716 debug_print (lazy ("refinement uncertain after disambiguation: " ^ err));
720 if not (test_interpr thing) then
721 (debug_print (lazy ("preliminary test fail: " ^ pp_thing thing));
722 raise (NoWellTypedInterpretation (0,[])))
724 let res = aux [thing] in
726 HExtlib.filter_map (fun t ->
729 debug_print (lazy ("can't interpretate/refine " ^ (pp_thing t)));None) res
732 | [] -> raise (NoWellTypedInterpretation (0,[]))
733 (* XXX : the boolean seems not to play a role any longer *)
736 (* let choices = List.map (fun (t,_,_,_,_) -> pp_thing t) res in
737 let user_choice = interactive_ast_choice choices in
738 [ List.nth res user_choice ], true
739 (* let pp_thing (t,_,_,_,_,_) = prerr_endline ("interpretation: " ^ (pp_thing t)) in
740 List.iter pp_thing res; res,true *) *)