]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/tactics/metadataQuery.ml
renamed Http_client to Http_user_agent to avoid clashes with Gerd's
[helm.git] / helm / ocaml / tactics / metadataQuery.ml
index 18ea81381eebb8ae2b025462bef1ecd4c52e9edd..3fdecb8c5850a55f700c333557d03892354c053f 100644 (file)
@@ -27,22 +27,29 @@ open Printf
 
 module Constr = MetadataConstraints
 
-let locate ~(dbh:Dbi.connection) name =
+let nonvar s =
+  let len = String.length s in
+  let suffix = String.sub s (len-4) 4 in
+  not (suffix  = ".var")
+
+let locate ~(dbh:Dbi.connection) ?(vars = false) name =
   let query =
-    dbh#prepare (sprintf "SELECT value FROM %s WHERE source = \"%s\""
+    dbh#prepare (sprintf "SELECT source FROM %s WHERE value = \"%s\""
       MetadataTypes.name_tbl name)
   in
   query#execute [];
-  List.map (function [`String s] -> s | _ -> assert false) (query#fetchall ())
+  List.filter nonvar
+    (List.map (function [`String s] -> s | _ -> assert false)
+      (query#fetchall ()))
 
 let match_term ~(dbh:Dbi.connection) ty =
   let metadata = MetadataExtractor.compute ~body:None ~ty in
-  Constr.at_least ~dbh metadata
-
-let nonvar (_, s) =
-  let len = String.length s in
-  let suffix = String.sub s (len-4) 4 in
-  not (suffix  = ".var")
+  let constants_no =
+    MetadataConstraints.StringSet.cardinal (MetadataConstraints.constants_of ty)
+  in
+  let constraints = List.map MetadataTypes.constr_of_metadata metadata in
+  Constr.at_least ~dbh ~full_card:(MetadataConstraints.Eq constants_no)
+    constraints
 
 let ( ** ) x y = int_of_float ((float_of_int x) ** (float_of_int y))
 
@@ -56,6 +63,47 @@ let signature_of_hypothesis context =
           Constr.StringSet.union set (Constr.constants_of t))
     Constr.StringSet.empty context
 
+let intersect uris siguris =
+  let set1 = List.fold_right Constr.StringSet.add uris Constr.StringSet.empty in
+  let set2 =
+    List.fold_right Constr.StringSet.add siguris Constr.StringSet.empty
+  in
+  let inter = Constr.StringSet.inter set1 set2 in
+  List.filter (fun s -> Constr.StringSet.mem s inter) uris
+
+let filter_uris_forward ~dbh (main, constants) uris =
+  let main_uris =
+    match main with
+    | None -> []
+    | Some (main, types) -> main :: types
+  in
+  let full_signature =
+    List.fold_right Constr.StringSet.add main_uris constants
+  in
+  List.filter (Constr.at_most ~dbh ~where:`Statement full_signature) uris
+
+let filter_uris_backward ~dbh signature uris =
+  let siguris =
+    List.map snd (MetadataConstraints.sigmatch ~dbh ~where:`Statement signature)
+  in
+  intersect uris siguris
+
+let compare_goal_list proof goal1 goal2 =
+  let _,metasenv,_,_ = proof in
+  let (_, ey1, ty1) = CicUtil.lookup_meta goal1 metasenv in
+  let (_, ey2, ty2) =  CicUtil.lookup_meta goal2 metasenv in
+  let ty_sort1 = CicTypeChecker.type_of_aux' metasenv ey1 ty1 in
+  let ty_sort2 = CicTypeChecker.type_of_aux' metasenv ey2 ty2 in
+  let prop1 =
+    if CicReduction.are_convertible ey1 (Cic.Sort Cic.Prop) ty_sort1 then 0
+    else 1
+  in
+  let prop2 =
+    if CicReduction.are_convertible ey2 (Cic.Sort Cic.Prop) ty_sort2 then 0
+    else 1
+  in
+  prop1 - prop2
+
 let hint ~(dbh:Dbi.connection) ?signature ((proof, goal) as status) =
   let (_, metasenv, _, _) = proof in
   let (_, context, ty) = CicUtil.lookup_meta goal metasenv in
@@ -64,15 +112,7 @@ let hint ~(dbh:Dbi.connection) ?signature ((proof, goal) as status) =
     | Some signature -> (Constr.sigmatch ~dbh signature, signature)
     | None -> (Constr.cmatch' ~dbh ty, Constr.signature_of ty)
   in
-  let uris = List.filter nonvar uris in
-(*
-  let concl_constants =
-    match main with
-    | None -> sig_constants
-    | Some (main, types) ->
-        List.fold_right Constr.StringSet.add sig_constants (main :: types)
-  in
-*)
+  let uris = List.filter nonvar (List.map snd uris) in
   let types_constants =
     match main with
     | None -> Constr.StringSet.empty
@@ -85,19 +125,48 @@ let hint ~(dbh:Dbi.connection) ?signature ((proof, goal) as status) =
   in
   let other_constants = Constr.StringSet.union sig_constants hyp_constants in
   let uris = 
-    if (List.length uris < 2 ** (Constr.StringSet.cardinal other_constants))
+    let pow = 2 ** (Constr.StringSet.cardinal other_constants) in
+    if ((List.length uris < pow) or (pow <= 0))
     then begin
-      prerr_endline
-        "MetadataQuery: large signature, falling back to old method";
-      List.filter (Filter_auto.filter_new_constants ~dbh all_constants main)
-        uris
+      prerr_endline "MetadataQuery: large sig, falling back to old method";
+      filter_uris_forward ~dbh (main, other_constants) uris
     end else
-      Filter_auto.filter_uris ~dbh all_constants uris main
+      filter_uris_backward ~dbh (main, other_constants) uris
+  in
+  let rec aux = function
+    | [] -> []
+    | uri :: tl ->
+        (let status' =
+            try
+              let (proof, goal_list) =
+                ProofEngineTypes.apply_tactic
+                  (PrimitiveTactics.apply_tac ~term:(CicUtil.term_of_uri uri))
+                  status
+              in
+              let goal_list =
+                List.stable_sort (compare_goal_list proof) goal_list
+              in
+              Some (uri, (proof, goal_list))
+            with ProofEngineTypes.Fail _ -> None
+          in
+          match status' with
+          | None -> aux tl
+          | Some status' ->
+              prerr_endline ("HO APPLICATO " ^ uri);
+              status' :: aux tl)
+  in
+  List.stable_sort
+    (fun (_, (_, goals1)) (_, (_, goals2)) ->
+      Pervasives.compare (List.length goals1) (List.length goals2))
+    (aux uris)
+
+let elim ~dbh uri =
+  let constraints =
+    [`Rel [`MainConclusion None];
+     `Sort (Cic.Prop,[`MainHypothesis (Some 1)]);
+     `Obj (uri,[`MainHypothesis (Some 0)]);
+     `Obj (uri,[`InHypothesis]);
+    ]
   in
-  List.map
-    (fun uri ->
-      (uri,
-       ProofEngineTypes.apply_tactic
-        (PrimitiveTactics.apply_tac ~term:(CicUtil.term_of_uri uri))
-        status))
+  MetadataConstraints.at_least ~dbh constraints