]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/paramodulation/inference.ml
fixes (mainly) to demodulation and meta_convertibility
[helm.git] / helm / ocaml / paramodulation / inference.ml
index c4b0a842f26c163c513dfc25089736a860f872ea..987c17cc83950fb00baeaff2b7825861b5081e20 100644 (file)
@@ -9,11 +9,18 @@ let meta_convertibility_aux table t1 t2 =
     match t1, t2 with
     | t1, t2 when t1 = t2 -> table
     | C.Meta (m1, tl1), C.Meta (m2, tl2) ->
-        let m1_binding, table =
-          try List.assoc m1 table, table
-          with Not_found -> m2, (m1, m2)::table
+        let m1_binding, m2_binding, table =
+          let m1b, table = 
+            try List.assoc m1 table, table
+            with Not_found -> m2, (m1, m2)::table
+          in
+          let m2b, table = 
+            try List.assoc m2 table, table
+            with Not_found -> m1, (m2, m1)::table
+          in
+          m1b, m2b, table
         in
-        if m1_binding <> m2 then
+        if m1_binding <> m2 || m2_binding <> m1 then
           raise NotMetaConvertible
         else (
           try
@@ -105,17 +112,18 @@ let meta_convertibility_eq eq1 eq2 =
     in
     try
       let table = meta_convertibility_aux [] left left' in
-(*       print_table table "before"; *)
       let _ = meta_convertibility_aux table right right' in
-(*       print_table table "after"; *)
+(*       Printf.printf "meta_convertibility_eq, ok:\n%s\n%s\n" *)
+(*         (string_of_equality eq1) (string_of_equality eq2); *)
+(*       print_newline (); *)
       true
     with NotMetaConvertible ->
-(*       Printf.printf "NotMetaConvertible:\n%s = %s\n%s = %s\n\n" *)
-(*         (CicPp.ppterm left) (CicPp.ppterm right) *)
-(*         (CicPp.ppterm left') (CicPp.ppterm right'); *)
       try
         let table = meta_convertibility_aux [] left right' in
         let _ = meta_convertibility_aux table right left' in
+(*         Printf.printf "meta_convertibility_eq, ok:\n%s\n%s\n" *)
+(*           (string_of_equality eq1) (string_of_equality eq2); *)
+(*         print_newline (); *)
         true
       with NotMetaConvertible ->
         false
@@ -135,6 +143,13 @@ let beta_expand ?(metas_ok=true) ?(match_only=false)
     what type_of_what where context metasenv ugraph = 
   let module S = CicSubstitution in
   let module C = Cic in
+(*   let _ = *)
+(*     let names = names_of_context context in *)
+(*     Printf.printf "beta_expand:\nwhat: %s, %s\nwhere: %s, %s\n" *)
+(*       (CicPp.pp what names) (CicPp.ppterm what) *)
+(*       (CicPp.pp where names) (CicPp.ppterm where); *)
+(*     print_newline (); *)
+(*   in *)
   (*
     return value:
     ((list of all possible beta expansions, subst, metasenv, ugraph),
@@ -381,6 +396,8 @@ let beta_expand ?(metas_ok=true) ?(match_only=false)
       | _ ->
           try
             let subst', metasenv', ugraph' =
+(*               Printf.printf "provo a unificare %s e %s\n" *)
+(*                 (CicPp.ppterm (S.lift lift_amount what)) (CicPp.ppterm term); *)
               CicUnification.fo_unif metasenv context
                 (S.lift lift_amount what) term ugraph
             in
@@ -390,11 +407,11 @@ let beta_expand ?(metas_ok=true) ?(match_only=false)
 (*           Printf.printf "metasenv': %s\n" (print_metasenv metasenv'); *)
             (* Printf.printf "metasenv: %s\n\n" (print_metasenv metasenv); *)
             if match_only then
-              let term' = CicMetaSubst.apply_subst subst' term in
-              if not (meta_convertibility term term') then (
-(*                 let names = names_of_context context in *)
-(*                 Printf.printf "\nterm e term' sono diversi!:\n%s\n%s\n\n" *)
-(*                   (CicPp.pp term names) (CicPp.pp term' names); *)
+              let t' = CicMetaSubst.apply_subst subst' term in
+              if not (meta_convertibility term t') then (
+                let names = names_of_context context in
+(*                 Printf.printf "\nbeta_expand: term e t' sono diversi!:\n%s\n%s\n\n" *)
+(*                   (CicPp.pp term names) (CicPp.pp t' names); *)
                 res, lifted_term
               )
               else
@@ -403,7 +420,8 @@ let beta_expand ?(metas_ok=true) ?(match_only=false)
             else
               ((C.Rel (1 + lift_amount), subst', metasenv', ugraph')::res,
                lifted_term)
-          with _ ->
+          with e ->
+(*             print_endline ("beta_expand ERROR!: " ^ (Printexc.to_string e)); *)
             res, lifted_term
     in
 (*     Printf.printf "exit aux\n"; *)
@@ -514,11 +532,14 @@ let find_equalities ?(eq_uri=HelmLibraryObjects.Logic.eq_URI) context proof =
 
 
 let fix_metas newmeta ((proof, (ty, left, right), menv, args) as equality) =
+  let table = Hashtbl.create (List.length args) in
   let newargs, _ =
     List.fold_right
       (fun t (newargs, index) ->
          match t with
-         | Cic.Meta (i, l) -> ((Cic.Meta (index, l))::newargs, index+1)
+         | Cic.Meta (i, l) ->
+             Hashtbl.add table i index;
+             ((Cic.Meta (index, l))::newargs, index+1)
          | _ -> assert false)
       args ([], newmeta)
   in
@@ -526,11 +547,15 @@ let fix_metas newmeta ((proof, (ty, left, right), menv, args) as equality) =
     ProofEngineReduction.replace ~equality:(=) ~what:args ~with_what:newargs
       ~where
   in
-  let menv', _ =
+  let menv' =
     List.fold_right
-      (fun (i, context, term) (menv, index) ->
-         ((index, context, term)::menv, index+1))
-      menv ([], newmeta)
+      (fun (i, context, term) menv ->
+         try
+           let index = Hashtbl.find table i in
+           (index, context, term)::menv
+         with Not_found ->
+           (i, context, term)::menv)
+      menv []
   in
   (newmeta + (List.length newargs) + 1,
    (repl proof, (repl ty, repl left, repl right), menv', newargs))
@@ -562,62 +587,66 @@ let superposition_left (metasenv, context, ugraph) target source =
   let eqproof, (ty, t1, t2), newmetas, args = source in
 
   (* ALB: TODO check that ty and eq_ty are indeed equal... *)
-  assert (eq_ty = ty);
-  
-  let where, is_left =
-    match nonrec_kbo left right with
-    | Lt -> right, false
-    | Gt -> left, true
-    | _ -> (
-        Printf.printf "????????? %s = %s" (CicPp.ppterm left)
-          (CicPp.ppterm right);
-        print_newline ();
-        assert false (* again, for ground terms this shouldn't happen... *)
-      )
-  in
-  let metasenv' = newmetas @ metasenv in
-  let res1 =
-    List.filter
-      (fun (t, s, m, ug) ->
-         nonrec_kbo (M.apply_subst s t1) (M.apply_subst s t2) = Gt)
-      (beta_expand t1 ty where context metasenv' ugraph)
-  and res2 =
-    List.filter
-      (fun (t, s, m, ug) ->
-         nonrec_kbo (M.apply_subst s t2) (M.apply_subst s t1) = Gt)
-      (beta_expand t2 ty where context metasenv' ugraph)
-  in
-(*   let what, other = *)
-(*     if is_left then left, right *)
-(*     else right, left *)
-(*   in *)
-  let build_new what other eq_URI (t, s, m, ug) =
-    let newgoal, newgoalproof =
-      match t with
-      | C.Lambda (nn, ty, bo) ->
-          let bo' = S.subst (M.apply_subst s other) bo in
-          let bo'' =
-            C.Appl (
-              [C.MutInd (HL.Logic.eq_URI, 0, []);
-               S.lift 1 eq_ty] @
-                if is_left then [bo'; S.lift 1 right] else [S.lift 1 left; bo'])
-          in
-          let t' = C.Lambda (nn, ty, bo'') in
-          S.subst (M.apply_subst s other) bo,
-          M.apply_subst s
-            (C.Appl [C.Const (eq_URI, []); ty; what; t';
-                     proof; other; eqproof])
-      | _ -> assert false
+  (* assert (eq_ty = ty); *)
+
+  if eq_ty <> ty then
+    []
+  else    
+    let where, is_left =
+      match nonrec_kbo left right with
+      | Lt -> right, false
+      | Gt -> left, true
+      | _ -> (
+          Printf.printf "????????? %s = %s" (CicPp.ppterm left)
+            (CicPp.ppterm right);
+          print_newline ();
+          assert false (* again, for ground terms this shouldn't happen... *)
+        )
     in
-    let equation =
-      if is_left then (eq_ty, newgoal, right)
-      else (eq_ty, left, newgoal)
+    let metasenv' = newmetas @ metasenv in
+    let res1 =
+      List.filter
+        (fun (t, s, m, ug) ->
+           nonrec_kbo (M.apply_subst s t1) (M.apply_subst s t2) = Gt)
+        (beta_expand t1 ty where context metasenv' ugraph)
+    and res2 =
+      List.filter
+        (fun (t, s, m, ug) ->
+           nonrec_kbo (M.apply_subst s t2) (M.apply_subst s t1) = Gt)
+        (beta_expand t2 ty where context metasenv' ugraph)
     in
-    (eqproof, equation, [], [])
-  in
-  let new1 = List.map (build_new t1 t2 HL.Logic.eq_ind_URI) res1
-  and new2 = List.map (build_new t2 t1 HL.Logic.eq_ind_r_URI) res2 in
-  new1 @ new2
+    (*   let what, other = *)
+    (*     if is_left then left, right *)
+    (*     else right, left *)
+    (*   in *)
+    let build_new what other eq_URI (t, s, m, ug) =
+      let newgoal, newgoalproof =
+        match t with
+        | C.Lambda (nn, ty, bo) ->
+            let bo' = S.subst (M.apply_subst s other) bo in
+            let bo'' =
+              C.Appl (
+                [C.MutInd (HL.Logic.eq_URI, 0, []);
+                 S.lift 1 eq_ty] @
+                  if is_left then [bo'; S.lift 1 right]
+                  else [S.lift 1 left; bo'])
+            in
+            let t' = C.Lambda (nn, ty, bo'') in
+            S.subst (M.apply_subst s other) bo,
+            M.apply_subst s
+              (C.Appl [C.Const (eq_URI, []); ty; what; t';
+                       proof; other; eqproof])
+        | _ -> assert false
+      in
+      let equation =
+        if is_left then (eq_ty, newgoal, right)
+        else (eq_ty, left, newgoal)
+      in
+      (eqproof, equation, [], [])
+    in
+    let new1 = List.map (build_new t1 t2 HL.Logic.eq_ind_URI) res1
+    and new2 = List.map (build_new t2 t1 HL.Logic.eq_ind_r_URI) res2 in
+    new1 @ new2
 ;;
 
 
@@ -632,84 +661,103 @@ let superposition_right newmeta (metasenv, context, ugraph) target source =
   let maxmeta = ref newmeta in
 
   (* TODO check if ty and ty' are equal... *)
-  assert (eq_ty = ty');
-  
-(*   let ok term subst other other_eq_side ugraph = *)
-(*     match term with *)
-(*     | C.Lambda (nn, ty, bo) -> *)
-(*         let bo' = S.subst (M.apply_subst subst other) bo in *)
-(*         let res, _ = CR.are_convertible context bo' other_eq_side ugraph in *)
-(*         not res *)
-(*     |  _ -> assert false *)
-(*   in *)
-  let condition left right what other (t, s, m, ug) =
-    let subst = M.apply_subst s in
-    let cmp1 = nonrec_kbo (subst what) (subst other) in
-    let cmp2 = nonrec_kbo (subst left) (subst right) in
-(*     cmp1 = Gt && cmp2 = Gt *)
-    cmp1 <> Lt && cmp1 <> Le && cmp2 <> Lt && cmp2 <> Le
-(*     && (ok t s other right ug) *)
-  in
-  let metasenv' = metasenv @ newmetas @ newm' in
-  let beta_expand = beta_expand ~metas_ok:false in
-  let res1 =
-    List.filter
-      (condition left right t1 t2)
-      (beta_expand t1 eq_ty left context metasenv' ugraph)
-  and res2 =
-    List.filter
-      (condition left right t2 t1)
-      (beta_expand t2 eq_ty left context metasenv' ugraph)
-  and res3 =
-    List.filter
-      (condition right left t1 t2)
-      (beta_expand t1 eq_ty right context metasenv' ugraph)
-  and res4 =
-    List.filter
-      (condition right left t2 t1)
-      (beta_expand t2 eq_ty right context metasenv' ugraph)
-  in
-  let newmetas = newmetas @ newm' in
-  let newargs = args @ args' in
-  let build_new what other is_left eq_URI (t, s, m, ug) =
-(*     let what, other = *)
-(*       if is_left then left, right *)
-(*       else right, left *)
-(*     in *)
-    let newterm, neweqproof =
-      match t with
-      | C.Lambda (nn, ty, bo) ->
-          let bo' = M.apply_subst s (S.subst other bo) in
-          let bo'' =
-            C.Appl (
-              [C.MutInd (HL.Logic.eq_URI, 0, []); S.lift 1 eq_ty] @
-                if is_left then [bo'; S.lift 1 right] else [S.lift 1 left; bo'])
-          in
-          let t' = C.Lambda (nn, ty, bo'') in
-          bo',
-          M.apply_subst s
-            (C.Appl [C.Const (eq_URI, []); ty; what; t'; eqproof; other; eqp'])
-      | _ -> assert false
+  (* assert (eq_ty = ty'); *)
+
+  if eq_ty <> ty' then
+    newmeta, []
+  else
+    (*   let ok term subst other other_eq_side ugraph = *)
+    (*     match term with *)
+    (*     | C.Lambda (nn, ty, bo) -> *)
+    (*         let bo' = S.subst (M.apply_subst subst other) bo in *)
+    (*         let res, _ = CR.are_convertible context bo' other_eq_side ugraph in *)
+    (*         not res *)
+    (*     |  _ -> assert false *)
+    (*   in *)
+    let condition left right what other (t, s, m, ug) =
+      let subst = M.apply_subst s in
+      let cmp1 = nonrec_kbo (subst what) (subst other) in
+      let cmp2 = nonrec_kbo (subst left) (subst right) in
+      (*     cmp1 = Gt && cmp2 = Gt *)
+      cmp1 <> Lt && cmp1 <> Le && cmp2 <> Lt && cmp2 <> Le
+        (*     && (ok t s other right ug) *)
     in
-    let newmeta, newequality =
-      let left, right =
-        if is_left then (newterm, M.apply_subst s right)
-        else (M.apply_subst s left, newterm) in
-      fix_metas !maxmeta
-        (neweqproof, (eq_ty, left, right), newmetas, newargs)
+    let metasenv' = metasenv @ newmetas @ newm' in
+    let beta_expand = beta_expand ~metas_ok:false in
+    let res1 =
+      List.filter
+        (condition left right t1 t2)
+        (beta_expand t1 eq_ty left context metasenv' ugraph)
+    and res2 =
+      List.filter
+        (condition left right t2 t1)
+        (beta_expand t2 eq_ty left context metasenv' ugraph)
+    and res3 =
+      List.filter
+        (condition right left t1 t2)
+        (beta_expand t1 eq_ty right context metasenv' ugraph)
+    and res4 =
+      List.filter
+        (condition right left t2 t1)
+        (beta_expand t2 eq_ty right context metasenv' ugraph)
     in
-    maxmeta := newmeta;
-    newequality
-  in
-  let new1 = List.map (build_new t1 t2 true HL.Logic.eq_ind_URI) res1
-  and new2 = List.map (build_new t2 t1 true HL.Logic.eq_ind_r_URI) res2
-  and new3 = List.map (build_new t1 t2 false HL.Logic.eq_ind_URI) res3
-  and new4 = List.map (build_new t2 t1 false HL.Logic.eq_ind_r_URI) res4 in
-  let ok = function
-    | _, (_, left, right), _, _ ->
-        not (fst (CR.are_convertible context left right ugraph))
-  in
-  !maxmeta, (List.filter ok (new1 @ new2 @ new3 @ new4))
+    let newmetas = newmetas @ newm' in
+    let newargs = args @ args' in
+    let build_new what other is_left eq_URI (t, s, m, ug) =
+      (*     let what, other = *)
+      (*       if is_left then left, right *)
+      (*       else right, left *)
+      (*     in *)
+      let newterm, neweqproof =
+        match t with
+        | C.Lambda (nn, ty, bo) ->
+            let bo' = M.apply_subst s (S.subst other bo) in
+            let bo'' =
+              C.Appl (
+                [C.MutInd (HL.Logic.eq_URI, 0, []); S.lift 1 eq_ty] @
+                  if is_left then [bo'; S.lift 1 right]
+                  else [S.lift 1 left; bo'])
+            in
+            let t' = C.Lambda (nn, ty, bo'') in
+            bo',
+            M.apply_subst s
+              (C.Appl [C.Const (eq_URI, []); ty; what; t';
+                       eqproof; other; eqp'])
+        | _ -> assert false
+      in
+      let newmeta, newequality =
+        let left, right =
+          if is_left then (newterm, M.apply_subst s right)
+          else (M.apply_subst s left, newterm) in
+        fix_metas !maxmeta
+          (neweqproof, (eq_ty, left, right), newmetas, newargs)
+      in
+      maxmeta := newmeta;
+      newequality
+    in
+    let new1 = List.map (build_new t1 t2 true HL.Logic.eq_ind_URI) res1
+    and new2 = List.map (build_new t2 t1 true HL.Logic.eq_ind_r_URI) res2
+    and new3 = List.map (build_new t1 t2 false HL.Logic.eq_ind_URI) res3
+    and new4 = List.map (build_new t2 t1 false HL.Logic.eq_ind_r_URI) res4 in
+    let ok = function
+      | _, (_, left, right), _, _ ->
+          not (fst (CR.are_convertible context left right ugraph))
+    in
+    !maxmeta, (List.filter ok (new1 @ new2 @ new3 @ new4))
+;;
+
+
+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
 ;;
 
 
@@ -743,7 +791,7 @@ let demodulation newmeta (metasenv, context, ugraph) target source =
 (*         "demodulate\ntarget: %s\nwhat: %s\nother: %s\nis_left: %s\n" *)
 (*         (string_of_equality ~env target) (CicPp.pp what names) *)
 (*         (CicPp.pp other names) (string_of_bool is_left); *)
-(*       Printf.printf "step: %d\n" step; *)
+(*       Printf.printf "step: %d" step; *)
 (*       print_newline (); *)
 
       let ok (t, s, m, ug) =
@@ -756,6 +804,9 @@ let demodulation newmeta (metasenv, context, ugraph) target source =
         in
 (*         print_endline "res:"; *)
 (*         List.iter (fun (t, s, m, ug) -> print_endline (CicPp.pp t names)) r; *)
+(*         print_newline (); *)
+(*         Printf.printf "metasenv:\n%s\n" (print_metasenv (metasenv @ metas)); *)
+(*         print_newline (); *)
         List.filter ok r
       in
       match res with
@@ -790,12 +841,15 @@ let demodulation newmeta (metasenv, context, ugraph) target source =
             fix_metas newmeta
               (newproof, (eq_ty, left, right), newmetasenv, newargs)
           in
-(*           Printf.printf *)
-(*             "demodulate, newtarget: %s\ntarget was: %s\n" *)
-(*             (string_of_equality ~env newtarget) *)
-(*             (string_of_equality ~env target); *)
-(*           print_newline (); *)
-          demodulate newmeta step metasenv newtarget
+          Printf.printf
+            "demodulate, newtarget: %s\ntarget was: %s\n"
+            (string_of_equality ~env newtarget)
+            (string_of_equality ~env target);
+          print_newline ();
+          if is_identity env newtarget then
+            newmeta, newtarget
+          else
+            demodulate newmeta step metasenv newtarget
     in
     demodulate newmeta 3 (metasenv @ metas') target
 ;;