]> matita.cs.unibo.it Git - helm.git/blob - matitaB/components/ng_disambiguation/nCicDisambiguate.ml
b34a2ec8b91a65e33d35f868bd22f1be9dbac6d1
[helm.git] / matitaB / components / ng_disambiguation / nCicDisambiguate.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.      
9      \ /   This software is distributed as is, NO WARRANTY.     
10       V_______________________________________________________________ *)
11
12 (* $Id: nCic.ml 9058 2008-10-13 17:42:30Z tassi $ *)
13
14 open Printf
15
16 open DisambiguateTypes
17
18 module Ast = NotationPt
19 module NRef = NReference 
20
21 let debug_print s = prerr_endline (Lazy.force s);;
22 let debug_print _ = ();;
23
24 let cic_name_of_name = function
25   | Ast.Ident (n,_) ->  n
26   | _ -> assert false
27 ;;
28
29 let rec mk_rels howmany from =
30   match howmany with 
31   | 0 -> []
32   | _ -> (NCic.Rel (howmany + from)) :: (mk_rels (howmany-1) from)
33 ;;
34
35 let refine_term (status: #NCicCoercion.status) metasenv subst context uri ~use_coercions term expty _
36  ~localization_tbl
37 =
38   assert (uri=None);
39   debug_print (lazy (sprintf "TEST_INTERPRETATION: %s" 
40     (status#ppterm ~metasenv ~subst ~context term)));
41   try
42     let localise t = 
43       try NCicUntrusted.NCicHash.find localization_tbl t
44       with Not_found -> 
45         prerr_endline ("NOT LOCALISED" ^ status#ppterm ~metasenv ~subst ~context t);
46         (*assert false*) HExtlib.dummy_floc
47     in
48     let metasenv, subst, term, _ = 
49       NCicRefiner.typeof 
50         (status#set_coerc_db 
51           (if use_coercions then status#coerc_db else NCicCoercion.empty_db))
52         metasenv subst context term expty ~localise 
53     in
54      Disambiguate.Ok (term, metasenv, subst, ())
55   with
56   | NCicRefiner.Uncertain loc_msg ->
57       debug_print (lazy ("UNCERTAIN: [" ^ snd (Lazy.force loc_msg) ^ "] " ^ 
58         status#ppterm ~metasenv ~subst ~context term)) ;
59       Disambiguate.Uncertain loc_msg
60   | NCicRefiner.RefineFailure loc_msg ->
61       debug_print (lazy (sprintf "PRUNED:\nterm%s\nmessage:%s"
62         (status#ppterm ~metasenv ~subst ~context term) (snd(Lazy.force loc_msg))));
63       Disambiguate.Ko loc_msg
64 ;;
65
66 let refine_obj status metasenv subst _context _uri ~use_coercions obj _ _ugraph
67  ~localization_tbl 
68 =
69   assert (metasenv=[]);
70   assert (subst=[]);
71   let localise t = 
72     try NCicUntrusted.NCicHash.find localization_tbl t
73     with Not_found -> 
74       (*assert false*)HExtlib.dummy_floc
75   in
76   try
77     let obj =
78       NCicRefiner.typeof_obj
79         (status#set_coerc_db
80            (if use_coercions then status#coerc_db 
81             else NCicCoercion.empty_db))
82         obj ~localise 
83     in
84       Disambiguate.Ok (obj, [], [], ())
85   with
86   | NCicRefiner.Uncertain loc_msg ->
87       debug_print (lazy ("UNCERTAIN: [" ^ snd (Lazy.force loc_msg) ^ "] " ^ 
88         status#ppobj obj)) ;
89       Disambiguate.Uncertain loc_msg
90   | NCicRefiner.RefineFailure loc_msg ->
91       debug_print (lazy (sprintf "PRUNED:\nobj: %s\nmessage: %s"
92         (status#ppobj obj) (snd(Lazy.force loc_msg))));
93       Disambiguate.Ko loc_msg
94 ;;
95   
96
97   (* TODO move it to Cic *)
98 let find_in_context name context =
99   let rec aux acc = function
100     | [] -> raise Not_found
101     | hd :: _ when hd = name -> acc
102     | _ :: tl ->  aux (acc + 1) tl
103   in
104   aux 1 context
105
106 let interpretate_term_and_interpretate_term_option (status: #NCic.status)
107   ?(create_dummy_ids=false) ~obj_context ~mk_choice ~env ~uri ~is_path
108   ~localization_tbl 
109 =
110   (* create_dummy_ids shouldbe used only for interpretating patterns *)
111   assert (uri = None);
112
113   let rec aux ~localize loc context = function
114     | NotationPt.AttributedTerm (`Loc loc, term) ->
115         let res = aux ~localize loc context term in
116         if localize then 
117          NCicUntrusted.NCicHash.add localization_tbl res loc;
118        res
119     | NotationPt.AttributedTerm (_, term) -> aux ~localize loc context term
120     | NotationPt.Appl (NotationPt.Appl inner :: args) ->
121         aux ~localize loc context (NotationPt.Appl (inner @ args))
122     | NotationPt.Appl 
123         (NotationPt.AttributedTerm (att,(NotationPt.Appl inner))::args)->
124         aux ~localize loc context 
125           (NotationPt.AttributedTerm (att,NotationPt.Appl (inner @ args)))
126     | NotationPt.Appl (NotationPt.Symbol (symb, None) :: args) ->
127         NCic.Implicit `Term
128     | NotationPt.Appl (NotationPt.Symbol (symb, i) :: args) ->
129         let cic_args = List.map (aux ~localize loc context) args in
130         Disambiguate.resolve ~mk_choice ~env (Symbol (symb, i)) (`Args cic_args)
131     | NotationPt.Appl terms ->
132        NCic.Appl (List.map (aux ~localize loc context) terms)
133     | NotationPt.Binder (binder_kind, (var, typ), body) ->
134         let cic_type = aux_option ~localize loc context `Type typ in
135         let cic_name = cic_name_of_name var  in
136         let cic_body = aux ~localize loc (cic_name :: context) body in
137         (match binder_kind with
138         | `Lambda -> NCic.Lambda (cic_name, cic_type, cic_body)
139         | `Pi
140         | `Forall -> NCic.Prod (cic_name, cic_type, cic_body)
141         | `Exists -> assert false)
142             (*Disambiguate.resolve ~env ~mk_choice (Symbol ("exists", None))
143               (`Args [ cic_type; NCic.Lambda (cic_name, cic_type, cic_body) ])*)
144     | NotationPt.Case (term, indty_ident, outtype, branches) ->
145         let cic_term = aux ~localize loc context term in
146         let cic_outtype = aux_option ~localize loc context `Term outtype in
147         let do_branch ((_, _, args), term) =
148          let rec do_branch' context = function
149            | [] -> aux ~localize loc context term
150            | (name, typ) :: tl ->
151                let cic_name = cic_name_of_name name in
152                let cic_body = do_branch' (cic_name :: context) tl in
153                let typ =
154                  match typ with
155                  | None -> NCic.Implicit `Type
156                  | Some typ -> aux ~localize loc context typ
157                in
158                NCic.Lambda (cic_name, typ, cic_body)
159          in
160           do_branch' context args
161         in
162         if create_dummy_ids then
163          let branches =
164           List.map
165            (function
166                Ast.Wildcard,term -> ("wildcard",None,[]), term
167              | Ast.Pattern _,_ ->
168                 raise (DisambiguateTypes.Invalid_choice 
169                  (lazy (loc, "Syntax error: the left hand side of a "^
170                    "branch pattern must be \"_\"")))
171            ) branches
172          in
173          (*
174           NCic.MutCase (ref, cic_outtype, cic_term,
175             (List.map do_branch branches))
176           *) ignore branches; assert false (* patterns not implemented yet *)
177         else
178          let indtype_ref =
179           match indty_ident with
180           | Some (_,Some r) -> r
181           | Some (_, None) ->
182               raise (Disambiguate.Try_again 
183                 (lazy "The type of the term to be matched is still unknown"))
184           | None ->
185               let rec fst_constructor =
186                 function
187                    (Ast.Pattern (head, href, _), _) :: _ -> 
188                      head, HExtlib.map_option NReference.string_of_reference href
189                  | (Ast.Wildcard, _) :: tl -> fst_constructor tl
190                  | [] -> raise (Invalid_choice (lazy (loc,"The type "^
191                      "of the term to be matched cannot be determined "^
192                      "because it is an inductive type without constructors "^
193                      "or because all patterns use wildcards")))
194               in
195 (*
196               DisambiguateTypes.Environment.iter
197                   (fun k v ->
198                       prerr_endline
199                         (DisambiguateTypes.string_of_domain_item k ^ " => " ^
200                         description_of_alias v)) env; 
201 *)
202               (match Disambiguate.resolve ~env ~mk_choice
203                 (Id (fst_constructor branches)) (`Args []) with
204               | NCic.Const (NReference.Ref (_,NReference.Con _) as r) -> 
205                    let b,_,_,_,_= NCicEnvironment.get_checked_indtys status r in
206                    NReference.mk_indty b r
207               | NCic.Implicit _ ->
208                  raise (Disambiguate.Try_again 
209                   (lazy "The type of the term to be matched is still unknown"))
210               | t ->
211                 raise (DisambiguateTypes.Invalid_choice 
212                   (lazy (loc, 
213                   "The type of the term to be matched is not (co)inductive: " 
214                   ^ status#ppterm ~metasenv:[] ~subst:[] ~context:[] t))))
215          in
216          let _,leftsno,itl,_,indtyp_no =
217           NCicEnvironment.get_checked_indtys status indtype_ref in
218          let _,_,_,cl =
219           try
220            List.nth itl indtyp_no
221           with _ -> assert false in
222          let rec count_prod t =
223                  match NCicReduction.whd status ~subst:[] [] t with
224                NCic.Prod (_, _, t) -> 1 + (count_prod t)
225              | _ -> 0 
226          in 
227          let rec sort branches cl =
228           match cl with
229              [] ->
230               let rec analyze unused unrecognized useless =
231                function
232                   [] ->
233                    if unrecognized != [] then
234                     raise (DisambiguateTypes.Invalid_choice
235                      (lazy
236                        (loc,"Unrecognized constructors: " ^
237                         String.concat " " unrecognized)))
238                    else if useless > 0 then
239                     raise (DisambiguateTypes.Invalid_choice
240                      (lazy
241                        (loc,"The last " ^ string_of_int useless ^
242                         "case" ^ if useless > 1 then "s are" else " is" ^
243                         " unused")))
244                    else
245                     []
246                 | (Ast.Wildcard,_)::tl when not unused ->
247                     analyze true unrecognized useless tl
248                 | (Ast.Pattern (head,_,_),_)::tl when not unused ->
249                     analyze unused (head::unrecognized) useless tl
250                 | _::tl -> analyze unused unrecognized (useless + 1) tl
251               in
252                analyze false [] 0 branches
253            | (_,name,ty)::cltl ->
254               let rec find_and_remove =
255                function
256                   [] ->
257                    raise
258                     (DisambiguateTypes.Invalid_choice
259                      (lazy (loc, "Missing case: " ^ name)))
260                 | ((Ast.Wildcard, _) as branch :: _) as branches ->
261                     branch, branches
262                 | (Ast.Pattern (name',_,_),_) as branch :: tl
263                    when name = name' ->
264                     branch,tl
265                 | branch::tl ->
266                    let found,rest = find_and_remove tl in
267                     found, branch::rest
268               in
269                let branch,tl = find_and_remove branches in
270                match branch with
271                   Ast.Pattern (name,y,args),term ->
272                    if List.length args = count_prod ty - leftsno then
273                     ((name,y,args),term)::sort tl cltl
274                    else
275                     raise
276                      (DisambiguateTypes.Invalid_choice
277                       (lazy (loc,"Wrong number of arguments for " ^ name)))
278                 | Ast.Wildcard,term ->
279                    let rec mk_lambdas =
280                     function
281                        0 -> term
282                      | n ->
283                         NotationPt.Binder
284                          (`Lambda, (NotationPt.Ident ("_", `Ambiguous), None),
285                            mk_lambdas (n - 1))
286                    in
287                     (("wildcard",None,[]),
288                      mk_lambdas (count_prod ty - leftsno)) :: sort tl cltl
289          in
290           let branches = sort branches cl in
291            NCic.Match (indtype_ref, cic_outtype, cic_term,
292             (List.map do_branch branches))
293     | NotationPt.Cast (t1, t2) ->
294         let cic_t1 = aux ~localize loc context t1 in
295         let cic_t2 = aux ~localize loc context t2 in
296         NCic.LetIn ("_",cic_t2,cic_t1, NCic.Rel 1)
297     | NotationPt.LetIn ((name, typ), def, body) ->
298         let cic_def = aux ~localize loc context def in
299         let cic_name = cic_name_of_name name in
300         let cic_typ =
301           match typ with
302           | None -> NCic.Implicit `Type
303           | Some t -> aux ~localize loc context t
304         in
305         let cic_body = aux ~localize loc (cic_name :: context) body in
306         NCic.LetIn (cic_name, cic_typ, cic_def, cic_body)
307     | NotationPt.LetRec (_kind, _defs, _body) -> NCic.Implicit `Term
308     | NotationPt.Ident _
309     | NotationPt.NRef _ when is_path -> raise Disambiguate.PathNotWellFormed
310     | NotationPt.Ident (name, `Rel) ->
311         (try NCic.Rel (find_in_context name context)
312         with Not_found -> 
313          (try NCic.Const (List.assoc name obj_context)
314           with Not_found -> assert false)) (* bug in initialize_ast *)
315     | NotationPt.Ident (name, `Ambiguous) ->
316          (try NCic.Const (List.assoc name obj_context)
317          with Not_found -> NCic.Implicit `Closed)
318             (* Disambiguate.resolve ~env ~mk_choice (Id (name,None)) (`Args [])) *)
319     | NotationPt.Ident (name, `Uri uri) ->
320        (try
321          NCic.Const (NReference.reference_of_string uri)
322         with NRef.IllFormedReference _ ->
323          NotationPt.fail loc "Ill formed reference")
324     | NotationPt.NRef nref -> NCic.Const nref
325     | NotationPt.NCic t ->  t
326     | NotationPt.Implicit `Vector -> NCic.Implicit `Vector
327     | NotationPt.Implicit `JustOne -> NCic.Implicit `Term
328     | NotationPt.Implicit (`Tagged s) -> NCic.Implicit (`Tagged s)
329     | NotationPt.UserInput -> NCic.Implicit `Hole
330     | NotationPt.Num (num, None) -> NCic.Implicit `Closed
331     | NotationPt.Num (num, i) -> 
332         Disambiguate.resolve ~env ~mk_choice (Num i) (`Num_arg num)
333     | NotationPt.Meta (index, subst) ->
334         let cic_subst =
335          List.map
336           (function None -> assert false| Some t -> aux ~localize loc context t)
337           subst
338         in
339          NCic.Meta (index, (0, NCic.Ctx cic_subst))
340     | NotationPt.Sort `Prop -> NCic.Sort NCic.Prop
341     | NotationPt.Sort `Set -> NCic.Sort (NCic.Type
342        [`Type,NUri.uri_of_string "cic:/matita/pts/Type.univ"])
343     | NotationPt.Sort (`NType s) -> NCic.Sort (NCic.Type
344        [`Type,NUri.uri_of_string ("cic:/matita/pts/Type" ^ s ^ ".univ")])
345     | NotationPt.Sort (`NCProp s) -> NCic.Sort (NCic.Type
346        [`CProp,NUri.uri_of_string ("cic:/matita/pts/Type" ^ s ^ ".univ")])
347     | NotationPt.Symbol (symbol, instance) ->
348         Disambiguate.resolve ~env ~mk_choice 
349          (Symbol (symbol, instance)) (`Args [])
350     | NotationPt.Variable _
351     | NotationPt.Magic _
352     | NotationPt.Layout _
353     | NotationPt.Literal _ -> assert false (* god bless Bologna *)
354   and aux_option ~localize loc context annotation = function
355     | None -> NCic.Implicit annotation
356     | Some (NotationPt.AttributedTerm (`Loc loc, term)) ->
357         let res = aux_option ~localize loc context annotation (Some term) in
358         if localize then 
359           NCicUntrusted.NCicHash.add localization_tbl res loc;
360         res
361     | Some (NotationPt.AttributedTerm (_, term)) ->
362         aux_option ~localize loc context annotation (Some term)
363     | Some NotationPt.Implicit `JustOne -> NCic.Implicit annotation
364     | Some NotationPt.Implicit `Vector -> NCic.Implicit `Vector
365     | Some term -> aux ~localize loc context term
366   in
367    (fun ~context -> aux ~localize:true HExtlib.dummy_floc context),
368    (fun ~context -> aux_option ~localize:true HExtlib.dummy_floc context)
369 ;;
370
371 let interpretate_term status ?(create_dummy_ids=false) ~context ~env ~uri
372  ~is_path ast ~obj_context ~localization_tbl ~mk_choice
373 =
374   let context = List.map fst context in
375   fst 
376     (interpretate_term_and_interpretate_term_option status
377       ~obj_context ~mk_choice ~create_dummy_ids ~env ~uri ~is_path
378       ~localization_tbl)
379     ~context ast
380 ;;
381
382 let interpretate_term_option status ?(create_dummy_ids=false) ~context ~env ~uri
383  ~is_path ~localization_tbl ~mk_choice ~obj_context
384 =
385   let context = List.map fst context in
386   snd 
387     (interpretate_term_and_interpretate_term_option status
388       ~obj_context ~mk_choice ~create_dummy_ids ~env ~uri ~is_path
389       ~localization_tbl)
390     ~context 
391 ;;
392
393 let disambiguate_path status path =
394   let localization_tbl = NCicUntrusted.NCicHash.create 23 in
395   fst
396     (interpretate_term_and_interpretate_term_option status
397     ~obj_context:[] ~mk_choice:(fun _ -> assert false)
398     ~create_dummy_ids:true ~env:DisambiguateTypes.Environment.empty
399     ~uri:None ~is_path:true ~localization_tbl) ~context:[] path
400 ;;
401
402 let ncic_name_of_ident = function
403   | Ast.Ident (name,_) -> name
404   | _ -> assert false
405 ;;
406
407 let interpretate_obj status
408 (*      ?(create_dummy_ids=false)  *)
409      ~context ~env ~uri ~is_path obj ~localization_tbl ~mk_choice 
410 =
411  assert (context = []);
412  assert (is_path = false);
413  let interpretate_term ~obj_context =
414   interpretate_term ~mk_choice ~localization_tbl ~obj_context in
415  let interpretate_term_option ~obj_context =
416    interpretate_term_option ~mk_choice ~localization_tbl ~obj_context in
417  let uri = match uri with | None -> assert false | Some u -> u in
418  match obj with
419  | NotationPt.Theorem (flavour, name, ty, bo, pragma) ->
420      let ty' = 
421        interpretate_term status
422          ~obj_context:[] ~context:[] ~env ~uri:None ~is_path:false ty 
423      in
424      let height = (* XXX calculate *) 0 in
425      uri, height, [], [], 
426      (match bo,flavour with
427       | None,`Axiom -> 
428           let attrs = `Provided, flavour, pragma in
429           NCic.Constant ([],name,None,ty',attrs)
430       | Some _,`Axiom -> assert false
431       | None,_ ->
432           let attrs = `Provided, flavour, pragma in
433           NCic.Constant ([],name,Some (NCic.Implicit `Term),ty',attrs)
434       | Some bo,_ ->
435         (match bo with
436          | NotationPt.LetRec (kind, defs, _) ->
437              let inductive = kind = `Inductive in
438              let _,obj_context =
439                List.fold_left
440                  (fun (i,acc) (_,(name,_),_,k) -> 
441                   (i+1, 
442                     (ncic_name_of_ident name, NReference.reference_of_spec uri 
443                      (if inductive then NReference.Fix (i,k,0)
444                       else NReference.CoFix i)) :: acc))
445                  (0,[]) defs
446              in
447              let inductiveFuns =
448                List.map
449                  (fun (params, (name, typ), body, decr_idx) ->
450                    let add_binders kind t =
451                     List.fold_right
452                      (fun var t -> 
453                         NotationPt.Binder (kind, var, t)) params t
454                    in
455                    let cic_body =
456                      interpretate_term status
457                        ~obj_context ~context ~env ~uri:None ~is_path:false
458                        (add_binders `Lambda body) 
459                    in
460                    let cic_type =
461                      interpretate_term_option status
462                        ~obj_context:[]
463                        ~context ~env ~uri:None ~is_path:false `Type
464                        (HExtlib.map_option (add_binders `Pi) typ)
465                    in
466                    ([],ncic_name_of_ident name, decr_idx, cic_type, cic_body))
467                  defs
468              in
469              let attrs = `Provided, flavour, pragma in
470              NCic.Fixpoint (inductive,inductiveFuns,attrs)
471          | bo -> 
472              let bo = 
473                interpretate_term status
474                 ~obj_context:[] ~context:[] ~env ~uri:None ~is_path:false bo
475              in
476              let attrs = `Provided, flavour, pragma in
477              NCic.Constant ([],name,Some bo,ty',attrs)))
478  | NotationPt.Inductive (params,tyl) ->
479     let context,params =
480      let context,res =
481       List.fold_left
482        (fun (context,res) (name,t) ->
483          let t =
484           match t with
485              None -> NotationPt.Implicit `JustOne
486            | Some t -> t in
487          let name = cic_name_of_name name in
488          let t =
489           interpretate_term status ~obj_context:[] ~context ~env ~uri:None
490            ~is_path:false t
491          in
492           (name,NCic.Decl t)::context,(name,t)::res
493        ) ([],[]) params
494      in
495       context,List.rev res in
496     let add_params =
497      List.fold_right (fun (name,ty) t -> NCic.Prod (name,ty,t)) params in
498     let leftno = List.length params in
499     let _,inductive,_,_ = try List.hd tyl with Failure _ -> assert false in
500     let obj_context =
501      snd (
502       List.fold_left
503        (fun (i,res) (name,_,_,_) ->
504          let nref =
505           NReference.reference_of_spec uri (NReference.Ind (inductive,i,leftno))
506          in
507           i+1,(name,nref)::res)
508        (0,[]) tyl) in
509     let tyl =
510      List.map
511       (fun (name,_,ty,cl) ->
512         let ty' =
513          add_params
514          (interpretate_term status ~obj_context:[] ~context ~env ~uri:None
515            ~is_path:false ty) in
516         let cl' =
517          List.map
518           (fun (name,ty) ->
519             let ty' =
520              add_params
521               (interpretate_term status ~obj_context ~context ~env ~uri:None
522                 ~is_path:false ty) in
523             let relevance = [] in
524              relevance,name,ty'
525           ) cl in
526         let relevance = [] in
527          relevance,name,ty',cl'
528       ) tyl
529     in
530      let height = (* XXX calculate *) 0 in
531      let attrs = `Provided, `Regular in
532      uri, height, [], [], 
533      NCic.Inductive (inductive,leftno,tyl,attrs)
534  | NotationPt.Record (params,name,ty,fields) ->
535     let context,params =
536      let context,res =
537       List.fold_left
538        (fun (context,res) (name,t) ->
539          let t =
540           match t with
541              None -> NotationPt.Implicit `JustOne
542            | Some t -> t in
543          let name = cic_name_of_name name in
544          let t =
545           interpretate_term status ~obj_context:[] ~context ~env ~uri:None
546            ~is_path:false t
547          in
548           (name,NCic.Decl t)::context,(name,t)::res
549        ) ([],[]) params
550      in
551       context,List.rev res in
552     let add_params =
553      List.fold_right (fun (name,ty) t -> NCic.Prod (name,ty,t)) params in
554     let leftno = List.length params in
555     let ty' =
556      add_params
557       (interpretate_term status ~obj_context:[] ~context ~env ~uri:None
558         ~is_path:false ty) in
559     let nref =
560      NReference.reference_of_spec uri (NReference.Ind (true,0,leftno)) in
561     let obj_context = [name,nref] in
562     let fields' =
563      snd (
564       List.fold_left
565        (fun (context,res) (name,ty,_coercion,_arity) ->
566          let ty =
567           interpretate_term status ~obj_context ~context ~env ~uri:None
568            ~is_path:false ty in
569          let context' = (name,NCic.Decl ty)::context in
570           context',(name,ty)::res
571        ) (context,[]) fields) in
572     let concl =
573      let mutind = NCic.Const nref in
574      if params = [] then mutind
575      else
576       NCic.Appl
577        (mutind::mk_rels (List.length params) (List.length fields)) in
578     let con =
579      List.fold_left (fun t (name,ty) -> NCic.Prod (name,ty,t)) concl fields' in
580     let con' = add_params con in
581     let relevance = [] in
582     let tyl = [relevance,name,ty',[relevance,"mk_" ^ name,con']] in
583     let field_names = List.map (fun (x,_,y,z) -> x,y,z) fields in
584      let height = (* XXX calculate *) 0 in
585      let attrs = `Provided, `Record field_names in
586      uri, height, [], [], 
587      NCic.Inductive (true,leftno,tyl,attrs)
588 ;;
589
590 let rec initialize_ast (* ~aliases *) ~universe ~lookup_in_library ~local_names t =
591   (* ast_of_alias_spec is duplicate in Disambiguate *)
592   let ast_of_alias_spec t alias = match (t,alias) with
593     | _, GrafiteAst.Ident_alias (id,uri) -> Ast.Ident(id,`Uri uri) 
594     | _, GrafiteAst.Symbol_alias (sym,uri,desc) -> Ast.Symbol (sym,Some (uri,desc))
595     | Ast.Num(m,_), GrafiteAst.Number_alias (uri,desc) -> Ast.Num(m,Some (uri,desc))
596     | _ -> assert false
597   in
598   let init = initialize_ast ~universe ~lookup_in_library in
599   let init_var ~local_names (n,ty) = 
600           (n,HExtlib.map_option (init ~local_names) ty)
601   in
602   let init_vars ~local_names vars =
603   (* 
604     List.fold_right (fun (n,ty) (nacc,tyacc) ->
605       (cic_name_of_name n::nacc,(init_var ~local_names:nacc (n,ty)::tyacc))
606     ) vars (local_names,[])
607   *)
608     let a,b = List.fold_left (fun (nacc,tyacc) (n,ty) ->
609       (cic_name_of_name n::nacc,(init_var ~local_names:nacc (n,ty)::tyacc))
610       ) (local_names,[]) vars
611     in a, List.rev b
612   in
613   let init_pattern ~local_names = function
614     | Ast.Wildcard as t -> local_names,t
615     | Ast.Pattern (c,uri,vars) -> 
616         (* XXX verificare ordine *)
617         let ln',vars' = init_vars ~local_names vars in
618         ln',Ast.Pattern (c,uri,vars')
619   in
620   let mk_alias = function
621     | Ast.Ident (id,_) -> DisambiguateTypes.Id (id,None)
622     | Ast.Symbol (sym,_) -> DisambiguateTypes.Symbol (sym,None)
623     | Ast.Num _ -> DisambiguateTypes.Num None
624     | _ -> assert false
625   in
626   let lookup_choices =
627      fun item ->
628       (*match universe with
629       | None -> 
630           lookup_in_library 
631             interactive_user_uri_choice 
632             input_or_locate_uri item
633       | Some e ->
634           (try Environment.find item e
635           with Not_found -> [])
636 *)
637           (try 
638              let res = Environment.find item universe in
639              let id = match item with
640                | DisambiguateTypes.Id (id,None) -> id ^ "?"
641                | DisambiguateTypes.Id (id,_) -> id ^ "!"
642                | DisambiguateTypes.Symbol _ -> "SYM"
643                | DisambiguateTypes.Num _ -> "NUM"
644              in
645              prerr_endline (Printf.sprintf "lookup_choices of %s returns length %d" id
646                (List.length res));
647              res
648           with Not_found -> [])
649    in
650    match t with
651    | Ast.Ident (id,(`Ambiguous|`Rel))
652        when List.mem id local_names -> Ast.Ident (id,`Rel)
653    | Ast.Ident (id,`Rel) -> init ~local_names (Ast.Ident (id,`Ambiguous))
654    | Ast.Ident (_,`Ambiguous)
655    | Ast.Num (_,None) 
656    | Ast.Symbol (_,None) -> 
657        let choices = lookup_choices (mk_alias t) in
658        if List.length choices <> 1 then t
659        else ast_of_alias_spec t (List.hd choices)
660    | Ast.AttributedTerm (a,u) -> Ast.AttributedTerm (a, init ~local_names u)
661    | Ast.Appl tl -> Ast.Appl (List.map (init ~local_names) tl)
662    | Ast.Binder (k,(n,ty),body) ->
663        let n' = cic_name_of_name n in
664        let ty' = HExtlib.map_option (init ~local_names) ty in
665        let body' = init ~local_names:(n'::local_names) body in
666        Ast.Binder (k,(n,ty'),body')
667    | Ast.Case (t,ity,oty,pl) -> 
668        let t' = init ~local_names t in
669        let oty' = HExtlib.map_option (init ~local_names) oty in
670        let pl' = 
671          List.map (fun (p,u) ->
672            let ns,p' = init_pattern ~local_names p in
673            p',init ~local_names:ns u) pl in
674        Ast.Case (t',ity,oty',pl')
675    | Ast.Cast (u,v) -> Ast.Cast (init ~local_names u,init ~local_names v)
676    | Ast.LetIn ((n,ty),u,v) -> 
677        let n' = cic_name_of_name n in
678        let ty' = HExtlib.map_option (init ~local_names) ty in
679        let u' = init ~local_names u in
680        let v' = init ~local_names:(n'::local_names) v in
681        Ast.LetIn ((n,ty'),u',v')
682    | Ast.LetRec (ik,l,t) ->
683        let recfuns = 
684          List.fold_right (fun (_,(n,_),_,_) acc ->
685            cic_name_of_name n::acc) l [] in
686        let l' = List.map (fun (vl,(n,ty),u,m) -> 
687          let ln',vl' = init_vars ~local_names vl in
688          let ty' = HExtlib.map_option (init ~local_names:ln') ty in
689          let ln'' = recfuns@ln' in
690          let u' = init ~local_names:ln'' u in
691          vl',(n,ty'),u',m) l in
692        let t' = init ~local_names:(recfuns@local_names) t in
693        Ast.LetRec (ik,l',t') (* XXX: t??? *)
694    | t -> t
695 ;;
696
697 let initialize_obj ~universe ~lookup_in_library o = 
698   let init = initialize_ast ~universe ~lookup_in_library in
699   let init_var ~local_names (n,ty) = 
700           (n,HExtlib.map_option (init ~local_names) ty)
701   in
702   let init_vars ~local_names vars = 
703     let a,b = List.fold_left (fun (nacc,tyacc) (n,ty) ->
704       (cic_name_of_name n::nacc,(init_var ~local_names:nacc (n,ty)::tyacc))
705       ) (local_names,[]) vars
706     in a, List.rev b
707     (*List.fold_right (fun (n,ty) (nacc,tyacc) ->
708       (cic_name_of_name n::nacc,(init_var ~local_names:nacc (n,ty)::tyacc))
709     ) vars (local_names,[])*)
710   in
711
712   match o with
713   | Ast.Inductive (ls,itl) ->
714       let ln,ls' = init_vars ~local_names:[] ls in
715       let indtys = 
716          List.fold_right 
717            (fun (name,_,_,_) acc -> name::acc) itl [] in
718       let itl' = List.map
719         (fun (name,isind,ty,cl) ->
720            let ty' = init ~local_names:ln ty in
721            let cl' = 
722              List.map (fun (cname,cty) -> 
723                cname, init ~local_names:(indtys@ln) cty) cl
724            in
725            name,isind,ty',cl') itl
726       in
727       Ast.Inductive (ls',itl')
728   | Ast.Theorem (flav,n,ty,bo,p) ->
729       Ast.Theorem (flav,n,init ~local_names:[] ty,
730                    HExtlib.map_option (init ~local_names:[]) bo,p)
731   | Ast.Record (ls,n,ty,fl) ->
732       let ln,ls' = init_vars ~local_names:[] ls in
733       let ty' = init ~local_names:ln ty in
734       let fl' = List.map (fun (fn,fty,b,i) -> 
735               fn,init ~local_names:ln fty,b,i) fl in
736       Ast.Record (ls,n,ty',fl')
737 ;;
738
739 let disambiguate_term (status: #NCicCoercion.status) ~context ~metasenv ~subst
740  ~expty ~mk_implicit ~description_of_alias ~fix_instance ~mk_choice
741  ~aliases ~universe ~lookup_in_library (text,prefix_len,term) 
742 =
743   let local_names = List.map (fun (n,_) -> n) context in
744   let mk_localization_tbl x = NCicUntrusted.NCicHash.create x in
745    let res,b =
746     MultiPassDisambiguator.disambiguate_thing
747      ~freshen_thing:NotationUtil.freshen_term
748      ~context ~metasenv ~initial_ugraph:() ~aliases
749      ~mk_implicit ~description_of_alias ~fix_instance
750      ~string_context_of_context:(List.map (fun (x,_) -> Some x))
751      ~universe ~uri:None ~pp_thing:(NotationPp.pp_term status) ~pp_term:(NotationPp.pp_term status)
752      ~passes:(MultiPassDisambiguator.passes ())
753      ~lookup_in_library ~domain_of_thing:Disambiguate.domain_of_term
754      ~interpretate_thing:(interpretate_term status ~obj_context:[] ~mk_choice (?create_dummy_ids:None))
755      ~refine_thing:(refine_term status) 
756      (text,prefix_len,
757       (initialize_ast ~universe ~lookup_in_library ~local_names term))
758      ~visit:Disambiguate.bfvisit
759      ~mk_localization_tbl ~expty ~subst
760    in
761     List.map (function (a,b,c,d,_) -> term,a,b,c,d) res, b
762 ;;
763
764
765 let disambiguate_obj (status: #NCicCoercion.status)
766    ~mk_implicit ~description_of_alias ~fix_instance ~mk_choice
767    ~aliases ~universe ~lookup_in_library ~uri (text,prefix_len,obj) 
768  =
769   let mk_localization_tbl x = NCicUntrusted.NCicHash.create x in
770    let res,b =
771     MultiPassDisambiguator.disambiguate_thing
772      ~freshen_thing:NotationUtil.freshen_obj
773      ~context:[] ~metasenv:[] ~subst:[] ~initial_ugraph:() ~aliases
774      ~mk_implicit ~description_of_alias ~fix_instance
775      ~string_context_of_context:(List.map (fun (x,_) -> Some x))
776      ~universe 
777      ~uri:(Some uri)
778      ~pp_thing:(NotationPp.pp_obj (NotationPp.pp_term status)) ~pp_term:(NotationPp.pp_term status)
779      ~passes:(MultiPassDisambiguator.passes ())
780      ~lookup_in_library ~domain_of_thing:Disambiguate.domain_of_obj
781      ~interpretate_thing:(interpretate_obj status ~mk_choice)
782      ~refine_thing:(refine_obj status) 
783      (text,prefix_len,(initialize_obj ~universe ~lookup_in_library obj))
784      ~visit:Disambiguate.bfvisit_obj
785      ~mk_localization_tbl ~expty:None
786    in
787     List.map (function (a,b,c,d,_) -> a,b,c,d) res, b
788 ;;
789 (*
790 let _ = 
791 let mk_type n = 
792   if n = 0 then
793      [false, NUri.uri_of_string ("cic:/matita/pts/Type.univ")]
794   else
795      [false, NUri.uri_of_string ("cic:/matita/pts/Type"^string_of_int n^".univ")]
796 in
797 let mk_cprop n = 
798   if n = 0 then 
799     [false, NUri.uri_of_string ("cic:/matita/pts/CProp.univ")]
800   else
801     [false, NUri.uri_of_string ("cic:/matita/pts/CProp"^string_of_int n^".univ")]
802 in
803          NCicEnvironment.add_constraint true (mk_type 0) (mk_type 1);
804          NCicEnvironment.add_constraint true (mk_cprop 0) (mk_cprop 1);
805          NCicEnvironment.add_constraint true (mk_cprop 0) (mk_type 1);
806          NCicEnvironment.add_constraint true (mk_type 0) (mk_cprop 1);
807          NCicEnvironment.add_constraint false (mk_cprop 0) (mk_type 0);
808          NCicEnvironment.add_constraint false (mk_type 0) (mk_cprop 0);
809
810          NCicEnvironment.add_constraint true (mk_type 1) (mk_type 2);
811          NCicEnvironment.add_constraint true (mk_cprop 1) (mk_cprop 2);
812          NCicEnvironment.add_constraint true (mk_cprop 1) (mk_type 2);
813          NCicEnvironment.add_constraint true (mk_type 1) (mk_cprop 2);
814          NCicEnvironment.add_constraint false (mk_cprop 1) (mk_type 1);
815          NCicEnvironment.add_constraint false (mk_type 1) (mk_cprop 1);
816
817          NCicEnvironment.add_constraint true (mk_type 2) (mk_type 3);
818          NCicEnvironment.add_constraint true (mk_cprop 2) (mk_cprop 3);
819          NCicEnvironment.add_constraint true (mk_cprop 2) (mk_type 3);
820          NCicEnvironment.add_constraint true (mk_type 2) (mk_cprop 3);
821          NCicEnvironment.add_constraint false (mk_cprop 2) (mk_type 2);
822          NCicEnvironment.add_constraint false (mk_type 2) (mk_cprop 2);
823
824          NCicEnvironment.add_constraint false (mk_cprop 3) (mk_type 3);
825          NCicEnvironment.add_constraint false (mk_type 3) (mk_cprop 3);
826
827 ;;
828 *)
829