src/HOL/Tools/Sledgehammer/sledgehammer_atp_reconstruct.ML
changeset 42755 4603154a3018
parent 42751 f42fd9754724
child 42759 fdd15e889ad7
equal deleted inserted replaced
42754:b9d7df8c51c8 42755:4603154a3018
    14   type minimize_command = string list -> string
    14   type minimize_command = string list -> string
    15   type metis_params =
    15   type metis_params =
    16     string * minimize_command * type_system * string proof * int
    16     string * minimize_command * type_system * string proof * int
    17     * (string * locality) list vector * thm * int
    17     * (string * locality) list vector * thm * int
    18   type isar_params =
    18   type isar_params =
    19      Proof.context * bool * int * string Symtab.table * int list list
    19     Proof.context * bool * int * string Symtab.table * int list list
       
    20     * int Symtab.table
    20   type text_result = string * (string * locality) list
    21   type text_result = string * (string * locality) list
    21 
    22 
    22   val repair_conjecture_shape_and_fact_names :
    23   val repair_conjecture_shape_and_fact_names :
    23     type_system -> string -> int list list -> int
    24     type_system -> string -> int list list -> int
    24     -> (string * locality) list vector
    25     -> (string * locality) list vector
    55 type metis_params =
    56 type metis_params =
    56   string * minimize_command * type_system * string proof * int
    57   string * minimize_command * type_system * string proof * int
    57   * (string * locality) list vector * thm * int
    58   * (string * locality) list vector * thm * int
    58 type isar_params =
    59 type isar_params =
    59   Proof.context * bool * int * string Symtab.table * int list list
    60   Proof.context * bool * int * string Symtab.table * int list list
       
    61   * int Symtab.table
    60 type text_result = string * (string * locality) list
    62 type text_result = string * (string * locality) list
    61 
    63 
    62 fun is_head_digit s = Char.isDigit (String.sub (s, 0))
    64 fun is_head_digit s = Char.isDigit (String.sub (s, 0))
    63 val scan_integer = Scan.many1 is_head_digit >> (the o Int.fromString o implode)
    65 val scan_integer = Scan.many1 is_head_digit >> (the o Int.fromString o implode)
    64 
    66 
   336     | _ => s
   338     | _ => s
   337   end
   339   end
   338 
   340 
   339 (* First-order translation. No types are known for variables. "HOLogic.typeT"
   341 (* First-order translation. No types are known for variables. "HOLogic.typeT"
   340    should allow them to be inferred. *)
   342    should allow them to be inferred. *)
   341 fun raw_term_from_pred thy type_sys tfrees =
   343 fun raw_term_from_pred thy sym_tab tfrees =
   342   let
   344   let
   343     fun aux opt_T extra_us u =
   345     fun aux opt_T extra_us u =
   344       case u of
   346       case u of
   345         ATerm (a, us) =>
   347         ATerm (a, us) =>
   346         if String.isPrefix tff_type_prefix a then
   348         if String.isPrefix tff_type_prefix a then
   352               (* Vampire is keen on producing these. *)
   354               (* Vampire is keen on producing these. *)
   353               @{const True}
   355               @{const True}
   354             else
   356             else
   355               list_comb (Const (@{const_name HOL.eq}, HOLogic.typeT), ts)
   357               list_comb (Const (@{const_name HOL.eq}, HOLogic.typeT), ts)
   356           end
   358           end
   357         | SOME b =>
   359         | SOME s =>
   358           let val (b, mangled_us) = b |> unmangled_const |>> invert_const in
   360           let val (s', mangled_us) = s |> unmangled_const |>> invert_const in
   359             if b = type_tag_name then
   361             if s' = type_tag_name then
   360               case mangled_us @ us of
   362               case mangled_us @ us of
   361                 [typ_u, term_u] =>
   363                 [typ_u, term_u] =>
   362                 aux (SOME (typ_from_fo_term tfrees typ_u)) extra_us term_u
   364                 aux (SOME (typ_from_fo_term tfrees typ_u)) extra_us term_u
   363               | _ => raise FO_TERM us
   365               | _ => raise FO_TERM us
   364             else if b = predicator_base then
   366             else if s' = predicator_base then
   365               aux (SOME @{typ bool}) [] (hd us)
   367               aux (SOME @{typ bool}) [] (hd us)
   366             else if b = explicit_app_base then
   368             else if s' = explicit_app_base then
   367               aux opt_T (nth us 1 :: extra_us) (hd us)
   369               aux opt_T (nth us 1 :: extra_us) (hd us)
   368             else if b = type_pred_base then
   370             else if s' = type_pred_base then
   369               @{const True} (* ignore type predicates *)
   371               @{const True} (* ignore type predicates *)
   370             else
   372             else
   371               let
   373               let
   372                 val num_ty_args = num_atp_type_args thy type_sys b
   374                 val num_ty_args =
       
   375                   length us - the_default 0 (Symtab.lookup sym_tab s)
   373                 val (type_us, term_us) =
   376                 val (type_us, term_us) =
   374                   chop num_ty_args us |>> append mangled_us
   377                   chop num_ty_args us |>> append mangled_us
   375                 (* Extra args from "hAPP" come after any arguments given
   378                 (* Extra args from "hAPP" come after any arguments given
   376                    directly to the constant. *)
   379                    directly to the constant. *)
   377                 val term_ts = map (aux NONE []) term_us
   380                 val term_ts = map (aux NONE []) term_us
   378                 val extra_ts = map (aux NONE []) extra_us
   381                 val extra_ts = map (aux NONE []) extra_us
   379                 val T =
   382                 val T =
   380                   case opt_T of
   383                   case opt_T of
   381                     SOME T => map fastype_of term_ts ---> T
   384                     SOME T => map fastype_of term_ts ---> T
   382                   | NONE =>
   385                   | NONE =>
   383                     if num_type_args thy b = length type_us then
   386                     if num_type_args thy s' = length type_us then
   384                       Sign.const_instance thy
   387                       Sign.const_instance thy
   385                           (b, map (typ_from_fo_term tfrees) type_us)
   388                           (s', map (typ_from_fo_term tfrees) type_us)
   386                     else
   389                     else
   387                       HOLogic.typeT
   390                       HOLogic.typeT
   388                 val b = unproxify_const b
   391                 val s' = s' |> unproxify_const
   389               in list_comb (Const (b, T), term_ts @ extra_ts) end
   392               in list_comb (Const (s', T), term_ts @ extra_ts) end
   390           end
   393           end
   391         | NONE => (* a free or schematic variable *)
   394         | NONE => (* a free or schematic variable *)
   392           let
   395           let
   393             val ts = map (aux NONE []) (us @ extra_us)
   396             val ts = map (aux NONE []) (us @ extra_us)
   394             val T = map fastype_of ts ---> HOLogic.typeT
   397             val T = map fastype_of ts ---> HOLogic.typeT
   405                     (* Skolem constants? *)
   408                     (* Skolem constants? *)
   406                     Var ((repair_atp_variable_name Char.toUpper a, 0), T)
   409                     Var ((repair_atp_variable_name Char.toUpper a, 0), T)
   407           in list_comb (t, ts) end
   410           in list_comb (t, ts) end
   408   in aux (SOME HOLogic.boolT) [] end
   411   in aux (SOME HOLogic.boolT) [] end
   409 
   412 
   410 fun term_from_pred thy type_sys tfrees pos (u as ATerm (s, _)) =
   413 fun term_from_pred thy sym_tab tfrees pos (u as ATerm (s, _)) =
   411   if String.isPrefix class_prefix s then
   414   if String.isPrefix class_prefix s then
   412     add_type_constraint pos (type_constraint_from_term tfrees u)
   415     add_type_constraint pos (type_constraint_from_term tfrees u)
   413     #> pair @{const True}
   416     #> pair @{const True}
   414   else
   417   else
   415     pair (raw_term_from_pred thy type_sys tfrees u)
   418     pair (raw_term_from_pred thy sym_tab tfrees u)
   416 
   419 
   417 val combinator_table =
   420 val combinator_table =
   418   [(@{const_name Meson.COMBI}, @{thm Meson.COMBI_def_raw}),
   421   [(@{const_name Meson.COMBI}, @{thm Meson.COMBI_def_raw}),
   419    (@{const_name Meson.COMBK}, @{thm Meson.COMBK_def_raw}),
   422    (@{const_name Meson.COMBK}, @{thm Meson.COMBK_def_raw}),
   420    (@{const_name Meson.COMBB}, @{thm Meson.COMBB_def_raw}),
   423    (@{const_name Meson.COMBB}, @{thm Meson.COMBB_def_raw}),
   452                   |> map Var
   455                   |> map Var
   453   in fold_rev quant_of vars t end
   456   in fold_rev quant_of vars t end
   454 
   457 
   455 (* Interpret an ATP formula as a HOL term, extracting sort constraints as they
   458 (* Interpret an ATP formula as a HOL term, extracting sort constraints as they
   456    appear in the formula. *)
   459    appear in the formula. *)
   457 fun prop_from_formula thy type_sys tfrees phi =
   460 fun prop_from_formula thy sym_tab tfrees phi =
   458   let
   461   let
   459     fun do_formula pos phi =
   462     fun do_formula pos phi =
   460       case phi of
   463       case phi of
   461         AQuant (_, [], phi) => do_formula pos phi
   464         AQuant (_, [], phi) => do_formula pos phi
   462       | AQuant (q, (s, _) :: xs, phi') =>
   465       | AQuant (q, (s, _) :: xs, phi') =>
   476              | AImplies => s_imp
   479              | AImplies => s_imp
   477              | AIf => s_imp o swap
   480              | AIf => s_imp o swap
   478              | AIff => s_iff
   481              | AIff => s_iff
   479              | ANotIff => s_not o s_iff
   482              | ANotIff => s_not o s_iff
   480              | _ => raise Fail "unexpected connective")
   483              | _ => raise Fail "unexpected connective")
   481       | AAtom tm => term_from_pred thy type_sys tfrees pos tm
   484       | AAtom tm => term_from_pred thy sym_tab tfrees pos tm
   482       | _ => raise FORMULA [phi]
   485       | _ => raise FORMULA [phi]
   483   in repair_tvar_sorts (do_formula true phi Vartab.empty) end
   486   in repair_tvar_sorts (do_formula true phi Vartab.empty) end
   484 
   487 
   485 fun check_formula ctxt =
   488 fun check_formula ctxt =
   486   Type.constraint HOLogic.boolT
   489   Type.constraint HOLogic.boolT
   490 (**** Translation of TSTP files to Isar Proofs ****)
   493 (**** Translation of TSTP files to Isar Proofs ****)
   491 
   494 
   492 fun unvarify_term (Var ((s, 0), T)) = Free (s, T)
   495 fun unvarify_term (Var ((s, 0), T)) = Free (s, T)
   493   | unvarify_term t = raise TERM ("unvarify_term: non-Var", [t])
   496   | unvarify_term t = raise TERM ("unvarify_term: non-Var", [t])
   494 
   497 
   495 fun decode_line type_sys tfrees (Definition (name, phi1, phi2)) ctxt =
   498 fun decode_line sym_tab tfrees (Definition (name, phi1, phi2)) ctxt =
   496     let
   499     let
   497       val thy = Proof_Context.theory_of ctxt
   500       val thy = Proof_Context.theory_of ctxt
   498       val t1 = prop_from_formula thy type_sys tfrees phi1
   501       val t1 = prop_from_formula thy sym_tab tfrees phi1
   499       val vars = snd (strip_comb t1)
   502       val vars = snd (strip_comb t1)
   500       val frees = map unvarify_term vars
   503       val frees = map unvarify_term vars
   501       val unvarify_args = subst_atomic (vars ~~ frees)
   504       val unvarify_args = subst_atomic (vars ~~ frees)
   502       val t2 = prop_from_formula thy type_sys tfrees phi2
   505       val t2 = prop_from_formula thy sym_tab tfrees phi2
   503       val (t1, t2) =
   506       val (t1, t2) =
   504         HOLogic.eq_const HOLogic.typeT $ t1 $ t2
   507         HOLogic.eq_const HOLogic.typeT $ t1 $ t2
   505         |> unvarify_args |> uncombine_term |> check_formula ctxt
   508         |> unvarify_args |> uncombine_term |> check_formula ctxt
   506         |> HOLogic.dest_eq
   509         |> HOLogic.dest_eq
   507     in
   510     in
   508       (Definition (name, t1, t2),
   511       (Definition (name, t1, t2),
   509        fold Variable.declare_term (maps OldTerm.term_frees [t1, t2]) ctxt)
   512        fold Variable.declare_term (maps OldTerm.term_frees [t1, t2]) ctxt)
   510     end
   513     end
   511   | decode_line type_sys tfrees (Inference (name, u, deps)) ctxt =
   514   | decode_line sym_tab tfrees (Inference (name, u, deps)) ctxt =
   512     let
   515     let
   513       val thy = Proof_Context.theory_of ctxt
   516       val thy = Proof_Context.theory_of ctxt
   514       val t = u |> prop_from_formula thy type_sys tfrees
   517       val t = u |> prop_from_formula thy sym_tab tfrees
   515                 |> uncombine_term |> check_formula ctxt
   518                 |> uncombine_term |> check_formula ctxt
   516     in
   519     in
   517       (Inference (name, t, deps),
   520       (Inference (name, t, deps),
   518        fold Variable.declare_term (OldTerm.term_frees t) ctxt)
   521        fold Variable.declare_term (OldTerm.term_frees t) ctxt)
   519     end
   522     end
   520 fun decode_lines ctxt type_sys tfrees lines =
   523 fun decode_lines ctxt sym_tab tfrees lines =
   521   fst (fold_map (decode_line type_sys tfrees) lines ctxt)
   524   fst (fold_map (decode_line sym_tab tfrees) lines ctxt)
   522 
   525 
   523 fun is_same_inference _ (Definition _) = false
   526 fun is_same_inference _ (Definition _) = false
   524   | is_same_inference t (Inference (_, t', _)) = t aconv t'
   527   | is_same_inference t (Inference (_, t', _)) = t aconv t'
   525 
   528 
   526 (* No "real" literals means only type information (tfree_tcs, clsrel, or
   529 (* No "real" literals means only type information (tfree_tcs, clsrel, or
   652       "c_equal" (* seen in Vampire proofs *)
   655       "c_equal" (* seen in Vampire proofs *)
   653     else
   656     else
   654       s
   657       s
   655 
   658 
   656 fun isar_proof_from_atp_proof pool ctxt type_sys tfrees isar_shrink_factor
   659 fun isar_proof_from_atp_proof pool ctxt type_sys tfrees isar_shrink_factor
   657         atp_proof conjecture_shape facts_offset fact_names params frees =
   660         atp_proof conjecture_shape facts_offset fact_names sym_tab params
       
   661         frees =
   658   let
   662   let
   659     val lines =
   663     val lines =
   660       atp_proof
   664       atp_proof
   661       |> nasty_atp_proof pool
   665       |> nasty_atp_proof pool
   662       |> map_term_names_in_atp_proof repair_name
   666       |> map_term_names_in_atp_proof repair_name
   663       |> decode_lines ctxt type_sys tfrees
   667       |> decode_lines ctxt sym_tab tfrees
   664       |> rpair [] |-> fold_rev (add_line type_sys conjecture_shape fact_names)
   668       |> rpair [] |-> fold_rev (add_line type_sys conjecture_shape fact_names)
   665       |> rpair [] |-> fold_rev add_nontrivial_line
   669       |> rpair [] |-> fold_rev add_nontrivial_line
   666       |> rpair (0, [])
   670       |> rpair (0, [])
   667       |-> fold_rev (add_desired_line type_sys isar_shrink_factor
   671       |-> fold_rev (add_desired_line type_sys isar_shrink_factor
   668                                      conjecture_shape fact_names frees)
   672                                      conjecture_shape fact_names frees)
   959         (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   963         (if i <> 1 then "prefer " ^ string_of_int i ^ "\n" else "") ^
   960         do_indent 0 ^ "proof -\n" ^ do_steps "" "" 1 proof ^ do_indent 0 ^
   964         do_indent 0 ^ "proof -\n" ^ do_steps "" "" 1 proof ^ do_indent 0 ^
   961         (if n <> 1 then "next" else "qed")
   965         (if n <> 1 then "next" else "qed")
   962   in do_proof end
   966   in do_proof end
   963 
   967 
   964 fun isar_proof_text (ctxt, debug, isar_shrink_factor, pool, conjecture_shape)
   968 fun isar_proof_text (ctxt, debug, isar_shrink_factor, pool, conjecture_shape,
       
   969                      sym_tab)
   965                     (metis_params as (_, _, type_sys, atp_proof, facts_offset,
   970                     (metis_params as (_, _, type_sys, atp_proof, facts_offset,
   966                                       fact_names, goal, i)) =
   971                                       fact_names, goal, i)) =
   967   let
   972   let
   968     val (params, hyp_ts, concl_t) = strip_subgoal goal i
   973     val (params, hyp_ts, concl_t) = strip_subgoal goal i
   969     val frees = fold Term.add_frees (concl_t :: hyp_ts) []
   974     val frees = fold Term.add_frees (concl_t :: hyp_ts) []
   971     val n = Logic.count_prems (prop_of goal)
   976     val n = Logic.count_prems (prop_of goal)
   972     val (one_line_proof, lemma_names) = metis_proof_text metis_params
   977     val (one_line_proof, lemma_names) = metis_proof_text metis_params
   973     fun isar_proof_for () =
   978     fun isar_proof_for () =
   974       case isar_proof_from_atp_proof pool ctxt type_sys tfrees
   979       case isar_proof_from_atp_proof pool ctxt type_sys tfrees
   975                isar_shrink_factor atp_proof conjecture_shape facts_offset
   980                isar_shrink_factor atp_proof conjecture_shape facts_offset
   976                fact_names params frees
   981                fact_names sym_tab params frees
   977            |> redirect_proof hyp_ts concl_t
   982            |> redirect_proof hyp_ts concl_t
   978            |> kill_duplicate_assumptions_in_proof
   983            |> kill_duplicate_assumptions_in_proof
   979            |> then_chain_proof
   984            |> then_chain_proof
   980            |> kill_useless_labels_in_proof
   985            |> kill_useless_labels_in_proof
   981            |> relabel_proof
   986            |> relabel_proof