]> matita.cs.unibo.it Git - helm.git/blob - helm/software/lambda-delta/toplevel/metaAut.ml
we now do some static analysis on the Automath text to possibly clear some language...
[helm.git] / helm / software / lambda-delta / toplevel / metaAut.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 module U = NUri
13 module H = U.UriHash
14 module M = Meta
15 module A = Aut
16
17 (* qualified identifier: uri, name, qualifiers *)
18 type qid = U.uri * M.id * M.id list
19
20 type environment = M.pars H.t
21
22 type context_node = qid option (* context node: None = root *)
23
24 type status = {
25    henv: environment;        (* optimized global environment *)
26    path: M.id list;          (* current section path *) 
27    hcnt: environment;        (* optimized context *)   
28    node: context_node;       (* current context node *)
29    nodes: context_node list; (* context node list *)
30    line: int;                (* line number *)
31    cover: string             (* initial segment of URI hierarchy *) 
32 }
33
34 type resolver = Local of int
35               | Global of M.pars
36
37 let hsize = 7000 (* hash tables initial size *)
38
39 (* Internal functions *******************************************************)
40
41 let initial_status size cover = {
42    path = []; node = None; nodes = []; line = 1; cover = cover;
43    henv = H.create size; hcnt = H.create size
44 }
45
46 let id_of_name (id, _, _) = id
47
48 let mk_qid st id path =
49    let uripath = if st.cover = "" then path else st.cover :: path in
50    let str = String.concat "/" uripath in
51    let str = Filename.concat str id in 
52    U.uri_of_string ("ld:/" ^ str), id, path
53
54 let uri_of_qid (uri, _, _) = uri
55
56 let complete_qid f st (id, is_local, qs) =
57    let f qs = f (mk_qid st id qs) in
58    let f path = Cps.list_rev_append f path ~tail:qs in
59    let rec skip f = function
60       | phd :: ptl, qshd :: _ when phd = qshd -> f ptl
61       | _ :: ptl, _ :: _                      -> skip f (ptl, qs)
62       | _                                     -> f []
63    in
64    if is_local then f st.path else skip f (st.path, qs)
65
66 let relax_qid f st (_, id, path) =
67    let f path = f (mk_qid st id path) in
68    let f = function
69       | _ :: tl -> Cps.list_rev f tl
70       | []      -> assert false
71    in
72    Cps.list_rev f path
73
74 let relax_opt_qid f st = function
75    | None     -> f None
76    | Some qid -> let f qid = f (Some qid) in relax_qid f st qid
77
78 let resolve_lref f st l lenv id =
79    let rec aux f i = function
80      | []                            -> f None
81      | (name, _) :: _ when name = id -> f (Some (M.LRef (l, i)))
82      | _ :: tl                       -> aux f (succ i) tl
83    in
84    aux f 0 lenv
85
86 let resolve_lref_strict f st l lenv id =
87    let f = function
88       | Some t -> f t
89       | None   -> assert false
90    in
91    resolve_lref f st l lenv id
92
93 let resolve_gref f st qid =
94    try let args = H.find st.henv (uri_of_qid qid) in f qid (Some args)
95    with Not_found -> f qid None
96
97 let resolve_gref_relaxed f st qid =
98    let rec g qid = function
99       | None      -> relax_qid (resolve_gref g st) st qid
100       | Some args -> f qid args
101    in
102    resolve_gref g st qid
103
104 let get_pars f st = function
105    | None              -> f [] None
106    | Some qid as node ->
107       try let pars = H.find st.hcnt (uri_of_qid qid) in f pars None
108       with Not_found -> f [] (Some node)
109
110 let get_pars_relaxed f st =
111    let rec g pars = function
112       | None      -> f pars 
113       | Some node -> relax_opt_qid (get_pars g st) st node
114    in
115    get_pars g st st.node
116
117 let rec xlate_term f st lenv = function
118    | A.Sort sort         -> 
119       f (M.Sort sort)
120    | A.Appl (v, t)       ->
121       let f vv tt = f (M.Appl (vv, tt)) in
122       let f vv = xlate_term (f vv) st lenv t in
123       xlate_term f st lenv v
124    | A.Abst (name, w, t) ->
125       let add name w lenv = (name, w) :: lenv in
126       let f ww tt = f (M.Abst (name, ww, tt)) in
127       let f ww = xlate_term (f ww) st (add name ww lenv) t in
128       xlate_term f st lenv w
129    | A.GRef (name, args) ->
130       let l = List.length lenv in
131       let g qid defs =
132          let map1 f = xlate_term f st lenv in       
133          let map2 f (id, _) = resolve_lref_strict f st l lenv id in
134          let f tail = 
135             let f args = f (M.GRef (l, uri_of_qid qid, args)) in
136             let f defs = Cps.list_rev_map_append f map2 defs ~tail in
137             Cps.list_sub_strict f defs args
138          in   
139          Cps.list_map f map1 args
140       in
141       let g qid = resolve_gref_relaxed g st qid in
142       let f = function
143          | Some t -> f t
144          | None   -> complete_qid g st name
145       in
146       resolve_lref f st l lenv (id_of_name name)
147
148 let xlate_item f st = function
149    | A.Section (Some (_, name))     ->
150       f {st with path = name :: st.path; nodes = st.node :: st.nodes} None
151    | A.Section None            ->
152       begin match st.path, st.nodes with
153          | _ :: ptl, nhd :: ntl -> 
154             f {st with path = ptl; node = nhd; nodes = ntl} None
155          | _                    -> assert false
156       end
157    | A.Context None            ->
158       f {st with node = None} None
159    | A.Context (Some name)     ->
160       let f name = f {st with node = Some name} None in
161       complete_qid f st name 
162    | A.Block (name, w)         ->
163       let f qid = 
164          let f pars =
165             let f ww = 
166                H.add st.hcnt (uri_of_qid qid) ((name, ww) :: pars);
167                f {st with node = Some qid} None
168             in
169             xlate_term f st pars w
170          in
171          get_pars_relaxed f st
172       in
173       complete_qid f st (name, true, [])
174    | A.Decl (name, w)          ->
175       let f pars = 
176          let f qid = 
177             let f ww =
178                let entry = (st.line, pars, uri_of_qid qid, ww, None) in
179                H.add st.henv (uri_of_qid qid) pars;
180                f {st with line = succ st.line} (Some entry)
181             in
182             xlate_term f st pars w
183          in
184          complete_qid f st (name, true, [])
185       in
186       get_pars_relaxed f st
187    | A.Def (name, w, trans, v) ->
188       let f pars = 
189          let f qid = 
190             let f ww vv = 
191                let entry = (st.line, pars, uri_of_qid qid, ww, Some (trans, vv)) in
192                H.add st.henv (uri_of_qid qid) pars;
193                f {st with line = succ st.line} (Some entry)
194             in
195             let f ww = xlate_term (f ww) st pars v in
196             xlate_term f st pars w
197          in
198          complete_qid f st (name, true, [])
199       in
200       get_pars_relaxed f st
201
202 (* Interface functions ******************************************************)
203
204 let initial_status ?(cover="") () =
205    initial_status hsize cover
206
207 let meta_of_aut = xlate_item