]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/lambda-delta/toplevel/metaAut.ml
we tranlate an Automath book in an itermediate format where:
[helm.git] / helm / software / lambda-delta / toplevel / metaAut.ml
index ac481a21d0f2b0ab95979b74aca7d73da411eadd..e94fd37bcd0288a32ccb8fb75bd1d3fcee3006c8 100644 (file)
  * http://cs.unibo.it/helm/.
  *)
 
-module H = Hashtbl
 module M = Meta
 module A = Aut
 
 type context_node = M.qid option (* context node: None = root *)
 
-type context = (M.qid, M.term * context_node) H.t (* context: son, parent *)
+type context = (M.qid * M.term * context_node) list (* context: son, parent *)
 
 type status = {
-   genv: M.environment; (* global environment *)
-   path: M.id list;     (* current section path *) 
-   cnt: context;        (* context *)
-   node: context_node;  (* current context node *)
-   explicit: bool       (* need explicit context root? *)
+   genv: M.environment;      (* global environment *)
+   path: M.id list;          (* current section path *) 
+   cnt: context;             (* context *)
+   node: context_node;       (* current context node *)
+   nodes: context_node list; (* context node list *)
+   explicit: bool            (* need explicit context root? *)
 }
 
 type resolver = Local of int
               | Global of M.pars
-             | Unresolved
 
 let initial_status = {
-   genv = []; path = []; cnt = H.create 11; node = None; explicit = true
+   genv = []; path = []; cnt = []; node = None; nodes = []; explicit = true
 }
 
+let find f cnt qid =
+   let rec aux f = function
+      | (name, w, node) :: tl when name = qid -> f tl (Some (w, node))
+      | _ :: tl                               -> aux f tl
+      | []                                    -> f cnt None
+   in
+   aux f cnt
+
 let complete_qid f st (id, is_local, qs) =
    let f qs = f (id, qs) in
-   if is_local then Cps.list_rev_append f st.path ~tail:qs else f qs
+   let f path = Cps.list_rev_append f path ~tail:qs in
+   let rec skip f = function
+      | phd :: ptl, qshd :: _ when phd = qshd -> f ptl
+      | _ :: ptl, _ :: _                      -> skip f (ptl, qs)
+      | _                                     -> f []
+   in
+   if is_local then f st.path else skip f (st.path, qs)
+
+let relax_qid f (id, path) =
+   let f path = f (id, path) in
+   let f = function
+      | _ :: tl -> Cps.list_rev f tl
+      | []      -> assert false
+   in
+   Cps.list_rev f path
+
+let relax_opt_qid f = function
+   | None     -> f None
+   | Some qid -> let f qid = f (Some qid) in relax_qid f qid
 
 let resolve_gref f st lenv gref =
   let rec get_local f i = function
-     | []                              -> f None
-     | (name, _) :: _ when name = gref -> f (Some i)
-     | _ :: tl                         -> get_local f (succ i) tl
+     | []                                      -> f None
+     | (name, _) :: _ when fst name = fst gref -> f (Some i)
+     | _ :: tl                                 -> get_local f (succ i) tl
   in
   let rec get_global f = function
      | []                                       -> f None
@@ -63,15 +88,43 @@ let resolve_gref f st lenv gref =
      | _ :: tl                                  -> get_global f tl
   in
   let g = function
-      | Some args -> f (Global args)
-      | None      -> f Unresolved
+      | Some args -> f gref (Some (Global args))
+      | None      -> f gref None
   in
   let f = function
-      | Some i -> f (Local i)
+      | Some i -> f gref (Some (Local i))
       | None   -> get_global g st.genv
   in
   get_local f 0 lenv
 
+let resolve_gref_relaxed f st lenv gref =
+   let rec g gref = function
+      | None          -> relax_qid (resolve_gref g st lenv) gref
+      | Some resolved -> f gref resolved
+   in
+   resolve_gref g st lenv gref
+
+let get_pars f st pars node =
+   let rec aux f cnt pars = function
+      | None              -> 
+         let f pars = f pars None in
+        Cps.list_rev f pars
+      | Some name as node ->
+        let f cnt = function
+           | Some (w, node) -> aux f cnt ((name, w) :: pars) node
+           | None           -> f pars (Some node)
+        in
+        find f cnt name
+   in
+   aux f st.cnt pars node
+
+let get_pars_relaxed f st =
+   let rec g pars = function
+      | None      -> f pars 
+      | Some node -> relax_opt_qid (get_pars g st pars) node
+   in
+   get_pars g st [] st.node
+
 let rec xlate_term f st lenv = function
    | A.Sort sort         -> f (M.Sort sort)
    | A.Appl (v, t)       ->
@@ -98,18 +151,18 @@ let rec xlate_term f st lenv = function
               Cps.list_sub_strict f defs args
            in
            Cps.list_map f map1 args
-        | Unresolved  -> assert false
       in
-      let f name = resolve_gref (f name) st lenv name in
+      let f name = resolve_gref_relaxed f st lenv name in
       complete_qid f st name
 
 let xlate_item f st = function
    | A.Section (Some name)     ->
-      f {st with path = name :: st.path}
+      f {st with path = name :: st.path; nodes = st.node :: st.nodes}
    | A.Section None            ->
-      begin match st.path with
-         | []      -> assert false
-        | _ :: tl -> f {st with path = tl}
+      begin match st.path, st.nodes with
+        | _ :: ptl, nhd :: ntl -> 
+           f {st with path = ptl; node = nhd; nodes = ntl}
+         | _                    -> assert false
       end
    | A.Context None            ->
       f {st with node = None}
@@ -117,11 +170,40 @@ let xlate_item f st = function
       let f name = f {st with node = Some name} in
       complete_qid f st name
    | A.Block (name, w)         ->
-      let f name ww = H.add st.cnt name (ww, st.node); f st in
-      let f name = xlate_term (f name) st [] w in
-      complete_qid f st (name, true, [])   
-   | A.Decl (name, w)          -> f st 
-   | A.Def (name, w, trans, v) -> f st
+      let f name = 
+         let f ww = 
+           let st = {st with cnt = (name, ww, st.node) :: st.cnt} in
+           f {st with node = Some name}
+        in
+         let f pars = xlate_term f st pars w in
+         get_pars_relaxed f st
+      in
+      complete_qid f st (name, true, [])
+   | A.Decl (name, w)          ->
+      let f pars = 
+         let f name = 
+            let f ww =
+              let entry = (pars, name, ww, None) in
+              f {st with genv = entry :: st.genv}
+           in
+           xlate_term f st pars w
+        in
+         complete_qid f st (name, true, [])
+      in
+      get_pars_relaxed f st
+   | A.Def (name, w, trans, v) ->
+      let f pars = 
+         let f name = 
+            let f ww vv = 
+              let entry = (pars, name, ww, Some (trans, vv)) in
+              f {st with genv = entry :: st.genv}
+           in
+           let f ww = xlate_term (f ww) st pars v in
+           xlate_term f st pars w
+        in
+         complete_qid f st (name, true, [])
+      in
+      get_pars_relaxed f st
 
 let meta_of_aut f book =
    let f st = f st.genv in