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