]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_notation/cicNotationRew.ml
Better handling of idref propagation, no more Href hack, multiple idrefs are
[helm.git] / helm / ocaml / cic_notation / cicNotationRew.ml
index 6340d88a15db67f3dddc364540bfddfb702dac02..ddf429db6d469f36a8d1542adf30ad63f0a1fcbc 100644 (file)
@@ -80,7 +80,8 @@ let rec remove_level_info =
   | Ast.AttributedTerm (a, t) -> Ast.AttributedTerm (a, remove_level_info t)
   | t -> t
 
-let add_xml_attrs attrs t = Ast.AttributedTerm (`XmlAttrs attrs, t)
+let add_xml_attrs attrs t =
+  if attrs = [] then t else Ast.AttributedTerm (`XmlAttrs attrs, t)
 
 let add_keyword_attrs =
   add_xml_attrs (RenderingAttrs.keyword_attributes `MathML)
@@ -106,7 +107,9 @@ let ident i =
 let ident_w_href href i =
   match href with
   | None -> ident i
-  | Some href -> Ast.AttributedTerm (`Href [href], ident i)
+  | Some href ->
+      let href = UriManager.string_of_uri href in
+      add_xml_attrs [Some "xlink", "href", href] (ident i)
 
 let binder_symbol s =
   add_xml_attrs (RenderingAttrs.builtin_symbol_attributes `MathML)
@@ -269,7 +272,8 @@ let pp_ast0 t k =
 
 let ast_of_acic0 term_info acic k =
   let k = k term_info in
-  let register_uri id uri = Hashtbl.add term_info.uri id uri in
+  let id_to_uris = term_info.uri in
+  let register_uri id uri = Hashtbl.add id_to_uris id uri in
   let sort_of_id id =
     try
       Hashtbl.find term_info.sort id
@@ -418,11 +422,18 @@ let get_compiled32 () =
 let set_compiled21 f = compiled21 := Some f
 let set_compiled32 f = compiled32 := Some f
 
-let instantiate21 env l1 =
-  let rec subst_singleton env t =
-    CicNotationUtil.group (subst env t)
+let add_idrefs =
+  List.fold_right (fun idref t -> Ast.AttributedTerm (`IdRef idref, t))
+
+let instantiate21 idrefs env l1 =
+  let rec subst_singleton env =
+    function
+      Ast.AttributedTerm (attr, t) ->
+        Ast.AttributedTerm (attr, subst_singleton env t)
+    | t -> CicNotationUtil.group (subst env t)
   and subst env = function
-    | Ast.AttributedTerm (attr, t) -> subst env t
+    | Ast.AttributedTerm (attr, t) as term ->
+        subst env t
     | Ast.Variable var ->
         let name, expected_ty = CicNotationEnv.declaration_of_var var in
         let ty, value =
@@ -438,8 +449,11 @@ let instantiate21 env l1 =
         assert (CicNotationEnv.well_typed expected_ty value);
         [ CicNotationEnv.term_of_value value ]
     | Ast.Magic m -> subst_magic env m
-    | Ast.Literal (`Keyword k) as t -> [ add_keyword_attrs t ]
-    | Ast.Literal _ as t -> [ t ]
+    | Ast.Literal l as t ->
+        let t = add_idrefs idrefs t in
+        (match l with
+        | `Keyword k -> [ add_keyword_attrs t ]
+        | _ -> [ t ])
     | Ast.Layout l -> [ Ast.Layout (subst_layout env l) ]
     | t -> [ CicNotationUtil.visit_ast (subst_singleton env) t ]
   and subst_magic env = function
@@ -509,19 +523,24 @@ let rec pp_ast1 term =
   in
 (* prerr_endline ("pattern matching from 2 to 1 on term " ^ CicNotationPp.pp_term term); *)
   match term with
-  | Ast.AttributedTerm (attrs, term) -> Ast.AttributedTerm (attrs, pp_ast1 term)
+  | Ast.AttributedTerm (attrs, term') ->
+      Ast.AttributedTerm (attrs, pp_ast1 term')
   | _ ->
       (match (get_compiled21 ()) term with
       | None -> pp_ast0 term pp_ast1
-      | Some (env, pid) ->
+      | Some (env, ctors, pid) ->
+          let idrefs =
+            List.flatten (List.map CicNotationUtil.get_idrefs ctors)
+          in
           let prec, assoc, l1 =
             try
               Hashtbl.find level1_patterns21 pid
             with Not_found -> assert false
           in
-          add_level_info prec assoc (instantiate21 (ast_env_of_env env) l1))
+          add_level_info prec assoc
+            (instantiate21 idrefs (ast_env_of_env env) l1))
 
-let instantiate32 term_info env symbol args =
+let instantiate32 term_info idrefs env symbol args =
   let rec instantiate_arg = function
     | Ast.IdentArg (n, name) ->
         let t = (try List.assoc name env with Not_found -> assert false) in
@@ -540,28 +559,41 @@ let instantiate32 term_info env symbol args =
         in
         add_lambda t (n - count_lambda t)
   in
-  let head = Ast.Symbol (symbol, 0) in
-  match args with
-  | [] -> head
-  | _ -> Ast.Appl (head :: List.map instantiate_arg args)
+  let head =
+    let symbol = Ast.Symbol (symbol, 0) in
+    add_idrefs idrefs symbol
+  in
+  if args = [] then head
+  else Ast.Appl (head :: List.map instantiate_arg args)
 
 let rec ast_of_acic1 term_info annterm = 
+  let id_to_uris = term_info.uri in
+  let register_uri id uri = Hashtbl.add id_to_uris id uri in
   match (get_compiled32 ()) annterm with
   | None -> ast_of_acic0 term_info annterm ast_of_acic1
-  | Some (env, pid) -> 
+  | Some (env, ctors, pid) -> 
+      let idrefs =
+        List.map
+          (fun annterm ->
+            let idref = CicUtil.id_of_annterm annterm in
+            (try
+              register_uri idref
+                (UriManager.string_of_uri
+                  (CicUtil.uri_of_term (Deannotate.deannotate_term annterm)))
+            with Invalid_argument _ -> ());
+            idref)
+          ctors
+      in
       let env' =
         List.map (fun (name, term) -> (name, ast_of_acic1 term_info term)) env
       in
-      let _, symbol, args, _, uris =
+      let _, symbol, args, _ =
         try
           Hashtbl.find level2_patterns32 pid
         with Not_found -> assert false
       in
-      let ast = instantiate32 term_info env' symbol args in
-      Ast.AttributedTerm (`IdRef (CicUtil.id_of_annterm annterm),
-        (match uris with
-        | [] -> ast
-        | _ -> Ast.AttributedTerm (`Href uris, ast)))
+      let ast = instantiate32 term_info idrefs env' symbol args in
+      Ast.AttributedTerm (`IdRef (CicUtil.id_of_annterm annterm), ast)
 
 let load_patterns32 t =
   set_compiled32 (lazy (CicNotationMatcher.Matcher32.compiler t))
@@ -591,8 +623,7 @@ let fresh_id =
 
 let add_interpretation dsc (symbol, args) appl_pattern =
   let id = fresh_id () in
-  let uris = CicNotationUtil.find_appl_pattern_uris appl_pattern in
-  Hashtbl.add level2_patterns32 id (dsc, symbol, args, appl_pattern, uris);
+  Hashtbl.add level2_patterns32 id (dsc, symbol, args, appl_pattern);
   pattern32_matrix := (appl_pattern, id) :: !pattern32_matrix;
   load_patterns32 !pattern32_matrix;
   (try
@@ -616,7 +647,7 @@ let lookup_interpretations symbol =
     (List.sort Pervasives.compare
      (List.map
       (fun id ->
-        let (dsc, _, args, appl_pattern, _) =
+        let (dsc, _, args, appl_pattern) =
           try
             Hashtbl.find level2_patterns32 id
           with Not_found -> assert false 
@@ -635,7 +666,7 @@ let add_pretty_printer ~precedence ~associativity l2 l1 =
 
 let remove_interpretation id =
   (try
-    let _, symbol, _, _, _ = Hashtbl.find level2_patterns32 id in
+    let _, symbol, _, _ = Hashtbl.find level2_patterns32 id in
     let ids = Hashtbl.find interpretations symbol in
     ids := List.filter ((<>) id) !ids;
     Hashtbl.remove level2_patterns32 id;