]> matita.cs.unibo.it Git - helm.git/blob - matita/components/lexicon/lexiconEngine.ml
7f16fe883c0e6564707ce12679c3dd136ae6443e
[helm.git] / matita / components / lexicon / lexiconEngine.ml
1 (* Copyright (C) 2004-2005, 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 module L = LexiconAst
29
30 let debug = ref false
31
32 (* lexicon file name * ma file name *)
33 exception IncludedFileNotCompiled of string * string 
34 exception MetadataNotFound of string        (* file name *)
35
36 type lexicon_status = {
37   aliases: L.alias_spec DisambiguateTypes.Environment.t;
38   multi_aliases: L.alias_spec list DisambiguateTypes.Environment.t;
39   lexicon_content_rev: LexiconMarshal.lexicon;
40   notation_ids: CicNotation.notation_id list;      (** in-scope notation ids *)
41 }
42
43 let initial_status = {
44   aliases = DisambiguateTypes.Environment.empty;
45   multi_aliases = DisambiguateTypes.Environment.empty;
46   lexicon_content_rev = [];
47   notation_ids = [];
48 }
49
50 class type g_status =
51  object
52   inherit CicNotation.g_status
53   method lstatus: lexicon_status
54  end
55
56 class status =
57  object(self)
58   inherit CicNotation.status
59   val lstatus = initial_status
60   method lstatus = lstatus
61   method set_lstatus v = {< lstatus = v >}
62   method set_lexicon_engine_status : 'status. #g_status as 'status -> 'self
63    = fun o -> (self#set_lstatus o#lstatus)#set_notation_status o
64  end
65
66 let dump_aliases out msg status =
67    out (if msg = "" then "aliases dump:" else msg ^ ": aliases dump:");
68    DisambiguateTypes.Environment.iter
69       (fun _ x -> out (LexiconAstPp.pp_alias x))
70       status#lstatus.aliases
71    
72 let add_lexicon_content cmds status =
73   let content = status#lstatus.lexicon_content_rev in
74   let content' =
75     List.fold_right
76      (fun cmd acc -> 
77         match cmd with
78         | L.Alias _ 
79         | L.Include _ 
80         | L.Notation _ -> cmd :: (List.filter ((<>) cmd) acc)
81         | L.Interpretation _ -> if List.exists ((=) cmd) acc then acc else cmd::acc)
82      cmds content
83   in
84 (*   
85   prerr_endline ("new lexicon content: " ^ 
86      String.concat "; " (List.map LexiconAstPp.pp_command content')
87   );
88 *)
89   status#set_lstatus
90    { status#lstatus with lexicon_content_rev = content' }
91
92 let set_proof_aliases mode status new_aliases =
93  if mode = L.WithoutPreferences then
94    status 
95  else
96    let commands_of_aliases =
97      List.map
98       (fun _,alias -> L.Alias (HExtlib.dummy_floc, alias))
99    in
100    let aliases =
101     List.fold_left (fun acc (d,c) -> DisambiguateTypes.Environment.add d c acc)
102      status#lstatus.aliases new_aliases in
103    let multi_aliases =
104     List.fold_left (fun acc (d,c) -> 
105       DisambiguateTypes.Environment.cons L.description_of_alias 
106          d c acc)
107      status#lstatus.multi_aliases new_aliases
108    in
109    let new_status =
110      { status#lstatus with
111         multi_aliases = multi_aliases ; aliases = aliases} in
112    let new_status = status#set_lstatus new_status in
113     if new_aliases = [] then
114       new_status
115     else
116       add_lexicon_content (commands_of_aliases new_aliases) new_status 
117
118 let rec eval_command ?(mode=L.WithPreferences) sstatus cmd =
119 (*
120  let bmode = match mode with L.WithPreferences -> true | _ -> false in
121  Printf.eprintf "Include preferences: %b\n" bmode;
122 *) 
123  let status = sstatus#lstatus in
124  let cmd =
125   match cmd with
126   | L.Interpretation (loc, dsc, (symbol, args), cic_appl_pattern) ->
127      let rec disambiguate =
128       function
129          NotationPt.ApplPattern l ->
130           NotationPt.ApplPattern (List.map disambiguate l)
131        | NotationPt.VarPattern id
132           when not
133            (List.exists
134             (function (NotationPt.IdentArg (_,id')) -> id'=id) args)
135           ->
136            let item = DisambiguateTypes.Id id in
137             begin try
138               match DisambiguateTypes.Environment.find item status.aliases with
139                  L.Ident_alias (_, uri) ->
140                   NotationPt.NRefPattern (NReference.reference_of_string uri)
141                | _ -> assert false
142              with Not_found -> 
143               prerr_endline ("LexiconEngine.eval_command: domain item not found: " ^ 
144                (DisambiguateTypes.string_of_domain_item item));
145               dump_aliases prerr_endline "" sstatus;
146               raise (Failure (
147                       (DisambiguateTypes.string_of_domain_item item) ^ 
148                       " not found"));
149             end
150        | p -> p
151      in
152       L.Interpretation
153        (loc, dsc, (symbol, args), disambiguate cic_appl_pattern)
154   | _-> cmd
155  in
156  let sstatus,notation_ids' = CicNotation.process_notation sstatus cmd in
157  let status =
158    { status with notation_ids = notation_ids' @ status.notation_ids } in
159  let sstatus = sstatus#set_lstatus status in
160   match cmd with
161   | L.Include (loc, baseuri, mode, fullpath) ->
162      let lexiconpath_rw, lexiconpath_r = 
163        LibraryMisc.lexicon_file_of_baseuri 
164          ~must_exist:false ~writable:true ~baseuri,
165        LibraryMisc.lexicon_file_of_baseuri 
166          ~must_exist:false ~writable:false ~baseuri
167      in
168      let lexiconpath = 
169        if Sys.file_exists lexiconpath_rw then lexiconpath_rw else
170          if Sys.file_exists lexiconpath_r then lexiconpath_r else
171           raise (IncludedFileNotCompiled (lexiconpath_rw,fullpath))
172      in
173      let lexicon = LexiconMarshal.load_lexicon lexiconpath in
174       List.fold_left (eval_command ~mode) sstatus lexicon
175   | L.Alias (loc, spec) -> 
176      let diff =
177       (*CSC: Warning: this code should be factorized with the corresponding
178              code in DisambiguatePp *)
179       match spec with
180       | L.Ident_alias (id,uri) -> 
181          [DisambiguateTypes.Id id,spec]
182       | L.Symbol_alias (symb, instance, desc) ->
183          [DisambiguateTypes.Symbol (symb,instance),spec]
184       | L.Number_alias (instance,desc) ->
185          [DisambiguateTypes.Num instance,spec]
186      in
187       set_proof_aliases mode sstatus diff
188   | L.Interpretation (_, dsc, (symbol, _), _) as stm ->
189       let sstatus = add_lexicon_content [stm] sstatus in
190       let diff =
191        try
192         [DisambiguateTypes.Symbol (symbol, 0),
193           L.Symbol_alias (symbol,0,dsc)]
194        with
195         DisambiguateChoices.Choice_not_found msg ->
196           prerr_endline (Lazy.force msg);
197           assert false
198       in
199       let sstatus = set_proof_aliases mode sstatus diff in
200       sstatus
201   | L.Notation _ as stm ->
202       add_lexicon_content [stm] sstatus
203
204 let eval_command status cmd = 
205    if !debug then dump_aliases prerr_endline "before eval_command" status;
206    let status = eval_command ?mode:None status cmd in
207    if !debug then dump_aliases prerr_endline "after eval_command" status;
208    status
209
210 let set_proof_aliases status aliases =
211    if !debug then dump_aliases prerr_endline "before set_proof_aliases" status;
212    let status = set_proof_aliases L.WithPreferences status aliases in
213    if !debug then dump_aliases prerr_endline "after set_proof_aliases" status;
214    status