src/HOL/Tools/Sledgehammer/sledgehammer_compress.ML
author blanchet
Thu, 19 Dec 2013 19:16:44 +0100
changeset 54828 b2271ad695db
parent 54827 14e2c7616209
child 55183 17ec4a29ef71
permissions -rw-r--r--
don't do 'isar_try0' if preplaying is off
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_compress.ML
54813
blanchet
parents: 54752
diff changeset
     2
    Author:     Steffen Juilf Smolka, TU Muenchen
50263
0b430064296a added comments to new source files
smolkas
parents: 50261
diff changeset
     3
    Author:     Jasmin Blanchette, TU Muenchen
0b430064296a added comments to new source files
smolkas
parents: 50261
diff changeset
     4
52633
smolkas
parents: 52626
diff changeset
     5
Compression of isar proofs by merging steps.
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
     6
Only proof steps using the same proof method are merged.
50263
0b430064296a added comments to new source files
smolkas
parents: 50261
diff changeset
     7
*)
0b430064296a added comments to new source files
smolkas
parents: 50261
diff changeset
     8
51130
76d68444cd59 renamed sledgehammer_shrink to sledgehammer_compress
smolkas
parents: 51128
diff changeset
     9
signature SLEDGEHAMMER_COMPRESS =
50259
9c64a52ae499 put shrink in own structure
smolkas
parents:
diff changeset
    10
sig
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
    11
  type isar_proof = Sledgehammer_Proof.isar_proof
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    12
  type preplay_interface = Sledgehammer_Preplay.preplay_interface
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    13
53763
70d370743dc6 hardcoded obscure option
blanchet
parents: 53762
diff changeset
    14
  val compress_proof : real -> preplay_interface -> isar_proof -> isar_proof
54504
blanchet
parents: 54503
diff changeset
    15
end;
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    16
51130
76d68444cd59 renamed sledgehammer_shrink to sledgehammer_compress
smolkas
parents: 51128
diff changeset
    17
structure Sledgehammer_Compress : SLEDGEHAMMER_COMPRESS =
50259
9c64a52ae499 put shrink in own structure
smolkas
parents:
diff changeset
    18
struct
9c64a52ae499 put shrink in own structure
smolkas
parents:
diff changeset
    19
50265
9eafa567e061 made use of sledgehammer_util
smolkas
parents: 50264
diff changeset
    20
open Sledgehammer_Util
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
    21
open Sledgehammer_Reconstructor
50264
a9ec48b98734 renamed sledgehammer_isar_reconstruct to sledgehammer_proof
smolkas
parents: 50263
diff changeset
    22
open Sledgehammer_Proof
50923
141d8f575f6f move preplaying to own structure
smolkas
parents: 50908
diff changeset
    23
open Sledgehammer_Preplay
50259
9c64a52ae499 put shrink in own structure
smolkas
parents:
diff changeset
    24
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    25
(* traverses steps in post-order and collects the steps with the given labels *)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    26
fun collect_successors steps lbls =
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    27
  let
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    28
    fun do_steps _ ([], accu) = ([], accu)
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    29
      | do_steps [] accum = accum
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    30
      | do_steps (step :: steps) accum = do_steps steps (do_step step accum)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    31
    and do_step (Let _) x = x
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    32
      | do_step (step as Prove (_, _, l, _, subproofs, _)) x =
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    33
        (case do_subproofs subproofs x of
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    34
          ([], accu) => ([], accu)
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    35
        | accum as (l' :: lbls', accu) => if l = l' then (lbls', step :: accu) else accum)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    36
    and do_subproofs [] x = x
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    37
      | do_subproofs (proof :: subproofs) x =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    38
        (case do_steps (steps_of_proof proof) x of
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    39
          accum as ([], _) => accum
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    40
        | accum => do_subproofs subproofs accum)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    41
  in
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    42
    (case do_steps steps (lbls, []) of
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    43
      ([], succs) => rev succs
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    44
    | _ => raise Fail "Sledgehammer_Compress: collect_successors")
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    45
  end
50259
9c64a52ae499 put shrink in own structure
smolkas
parents:
diff changeset
    46
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    47
(* traverses steps in reverse post-order and inserts the given updates *)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    48
fun update_steps steps updates =
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    49
  let
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    50
    fun do_steps [] updates = ([], updates)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    51
      | do_steps steps [] = (steps, [])
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    52
      | do_steps (step :: steps) updates = do_step step (do_steps steps updates)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    53
    and do_step step (steps, []) = (step :: steps, [])
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    54
      | do_step (step as Let _) (steps, updates) = (step :: steps, updates)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    55
      | do_step (Prove (qs, xs, l, t, subproofs, by))
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    56
          (steps, updates as Prove (qs', xs', l', t', subproofs', by') :: updates') =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    57
        let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    58
          val (subproofs, updates) =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    59
            if l = l' then do_subproofs subproofs' updates' else do_subproofs subproofs updates
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    60
        in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    61
          if l = l' then (Prove (qs', xs', l', t', subproofs, by') :: steps, updates)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    62
          else (Prove (qs, xs, l, t, subproofs, by) :: steps, updates)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    63
        end
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    64
      | do_step _ _ = raise Fail "Sledgehammer_Compress: update_steps (invalid update)"
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    65
    and do_subproofs [] updates = ([], updates)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    66
      | do_subproofs steps [] = (steps, [])
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    67
      | do_subproofs (proof :: subproofs) updates =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    68
        do_proof proof (do_subproofs subproofs updates)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    69
    and do_proof proof (proofs, []) = (proof :: proofs, [])
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    70
      | do_proof (Proof (fix, assms, steps)) (proofs, updates) =
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    71
        let val (steps, updates) = do_steps steps updates in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    72
          (Proof (fix, assms, steps) :: proofs, updates)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    73
        end
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    74
  in
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    75
    (case do_steps steps (rev updates) of
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    76
      (steps, []) => steps
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    77
    | _ => raise Fail "Sledgehammer_Compress: update_steps")
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    78
  end
50672
ab5b8b5c9cbe added "obtain" to Isar proof construction data structure
blanchet
parents: 50557
diff changeset
    79
54752
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    80
(* Tries merging the first step into the second step. Arbitrarily picks the second step's method. *)
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    81
fun try_merge (Prove (_, [], lbl1, _, [], ((lfs1, gfs1), _)))
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    82
      (Prove (qs2, fix, lbl2, t, subproofs, ((lfs2, gfs2), meth2))) =
54752
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    83
    let
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    84
      val lfs = remove (op =) lbl1 lfs2 |> union (op =) lfs1
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    85
      val gfs = union (op =) gfs1 gfs2
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    86
    in
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    87
      SOME (Prove (qs2, fix, lbl2, t, subproofs, ((lfs, gfs), meth2)))
dad9e5393524 more aggressive merging
blanchet
parents: 54712
diff changeset
    88
    end
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    89
  | try_merge _ _ = NONE
50672
ab5b8b5c9cbe added "obtain" to Isar proof construction data structure
blanchet
parents: 50557
diff changeset
    90
53763
70d370743dc6 hardcoded obscure option
blanchet
parents: 53762
diff changeset
    91
val compress_degree = 2
53762
06510d01a07b hard-coded an obscure option
blanchet
parents: 52692
diff changeset
    92
val merge_timeout_slack = 1.2
06510d01a07b hard-coded an obscure option
blanchet
parents: 52692
diff changeset
    93
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    94
(* Precondition: The proof must be labeled canonically
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
    95
   (cf. "Slegehammer_Proof.relabel_proof_canonically"). *)
53763
70d370743dc6 hardcoded obscure option
blanchet
parents: 53762
diff changeset
    96
fun compress_proof isar_compress
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
    97
    ({get_preplay_outcome, set_preplay_outcome, preplay_quietly, ...} : preplay_interface) proof =
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    98
  if isar_compress <= 1.0 then
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
    99
    proof
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   100
  else
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   101
    let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   102
      val (compress_further, decrement_step_count) =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   103
        let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   104
          val number_of_steps = add_proof_steps (steps_of_proof proof) 0
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   105
          val target_number_of_steps = Real.round (Real.fromInt number_of_steps / isar_compress)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   106
          val delta = Unsynchronized.ref (number_of_steps - target_number_of_steps)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   107
        in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   108
          (fn () => !delta > 0, fn () => delta := !delta - 1)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   109
        end
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   110
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   111
      val (get_successors, replace_successor) =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   112
        let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   113
          fun add_refs (Let _) = I
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   114
            | add_refs (Prove (_, _, v, _, _, ((lfs, _), _))) =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   115
              fold (fn key => Canonical_Lbl_Tab.cons_list (key, v)) lfs
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   116
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   117
          val tab =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   118
            Canonical_Lbl_Tab.empty
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   119
            |> fold_isar_steps add_refs (steps_of_proof proof)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   120
            (* "rev" should have the same effect as "sort canonical_label_ord" *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   121
            |> Canonical_Lbl_Tab.map (K rev)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   122
            |> Unsynchronized.ref
51260
61bc5a3bef09 tuned agressiveness of isar compression
smolkas
parents: 51179
diff changeset
   123
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   124
          fun get_successors l = Canonical_Lbl_Tab.lookup_list (!tab) l
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   125
          fun set_successors l refs = tab := Canonical_Lbl_Tab.update (l, refs) (!tab)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   126
          fun replace_successor old new dest =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   127
            get_successors dest
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   128
            |> Ord_List.remove canonical_label_ord old
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   129
            |> Ord_List.union canonical_label_ord new
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   130
            |> set_successors dest
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   131
        in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   132
          (get_successors, replace_successor)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   133
        end
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   134
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   135
      (** elimination of trivial, one-step subproofs **)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   136
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   137
      fun elim_subproofs' time qs fix l t lfs gfs meth subs nontriv_subs =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   138
        if null subs orelse not (compress_further ()) then
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   139
          (set_preplay_outcome l (Played time);
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   140
           Prove (qs, fix, l, t, List.revAppend (nontriv_subs, subs), ((lfs, gfs), meth)))
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   141
        else
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   142
          (case subs of
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   143
            (sub as Proof (_, assms, sub_steps)) :: subs =>
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   144
            (let
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   145
              (* trivial subproofs have exactly one Prove step *)
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   146
              val SOME (Prove (_, [], l', _, [], ((lfs', gfs'), _))) = try the_single sub_steps
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   147
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   148
              (* only touch proofs that can be preplayed sucessfully *)
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   149
              val Played time' = get_preplay_outcome l'
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   150
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   151
              (* merge steps *)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   152
              val subs'' = subs @ nontriv_subs
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   153
              val lfs'' =
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   154
                subtract (op =) (map fst assms) lfs'
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   155
                |> union (op =) lfs
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   156
              val gfs'' = union (op =) gfs' gfs
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   157
              val by = ((lfs'', gfs''), meth)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   158
              val step'' = Prove (qs, fix, l, t, subs'', by)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   159
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   160
              (* check if the modified step can be preplayed fast enough *)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   161
              val timeout = time_mult merge_timeout_slack (Time.+(time, time'))
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   162
              val Played time'' = preplay_quietly timeout step''
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   163
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   164
            in
52626
79a4e7f8d758 cleaner preplay interface
smolkas
parents: 52614
diff changeset
   165
              decrement_step_count (); (* l' successfully eliminated! *)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   166
              map (replace_successor l' [l]) lfs';
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   167
              elim_subproofs' time'' qs fix l t lfs'' gfs'' meth subs nontriv_subs
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   168
            end
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   169
            handle Bind =>
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   170
              elim_subproofs' time qs fix l t lfs gfs meth subs (sub :: nontriv_subs))
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   171
          | _ => raise Fail "Sledgehammer_Compress: elim_subproofs'")
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   172
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   173
      fun elim_subproofs (step as Let _) = step
54813
blanchet
parents: 54752
diff changeset
   174
        | elim_subproofs (step as Prove (qs, fix, l, t, subproofs, ((lfs, gfs), meth))) =
blanchet
parents: 54752
diff changeset
   175
          if subproofs = [] then
blanchet
parents: 54752
diff changeset
   176
            step
blanchet
parents: 54752
diff changeset
   177
          else
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   178
            (case get_preplay_outcome l of
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   179
              Played time => elim_subproofs' time qs fix l t lfs gfs meth subproofs []
54826
79745ba60a5a data structure rationalization
blanchet
parents: 54813
diff changeset
   180
            | _ => step)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   181
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   182
      (** top_level compression: eliminate steps by merging them into their
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   183
          successors **)
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   184
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   185
      fun compress_top_level steps =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   186
        let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   187
          (* (#successors, (size_of_term t, position)) *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   188
          fun cand_key (i, l, t_size) = (get_successors l |> length, (t_size, i))
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   189
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   190
          val compression_ord =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   191
            prod_ord int_ord (prod_ord (int_ord #> rev_order) int_ord)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   192
            #> rev_order
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   193
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   194
          val cand_ord = pairself cand_key #> compression_ord
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   195
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   196
          fun pop_next_cand candidates =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   197
            (case max_list cand_ord candidates of
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   198
              NONE => (NONE, [])
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   199
            | cand as SOME (i, _, _) => (cand, filter_out (fn (j, _, _) => j = i) candidates))
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   200
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   201
          val candidates =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   202
            let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   203
              fun add_cand (_, Let _) = I
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   204
                | add_cand (i, Prove (_, _, l, t, _, _)) = cons (i, l, size_of_term t)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   205
            in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   206
              (steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   207
              |> split_last |> fst (* keep last step *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   208
              |> fold_index add_cand) []
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   209
            end
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   210
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   211
          fun try_eliminate (i, l, _) succ_lbls steps =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   212
            let
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   213
              (* only touch steps that can be preplayed successfully *)
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   214
              val Played time = get_preplay_outcome l
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   215
54826
79745ba60a5a data structure rationalization
blanchet
parents: 54813
diff changeset
   216
              val succ_times =
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   217
                map (get_preplay_outcome #> (fn Played t => t)) succ_lbls
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   218
              val timeslice = time_mult (1.0 / (Real.fromInt (length succ_lbls))) time
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   219
              val timeouts =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   220
                map (curry Time.+ timeslice #> time_mult merge_timeout_slack) succ_times
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   221
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   222
              val ((cand as Prove (_, _, l, _, _, ((lfs, _), _))) :: steps') = drop i steps
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   223
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   224
              (* FIXME: debugging *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   225
              val _ =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   226
                if the (label_of_step cand) <> l then
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   227
                  raise Fail "Sledgehammer_Compress: try_eliminate"
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   228
                else
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   229
                  ()
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   230
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   231
              val succs = collect_successors steps' succ_lbls
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   232
              val succs' = map (try_merge cand #> the) succs
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   233
54813
blanchet
parents: 54752
diff changeset
   234
              (* TODO: should be lazy: stop preplaying as soon as one step fails/times out *)
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   235
              val play_outcomes = map2 preplay_quietly timeouts succs'
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   236
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   237
              (* ensure none of the modified successors timed out *)
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   238
              val true = List.all (fn Played _ => true) play_outcomes
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   239
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   240
              val (steps1, _ :: steps2) = chop i steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   241
              (* replace successors with their modified versions *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   242
              val steps2 = update_steps steps2 succs'
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   243
            in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   244
              decrement_step_count (); (* candidate successfully eliminated *)
54828
b2271ad695db don't do 'isar_try0' if preplaying is off
blanchet
parents: 54827
diff changeset
   245
              map2 set_preplay_outcome succ_lbls play_outcomes;
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   246
              map (replace_successor l succ_lbls) lfs;
54813
blanchet
parents: 54752
diff changeset
   247
              (* removing the step would mess up the indices -> replace with dummy step instead *)
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   248
              steps1 @ dummy_isar_step :: steps2
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   249
            end
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   250
            handle Bind => steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   251
                 | Match => steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   252
                 | Option.Option => steps
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   253
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   254
          fun compression_loop candidates steps =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   255
            if not (compress_further ()) then
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   256
              steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   257
            else
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   258
              (case pop_next_cand candidates of
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   259
                (NONE, _) => steps (* no more candidates for elimination *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   260
              | (SOME (cand as (_, l, _)), candidates) =>
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   261
                let val successors = get_successors l in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   262
                  if length successors > compress_degree then steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   263
                  else compression_loop candidates (try_eliminate cand successors steps)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   264
                end)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   265
        in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   266
          compression_loop candidates steps
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   267
          |> remove (op =) dummy_isar_step
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   268
        end
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   269
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   270
      (** recusion over the proof tree **)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   271
      (*
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   272
         Proofs are compressed bottom-up, beginning with the innermost
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   273
         subproofs.
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   274
         On the innermost proof level, the proof steps have no subproofs.
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   275
         In the best case, these steps can be merged into just one step,
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   276
         resulting in a trivial subproof. Going one level up, trivial subproofs
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   277
         can be eliminated. In the best case, this once again leads to a proof
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   278
         whose proof steps do not have subproofs. Applying this approach
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   279
         recursively will result in a flat proof in the best cast.
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   280
      *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   281
      fun do_proof (proof as (Proof (fix, assms, steps))) =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   282
        if compress_further () then Proof (fix, assms, do_steps steps) else proof
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   283
      and do_steps steps =
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   284
        (* bottom-up: compress innermost proofs first *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   285
        steps |> map (fn step => step |> compress_further () ? do_sub_levels)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   286
              |> compress_further () ? compress_top_level
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   287
      and do_sub_levels (Let x) = Let x
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   288
        | do_sub_levels (Prove (qs, xs, l, t, subproofs, by)) =
52556
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   289
          (* compress subproofs *)
c8357085217c completely rewrote SH compress; added two parameters for experimentation/fine grained control
smolkas
parents: 52454
diff changeset
   290
          Prove (qs, xs, l, t, map do_proof subproofs, by)
54712
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   291
          (* eliminate trivial subproofs *)
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   292
          |> compress_further () ? elim_subproofs
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   293
    in
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   294
      do_proof proof
cbebe2cf77f1 more work on Z3 Isar proofs
blanchet
parents: 54700
diff changeset
   295
    end
50259
9c64a52ae499 put shrink in own structure
smolkas
parents:
diff changeset
   296
54504
blanchet
parents: 54503
diff changeset
   297
end;