fix bug in Isar proof reconstruction step relabeling + don't try to infer the sorts of TVars, since this often fails miserably
authorblanchet
Mon, 17 May 2010 12:15:37 +0200
changeset 369603c804030474b
parent 36959 adc11fb3f3aa
child 36961 62e29faa3718
fix bug in Isar proof reconstruction step relabeling + don't try to infer the sorts of TVars, since this often fails miserably
src/HOL/Tools/Sledgehammer/metis_tactics.ML
src/HOL/Tools/Sledgehammer/sledgehammer_proof_reconstruct.ML
     1.1 --- a/src/HOL/Tools/Sledgehammer/metis_tactics.ML	Mon May 17 10:18:14 2010 +0200
     1.2 +++ b/src/HOL/Tools/Sledgehammer/metis_tactics.ML	Mon May 17 12:15:37 2010 +0200
     1.3 @@ -217,6 +217,8 @@
     1.4  fun strip_happ args (Metis.Term.Fn(".",[t,u])) = strip_happ (u::args) t
     1.5    | strip_happ args x = (x, args);
     1.6  
     1.7 +fun make_tvar s = TVar (("'" ^ s, 0), HOLogic.typeS)
     1.8 +
     1.9  fun fol_type_to_isa _ (Metis.Term.Var v) =
    1.10       (case strip_prefix tvar_prefix v of
    1.11            SOME w => make_tvar w
     2.1 --- a/src/HOL/Tools/Sledgehammer/sledgehammer_proof_reconstruct.ML	Mon May 17 10:18:14 2010 +0200
     2.2 +++ b/src/HOL/Tools/Sledgehammer/sledgehammer_proof_reconstruct.ML	Mon May 17 12:15:37 2010 +0200
     2.3 @@ -14,7 +14,6 @@
     2.4    val invert_const: string -> string
     2.5    val invert_type_const: string -> string
     2.6    val num_type_args: theory -> string -> int
     2.7 -  val make_tvar: string -> typ
     2.8    val strip_prefix: string -> string -> string option
     2.9    val metis_line: int -> int -> string list -> string
    2.10    val metis_proof_text:
    2.11 @@ -235,26 +234,27 @@
    2.12          SOME c' => c'
    2.13        | NONE => c;
    2.14  
    2.15 -fun make_tvar s = TVar (("'" ^ s, 0), HOLogic.typeS);
    2.16 -fun make_tparam s = TypeInfer.param 0 (s, HOLogic.typeS)
    2.17 -fun make_var (b,T) = Var((b,0),T);
    2.18 -
    2.19  (* Type variables are given the basic sort "HOL.type". Some will later be
    2.20    constrained by information from type literals, or by type inference. *)
    2.21 -fun type_from_node (u as IntLeaf _) = raise NODE [u]
    2.22 -  | type_from_node (u as StrNode (a, us)) =
    2.23 -    let val Ts = map type_from_node us in
    2.24 +fun type_from_node _ (u as IntLeaf _) = raise NODE [u]
    2.25 +  | type_from_node tfrees (u as StrNode (a, us)) =
    2.26 +    let val Ts = map (type_from_node tfrees) us in
    2.27        case strip_prefix tconst_prefix a of
    2.28          SOME b => Type (invert_type_const b, Ts)
    2.29        | NONE =>
    2.30          if not (null us) then
    2.31            raise NODE [u]  (* only "tconst"s have type arguments *)
    2.32          else case strip_prefix tfree_prefix a of
    2.33 -          SOME b => TFree ("'" ^ b, HOLogic.typeS)
    2.34 +          SOME b =>
    2.35 +          let val s = "'" ^ b in
    2.36 +            TFree (s, AList.lookup (op =) tfrees s |> the_default HOLogic.typeS)
    2.37 +          end
    2.38          | NONE =>
    2.39            case strip_prefix tvar_prefix a of
    2.40 -            SOME b => make_tvar b
    2.41 -          | NONE => make_tparam a  (* Variable from the ATP, say "X1" *)
    2.42 +            SOME b => TVar (("'" ^ b, 0), HOLogic.typeS)
    2.43 +          | NONE =>
    2.44 +            (* Variable from the ATP, say "X1" *)
    2.45 +            TypeInfer.param 0 (a, HOLogic.typeS)
    2.46      end
    2.47  
    2.48  (*Invert the table of translations between Isabelle and ATPs*)
    2.49 @@ -287,7 +287,7 @@
    2.50  
    2.51  (* First-order translation. No types are known for variables. "HOLogic.typeT"
    2.52     should allow them to be inferred.*)
    2.53 -fun term_from_node thy full_types =
    2.54 +fun term_from_node thy full_types tfrees =
    2.55    let
    2.56      fun aux opt_T args u =
    2.57        case u of
    2.58 @@ -298,7 +298,8 @@
    2.59        | StrNode (a, us) =>
    2.60          if a = type_wrapper_name then
    2.61            case us of
    2.62 -            [term_u, typ_u] => aux (SOME (type_from_node typ_u)) args term_u
    2.63 +            [term_u, typ_u] =>
    2.64 +            aux (SOME (type_from_node tfrees typ_u)) args term_u
    2.65            | _ => raise NODE us
    2.66          else case strip_prefix const_prefix a of
    2.67            SOME "equal" =>
    2.68 @@ -324,7 +325,8 @@
    2.69                            (* Extra args from "hAPP" come after any arguments
    2.70                               given directly to the constant. *)
    2.71                            Sign.const_instance thy (c,
    2.72 -                                    map type_from_node (drop num_term_args us)))
    2.73 +                                    map (type_from_node tfrees)
    2.74 +                                        (drop num_term_args us)))
    2.75            in list_comb (t, ts) end
    2.76          | NONE => (* a free or schematic variable *)
    2.77            let
    2.78 @@ -335,21 +337,22 @@
    2.79                  SOME b => Free (b, T)
    2.80                | NONE =>
    2.81                  case strip_prefix schematic_var_prefix a of
    2.82 -                  SOME b => make_var (b, T)
    2.83 +                  SOME b => Var ((b, 0), T)
    2.84                  | NONE =>
    2.85                    (* Variable from the ATP, say "X1" *)
    2.86 -                  make_var (fix_atp_variable_name a, T)
    2.87 +                  Var ((fix_atp_variable_name a, 0), T)
    2.88            in list_comb (t, ts) end
    2.89    in aux end
    2.90  
    2.91  (* Type class literal applied to a type. Returns triple of polarity, class,
    2.92     type. *)
    2.93 -fun type_constraint_from_node pos (StrNode ("c_Not", [u])) =
    2.94 -    type_constraint_from_node (not pos) u
    2.95 -  | type_constraint_from_node pos u = case u of
    2.96 +fun type_constraint_from_node pos tfrees (StrNode ("c_Not", [u])) =
    2.97 +    type_constraint_from_node (not pos) tfrees u
    2.98 +  | type_constraint_from_node pos tfrees u = case u of
    2.99          IntLeaf _ => raise NODE [u]
   2.100        | StrNode (a, us) =>
   2.101 -            (case (strip_prefix class_prefix a, map type_from_node us) of
   2.102 +            (case (strip_prefix class_prefix a,
   2.103 +                   map (type_from_node tfrees) us) of
   2.104                   (SOME b, [T]) => (pos, b, T)
   2.105                 | _ => raise NODE [u])
   2.106  
   2.107 @@ -395,24 +398,24 @@
   2.108           |> clause_for_literals thy
   2.109  
   2.110  (*Accumulate sort constraints in vt, with "real" literals in lits.*)
   2.111 -fun lits_of_nodes thy full_types (vt, lits) us =
   2.112 -  case us of
   2.113 -    [] => (vt, finish_clause thy lits)
   2.114 -  | (u :: us) =>
   2.115 -    lits_of_nodes thy full_types
   2.116 -        (add_type_constraint (type_constraint_from_node true u) vt, lits) us
   2.117 -    handle NODE _ =>
   2.118 -           lits_of_nodes thy full_types
   2.119 -                         (vt, term_from_node thy full_types (SOME @{typ bool})
   2.120 -                                             [] u :: lits) us
   2.121 +fun lits_of_nodes thy full_types tfrees =
   2.122 +  let
   2.123 +    fun aux (vt, lits) [] = (vt, finish_clause thy lits)
   2.124 +      | aux (vt, lits) (u :: us) =
   2.125 +        aux (add_type_constraint
   2.126 +                 (type_constraint_from_node true tfrees u) vt, lits) us
   2.127 +        handle NODE _ =>
   2.128 +               aux (vt, term_from_node thy full_types tfrees (SOME @{typ bool})
   2.129 +                                       [] u :: lits) us
   2.130 +  in aux end
   2.131  
   2.132 -(*Update TVars/TFrees with detected sort constraints.*)
   2.133 -fun repair_sorts vt =
   2.134 +(* Update TVars with detected sort constraints. It's not totally clear when
   2.135 +   this code is necessary. *)
   2.136 +fun repair_tvar_sorts vt =
   2.137    let
   2.138      fun do_type (Type (a, Ts)) = Type (a, map do_type Ts)
   2.139        | do_type (TVar (xi, s)) = TVar (xi, the_default s (Vartab.lookup vt xi))
   2.140 -      | do_type (TFree (x, s)) =
   2.141 -        TFree (x, the_default s (Vartab.lookup vt (x, ~1)))
   2.142 +      | do_type (TFree z) = TFree z
   2.143      fun do_term (Const (a, T)) = Const (a, do_type T)
   2.144        | do_term (Free (a, T)) = Free (a, do_type T)
   2.145        | do_term (Var (xi, T)) = Var (xi, do_type T)
   2.146 @@ -444,45 +447,28 @@
   2.147  (* Interpret a list of syntax trees as a clause, given by "real" literals and
   2.148     sort constraints. "vt" holds the initial sort constraints, from the
   2.149     conjecture clauses. *)
   2.150 -fun clause_of_nodes ctxt full_types vt us =
   2.151 +fun clause_of_nodes ctxt full_types tfrees us =
   2.152    let
   2.153      val thy = ProofContext.theory_of ctxt
   2.154 -    val (vt, t) = lits_of_nodes thy full_types (vt, []) us
   2.155 -  in repair_sorts vt t end
   2.156 +    val (vt, t) = lits_of_nodes thy full_types tfrees (Vartab.empty, []) us
   2.157 +  in repair_tvar_sorts vt t end
   2.158  fun check_formula ctxt =
   2.159    TypeInfer.constrain @{typ bool}
   2.160    #> Syntax.check_term (ProofContext.set_mode ProofContext.mode_schematic ctxt)
   2.161  
   2.162 -(** Global sort constraints on TFrees (from tfree_tcs) are positive unit
   2.163 -    clauses. **)
   2.164 -
   2.165 -fun add_tfree_constraint (true, cl, TFree (a, _)) = add_var ((a, ~1), cl)
   2.166 -  | add_tfree_constraint _ = I
   2.167 -fun tfree_constraints_of_clauses vt [] = vt
   2.168 -  | tfree_constraints_of_clauses vt ([lit] :: uss) =
   2.169 -    (tfree_constraints_of_clauses (add_tfree_constraint
   2.170 -                                    (type_constraint_from_node true lit) vt) uss
   2.171 -     handle NODE _ => (* Not a positive type constraint? Ignore the literal. *)
   2.172 -     tfree_constraints_of_clauses vt uss)
   2.173 -  | tfree_constraints_of_clauses vt (_ :: uss) =
   2.174 -    tfree_constraints_of_clauses vt uss
   2.175 -
   2.176  
   2.177  (**** Translation of TSTP files to Isar Proofs ****)
   2.178  
   2.179  fun unvarify_term (Var ((s, 0), T)) = Free (s, T)
   2.180    | unvarify_term t = raise TERM ("unvarify_term: non-Var", [t])
   2.181  
   2.182 -fun clauses_in_lines (Definition (_, u, us)) = u :: us
   2.183 -  | clauses_in_lines (Inference (_, us, _)) = us
   2.184 -
   2.185 -fun decode_line full_types vt (Definition (num, u, us)) ctxt =
   2.186 +fun decode_line full_types tfrees (Definition (num, u, us)) ctxt =
   2.187      let
   2.188 -      val t1 = clause_of_nodes ctxt full_types vt [u]
   2.189 +      val t1 = clause_of_nodes ctxt full_types tfrees [u]
   2.190        val vars = snd (strip_comb t1)
   2.191        val frees = map unvarify_term vars
   2.192        val unvarify_args = subst_atomic (vars ~~ frees)
   2.193 -      val t2 = clause_of_nodes ctxt full_types vt us
   2.194 +      val t2 = clause_of_nodes ctxt full_types tfrees us
   2.195        val (t1, t2) =
   2.196          HOLogic.eq_const HOLogic.typeT $ t1 $ t2
   2.197          |> unvarify_args |> uncombine_term |> check_formula ctxt
   2.198 @@ -491,19 +477,16 @@
   2.199        (Definition (num, t1, t2),
   2.200         fold Variable.declare_term (maps OldTerm.term_frees [t1, t2]) ctxt)
   2.201      end
   2.202 -  | decode_line full_types vt (Inference (num, us, deps)) ctxt =
   2.203 +  | decode_line full_types tfrees (Inference (num, us, deps)) ctxt =
   2.204      let
   2.205 -      val t = us |> clause_of_nodes ctxt full_types vt
   2.206 +      val t = us |> clause_of_nodes ctxt full_types tfrees
   2.207                   |> unskolemize_term |> uncombine_term |> check_formula ctxt
   2.208      in
   2.209        (Inference (num, t, deps),
   2.210         fold Variable.declare_term (OldTerm.term_frees t) ctxt)
   2.211      end
   2.212 -fun decode_lines ctxt full_types lines =
   2.213 -  let
   2.214 -    val vt = tfree_constraints_of_clauses Vartab.empty
   2.215 -                                          (map clauses_in_lines lines)
   2.216 -  in #1 (fold_map (decode_line full_types vt) lines ctxt) end
   2.217 +fun decode_lines ctxt full_types tfrees lines =
   2.218 +  fst (fold_map (decode_line full_types tfrees) lines ctxt)
   2.219  
   2.220  fun aint_inference _ (Definition _) = true
   2.221    | aint_inference t (Inference (_, t', _)) = not (t aconv t')
   2.222 @@ -674,13 +657,13 @@
   2.223            forall_vars t,
   2.224            ByMetis (fold (add_fact_from_dep thm_names) deps ([], [])))
   2.225  
   2.226 -fun proof_from_atp_proof pool ctxt full_types isar_shrink_factor atp_proof
   2.227 -                         conjecture_shape thm_names params frees =
   2.228 +fun proof_from_atp_proof pool ctxt full_types tfrees isar_shrink_factor
   2.229 +                         atp_proof conjecture_shape thm_names params frees =
   2.230    let
   2.231      val lines =
   2.232        atp_proof ^ "$" (* the $ sign acts as a sentinel *)
   2.233        |> parse_proof pool
   2.234 -      |> decode_lines ctxt full_types
   2.235 +      |> decode_lines ctxt full_types tfrees
   2.236        |> rpair [] |-> fold_rev (add_line conjecture_shape thm_names)
   2.237        |> rpair [] |-> fold_rev add_nontrivial_line
   2.238        |> rpair (0, []) |-> fold_rev (add_desired_line ctxt isar_shrink_factor
   2.239 @@ -839,7 +822,7 @@
   2.240        apfst (map (fn l => AList.lookup (op =) subst l |> the_default l))
   2.241      fun do_step (step as Assume (l, t)) (proof, subst, assums) =
   2.242          (case AList.lookup (op aconv) assums t of
   2.243 -           SOME l' => (proof, (l', l) :: subst, assums)
   2.244 +           SOME l' => (proof, (l, l') :: subst, assums)
   2.245           | NONE => (step :: proof, subst, (t, l) :: assums))
   2.246        | do_step (Have (qs, l, t, by)) (proof, subst, assums) =
   2.247          (Have (qs, l, t,
   2.248 @@ -988,11 +971,12 @@
   2.249      val thy = ProofContext.theory_of ctxt
   2.250      val (params, hyp_ts, concl_t) = strip_subgoal goal i
   2.251      val frees = fold Term.add_frees (concl_t :: hyp_ts) []
   2.252 +    val tfrees = fold Term.add_tfrees (concl_t :: hyp_ts) []
   2.253      val n = Logic.count_prems (prop_of goal)
   2.254      val (one_line_proof, lemma_names) =
   2.255        metis_proof_text (minimize_command, atp_proof, thm_names, goal, i)
   2.256      fun isar_proof_for () =
   2.257 -      case proof_from_atp_proof pool ctxt full_types isar_shrink_factor
   2.258 +      case proof_from_atp_proof pool ctxt full_types tfrees isar_shrink_factor
   2.259                                  atp_proof conjecture_shape thm_names params
   2.260                                  frees
   2.261             |> redirect_proof thy conjecture_shape hyp_ts concl_t