| author | haftmann | 
| Fri, 03 Jan 2014 22:04:44 +0100 | |
| changeset 54929 | f1ded3cea58d | 
| parent 54821 | a12796872603 | 
| child 55212 | 5832470d956e | 
| permissions | -rw-r--r-- | 
| 36062 | 1 | (* Title: HOL/Tools/Sledgehammer/sledgehammer_util.ML | 
| 35963 | 2 | Author: Jasmin Blanchette, TU Muenchen | 
| 3 | ||
| 4 | General-purpose functions used by the Sledgehammer modules. | |
| 5 | *) | |
| 6 | ||
| 7 | signature SLEDGEHAMMER_UTIL = | |
| 8 | sig | |
| 48392 
ca998fa08cd9
added "learn_from_atp" command to MaSh, for patient users
 blanchet parents: 
48383diff
changeset | 9 | val sledgehammerN : string | 
| 50608 | 10 | val log2 : real -> real | 
| 51181 
d0fa18638478
implement (more) accurate computation of parents
 blanchet parents: 
51010diff
changeset | 11 |   val app_hd : ('a -> 'a) -> 'a list -> 'a list
 | 
| 54695 | 12 | val n_fold_cartesian_product : 'a list list -> 'a list list | 
| 36142 
f5e15e9aae10
make Sledgehammer "minimize" output less confusing + round up (not down) time limits to nearest second
 blanchet parents: 
36062diff
changeset | 13 | val plural_s : int -> string | 
| 35963 | 14 | val serial_commas : string -> string list -> string list | 
| 38738 
0ce517c1970f
make sure that "undo_ascii_of" is the inverse of "ascii_of", also for non-printable characters -- and avoid those in ``-style facts
 blanchet parents: 
38698diff
changeset | 15 | val simplify_spaces : string -> string | 
| 48656 
5caa414ce9a2
cleaner temporary file cleanup for MaSh, based on tried-and-trusted code
 blanchet parents: 
48392diff
changeset | 16 |   val with_cleanup : ('a -> unit) -> ('a -> 'b) -> 'a -> 'b
 | 
| 48383 | 17 | val infinite_timeout : Time.time | 
| 48318 | 18 | val time_mult : real -> Time.time -> Time.time | 
| 35963 | 19 | val parse_bool_option : bool -> string -> string -> bool option | 
| 54816 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 20 | val parse_time : string -> string -> Time.time | 
| 38044 | 21 | val subgoal_count : Proof.state -> int | 
| 38696 
4c6b65d6a135
quote facts whose names collide with a keyword or command name (cf. "subclass" in "Jinja/J/TypeSafe.thy")
 blanchet parents: 
38652diff
changeset | 22 | val reserved_isar_keyword_table : unit -> unit Symtab.table | 
| 54816 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 23 | val thms_in_proof : (string Symtab.table * string Symtab.table) option -> thm -> string list | 
| 50267 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 24 | val thms_of_name : Proof.context -> string -> thm list | 
| 50557 | 25 | val one_day : Time.time | 
| 26 | val one_year : Time.time | |
| 50048 | 27 |   val with_vanilla_print_mode : ('a -> 'b) -> 'a -> 'b
 | 
| 53815 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 28 | val hackish_string_of_term : Proof.context -> term -> string | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 29 | val spying : bool -> (unit -> Proof.state * int * string * string) -> unit | 
| 52556 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 30 | |
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 31 | (** extrema **) | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 32 |   val max : ('a * 'a -> order) -> 'a -> 'a -> 'a
 | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 33 |   val max_option : ('a * 'a -> order) -> 'a option -> 'a option -> 'a option
 | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 34 |   val max_list : ('a * 'a -> order) -> 'a list -> 'a option
 | 
| 35963 | 35 | end; | 
| 39318 | 36 | |
| 35963 | 37 | structure Sledgehammer_Util : SLEDGEHAMMER_UTIL = | 
| 38 | struct | |
| 39 | ||
| 43085 
0a2f5b86bdd7
first step in sharing more code between ATP and Metis translation
 blanchet parents: 
43043diff
changeset | 40 | open ATP_Util | 
| 
0a2f5b86bdd7
first step in sharing more code between ATP and Metis translation
 blanchet parents: 
43043diff
changeset | 41 | |
| 48392 
ca998fa08cd9
added "learn_from_atp" command to MaSh, for patient users
 blanchet parents: 
48383diff
changeset | 42 | val sledgehammerN = "sledgehammer" | 
| 
ca998fa08cd9
added "learn_from_atp" command to MaSh, for patient users
 blanchet parents: 
48383diff
changeset | 43 | |
| 50608 | 44 | val log10_2 = Math.log10 2.0 | 
| 45 | ||
| 46 | fun log2 n = Math.log10 n / log10_2 | |
| 47 | ||
| 51181 
d0fa18638478
implement (more) accurate computation of parents
 blanchet parents: 
51010diff
changeset | 48 | fun app_hd f (x :: xs) = f x :: xs | 
| 
d0fa18638478
implement (more) accurate computation of parents
 blanchet parents: 
51010diff
changeset | 49 | |
| 54695 | 50 | fun cartesian_product [] _ = [] | 
| 51 | | cartesian_product (x :: xs) yss = | |
| 52 | map (cons x) yss @ cartesian_product xs yss | |
| 53 | ||
| 54 | fun n_fold_cartesian_product xss = fold_rev cartesian_product xss [[]] | |
| 55 | ||
| 36142 
f5e15e9aae10
make Sledgehammer "minimize" output less confusing + round up (not down) time limits to nearest second
 blanchet parents: 
36062diff
changeset | 56 | fun plural_s n = if n = 1 then "" else "s" | 
| 36062 | 57 | |
| 43029 
3e060b1c844b
use helpers and tweak Quickcheck's priority to it comes second (to give Solve Direct slightly more time before another prover runs)
 blanchet parents: 
43005diff
changeset | 58 | val serial_commas = Try.serial_commas | 
| 43085 
0a2f5b86bdd7
first step in sharing more code between ATP and Metis translation
 blanchet parents: 
43043diff
changeset | 59 | val simplify_spaces = strip_spaces false (K true) | 
| 37962 
d7dbe01f48d7
keep track of clause numbers for SPASS now that we generate FOF rather than CNF problems;
 blanchet parents: 
37575diff
changeset | 60 | |
| 48656 
5caa414ce9a2
cleaner temporary file cleanup for MaSh, based on tried-and-trusted code
 blanchet parents: 
48392diff
changeset | 61 | fun with_cleanup clean_up f x = | 
| 
5caa414ce9a2
cleaner temporary file cleanup for MaSh, based on tried-and-trusted code
 blanchet parents: 
48392diff
changeset | 62 | Exn.capture f x | 
| 
5caa414ce9a2
cleaner temporary file cleanup for MaSh, based on tried-and-trusted code
 blanchet parents: 
48392diff
changeset | 63 | |> tap (fn _ => clean_up x) | 
| 
5caa414ce9a2
cleaner temporary file cleanup for MaSh, based on tried-and-trusted code
 blanchet parents: 
48392diff
changeset | 64 | |> Exn.release | 
| 
5caa414ce9a2
cleaner temporary file cleanup for MaSh, based on tried-and-trusted code
 blanchet parents: 
48392diff
changeset | 65 | |
| 48383 | 66 | val infinite_timeout = seconds 31536000.0 (* one year *) | 
| 67 | ||
| 48318 | 68 | fun time_mult k t = | 
| 69 | Time.fromMilliseconds (Real.ceil (k * Real.fromInt (Time.toMilliseconds t))) | |
| 70 | ||
| 35963 | 71 | fun parse_bool_option option name s = | 
| 72 | (case s of | |
| 51930 
52fd62618631
prefer explicitly qualified exceptions, which is particular important for robust handlers;
 wenzelm parents: 
51181diff
changeset | 73 | "smart" => if option then NONE else raise Option.Option | 
| 35963 | 74 | | "false" => SOME false | 
| 75 | | "true" => SOME true | |
| 76 | | "" => SOME true | |
| 51930 
52fd62618631
prefer explicitly qualified exceptions, which is particular important for robust handlers;
 wenzelm parents: 
51181diff
changeset | 77 | | _ => raise Option.Option) | 
| 35963 | 78 | handle Option.Option => | 
| 79 | let val ss = map quote ((option ? cons "smart") ["true", "false"]) in | |
| 80 |            error ("Parameter " ^ quote name ^ " must be assigned " ^
 | |
| 81 | space_implode " " (serial_commas "or" ss) ^ ".") | |
| 82 | end | |
| 83 | ||
| 40341 
03156257040f
standardize on seconds for Nitpick and Sledgehammer timeouts
 blanchet parents: 
39890diff
changeset | 84 | val has_junk = | 
| 40627 
becf5d5187cc
renamed raw "explode" function to "raw_explode" to emphasize its meaning;
 wenzelm parents: 
40341diff
changeset | 85 | exists (fn s => not (Symbol.is_digit s) andalso s <> ".") o raw_explode (* FIXME Symbol.explode (?) *) | 
| 40341 
03156257040f
standardize on seconds for Nitpick and Sledgehammer timeouts
 blanchet parents: 
39890diff
changeset | 86 | |
| 54816 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 87 | fun parse_time name s = | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 88 | let val secs = if has_junk s then NONE else Real.fromString s in | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 89 | if is_none secs orelse Real.< (the secs, 0.0) then | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 90 |       error ("Parameter " ^ quote name ^ " must be assigned a nonnegative \
 | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 91 | \number of seconds (e.g., \"60\", \"0.5\") or \"none\".") | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 92 | else | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 93 | seconds (the secs) | 
| 
10d48c2a3e32
made timeouts in Sledgehammer not be 'option's -- simplified lots of code
 blanchet parents: 
54695diff
changeset | 94 | end | 
| 35963 | 95 | |
| 43029 
3e060b1c844b
use helpers and tweak Quickcheck's priority to it comes second (to give Solve Direct slightly more time before another prover runs)
 blanchet parents: 
43005diff
changeset | 96 | val subgoal_count = Try.subgoal_count | 
| 38044 | 97 | |
| 38696 
4c6b65d6a135
quote facts whose names collide with a keyword or command name (cf. "subclass" in "Jinja/J/TypeSafe.thy")
 blanchet parents: 
38652diff
changeset | 98 | fun reserved_isar_keyword_table () = | 
| 48292 | 99 | Keyword.dest () |-> union (op =) |> map (rpair ()) |> Symtab.make | 
| 38696 
4c6b65d6a135
quote facts whose names collide with a keyword or command name (cf. "subclass" in "Jinja/J/TypeSafe.thy")
 blanchet parents: 
38652diff
changeset | 100 | |
| 48251 
6cdcfbddc077
moved most of MaSh exporter code to Sledgehammer
 blanchet parents: 
46957diff
changeset | 101 | (* FIXME: Similar yet different code in "mirabelle.ML". The code here has a few | 
| 
6cdcfbddc077
moved most of MaSh exporter code to Sledgehammer
 blanchet parents: 
46957diff
changeset | 102 | fixes that seem to be missing over there; or maybe the two code portions are | 
| 
6cdcfbddc077
moved most of MaSh exporter code to Sledgehammer
 blanchet parents: 
46957diff
changeset | 103 | not doing the same? *) | 
| 54116 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 104 | fun fold_body_thm outer_name (map_plain_name, map_inclass_name) = | 
| 48251 
6cdcfbddc077
moved most of MaSh exporter code to Sledgehammer
 blanchet parents: 
46957diff
changeset | 105 | let | 
| 54116 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 106 | fun app_thm map_name (_, (name, _, body)) accum = | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 107 | let | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 108 | val (anonymous, enter_class) = | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 109 | (* The "name = outer_name" case caters for the uncommon case where the proved theorem | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 110 | occurs in its own proof (e.g., "Transitive_Closure.trancl_into_trancl"). *) | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 111 | if name = "" orelse name = outer_name then (true, false) | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 112 | else if map_inclass_name name = SOME outer_name then (true, true) | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 113 | else (false, false) | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 114 | in | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 115 | if anonymous then | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 116 | accum |> app_body (if enter_class then map_inclass_name else map_name) (Future.join body) | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 117 | else | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 118 | accum |> union (op =) (the_list (map_name name)) | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 119 | end | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 120 |     and app_body map_name (PBody {thms, ...}) = fold (app_thm map_name) thms
 | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 121 | in app_body map_plain_name end | 
| 48251 
6cdcfbddc077
moved most of MaSh exporter code to Sledgehammer
 blanchet parents: 
46957diff
changeset | 122 | |
| 50735 
6b232d76cbc9
refined class handling, to prevent cycles in fact graph
 blanchet parents: 
50734diff
changeset | 123 | fun thms_in_proof name_tabs th = | 
| 54116 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 124 | let val map_names = (case name_tabs of SOME p => pairself Symtab.lookup p | NONE => `I SOME) in | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 125 | fold_body_thm (Thm.get_name_hint th) map_names (Proofterm.strip_thm (Thm.proof_body_of th)) [] | 
| 
ba709c934470
made theorem extraction code not delve too far when looking at local fact, by relying on 'strip_thm' instead of (wrongly) reverse-engineering proof terms
 blanchet parents: 
54062diff
changeset | 126 | end | 
| 48251 
6cdcfbddc077
moved most of MaSh exporter code to Sledgehammer
 blanchet parents: 
46957diff
changeset | 127 | |
| 50267 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 128 | fun thms_of_name ctxt name = | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 129 | let | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 130 | val lex = Keyword.get_lexicons | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 131 | val get = maps (Proof_Context.get_fact ctxt o fst) | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 132 | in | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 133 | Source.of_string name | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 134 | |> Symbol.source | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 135 |     |> Token.source {do_recover = SOME false} lex Position.start
 | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 136 | |> Token.source_proper | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 137 | |> Source.source Token.stopper (Parse_Spec.xthms1 >> get) NONE | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 138 | |> Source.exhaust | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 139 | end | 
| 
1da2e67242d6
moved thms_of_name to Sledgehammer_Util and removed copies, updated references
 smolkas parents: 
50049diff
changeset | 140 | |
| 50557 | 141 | val one_day = seconds (24.0 * 60.0 * 60.0) | 
| 142 | val one_year = seconds (365.0 * 24.0 * 60.0 * 60.0) | |
| 143 | ||
| 50048 | 144 | fun with_vanilla_print_mode f x = | 
| 54821 | 145 | Print_Mode.setmp (filter (curry (op =) Symbol.xsymbolsN) (print_mode_value ())) f x | 
| 50048 | 146 | |
| 53815 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 147 | fun hackish_string_of_term ctxt = | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 148 | with_vanilla_print_mode (Syntax.string_of_term ctxt) #> simplify_spaces | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 149 | |
| 54062 | 150 | val spying_version = "c" | 
| 53815 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 151 | |
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 152 | fun spying false _ = () | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 153 | | spying true f = | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 154 | let | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 155 | val (state, i, tool, message) = f () | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 156 | val ctxt = Proof.context_of state | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 157 | val goal = Logic.get_goal (prop_of (#goal (Proof.goal state))) i | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 158 | val hash = String.substring (SHA1.rep (SHA1.digest (hackish_string_of_term ctxt goal)), 0, 12) | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 159 | in | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 160 | File.append (Path.explode "$ISABELLE_HOME_USER/spy_sledgehammer") | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 161 | (spying_version ^ " " ^ timestamp () ^ ": " ^ hash ^ ": " ^ tool ^ ": " ^ message ^ "\n") | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 162 | end | 
| 
e8aa538e959e
encode goal digest in spying log (to detect duplicates)
 blanchet parents: 
53800diff
changeset | 163 | |
| 52556 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 164 | (** extrema **) | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 165 | |
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 166 | fun max ord x y = case ord(x,y) of LESS => y | _ => x | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 167 | |
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 168 | fun max_option ord = max (option_ord ord) | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 169 | |
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 170 | fun max_list ord xs = fold (SOME #> max_option ord) xs NONE | 
| 
c8357085217c
completely rewrote SH compress; added two parameters for experimentation/fine grained control
 smolkas parents: 
51930diff
changeset | 171 | |
| 35963 | 172 | end; |