]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/paramodulation/saturation.ml
fixes (mainly) to demodulation and meta_convertibility
[helm.git] / helm / ocaml / paramodulation / saturation.ml
index 6508e75dac896900d9941f3a486685b7c463757b..a0148fb358398b9cd89cc8fff49827bf84ae399c 100644 (file)
@@ -22,32 +22,84 @@ struct
   let compare eq1 eq2 =
     match meta_convertibility_eq eq1 eq2 with
     | true -> 0
-    | false -> Pervasives.compare eq1 eq2
+    | false ->
+        let _, (ty, left, right), _, _ = eq1
+        and _, (ty', left', right'), _, _ = eq2 in
+        let weight_of t = fst (weight_of_term ~consider_metas:false t) in
+        let w1 = (weight_of ty) + (weight_of left) + (weight_of right)
+        and w2 = (weight_of ty') + (weight_of left') + (weight_of right') in
+        match Pervasives.compare w1 w2 with
+        | 0 -> Pervasives.compare eq1 eq2
+        | res -> res
 end
 
 module EqualitySet = Set.Make(OrderedEquality);;
-    
 
 
+let weight_age_ratio = ref 0;; (* settable by the user from the command line *)
+let weight_age_counter = ref !weight_age_ratio;;
+
+let set_selection = ref (fun set -> EqualitySet.min_elt set);;
+
 let select env passive =
-  match passive with
-  | hd::tl, pos -> (Negative, hd), (tl, pos)
-  | [], hd::tl -> (Positive, hd), ([], tl)
-  | _, _ -> assert false
+  let (neg_list, neg_set), (pos_list, pos_set) = passive in
+  if !weight_age_ratio > 0 then
+    weight_age_counter := !weight_age_counter - 1;
+  match !weight_age_counter with
+  | 0 -> (
+      weight_age_counter := !weight_age_ratio;
+      match neg_list, pos_list with
+      | hd::tl, pos ->
+          (Negative, hd), ((tl, EqualitySet.remove hd neg_set), (pos, pos_set))
+      | [], hd::tl ->
+          (Positive, hd), (([], neg_set), (tl, EqualitySet.remove hd pos_set))
+      | _, _ -> assert false
+    )
+  | _ ->
+      let remove eq l =
+        List.filter (fun e -> not (e = eq)) l
+      in
+      if EqualitySet.is_empty neg_set then
+        let current = !set_selection pos_set in
+        let passive =
+          (neg_list, neg_set),
+          (remove current pos_list, EqualitySet.remove current pos_set)
+        in
+        (Positive, current), passive
+      else
+        let current = !set_selection neg_set in
+        let passive =
+          (remove current neg_list, EqualitySet.remove current neg_set),
+          (pos_list, pos_set)
+        in
+        (Negative, current), passive
 ;;
 
 
-(*
-let select env passive =
-  match passive with
-  | neg, pos when EqualitySet.is_empty neg ->
-      let elem = EqualitySet.min_elt pos in
-      (Positive, elem), (neg, EqualitySet.remove elem pos)
-  | neg, pos ->
-      let elem = EqualitySet.min_elt neg in
-      (Negative, elem), (EqualitySet.remove elem neg, pos)
+let make_passive neg pos =
+  let set_of equalities =
+    List.fold_left (fun s e -> EqualitySet.add e s) EqualitySet.empty equalities
+  in
+  (neg, set_of neg), (pos, set_of pos)
+;;
+
+
+let add_to_passive passive (new_neg, new_pos) =
+  let (neg_list, neg_set), (pos_list, pos_set) = passive in
+  let ok set equality = not (EqualitySet.mem equality set) in
+  let neg = List.filter (ok neg_set) new_neg
+  and pos = List.filter (ok pos_set) new_pos in
+  let add set equalities =
+    List.fold_left (fun s e -> EqualitySet.add e s) set equalities
+  in
+  (neg @ neg_list, add neg_set neg), (pos_list @ pos, add pos_set pos)
+;;
+
+
+let passive_is_empty = function
+  | ([], _), ([], _) -> true
+  | _ -> false
 ;;
-*)
 
 
 (* TODO: find a better way! *)
@@ -104,54 +156,32 @@ let contains_empty env (negative, positive) =
 ;;
 
 
-let add_to_passive (passive_neg, passive_pos) (new_neg, new_pos) =
-  let find sign eq1 eq2 =
-    if meta_convertibility_eq eq1 eq2 then (
-(*       Printf.printf "Trovato equazione duplicata di segno %s\n%s\n\n" *)
-(*         (string_of_sign sign) (string_of_equality eq1); *)
-      true
-    ) else
-      false
-  in
-  let ok sign equalities equality =
-    not (List.exists (find sign equality) equalities)
-  in
-  let neg = List.filter (ok Negative passive_neg) new_neg in
-  let pos = List.filter (ok Positive passive_pos) new_pos in
-(*   let neg, pos = new_neg, new_pos in *)
-  (neg @ passive_neg, passive_pos @ pos)
-;;
-
-
-let is_identity ((_, context, ugraph) as env) = function
-  | ((_, (ty, left, right), _, _) as equality) ->
-      let res =
-        (left = right ||
-            (fst (CicReduction.are_convertible context left right ugraph)))
-      in
-(*       if res then ( *)
-(*         Printf.printf "is_identity: %s" (string_of_equality ~env equality); *)
-(*         print_newline (); *)
-(*       ); *)
-      res
-;;
-
-
 let forward_simplify env (sign, current) active =
-(*   if sign = Negative then *)
-(*     Some (sign, current) *)
-(*   else *)
-    let rec aux env (sign, current) =
-      function
-        | [] -> Some (sign, current)
-        | (Negative, _)::tl -> aux env (sign, current) tl
-        | (Positive, equality)::tl ->
-            let newmeta, current = demodulation !maxmeta env current equality in
-            maxmeta := newmeta;
-            if is_identity env current then
-              None
-            else
-              aux env (sign, current) tl
+  (* first step, remove already present equalities *)
+  let duplicate =
+    let rec aux = function
+      | [] -> false
+      | (s, eq)::tl when s = sign ->
+          if meta_convertibility_eq current eq then true
+          else aux tl
+      | _::tl -> aux tl
+    in
+    aux active
+  in
+  if duplicate then
+    None
+  else
+    let rec aux env (sign, current) = function
+      | [] -> Some (sign, current)
+      | (Negative, _)::tl -> aux env (sign, current) tl
+      | (Positive, equality)::tl ->
+          let newmeta, current =
+            demodulation !maxmeta env current equality in
+          maxmeta := newmeta;
+          if is_identity env current then
+            None
+          else
+            aux env (sign, current) tl
     in
     aux env (sign, current) active
 ;;
@@ -204,22 +234,12 @@ let backward_simplify env (sign, current) active =
         (fun (s, eq) res -> if find eq res then res else (s, eq)::res)
         active []
 ;;
-      
-
-(*
-let add_to_passive (passive_neg, passive_pos) (new_neg, new_pos) =
-  let add_all = List.fold_left (fun res eq -> EqualitySet.add eq res) in
-  add_all passive_neg new_neg, add_all passive_pos new_pos
-;;
-*)
 
 
 let rec given_clause env passive active =
-  match passive with
-(*   | s1, s2 when (EqualitySet.is_empty s1) && (EqualitySet.is_empty s2) -> *)
-(*       Failure *)
-  | [], [] -> Failure
-  | passive ->
+  match passive_is_empty passive with
+  | true -> Failure
+  | false ->
 (*       Printf.printf "before select\n"; *)
       let (sign, current), passive = select env passive in
 (*       Printf.printf "before simplification: sign: %s\ncurrent: %s\n\n" *)
@@ -232,17 +252,19 @@ let rec given_clause env passive active =
           let proof, _, _, _ = current in
           Success (Some proof, env)
       | None ->
-          Printf.printf "avanti... %s %s" (string_of_sign sign)
-            (string_of_equality ~env current);
-          print_newline ();
+(*           Printf.printf "avanti... %s %s" (string_of_sign sign) *)
+(*             (string_of_equality ~env current); *)
+(*           print_newline (); *)
           given_clause env passive active
       | Some (sign, current) ->
-(*           Printf.printf "sign: %s\ncurrent: %s\n" *)
+(*           Printf.printf "selected: %s %s" *)
 (*             (string_of_sign sign) (string_of_equality ~env current); *)
 (*           print_newline (); *)
 
           let new' = infer env sign current active in
 
+          let new' = forward_simplify_new env new' active in
+          
           let active =
             backward_simplify env (sign, current) active
 (*             match new' with *)
@@ -250,8 +272,6 @@ let rec given_clause env passive active =
 (*             | _ -> active *)
           in
 
-          let new' = forward_simplify_new env new' active in
-          
           print_endline "\n================================================";
           let _ =
             Printf.printf "active:\n%s\n"
@@ -261,6 +281,7 @@ let rec given_clause env passive active =
                         (string_of_equality ~env e)) active)));
             print_newline ();
           in
+
 (*           let _ = *)
 (*             match new' with *)
 (*             | neg, pos -> *)
@@ -323,12 +344,7 @@ let main () =
     let term_equality = equality_of_term meta_proof goal in
     let meta_proof, (eq_ty, left, right), _, _ = term_equality in
     let active = [] in
-(*     let passive = *)
-(*       (EqualitySet.singleton term_equality, *)
-(*        List.fold_left *)
-(*          (fun res eq -> EqualitySet.add eq res) EqualitySet.empty equalities) *)
-(*     in *)
-    let passive = [term_equality], equalities in
+    let passive = make_passive [term_equality] equalities in
     Printf.printf "\ncurrent goal: %s ={%s} %s\n"
       (PP.ppterm left) (PP.ppterm eq_ty) (PP.ppterm right);
     Printf.printf "\ncontext:\n%s\n" (PP.ppcontext context);
@@ -362,8 +378,21 @@ let main () =
 ;;
 
 
+let configuration_file = ref "../../gTopLevel/gTopLevel.conf.xml";;
+
 let _ =
-  let configuration_file = "../../gTopLevel/gTopLevel.conf.xml" in
-  Helm_registry.load_from configuration_file
+  let set_ratio v = weight_age_ratio := v; weight_age_counter := v
+  and set_sel () = set_selection := (fun s -> EqualitySet.max_elt s)
+  and set_conf f = configuration_file := f
+  in
+  Arg.parse [
+    "-r", Arg.Int set_ratio, "Weight-Age equality selection ratio";
+
+    "-i", Arg.Unit set_sel,
+    "Inverse selection (select heaviest equalities before)";
+
+    "-c", Arg.String set_conf, "Configuration file (for the db connection)";
+  ] (fun a -> ()) "Usage:"
 in
+Helm_registry.load_from !configuration_file;
 main ()