]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/paramodulation/utils.ml
version 0.7.1
[helm.git] / helm / ocaml / paramodulation / utils.ml
index 8d97e0c4bbb8ca198d2ecf9fb449527432edac13..d6454f2027d4799fdf2dd49bf1ade2bdd685f24d 100644 (file)
@@ -7,8 +7,8 @@ let print_metasenv metasenv =
 ;;
 
 
-let print_subst subst =
-  String.concat "\n"
+let print_subst ?(prefix="\n") subst =
+  String.concat prefix
     (List.map
        (fun (i, (c, t, ty)) ->
           Printf.sprintf "?%d -> %s : %s" i
@@ -27,20 +27,21 @@ let string_of_weight (cw, mw) =
   Printf.sprintf "[%d; %s]" cw s
 
 
-let weight_of_term term =
+let weight_of_term ?(consider_metas=true) term =
   (* ALB: what to consider as a variable? I think "variables" in our case are
      Metas and maybe Rels... *)
   let module C = Cic in
   let vars_dict = Hashtbl.create 5 in
   let rec aux = function
-    | C.Meta (metano, _) ->
+    | C.Meta (metano, _) when consider_metas ->
         (try
            let oldw = Hashtbl.find vars_dict metano in
            Hashtbl.replace vars_dict metano (oldw+1)
          with Not_found ->
            Hashtbl.add vars_dict metano 1);
         0
-          
+    | C.Meta _ -> 0 (* "variables" are lighter than constants and functions...*)
+                  
     | C.Var (_, ens)
     | C.Const (_, ens)
     | C.MutInd (_, _, ens)
@@ -82,6 +83,19 @@ let weight_of_term term =
 ;;
 
 
+let compute_equality_weight ty left right =
+  let metasw = ref 0 in
+  let weight_of t =
+    let w, m = (weight_of_term ~consider_metas:true(* false *) t) in
+(*     let mw = List.fold_left (fun mw (_, c) -> mw + 2 * c) 0 m in *)
+(*     metasw := !metasw + mw; *)
+    metasw := !metasw + (2 * (List.length m));
+    w
+  in
+  (weight_of ty) + (weight_of left) + (weight_of right) + !metasw
+;;
+
+
 (* returns a "normalized" version of the polynomial weight wl (with type
  * weight list), i.e. a list sorted ascending by meta number,
  * from 0 to maxmeta. wl must be sorted descending by meta number. Example:
@@ -221,7 +235,7 @@ let rec aux_ordering t1 t2 =
 
   | t1, t2 when t1 = t2 -> Eq
 
-  | C.Rel n, C.Rel m -> if n > m then Lt else Gt (* ALB: changed < to > *)
+  | C.Rel n, C.Rel m -> if n > m then Lt else Gt
   | C.Rel _, _ -> Lt
   | _, C.Rel _ -> Gt
 
@@ -288,21 +302,127 @@ let names_of_context context =
 ;;
 
 
-let string_of_equality ?env =
-  match env with
-  | None -> (
-      function
-        | _, (ty, left, right), _, _ ->
-            Printf.sprintf "{%s}: %s = %s" (CicPp.ppterm ty)
-              (CicPp.ppterm left) (CicPp.ppterm right)
-    )
-  | Some (_, context, _) -> (
-      let names = names_of_context context in
-      function
-        | _, (ty, left, right), _, _ ->
-            Printf.sprintf "{%s}: %s = %s" (CicPp.pp ty names)
-              (CicPp.pp left names) (CicPp.pp right names)
+module OrderedTerm =
+struct
+  type t = Cic.term
+      
+  let compare = Pervasives.compare
+end
+
+module TermSet = Set.Make(OrderedTerm);;
+module TermMap = Map.Make(OrderedTerm);;
+
+let symbols_of_term term =
+  let module C = Cic in
+  let rec aux map = function
+    | C.Meta _ -> map
+    | C.Appl l ->
+        List.fold_left (fun res t -> (aux res t)) map l
+    | t ->
+        let map = 
+          try
+            let c = TermMap.find t map in
+            TermMap.add t (c+1) map
+          with Not_found ->
+            TermMap.add t 1 map
+        in
+        map
+  in
+  aux TermMap.empty term
+;;
+
+
+let metas_of_term term =
+  let module C = Cic in
+  let rec aux = function
+    | C.Meta _ as t -> TermSet.singleton t
+    | C.Appl l ->
+        List.fold_left (fun res t -> TermSet.union res (aux t)) TermSet.empty l
+    | t -> TermSet.empty (* TODO: maybe add other cases? *)
+  in
+  aux term
+;;
+
+
+let rec lpo t1 t2 =
+  let module C = Cic in
+  match t1, t2 with
+  | t1, t2 when t1 = t2 -> Eq
+  | t1, (C.Meta _ as m) ->
+      if TermSet.mem m (metas_of_term t1) then Gt else Incomparable
+  | (C.Meta _ as m), t2 ->
+      if TermSet.mem m (metas_of_term t2) then Lt else Incomparable
+  | C.Appl (hd1::tl1), C.Appl (hd2::tl2) -> (
+      let res =
+        let f o r t =
+          if r then true else
+            match lpo t o with
+            | Gt | Eq -> true
+            | _ -> false
+        in
+        let res1 = List.fold_left (f t2) false tl1 in
+        if res1 then Gt
+        else let res2 = List.fold_left (f t1) false tl2 in
+        if res2 then Lt
+        else Incomparable
+      in
+      if res <> Incomparable then
+        res
+      else
+        let f o r t =
+          if not r then false else
+            match lpo o t with
+            | Gt -> true
+            | _ -> false
+        in
+        match aux_ordering hd1 hd2 with
+        | Gt ->
+            let res = List.fold_left (f t1) false tl2 in
+            if res then Gt
+            else Incomparable
+        | Lt ->
+            let res = List.fold_left (f t2) false tl1 in
+            if res then Lt
+            else Incomparable
+        | Eq -> (
+            let lex_res =
+              try
+                List.fold_left2
+                  (fun r t1 t2 -> if r <> Eq then r else lpo t1 t2)
+                  Eq tl1 tl2
+              with Invalid_argument _ ->
+                Incomparable
+            in
+            match lex_res with
+            | Gt ->
+                if List.fold_left (f t1) false tl2 then Gt
+                else Incomparable
+            | Lt ->
+                if List.fold_left (f t2) false tl1 then Lt
+                else Incomparable
+            | _ -> Incomparable
+          )
+        | _ -> Incomparable
     )
+  | t1, t2 -> aux_ordering t1 t2
 ;;
 
 
+(* settable by the user... *)
+let compare_terms = ref nonrec_kbo;;
+
+
+type equality_sign = Negative | Positive;;
+
+let string_of_sign = function
+  | Negative -> "Negative"
+  | Positive -> "Positive"
+;;
+
+
+type pos = Left | Right 
+
+let string_of_pos = function
+  | Left -> "Left"
+  | Right -> "Right"
+;;