src/HOL/TPTP/atp_problem_import.ML
changeset 72001 3e08311ada8e
parent 69597 ff784d5a5bfb
child 72400 abfeed05c323
equal deleted inserted replaced
72000:379d0c207c29 72001:3e08311ada8e
     6 *)
     6 *)
     7 
     7 
     8 signature ATP_PROBLEM_IMPORT =
     8 signature ATP_PROBLEM_IMPORT =
     9 sig
     9 sig
    10   val read_tptp_file : theory -> (string * term -> 'a) -> string ->
    10   val read_tptp_file : theory -> (string * term -> 'a) -> string ->
    11     'a list * ('a list * 'a list) * Proof.context
    11     'a list * ('a list * 'a list) * local_theory
    12   val nitpick_tptp_file : theory -> int -> string -> unit
    12   val nitpick_tptp_file : theory -> int -> string -> unit
    13   val refute_tptp_file : theory -> int -> string -> unit
    13   val refute_tptp_file : theory -> int -> string -> unit
    14   val can_tac : Proof.context -> (Proof.context -> tactic) -> term -> bool
    14   val can_tac : Proof.context -> (Proof.context -> tactic) -> term -> bool
    15   val SOLVE_TIMEOUT :  int -> string -> tactic -> tactic
    15   val SOLVE_TIMEOUT :  int -> string -> tactic -> tactic
    16   val atp_tac : Proof.context -> int -> (string * string) list -> int -> term list -> string ->
    16   val atp_tac : local_theory -> int -> (string * string) list -> int -> term list -> string ->
    17     int -> tactic
    17     int -> tactic
    18   val smt_solver_tac : string -> Proof.context -> int -> tactic
    18   val smt_solver_tac : string -> local_theory -> int -> tactic
    19   val freeze_problem_consts : theory -> term -> term
       
    20   val make_conj : term list * term list -> term list -> term
    19   val make_conj : term list * term list -> term list -> term
    21   val sledgehammer_tptp_file : theory -> int -> string -> unit
    20   val sledgehammer_tptp_file : theory -> int -> string -> unit
    22   val isabelle_tptp_file : theory -> int -> string -> unit
    21   val isabelle_tptp_file : theory -> int -> string -> unit
    23   val isabelle_hot_tptp_file : theory -> int -> string -> unit
    22   val isabelle_hot_tptp_file : theory -> int -> string -> unit
    24   val translate_tptp_file : theory -> string -> string -> unit
    23   val translate_tptp_file : theory -> string -> string -> unit
    71     (is_Const t orelse is_Free t) andalso not (exists_subterm (curry (op =) t) u)
    70     (is_Const t orelse is_Free t) andalso not (exists_subterm (curry (op =) t) u)
    72   | is_legitimate_tptp_def _ = false
    71   | is_legitimate_tptp_def _ = false
    73 
    72 
    74 fun nitpick_tptp_file thy timeout file_name =
    73 fun nitpick_tptp_file thy timeout file_name =
    75   let
    74   let
    76     val (conjs, (defs, nondefs), ctxt) = read_tptp_file thy snd file_name
    75     val (conjs, (defs, nondefs), lthy) = read_tptp_file thy snd file_name
    77     val thy = Proof_Context.theory_of ctxt
    76     val thy = Proof_Context.theory_of lthy
    78     val (defs, pseudo_defs) = defs
    77     val (defs, pseudo_defs) = defs
    79       |> map (ATP_Util.abs_extensionalize_term ctxt #> aptrueprop (hol_open_form I))
    78       |> map (ATP_Util.abs_extensionalize_term lthy #> aptrueprop (hol_open_form I))
    80       |> List.partition (is_legitimate_tptp_def o perhaps (try HOLogic.dest_Trueprop)
    79       |> List.partition (is_legitimate_tptp_def o perhaps (try HOLogic.dest_Trueprop)
    81         o ATP_Util.unextensionalize_def)
    80         o ATP_Util.unextensionalize_def)
    82     val nondefs = pseudo_defs @ nondefs
    81     val nondefs = pseudo_defs @ nondefs
    83     val state = Proof.init ctxt
    82     val state = Proof.init lthy
    84     val params =
    83     val params =
    85       [("card", "1-100"),
    84       [("card", "1-100"),
    86        ("box", "false"),
    85        ("box", "false"),
    87        ("max_threads", "1"),
    86        ("max_threads", "1"),
    88        ("batch_size", "5"),
    87        ("batch_size", "5"),
   116       (if s = "genuine" then
   115       (if s = "genuine" then
   117          if falsify then "CounterSatisfiable" else "Satisfiable"
   116          if falsify then "CounterSatisfiable" else "Satisfiable"
   118        else
   117        else
   119          "GaveUp")
   118          "GaveUp")
   120       |> writeln
   119       |> writeln
   121     val (conjs, (defs, nondefs), ctxt) = read_tptp_file thy snd file_name
   120     val (conjs, (defs, nondefs), lthy) = read_tptp_file thy snd file_name
   122     val params =
   121     val params =
   123       [("maxtime", string_of_int timeout),
   122       [("maxtime", string_of_int timeout),
   124        ("maxvars", "100000")]
   123        ("maxvars", "100000")]
   125   in
   124   in
   126     Refute.refute_term ctxt params (defs @ nondefs)
   125     Refute.refute_term lthy params (defs @ nondefs)
   127       (case conjs of conj :: _ => conj | [] => \<^prop>\<open>True\<close>)
   126       (case conjs of conj :: _ => conj | [] => \<^prop>\<open>True\<close>)
   128     |> print_szs_of_outcome (not (null conjs))
   127     |> print_szs_of_outcome (not (null conjs))
   129   end
   128   end
   130 
   129 
   131 
   130 
   144     (case result of
   143     (case result of
   145       NONE => (writeln ("FAILURE: " ^ name); Seq.empty)
   144       NONE => (writeln ("FAILURE: " ^ name); Seq.empty)
   146     | SOME st' => (writeln ("SUCCESS: " ^ name); Seq.single st'))
   145     | SOME st' => (writeln ("SUCCESS: " ^ name); Seq.single st'))
   147   end
   146   end
   148 
   147 
   149 fun nitpick_finite_oracle_tac ctxt timeout i th =
   148 fun nitpick_finite_oracle_tac lthy timeout i th =
   150   let
   149   let
   151     fun is_safe (Type (\<^type_name>\<open>fun\<close>, Ts)) = forall is_safe Ts
   150     fun is_safe (Type (\<^type_name>\<open>fun\<close>, Ts)) = forall is_safe Ts
   152       | is_safe \<^typ>\<open>prop\<close> = true
   151       | is_safe \<^typ>\<open>prop\<close> = true
   153       | is_safe \<^typ>\<open>bool\<close> = true
   152       | is_safe \<^typ>\<open>bool\<close> = true
   154       | is_safe _ = false
   153       | is_safe _ = false
   157   in
   156   in
   158     if exists_type (not o is_safe) conj then
   157     if exists_type (not o is_safe) conj then
   159       Seq.empty
   158       Seq.empty
   160     else
   159     else
   161       let
   160       let
   162         val thy = Proof_Context.theory_of ctxt
   161         val thy = Proof_Context.theory_of lthy
   163         val state = Proof.init ctxt
   162         val state = Proof.init lthy
   164         val params =
   163         val params =
   165           [("box", "false"),
   164           [("box", "false"),
   166            ("max_threads", "1"),
   165            ("max_threads", "1"),
   167            ("verbose", "true"),
   166            ("verbose", "true"),
   168            ("debug", if debug then "true" else "false"),
   167            ("debug", if debug then "true" else "false"),
   175         val step = 0
   174         val step = 0
   176         val subst = []
   175         val subst = []
   177         val (outcome, _) =
   176         val (outcome, _) =
   178           Nitpick.pick_nits_in_term state params Nitpick.Normal i n step subst [] [] conj
   177           Nitpick.pick_nits_in_term state params Nitpick.Normal i n step subst [] [] conj
   179       in
   178       in
   180         if outcome = "none" then ALLGOALS (Skip_Proof.cheat_tac ctxt) th else Seq.empty
   179         if outcome = "none" then ALLGOALS (Skip_Proof.cheat_tac lthy) th else Seq.empty
   181       end
   180       end
   182   end
   181   end
   183 
   182 
   184 fun atp_tac ctxt completeness override_params timeout assms prover =
   183 fun atp_tac lthy completeness override_params timeout assms prover =
   185   let
   184   let
   186     val thy = Proof_Context.theory_of ctxt
   185     val thy = Proof_Context.theory_of lthy
   187     val assm_ths0 = map (Skip_Proof.make_thm thy) assms
   186     val assm_ths0 = map (Skip_Proof.make_thm thy) assms
   188     val ((assm_name, _), ctxt) = ctxt
   187     val ((assm_name, _), lthy) = lthy
   189       |> Config.put Sledgehammer_Prover_ATP.atp_completish (if completeness > 0 then 3 else 0)
   188       |> Config.put Sledgehammer_Prover_ATP.atp_completish (if completeness > 0 then 3 else 0)
   190       |> Local_Theory.note ((\<^binding>\<open>thms\<close>, []), assm_ths0)
   189       |> Local_Theory.note ((\<^binding>\<open>thms\<close>, []), assm_ths0)
   191 
   190 
   192     fun ref_of th = (Facts.named (Thm.derivation_name th), [])
   191     fun ref_of th = (Facts.named (Thm.derivation_name th), [])
   193     val ref_of_assms = (Facts.named assm_name, [])
   192     val ref_of_assms = (Facts.named assm_name, [])
   194   in
   193   in
   195     Sledgehammer_Tactics.sledgehammer_as_oracle_tac ctxt
   194     Sledgehammer_Tactics.sledgehammer_as_oracle_tac lthy
   196       ([("debug", if debug then "true" else "false"),
   195       ([("debug", if debug then "true" else "false"),
   197         ("overlord", if overlord then "true" else "false"),
   196         ("overlord", if overlord then "true" else "false"),
   198         ("provers", prover),
   197         ("provers", prover),
   199         ("timeout", string_of_int timeout)] @
   198         ("timeout", string_of_int timeout)] @
   200        (if completeness > 0 then
   199        (if completeness > 0 then
   203           []) @
   202           []) @
   204        override_params)
   203        override_params)
   205       {add = ref_of_assms :: map ref_of [ext, @{thm someI}], del = [], only = true} []
   204       {add = ref_of_assms :: map ref_of [ext, @{thm someI}], del = [], only = true} []
   206   end
   205   end
   207 
   206 
   208 fun sledgehammer_tac demo ctxt timeout assms i =
   207 fun sledgehammer_tac demo lthy timeout assms i =
   209   let
   208   let
   210     val frac = if demo then 16 else 12
   209     val frac = if demo then 16 else 12
   211     fun slice mult completeness prover =
   210     fun slice mult completeness prover =
   212       SOLVE_TIMEOUT (mult * timeout div frac)
   211       SOLVE_TIMEOUT (mult * timeout div frac)
   213         (prover ^ (if completeness > 0 then "(" ^ string_of_int completeness ^ ")" else ""))
   212         (prover ^ (if completeness > 0 then "(" ^ string_of_int completeness ^ ")" else ""))
   214         (atp_tac ctxt completeness [] (mult * timeout div frac) assms prover i)
   213         (atp_tac lthy completeness [] (mult * timeout div frac) assms prover i)
   215   in
   214   in
   216     slice 2 0 ATP_Proof.spassN
   215     slice 2 0 ATP_Proof.spassN
   217     ORELSE slice 2 0 ATP_Proof.vampireN
   216     ORELSE slice 2 0 ATP_Proof.vampireN
   218     ORELSE slice 2 0 ATP_Proof.eN
   217     ORELSE slice 2 0 ATP_Proof.eN
   219     ORELSE slice 2 0 ATP_Proof.z3_tptpN
   218     ORELSE slice 2 0 ATP_Proof.z3_tptpN
   227          ORELSE slice 2 0 ATP_Proof.leo2N
   226          ORELSE slice 2 0 ATP_Proof.leo2N
   228        else
   227        else
   229          no_tac)
   228          no_tac)
   230   end
   229   end
   231 
   230 
   232 fun smt_solver_tac solver ctxt =
   231 fun smt_solver_tac solver lthy =
   233   let
   232   let
   234     val ctxt = ctxt |> Context.proof_map (SMT_Config.select_solver solver)
   233     val lthy = lthy |> Context.proof_map (SMT_Config.select_solver solver)
   235   in SMT_Solver.smt_tac ctxt [] end
   234   in SMT_Solver.smt_tac lthy [] end
   236 
   235 
   237 fun auto_etc_tac ctxt timeout assms i =
   236 fun auto_etc_tac lthy timeout assms i =
   238   SOLVE_TIMEOUT (timeout div 20) "nitpick" (nitpick_finite_oracle_tac ctxt (timeout div 20) i)
   237   SOLVE_TIMEOUT (timeout div 20) "nitpick" (nitpick_finite_oracle_tac lthy (timeout div 20) i)
   239   ORELSE SOLVE_TIMEOUT (timeout div 10) "simp" (asm_full_simp_tac ctxt i)
   238   ORELSE SOLVE_TIMEOUT (timeout div 10) "simp" (asm_full_simp_tac lthy i)
   240   ORELSE SOLVE_TIMEOUT (timeout div 10) "blast" (blast_tac ctxt i)
   239   ORELSE SOLVE_TIMEOUT (timeout div 10) "blast" (blast_tac lthy i)
   241   ORELSE SOLVE_TIMEOUT (timeout div 5) "auto+spass"
   240   ORELSE SOLVE_TIMEOUT (timeout div 5) "auto+spass"
   242     (auto_tac ctxt THEN ALLGOALS (atp_tac ctxt 0 [] (timeout div 5) assms ATP_Proof.spassN))
   241     (auto_tac lthy THEN ALLGOALS (atp_tac lthy 0 [] (timeout div 5) assms ATP_Proof.spassN))
   243   ORELSE SOLVE_TIMEOUT (timeout div 10) "fast" (fast_tac ctxt i)
   242   ORELSE SOLVE_TIMEOUT (timeout div 10) "fast" (fast_tac lthy i)
   244   ORELSE SOLVE_TIMEOUT (timeout div 20) "z3" (smt_solver_tac "z3" ctxt i)
   243   ORELSE SOLVE_TIMEOUT (timeout div 20) "z3" (smt_solver_tac "z3" lthy i)
   245   ORELSE SOLVE_TIMEOUT (timeout div 20) "cvc4" (smt_solver_tac "cvc4" ctxt i)
   244   ORELSE SOLVE_TIMEOUT (timeout div 20) "cvc4" (smt_solver_tac "cvc4" lthy i)
   246   ORELSE SOLVE_TIMEOUT (timeout div 20) "best" (best_tac ctxt i)
   245   ORELSE SOLVE_TIMEOUT (timeout div 20) "best" (best_tac lthy i)
   247   ORELSE SOLVE_TIMEOUT (timeout div 10) "force" (force_tac ctxt i)
   246   ORELSE SOLVE_TIMEOUT (timeout div 10) "force" (force_tac lthy i)
   248   ORELSE SOLVE_TIMEOUT (timeout div 10) "meson" (Meson.meson_tac ctxt [] i)
   247   ORELSE SOLVE_TIMEOUT (timeout div 10) "meson" (Meson.meson_tac lthy [] i)
   249   ORELSE SOLVE_TIMEOUT (timeout div 10) "fastforce" (fast_force_tac ctxt i)
   248   ORELSE SOLVE_TIMEOUT (timeout div 10) "fastforce" (fast_force_tac lthy i)
   250 
   249 
   251 fun problem_const_prefix thy = Context.theory_name thy ^ Long_Name.separator
   250 fun problem_const_prefix thy = Context.theory_name thy ^ Long_Name.separator
   252 
       
   253 (* Isabelle's standard automatic tactics ("auto", etc.) are more eager to
       
   254    unfold "definitions" of free variables than of constants (cf. PUZ107^5). *)
       
   255 fun freeze_problem_consts thy =
       
   256   let val is_problem_const = String.isPrefix (problem_const_prefix thy) in
       
   257     map_aterms
       
   258       (fn t as Const (s, T) => if is_problem_const s then Free (Long_Name.base_name s, T) else t
       
   259         | t => t)
       
   260   end
       
   261 
   251 
   262 fun make_conj (defs, nondefs) conjs =
   252 fun make_conj (defs, nondefs) conjs =
   263   Logic.list_implies (rev defs @ rev nondefs, case conjs of conj :: _ => conj | [] => \<^prop>\<open>False\<close>)
   253   Logic.list_implies (rev defs @ rev nondefs, case conjs of conj :: _ => conj | [] => \<^prop>\<open>False\<close>)
   264 
   254 
   265 fun print_szs_of_success conjs success =
   255 fun print_szs_of_success conjs success =
   269      else
   259      else
   270        "GaveUp"))
   260        "GaveUp"))
   271 
   261 
   272 fun sledgehammer_tptp_file thy timeout file_name =
   262 fun sledgehammer_tptp_file thy timeout file_name =
   273   let
   263   let
   274     val (conjs, assms, ctxt) = read_tptp_file thy (freeze_problem_consts thy o snd) file_name
   264     val (conjs, assms, lthy) = read_tptp_file thy snd file_name
   275     val conj = make_conj ([], []) conjs
   265     val conj = make_conj ([], []) conjs
   276     val assms = op @ assms
   266     val assms = op @ assms
   277   in
   267   in
   278     can_tac ctxt (fn ctxt => sledgehammer_tac true ctxt timeout assms 1) conj
   268     can_tac lthy (fn lthy => sledgehammer_tac true lthy timeout assms 1) conj
   279     |> print_szs_of_success conjs
   269     |> print_szs_of_success conjs
   280   end
   270   end
   281 
   271 
   282 fun generic_isabelle_tptp_file demo thy timeout file_name =
   272 fun generic_isabelle_tptp_file demo thy timeout file_name =
   283   let
   273   let
   284     val (conjs, assms, ctxt) = read_tptp_file thy (freeze_problem_consts thy o snd) file_name
   274     val (conjs, assms, lthy) = read_tptp_file thy snd file_name
   285     val conj = make_conj ([], []) conjs
   275     val conj = make_conj ([], []) conjs
   286     val full_conj = make_conj assms conjs
   276     val full_conj = make_conj assms conjs
   287     val assms = op @ assms
   277     val assms = op @ assms
   288     val (last_hope_atp, last_hope_completeness) =
   278     val (last_hope_atp, last_hope_completeness) =
   289       if demo then (ATP_Proof.satallaxN, 0) else (ATP_Proof.vampireN, 2)
   279       if demo then (ATP_Proof.satallaxN, 0) else (ATP_Proof.vampireN, 2)
   290   in
   280   in
   291     (can_tac ctxt (fn ctxt => auto_etc_tac ctxt (timeout div 2) assms 1) full_conj orelse
   281     (can_tac lthy (fn lthy => auto_etc_tac lthy (timeout div 2) assms 1) full_conj orelse
   292      can_tac ctxt (fn ctxt => sledgehammer_tac demo ctxt (timeout div 2) assms 1) conj orelse
   282      can_tac lthy (fn lthy => sledgehammer_tac demo lthy (timeout div 2) assms 1) conj orelse
   293      can_tac ctxt (fn ctxt => SOLVE_TIMEOUT timeout (last_hope_atp ^ "(*)")
   283      can_tac lthy (fn lthy => SOLVE_TIMEOUT timeout (last_hope_atp ^ "(*)")
   294        (atp_tac ctxt last_hope_completeness [] timeout assms last_hope_atp 1)) full_conj)
   284        (atp_tac lthy last_hope_completeness [] timeout assms last_hope_atp 1)) full_conj)
   295     |> print_szs_of_success conjs
   285     |> print_szs_of_success conjs
   296   end
   286   end
   297 
   287 
   298 val isabelle_tptp_file = generic_isabelle_tptp_file false
   288 val isabelle_tptp_file = generic_isabelle_tptp_file false
   299 val isabelle_hot_tptp_file = generic_isabelle_tptp_file true
   289 val isabelle_hot_tptp_file = generic_isabelle_tptp_file true
   301 
   291 
   302 (** Translator between TPTP(-like) file formats **)
   292 (** Translator between TPTP(-like) file formats **)
   303 
   293 
   304 fun translate_tptp_file thy format_str file_name =
   294 fun translate_tptp_file thy format_str file_name =
   305   let
   295   let
   306     val (conjs, (defs, nondefs), ctxt) = read_tptp_file thy I file_name
   296     val (conjs, (defs, nondefs), lthy) = read_tptp_file thy I file_name
   307     val conj = make_conj ([], []) (map snd conjs)
   297     val conj = make_conj ([], []) (map snd conjs)
   308 
   298 
   309     val (format, type_enc, lam_trans) =
   299     val (format, type_enc, lam_trans) =
   310       (case format_str of
   300       (case format_str of
   311         "FOF" => (FOF, "mono_guards??", liftingN)
   301         "FOF" => (FOF, "mono_guards??", liftingN)
   320     val presimp = true
   310     val presimp = true
   321     val facts =
   311     val facts =
   322       map (apfst (rpair (Global, Non_Rec_Def))) defs @
   312       map (apfst (rpair (Global, Non_Rec_Def))) defs @
   323       map (apfst (rpair (Global, General))) nondefs
   313       map (apfst (rpair (Global, General))) nondefs
   324     val (atp_problem, _, _, _) =
   314     val (atp_problem, _, _, _) =
   325       generate_atp_problem ctxt generate_info format Hypothesis (type_enc_of_string Strict type_enc)
   315       generate_atp_problem lthy generate_info format Hypothesis (type_enc_of_string Strict type_enc)
   326         Translator
   316         Translator
   327         lam_trans uncurried_aliases readable_names presimp [] conj facts
   317         lam_trans uncurried_aliases readable_names presimp [] conj facts
   328 
   318 
   329     val ord = effective_term_order ctxt spassN
   319     val ord = effective_term_order lthy spassN
   330     val ord_info = K []
   320     val ord_info = K []
   331     val lines = lines_of_atp_problem format ord ord_info atp_problem
   321     val lines = lines_of_atp_problem format ord ord_info atp_problem
   332   in
   322   in
   333     List.app Output.physical_stdout lines
   323     List.app Output.physical_stdout lines
   334   end
   324   end