src/HOL/Tools/Sledgehammer/sledgehammer_preplay.ML
author traytel
Wed, 08 May 2013 09:45:30 +0200
changeset 51916 eac9e9a45bf5
parent 51879 ee9562d31778
child 51998 f732a674db1b
permissions -rw-r--r--
stronger monotonicity property for relators
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
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    16
  val try_metis : bool -> bool -> string -> string -> Proof.context ->
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    17
    Time.time -> isar_step -> unit -> preplay_time
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    18
  val try_metis_quietly : bool -> bool -> string -> string -> Proof.context ->
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    19
    Time.time -> 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
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    41
(* preplay tracing *)
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    42
fun preplay_trace ctxt assms concl time =
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    43
  let
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    44
    val ctxt = ctxt |> Config.put show_markup true
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    45
    val time = "[" ^ (string_of_preplay_time time) ^ "]" |> Pretty.str
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    46
    val nr_of_assms = length assms
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    47
    val assms = assms |> map (Display.pretty_thm ctxt)
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    48
                      |> (fn [] => Pretty.str ""
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    49
                           | [a] => a
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    50
                           | assms => Pretty.enum ";" "⟦" "⟧" assms)
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    51
    val concl = concl |> Syntax.pretty_term ctxt
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    52
    val trace_list = [] |> cons concl
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    53
                        |> nr_of_assms>0 ? cons (Pretty.str "⟹")
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    54
                        |> cons assms
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    55
                        |> cons time
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    56
    val pretty_trace = Pretty.blk(2, Pretty.breaks trace_list)
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    57
  in tracing (Pretty.string_of pretty_trace) end
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    58
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    59
(* timing *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    60
fun take_time timeout tac arg =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    61
  let
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    62
    val timing = Timing.start ()
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    63
  in
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    64
    (TimeLimit.timeLimit timeout tac arg;
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    65
      Timing.result timing |> #cpu |> pair false)
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
    66
    handle TimeLimit.TimeOut => (true, timeout)
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    67
  end
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    68
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    69
(* lookup facts in context *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    70
fun resolve_fact_names ctxt names =
51179
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
    71
  (names
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    72
    |>> map string_for_label
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    73
    |> op @
51179
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
    74
    |> maps (thms_of_name ctxt))
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
    75
  handle ERROR msg => error ("preplay error: " ^ msg)
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    76
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    77
(* turn terms/proofs into theorems *)
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    78
fun thm_of_term ctxt = Skip_Proof.make_thm (Proof_Context.theory_of ctxt)
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    79
fun thm_of_proof ctxt (Proof (Fix fixed_frees, Assume assms, steps)) =
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    80
  let
51179
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
    81
    val concl = (case try List.last steps of
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
    82
                  SOME (Prove (_, _, t, _)) => t
51876
724c67f59929 added informative error messages
smolkas
parents: 51179
diff changeset
    83
                | _ => raise Fail "preplay error: malformed subproof")
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    84
    val var_idx = maxidx_of_term concl + 1
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    85
    fun var_of_free (x, T) = Var((x, var_idx), T)
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    86
    val substitutions =
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    87
      map (`var_of_free #> swap #> apfst Free) fixed_frees
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    88
  in
51179
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
    89
    Logic.list_implies (assms |> map snd, concl)
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    90
      |> subst_free substitutions
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    91
      |> thm_of_term ctxt
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    92
  end
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    93
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    94
exception ZEROTIME
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    95
fun try_metis debug trace type_enc lam_trans ctxt timeout step =
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    96
  let
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
    97
    val (prop, subproofs, fact_names, obtain) =
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
    98
      (case step of
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
    99
        Prove (_, _, t, By_Metis (subproofs, fact_names)) =>
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
   100
            (t, subproofs, fact_names, false)
51179
0d5f8812856f split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents: 51178
diff changeset
   101
      | Obtain (_, Fix xs, _, t, By_Metis (subproofs, fact_names)) =>
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   102
        (* proof obligation: !!thesis. (!!x. A x ==> thesis) ==> thesis
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   103
           (see ~~/src/Pure/Isar/obtain.ML) *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   104
        let
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   105
          val thesis = Term.Free ("thesis", HOLogic.boolT)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   106
          val thesis_prop = thesis |> HOLogic.mk_Trueprop
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   107
          val frees = map Term.Free xs
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   108
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   109
          (* !!x1..xn. t ==> thesis (xs = [x1, .., xn]) *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   110
          val inner_prop =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   111
            fold_rev Logic.all frees (Logic.mk_implies (t, thesis_prop))
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   112
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   113
          (* !!thesis. (!!x1..xn. t ==> thesis) ==> thesis *)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   114
          val prop =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   115
            Logic.all thesis (Logic.mk_implies (inner_prop, thesis_prop))
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   116
        in
51178
06689dbfe072 simplified byline, isar_qualifier
smolkas
parents: 51155
diff changeset
   117
          (prop, subproofs, fact_names, true)
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   118
        end
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   119
      | _ => raise ZEROTIME)
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   120
    val facts =
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   121
      map (thm_of_proof ctxt) subproofs @ resolve_fact_names ctxt fact_names
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   122
    val ctxt = ctxt |> Config.put Metis_Tactic.verbose debug
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   123
                    |> obtain ? Config.put Metis_Tactic.new_skolem true
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   124
    val goal =
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   125
      Goal.prove (Config.put Metis_Tactic.verbose debug ctxt) [] [] prop
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   126
    fun tac {context = ctxt, prems = _} =
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   127
      Metis_Tactic.metis_tac [type_enc] lam_trans ctxt facts 1
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   128
    fun run_tac () = goal tac
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   129
      handle ERROR msg => error ("preplay error: " ^ msg)
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   130
  in
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   131
    fn () =>
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   132
      let
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   133
        val preplay_time = take_time timeout run_tac ()
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   134
        (* tracing *)
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   135
        val _ = if trace then preplay_trace ctxt facts prop preplay_time else ()
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   136
      in
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   137
        preplay_time
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   138
      end
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   139
  end
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   140
  handle ZEROTIME => K zero_preplay_time
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   141
50924
beb95bf66b21 changed type of preplay time; tuned preplaying
smolkas
parents: 50923
diff changeset
   142
(* this version treats exceptions like timeouts *)
51879
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   143
fun try_metis_quietly debug trace type_enc lam_trans ctxt timeout =
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   144
  the_default (true, timeout) oo try
ee9562d31778 added preplay tracing
smolkas
parents: 51876
diff changeset
   145
  o try_metis debug trace type_enc lam_trans ctxt timeout
50923
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   146
141d8f575f6f move preplaying to own structure
smolkas
parents:
diff changeset
   147
end