]> matita.cs.unibo.it Git - helm.git/blobdiff - components/library/coercDb.ml
BIG FAT COMMIT REGARDING COERCIONS:
[helm.git] / components / library / coercDb.ml
index 3a4dac726783e0e6584a8a772efc8d7f1c7aaaa4..9a1fdb0ea85de8434cf529ccfa183151960fb455 100644 (file)
 
 (* $Id$ *)
 
-type coerc_carr = Uri of UriManager.uri | Sort of Cic.sort | Term of Cic.term
+type coerc_carr = 
+  | Uri of UriManager.uri 
+  | Sort of Cic.sort 
+  | Term of Cic.term
+  | Fun of int 
+;;
+
 exception EqCarrNotImplemented of string Lazy.t
 exception EqCarrOnNonMetaClosed
 
@@ -56,6 +62,8 @@ let rec name_of_carr = function
   | Term t -> 
       prerr_endline ("CoercDb.name_of_carr:" ^ CicPp.ppterm t); 
       "FixTheNameMangler"
+  | Fun i -> "FunClass_" ^ string_of_int i   
+;;
 
 let eq_carr src tgt =
   match src, tgt with
@@ -71,35 +79,54 @@ let eq_carr src tgt =
           (lazy ("Unsupported carr for coercions: " ^ 
           CicPp.ppterm t1 ^ " or " ^ CicPp.ppterm t2)))
       else raise EqCarrOnNonMetaClosed
+  | Fun _,Fun _ -> true (* only one Funclass? *)
+(*   | Fun i,Fun j when i=j -> true *)
   | _, _ -> false
+;;
 
 let to_list () =
-  !db
+  List.map (fun (s,t,l) -> s,t,List.map fst l) !db
+;;
 
 let rec myfilter p = function
   | [] -> []
   | (s,t,l)::tl ->
-      let l = List.filter (fun u -> not (p (s,t,u))) l in
+      let l = 
+        HExtlib.filter_map 
+          (fun (u,n) -> 
+            if p (s,t,u) then
+              if n = 1 then
+                None
+              else
+                Some (u,n-1)
+            else
+              Some (u,n)) 
+          l 
+      in
       if l = [] then myfilter p tl else (s,t,l)::myfilter p tl
 ;;
   
 let remove_coercion p = db := myfilter p !db;;
 
 let find_coercion f =
-  List.flatten 
-    (List.map 
-      (fun (_,_,x) -> x) 
-      (List.filter (fun (s,t,_) -> f (s,t)) !db))
+    List.map
+    fst
+    (List.flatten
+    (HExtlib.filter_map (fun (s,t,l) -> if f (s,t) then Some l else None) !db))
 ;;
 
 let is_a_coercion u = 
-  List.exists (fun (_,_,xl) -> List.exists (UriManager.eq u) xl) !db
+  List.exists 
+    (fun (_,_,xl) -> List.exists (fun (x,_) -> UriManager.eq u x) xl) 
+    !db
 ;;
 
 let get_carr uri =
   try
     let src, tgt, _ = 
-      List.find (fun (_,_,xl) -> List.exists (UriManager.eq uri) xl) !db 
+      List.find 
+        (fun (_,_,xl) -> List.exists (fun (x,_) -> UriManager.eq uri x) xl) 
+        !db 
     in
     src, tgt
   with Not_found -> assert false (* uri must be a coercion *)
@@ -108,6 +135,7 @@ let get_carr uri =
 let term_of_carr = function
   | Uri u -> CicUtil.term_of_uri u
   | Sort s -> Cic.Sort s
+  | Fun _ -> assert false
   | Term _ -> assert false
 ;;
   
@@ -116,10 +144,18 @@ let add_coercion (src,tgt,u) =
   let where = List.filter (fun (s,t,_) -> f s t) !db in
   let rest = List.filter (fun (s,t,_) -> not (f s t)) !db in
   match where with
-  | [] -> db := (src,tgt,[u]) :: !db
+  | [] -> db := (src,tgt,[u,1]) :: !db
   | (src,tgt,l)::tl ->
       assert (tl = []); (* not sure, this may be a feature *)
-      db := (src,tgt,u::l)::tl @ rest
+      if List.exists (fun (x,_) -> UriManager.eq u x) l then
+        let l' = List.map 
+          (fun (x,n) -> if UriManager.eq u x then (x,n+1) else (x,n))
+          l
+        in
+        db := (src,tgt,l')::tl @ rest
+      else
+        db := (src,tgt,(u,1)::l)::tl @ rest
+      
 ;;