src/HOL/Tools/Sledgehammer/sledgehammer_preplay.ML
author smolkas
Thu, 14 Feb 2013 22:49:22 +0100
changeset 51131 7de262be1e95
parent 51130 76d68444cd59
child 51147 020a6812a204
permissions -rw-r--r--
preplay subblocks
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
51130
76d68444cd59 renamed sledgehammer_shrink to sledgehammer_compress
smolkas
parents: 51128
diff changeset
     1
(*  Title:      HOL/Tools/Sledgehammer/sledgehammer_preplay.ML
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     2
    Author:     Jasmin Blanchette, TU Muenchen
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     3
    Author:     Steffen Juilf Smolka, TU Muenchen
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     4
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
     5
Preplaying of isar proofs.
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     6
*)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     7
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     8
signature SLEDGEHAMMER_PREPLAY =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
     9
sig
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    10
  type isar_step = Sledgehammer_Proof.isar_step
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    11
  eqtype preplay_time
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    12
  val zero_preplay_time : preplay_time
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    13
  val some_preplay_time : preplay_time
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    14
  val add_preplay_time : preplay_time -> preplay_time -> preplay_time
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    15
  val string_of_preplay_time : preplay_time -> string
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    16
  val try_metis : bool -> string -> string -> Proof.context ->
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    17
    Time.time -> (isar_step option * isar_step) -> unit -> preplay_time
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    18
  val try_metis_quietly : bool -> string -> string -> Proof.context ->
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    19
    Time.time -> (isar_step option * isar_step) -> unit -> preplay_time
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    20
end
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    21
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    22
structure Sledgehammer_Preplay : SLEDGEHAMMER_PREPLAY =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    23
struct
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    24
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    25
open Sledgehammer_Util
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    26
open Sledgehammer_Proof
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    27
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    28
(* The boolean flag encodes whether the time is exact (false) or an lower bound
51131
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    29
   (true):
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    30
      (t, false) = "t ms"
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    31
      (t, true)  = "> t ms" *)
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    32
type preplay_time = bool * Time.time
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    33
51131
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    34
val zero_preplay_time = (false, Time.zeroTime) (* 0 ms *)
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    35
val some_preplay_time = (true, Time.zeroTime)  (* > 0 ms *)
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    36
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    37
fun add_preplay_time (b1, t1) (b2, t2) = (b1 orelse b2, Time.+(t1,t2))
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    38
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    39
val string_of_preplay_time = ATP_Util.string_from_ext_time
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    40
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    41
(* timing *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    42
fun take_time timeout tac arg =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    43
  let
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    44
    val timing = Timing.start ()
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    45
  in
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    46
    (TimeLimit.timeLimit timeout tac arg;
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    47
      Timing.result timing |> #cpu |> pair false)
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    48
    handle TimeLimit.TimeOut => (true, timeout)
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    49
  end
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    50
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    51
(* lookup facts in context *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    52
fun resolve_fact_names ctxt names =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    53
  names
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    54
    |>> map string_for_label
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    55
    |> op @
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    56
    |> maps (thms_of_name ctxt)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    57
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    58
exception ZEROTIME
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    59
fun try_metis debug type_enc lam_trans ctxt timeout (succedent, step) =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    60
  let
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    61
    val (t, byline, obtain) =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    62
      (case step of
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    63
        Prove (_, _, t, byline) => (t, byline, false)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    64
      | Obtain (_, xs, _, t, byline) =>
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    65
        (* proof obligation: !!thesis. (!!x. A x ==> thesis) ==> thesis
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    66
           (see ~~/src/Pure/Isar/obtain.ML) *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    67
        let
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    68
          val thesis = Term.Free ("thesis", HOLogic.boolT)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    69
          val thesis_prop = thesis |> HOLogic.mk_Trueprop
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    70
          val frees = map Term.Free xs
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    71
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    72
          (* !!x1..xn. t ==> thesis (xs = [x1, .., xn]) *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    73
          val inner_prop =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    74
            fold_rev Logic.all frees (Logic.mk_implies (t, thesis_prop))
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    75
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    76
          (* !!thesis. (!!x1..xn. t ==> thesis) ==> thesis *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    77
          val prop =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    78
            Logic.all thesis (Logic.mk_implies (inner_prop, thesis_prop))
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    79
        in
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    80
          (prop, byline, true)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    81
        end
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    82
      | _ => raise ZEROTIME)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    83
    val make_thm = Skip_Proof.make_thm (Proof_Context.theory_of ctxt)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    84
    val facts =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    85
      (case byline of
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    86
        By_Metis fact_names => resolve_fact_names ctxt fact_names
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    87
      | Case_Split (cases, fact_names) =>
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    88
        resolve_fact_names ctxt fact_names
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    89
          @ (case the succedent of
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    90
              Assume (_, t) => make_thm t
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    91
            | Obtain (_, _, _, t, _) => make_thm t
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    92
            | Prove (_, _, t, _) => make_thm t
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    93
            | _ => error "preplay error: unexpected succedent of case split")
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    94
          :: map (hd #> (fn Assume (_, a) => Logic.mk_implies (a, t)
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    95
                          | _ => error "preplay error: malformed case split")
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    96
                     #> make_thm)
51128
0021ea861129 introduced subblock in isar_step datatype for conjecture herbrandization
smolkas
parents: 50924
diff changeset
    97
               cases
51131
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    98
      | Subblock proof =>
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
    99
        let
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   100
          val (steps, last_step) = split_last proof
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   101
          (* TODO: assuming Fix may only occur at the beginning of a subblock,
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   102
             this can be optimized *)
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   103
          val fixed_frees =
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   104
            fold (fn Fix xs => append (map Free xs) | _ => I) steps []
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   105
          (* TODO: make sure the var indexnames are actually fresh *)
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   106
          fun var_of_free (Free (x, T)) = Var((x, 1), T)
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   107
            | var_of_free _ = error "preplay error: not a free variable"
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   108
          val substitutions = map (`var_of_free #> swap) fixed_frees
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   109
          val concl =
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   110
            (case last_step of
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   111
              Prove (_, _, t, _) => t
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   112
            | _ => error "preplay error: unexpected conclusion of subblock")
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   113
        in
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   114
          concl |> subst_free substitutions |> make_thm |> single
7de262be1e95 preplay subblocks
smolkas
parents: 51130
diff changeset
   115
        end)
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   116
    val ctxt = ctxt |> Config.put Metis_Tactic.verbose debug
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   117
                    |> obtain ? Config.put Metis_Tactic.new_skolem true
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   118
    val goal =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   119
      Goal.prove (Config.put Metis_Tactic.verbose debug ctxt) [] [] t
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   120
    fun tac {context = ctxt, prems = _} =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   121
      Metis_Tactic.metis_tac [type_enc] lam_trans ctxt facts 1
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   122
  in
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   123
    take_time timeout
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   124
      (fn () => goal tac handle ERROR msg => error ("preplay error: " ^ msg))
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   125
  end
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   126
  handle ZEROTIME => K zero_preplay_time
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   127
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   128
(* this version treats exceptions like timeouts *)
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   129
fun try_metis_quietly debug type_enc lam_trans ctxt timeout =
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   130
   the_default (true, timeout) oo try o try_metis debug type_enc lam_trans ctxt timeout
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   131
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   132
end