src/HOL/Tools/Sledgehammer/sledgehammer_minimize_isar.ML
author blanchet
Thu Dec 19 18:22:31 2013 +0100 (2013-12-19 ago)
changeset 54826 79745ba60a5a
parent 54813 c8b04da1bd01
child 54827 14e2c7616209
permissions -rw-r--r--
data structure rationalization
smolkas@52611
     1
(*  Title:      HOL/Tools/Sledgehammer/sledgehammer_minimize_isar.ML
blanchet@54712
     2
    Author:     Steffen Juilf Smolka, TU Muenchen
smolkas@52611
     3
    Author:     Jasmin Blanchette, TU Muenchen
smolkas@52611
     4
smolkas@52611
     5
Minimize dependencies (used facts) of Isar proof steps.
smolkas@52611
     6
*)
smolkas@52611
     7
smolkas@52611
     8
signature SLEDGEHAMMER_MINIMIZE_ISAR =
smolkas@52611
     9
sig
smolkas@52611
    10
  type preplay_interface = Sledgehammer_Preplay.preplay_interface
blanchet@54712
    11
  type isar_step = Sledgehammer_Proof.isar_step
smolkas@52611
    12
  type isar_proof = Sledgehammer_Proof.isar_proof
blanchet@54712
    13
blanchet@54712
    14
  val min_deps_of_step : preplay_interface -> isar_step -> isar_step
blanchet@54712
    15
  val postprocess_remove_unreferenced_steps : (isar_step -> isar_step) -> isar_proof -> isar_proof
blanchet@54504
    16
end;
smolkas@52611
    17
smolkas@52611
    18
structure Sledgehammer_Minimize_Isar : SLEDGEHAMMER_MINIMIZE_ISAR =
smolkas@52611
    19
struct
smolkas@52611
    20
smolkas@52611
    21
open Sledgehammer_Util
smolkas@52611
    22
open Sledgehammer_Proof
smolkas@52611
    23
open Sledgehammer_Preplay
smolkas@52611
    24
blanchet@54712
    25
val slack = seconds 0.1
smolkas@52611
    26
smolkas@52611
    27
fun min_deps_of_step (_ : preplay_interface) (step as Let _) = step
blanchet@54826
    28
  | min_deps_of_step {get_preplay_result, set_preplay_result, preplay_quietly, ...}
blanchet@54712
    29
      (step as Prove (qs, xs, l, t, subproofs, ((lfs, gfs), meth))) =
blanchet@54826
    30
    (case get_preplay_result l of
blanchet@54826
    31
      Preplay_Success (false, time) =>
blanchet@54712
    32
      let
blanchet@54712
    33
        fun mk_step_lfs_gfs lfs gfs = Prove (qs, xs, l, t, subproofs, ((lfs, gfs), meth))
blanchet@54712
    34
        val mk_step_gfs_lfs = curry (swap #> uncurry mk_step_lfs_gfs)
smolkas@52611
    35
blanchet@54712
    36
        fun minimize_facts _ time min_facts [] = (time, min_facts)
blanchet@54712
    37
          | minimize_facts mk_step time min_facts (f :: facts) =
blanchet@54712
    38
            (case preplay_quietly (Time.+ (time, slack)) (mk_step (min_facts @ facts)) of
blanchet@54712
    39
              (true, _) => minimize_facts mk_step time (f :: min_facts) facts
blanchet@54712
    40
            | (false, time) => minimize_facts mk_step time min_facts facts)
smolkas@52611
    41
blanchet@54712
    42
        val (time, min_lfs) = minimize_facts (mk_step_gfs_lfs gfs) time [] lfs
blanchet@54712
    43
        val (time, min_gfs) = minimize_facts (mk_step_lfs_gfs min_lfs) time [] gfs
blanchet@54712
    44
      in
blanchet@54826
    45
        set_preplay_result l (Preplay_Success (false, time)); mk_step_lfs_gfs min_lfs min_gfs
blanchet@54826
    46
      end
blanchet@54826
    47
    | _ => step (* don't touch steps that time out or fail *))
smolkas@52611
    48
blanchet@54712
    49
fun postprocess_remove_unreferenced_steps postproc_step =
smolkas@52611
    50
  let
smolkas@52611
    51
    val add_lfs = fold (Ord_List.insert label_ord)
smolkas@52611
    52
smolkas@52611
    53
    fun do_proof (Proof (fix, assms, steps)) =
blanchet@54712
    54
      let val (refed, steps) = do_steps steps in
smolkas@52611
    55
        (refed, Proof (fix, assms, steps))
smolkas@52611
    56
      end
blanchet@54754
    57
    and do_steps [] = ([], [])
blanchet@54754
    58
      | do_steps steps =
blanchet@54754
    59
        let
blanchet@54754
    60
          (* the last step is always implicitly referenced *)
blanchet@54754
    61
          val (steps, (refed, concl)) =
blanchet@54754
    62
            split_last steps
blanchet@54754
    63
            ||> do_refed_step
blanchet@54754
    64
        in
blanchet@54754
    65
          fold_rev do_step steps (refed, [concl])
blanchet@54754
    66
        end
smolkas@52611
    67
    and do_step step (refed, accu) =
blanchet@54754
    68
      (case label_of_step step of
smolkas@52611
    69
        NONE => (refed, step :: accu)
smolkas@52611
    70
      | SOME l =>
blanchet@54813
    71
        if Ord_List.member label_ord refed l then
blanchet@54813
    72
          do_refed_step step
blanchet@54813
    73
          |>> Ord_List.union label_ord refed
blanchet@54813
    74
          ||> (fn x => x :: accu)
blanchet@54813
    75
        else
blanchet@54813
    76
          (refed, accu))
blanchet@54712
    77
    and do_refed_step step = step |> postproc_step |> do_refed_step'
smolkas@52611
    78
    and do_refed_step' (Let _) = raise Fail "Sledgehammer_Minimize_Isar"
blanchet@54700
    79
      | do_refed_step' (Prove (qs, xs, l, t, subproofs, ((lfs, gfs), m))) =
smolkas@52611
    80
        let
smolkas@52611
    81
          val (refed, subproofs) =
smolkas@52611
    82
            map do_proof subproofs
smolkas@52611
    83
            |> split_list
smolkas@52611
    84
            |>> Ord_List.unions label_ord
smolkas@52611
    85
            |>> add_lfs lfs
blanchet@54700
    86
          val step = Prove (qs, xs, l, t, subproofs, ((lfs, gfs), m))
smolkas@52611
    87
        in
smolkas@52611
    88
          (refed, step)
smolkas@52611
    89
        end
smolkas@52611
    90
  in
blanchet@54712
    91
    snd o do_proof
smolkas@52611
    92
  end
smolkas@52611
    93
blanchet@54504
    94
end;