]> matita.cs.unibo.it Git - helm.git/blob - matitaB/components/ng_disambiguation/grafiteDisambiguate.ml
Fixes a bug (introduced in the previous revision) which caused the environment
[helm.git] / matitaB / components / ng_disambiguation / grafiteDisambiguate.ml
1 (*
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 module Ast = NotationPt
29
30 type db = {
31   (* maps (loc,domain_item) to alias *)
32   interpr: GrafiteAst.alias_spec DisambiguateTypes.InterprEnv.t;
33   (* the universe of possible interpretations for all symbols/ids/nums *)
34   multi_aliases: GrafiteAst.alias_spec list DisambiguateTypes.Environment.t;
35   (* new_aliases: ((Stdpp.location * DisambiguateTypes.domain_item) * GrafiteAst.alias_spec) list *)
36 }
37
38 let get_interpr db =
39   db.interpr
40 ;;
41
42 let initial_status = {
43   interpr = DisambiguateTypes.InterprEnv.empty;
44   multi_aliases = DisambiguateTypes.Environment.empty;
45   (* new_aliases = [] *)
46 }
47
48 class type g_status =
49   object
50    inherit Interpretations.g_status
51    inherit NCicLibrary.g_status
52    method disambiguate_db: db
53   end
54
55 class virtual status uid =
56  object (self)
57   inherit Interpretations.status uid
58   inherit NCicLibrary.status uid
59   val disambiguate_db = initial_status
60   method disambiguate_db = disambiguate_db
61   method set_disambiguate_db v = {< disambiguate_db = v >}
62   method reset_disambiguate_db () = 
63     {< disambiguate_db = { self#disambiguate_db with interpr =
64             DisambiguateTypes.InterprEnv.empty } >}
65   method set_disambiguate_status
66    : 'status. #g_status as 'status -> 'self
67       = fun o -> ((self#set_interp_status o)#set_disambiguate_db
68       o#disambiguate_db)#set_lib_status o
69  end
70
71 (* let eval_with_new_aliases status f =
72  let status =
73   status#set_disambiguate_db { status#disambiguate_db with new_aliases = [] } in
74  let res = f status in
75  let new_aliases = status#disambiguate_db.new_aliases in
76   new_aliases,res
77 ;;*)
78
79 let dump_aliases out msg status =
80    out (if msg = "" then "aliases dump:" else msg ^ ": aliases dump:");
81    DisambiguateTypes.InterprEnv.iter (fun _ x -> out (GrafiteAstPp.pp_alias x))
82     status#disambiguate_db.interpr
83
84 let add_to_interpr status new_aliases =
85    let interpr =
86     List.fold_left (fun acc (k,c) -> 
87       DisambiguateTypes.InterprEnv.add k c acc)
88       status#disambiguate_db.interpr new_aliases 
89    in
90    let new_status =
91      {status#disambiguate_db with interpr = interpr }
92    in
93     status#set_disambiguate_db new_status
94    
95 let add_to_disambiguation_univ status new_aliases =
96    let multi_aliases =
97     List.fold_left (fun acc (d,c) -> 
98       DisambiguateTypes.Environment.cons GrafiteAst.description_of_alias 
99          d c acc)
100      status#disambiguate_db.multi_aliases new_aliases
101    in
102    let new_status =
103      {status#disambiguate_db with multi_aliases = multi_aliases }
104    in
105     status#set_disambiguate_db new_status
106
107
108 exception BaseUriNotSetYet
109
110 let singleton msg = function
111   | [x], _ -> x
112   | l, _   ->
113       let debug = 
114          Printf.sprintf "GrafiteDisambiguate.singleton (%s): %u interpretations"
115          msg (List.length l)
116       in
117       prerr_endline debug; assert false
118
119 let __Implicit = "__Implicit__"
120 let __Closed_Implicit = "__Closed_Implicit__"
121
122 let ncic_mk_choice status a =
123   prerr_endline "ncic_mk_choice";
124   match a with
125   | GrafiteAst.Symbol_alias (name,_, dsc) ->
126      prerr_endline ("caso 1: " ^ name ^ "; " ^ dsc);
127      if name = __Implicit then
128        dsc, `Sym_interp (fun _ -> NCic.Implicit `Term)
129      else if name = __Closed_Implicit then 
130        dsc, `Sym_interp (fun _ -> NCic.Implicit `Closed)
131      else
132        (prerr_endline (Printf.sprintf "mk_choice: symbol %s, interpr %s"
133          name dsc);
134        DisambiguateChoices.lookup_symbol_by_dsc status
135         ~mk_implicit:(function 
136            | true -> NCic.Implicit `Closed
137            | false -> NCic.Implicit `Term)
138         ~mk_appl:(function 
139            (NCic.Appl l)::tl -> NCic.Appl (l@tl) | l -> NCic.Appl l)
140         ~term_of_nref:(fun nref -> NCic.Const nref)
141        name dsc)
142   | GrafiteAst.Number_alias (_,dsc) -> 
143      prerr_endline ("caso 2: " ^ dsc);
144      let desc,f = DisambiguateChoices.nlookup_num_by_dsc dsc in
145       desc, `Num_interp
146        (fun num -> match f with `Num_interp f -> f num | _ -> assert false)
147   | GrafiteAst.Ident_alias (name, uri) -> 
148      prerr_endline ("caso 3: " ^ name);
149      uri, `Sym_interp 
150       (fun l->assert(l = []);
151         let nref = NReference.reference_of_string uri in
152          NCic.Const nref)
153 ;;
154
155
156 let mk_implicit b =
157   match b with
158   | false -> 
159       GrafiteAst.Symbol_alias (__Implicit,None,"Fake Implicit")
160   | true -> 
161       GrafiteAst.Symbol_alias (__Closed_Implicit,None,"Fake Closed Implicit")
162 ;;
163
164 let nlookup_in_library status
165   interactive_user_uri_choice input_or_locate_uri item 
166 =
167   match item with
168   | DisambiguateTypes.Id id -> 
169      (try
170        let references = NCicLibrary.resolve status id in
171         List.map
172          (fun u -> 
173            GrafiteAst.Ident_alias (id,NReference.string_of_reference u)
174          ) references
175       with
176        NCicEnvironment.ObjectNotFound _ -> [])
177   | _ -> []
178 ;;
179
180 (* XXX TO BE REMOVED: no need to fix instances any more *)
181 (*let fix_instance item l =
182  match item with
183     DisambiguateTypes.Symbol (_,n) ->
184      List.map
185       (function
186           GrafiteAst.Symbol_alias (s,d) -> GrafiteAst.Symbol_alias (s,n,d)
187         | _ -> assert false
188       ) l
189   | DisambiguateTypes.Num n ->
190      List.map
191       (function
192           GrafiteAst.Number_alias (_,d) -> GrafiteAst.Number_alias (n,d)
193         | _ -> assert false
194       ) l
195   | DisambiguateTypes.Id _ -> l
196 ;;*)
197 let fix_instance _ l = l;;
198
199 let rec diff_term loc t u = match (t,u) with
200   | Ast.AttributedTerm (`Loc l,t'), Ast.AttributedTerm (_,u') -> diff_term l t' u'
201   | Ast.AttributedTerm (_,t'), Ast.AttributedTerm (_,u') -> diff_term loc t' u' 
202   | Ast.Appl tl, Ast.Appl ul ->
203       List.fold_left2 (fun acc t0 u0 -> diff_term loc t0 u0@acc) [] tl ul
204   | Ast.Binder (_,v1,b1), Ast.Binder (_,v2,b2) -> 
205      diff_var loc v1 v2@ diff_term loc b1 b2
206   | Ast.Case (t1,ity1,outty1,pl1),Ast.Case (t2,ity2,outty2,pl2) -> 
207       let ity_interp = match ity1,ity2 with
208       | Some (i,None), Some (_,Some r) -> 
209          let uri = NReference.string_of_reference r in
210          [loc,GrafiteAst.Ident_alias (i,uri)]
211       | _ -> []
212       in
213       let oty_interp = match outty1,outty2 with
214       | Some o1, Some o2 -> diff_term loc o1 o2
215       | _ -> []
216       in
217       (* pl = (case_pattern * term) list *)
218       let auxpatt (c1,u1) (c2,u2) acc =
219         let diff_cp = match c1,c2 with
220         | Ast.Pattern (i,href1,vars1), Ast.Pattern (_,href2,vars2) ->
221            let diff_i = match href1,href2 with
222              | None, Some r ->
223                 let uri = NReference.string_of_reference r in
224                 [loc,GrafiteAst.Ident_alias (i,uri)]
225              | _ -> []
226            in
227            let diff_vars = 
228              List.fold_right2 (fun v1 v2 acc0 -> diff_var loc v1 v2 @ acc0) vars1 vars2 []
229            in
230            diff_i @ diff_vars
231         | _ -> []
232         in
233         diff_term loc u1 u2 @ diff_cp @ acc
234       in
235       let pl_interp = List.fold_right2 auxpatt pl1 pl2 [] in
236       diff_term loc t1 t2 @ ity_interp @ oty_interp @ pl_interp
237   | Ast.Cast (u1,v1),Ast.Cast (u2,v2) -> 
238      diff_term loc u1 u2@diff_term loc v1 v2
239   | Ast.LetIn (var1,u1,v1),Ast.LetIn (var2,u2,v2) ->
240      diff_var loc var1 var2 @ diff_term loc u1 u2 @ diff_term loc v1 v2
241   | Ast.LetRec (_,fl1,w1),Ast.LetRec (_,fl2,w2) ->
242     let diff_funs =
243       List.fold_right2 
244         (fun (vars1,f1,b1,_) (vars2,f2,b2,_) acc ->
245            let diff_vars = 
246              List.fold_right2 
247                (fun v1 v2 acc0 -> diff_var loc v1 v2 @ acc0) vars1 vars2 [] 
248            in
249            diff_vars @ diff_var loc f1 f2 @ diff_term loc b1 b2 @ acc)
250         fl1 fl2 []
251     in  
252     diff_funs @ diff_term loc w1 w2
253   | Ast.Ident (n,`Ambiguous),Ast.Ident (_,`Uri u) ->
254       [loc,GrafiteAst.Ident_alias (n,u)]
255   | Ast.Symbol (s, None),Ast.Symbol(_,Some (uri,desc)) ->
256       [loc,GrafiteAst.Symbol_alias (s,uri,desc)]
257   | Ast.Num (_, None),Ast.Num (_,Some (uri,desc)) ->
258       [loc,GrafiteAst.Number_alias (uri,desc)]
259   | _ -> [] (* leaves *)
260 and diff_var loc (_,v1) (_,v2) = match v1,v2 with
261   | Some v1', Some v2' -> diff_term loc v1' v2'
262   | _ -> []
263 ;;
264
265 let diff_obj loc o1 o2 = match o1,o2 with
266  | Ast.Inductive (ls1,itys1), Ast.Inductive (ls2,itys2) ->
267      let diff_ls = 
268        List.fold_right2 (fun v1 v2 acc -> diff_var loc v1 v2 @ acc) ls1 ls2 []
269      in
270      let diff_itys =
271        List.fold_right2
272          (fun (i1,_,ty1,cl1) (i2,_,ty2,cl2) acc0 -> 
273             let diff_cl =
274               List.fold_right2 
275                (fun (_,u) (_,v) acc1 -> diff_term loc u v @ acc1)
276                cl1 cl2 []
277             in
278             diff_term loc ty1 ty2 @ diff_cl @ acc0)
279          itys1 itys2 []
280      in
281      diff_ls @ diff_itys
282  | Ast.Theorem (_,i1,b1,ty1,_), Ast.Theorem (_,i2,b2,ty2,_) ->
283      let diff_tys = match ty1,ty2 with
284      | Some ty1', Some ty2' -> diff_term loc ty1' ty2'
285      | _ -> []
286      in
287      diff_term loc b1 b2 @ diff_tys
288  | Ast.Record (ls1,_,ty1,fl1),Ast.Record (ls2,_,ty2,fl2) ->
289      let diff_ls = 
290        List.fold_right2 (fun v1 v2 acc -> diff_var loc v1 v2 @ acc) ls1 ls2 []
291      in
292      let diff_fl =
293        List.fold_right2
294          (fun (_,f1,_,_) (_,f2,_,_) acc -> diff_term loc f1 f2 @ acc) fl1 fl2 []
295      in
296      diff_ls @ diff_term loc ty1 ty2 @ diff_fl
297  | _ -> assert false
298 ;;
299
300 let disambiguate_nterm status expty context metasenv subst thing
301
302   let newast, metasenv, subst, cic =
303     singleton "first"
304       (NCicDisambiguate.disambiguate_term
305         status
306         ~aliases:status#disambiguate_db.interpr
307         ~expty 
308         ~universe:(status#disambiguate_db.multi_aliases)
309         ~lookup_in_library:(nlookup_in_library status)
310         ~mk_choice:(ncic_mk_choice status)
311         ~mk_implicit ~fix_instance
312         ~description_of_alias:GrafiteAst.description_of_alias
313         ~context ~metasenv ~subst thing)
314   in
315   let _,_,thing' = thing in
316   let diff = diff_term Stdpp.dummy_loc thing' newast in
317   let status = add_to_interpr status diff 
318   in
319    metasenv, subst, status, cic
320 ;;
321
322
323 type pattern = 
324   NotationPt.term Disambiguate.disambiguator_input option * 
325   (string * NCic.term) list * NCic.term option
326
327 let disambiguate_npattern status (text, prefix_len, (wanted, hyp_paths, goal_path)) =
328   let interp path = NCicDisambiguate.disambiguate_path status path in
329   let goal_path = HExtlib.map_option interp goal_path in
330   let hyp_paths = List.map (fun (name, path) -> name, interp path) hyp_paths in
331   let wanted = HExtlib.map_option (fun x -> text,prefix_len,x) wanted in
332    (wanted, hyp_paths, goal_path)
333 ;;
334
335 let disambiguate_reduction_kind text prefix_len = function
336   | `Unfold (Some t) -> assert false (* MATITA 1.0 *)
337   | `Normalize
338   | `Simpl
339   | `Unfold None
340   | `Whd as kind -> kind
341 ;;
342
343 let disambiguate_auto_params 
344   disambiguate_term metasenv context (oterms, params) 
345 =
346   match oterms with 
347     | None -> metasenv, (None, params)
348     | Some terms ->
349         let metasenv, terms = 
350           List.fold_right 
351             (fun t (metasenv, terms) ->
352                let metasenv,t = disambiguate_term context metasenv t in
353                  metasenv,t::terms) terms (metasenv, [])
354         in
355           metasenv, (Some terms, params)
356 ;;
357
358 let disambiguate_just disambiguate_term context metasenv =
359  function
360     `Term t ->
361       let metasenv,t = disambiguate_term context metasenv t in
362        metasenv, `Term t
363   | `Auto params ->
364       let metasenv,params = disambiguate_auto_params disambiguate_term metasenv
365        context params
366       in
367        metasenv, `Auto params
368 ;;
369       
370 let disambiguate_nobj status ?baseuri (text,prefix_len,obj) =
371   let uri =
372    let baseuri = 
373      match baseuri with Some x -> x | None -> raise BaseUriNotSetYet
374    in
375    let name = 
376      match obj with
377      | NotationPt.Inductive (_,(name,_,_,_)::_)
378      | NotationPt.Record (_,name,_,_) -> name ^ ".ind"
379      | NotationPt.Theorem (_,name,_,_,_) -> name ^ ".con"
380      | NotationPt.Inductive _ -> assert false
381    in
382      NUri.uri_of_string (baseuri ^ "/" ^ name)
383   in
384   let ast, _, _, cic =
385    singleton "third"
386     (NCicDisambiguate.disambiguate_obj
387       status
388       ~lookup_in_library:(nlookup_in_library status)
389       ~description_of_alias:GrafiteAst.description_of_alias
390       ~mk_choice:(ncic_mk_choice status)
391       ~mk_implicit ~fix_instance ~uri
392       ~aliases:status#disambiguate_db.interpr
393       ~universe:(status#disambiguate_db.multi_aliases) 
394       (text,prefix_len,obj)) in
395   let diff = diff_obj Stdpp.dummy_loc obj ast in
396   let status = add_to_interpr status diff
397   in
398    status, cic
399 ;;
400
401 let disambiguate_cic_appl_pattern status args =
402  let rec disambiguate =
403   function
404     NotationPt.ApplPattern l ->
405      NotationPt.ApplPattern (List.map disambiguate l)
406   | NotationPt.VarPattern id
407      when not
408       (List.exists
409        (function (NotationPt.IdentArg (_,id')) -> id'=id) args)
410      ->
411       let item = DisambiguateTypes.Id id in
412        begin
413         try
414          match
415           DisambiguateTypes.Environment.find item
416            (* status#disambiguate_db.aliases *)
417            status#disambiguate_db.multi_aliases
418          with
419          (* XXX : we only try the first match *)
420             GrafiteAst.Ident_alias (_,uri)::_ ->
421              NotationPt.NRefPattern (NReference.reference_of_string uri)
422           | _ -> assert false
423         with Not_found -> 
424          prerr_endline
425           ("LexiconEngine.eval_command: domain item not found: " ^ 
426           (DisambiguateTypes.string_of_domain_item item));
427          dump_aliases prerr_endline "" status;
428          raise 
429           (Failure
430            ((DisambiguateTypes.string_of_domain_item item) ^ " not found"))
431              end
432   | p -> p
433  in
434   disambiguate
435 ;;
436
437 let aliases_for_objs status refs =
438  List.concat
439   (List.map
440     (fun nref ->
441       let references = NCicLibrary.aliases_of status nref in
442        List.map
443         (fun u ->
444           let name = NCicPp.r2s status true u in
445            (* FIXME : we are forgetting the interpretation of the Id
446             * but is this useful anymore?!?!? *)
447            DisambiguateTypes.Id name,
448             GrafiteAst.Ident_alias (name,NReference.string_of_reference u)
449         ) references) refs)