| author | huffman | 
| Tue, 13 Jan 2009 10:18:23 -0800 | |
| changeset 29475 | c06d1b0a970f | 
| parent 27605 | 2c281958e45d | 
| child 29606 | fedb8be05f24 | 
| permissions | -rw-r--r-- | 
| 14815 | 1 | (* Title: Pure/General/output.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Makarius, Hagia Maria Sion Abbey (Jerusalem) | |
| 4 | ||
| 22585 | 5 | Output channels and timing messages. | 
| 14815 | 6 | *) | 
| 7 | ||
| 8 | signature BASIC_OUTPUT = | |
| 9 | sig | |
| 23660 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 10 | type output = string | 
| 18682 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 wenzelm parents: 
17539diff
changeset | 11 | val writeln: string -> unit | 
| 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 wenzelm parents: 
17539diff
changeset | 12 | val priority: string -> unit | 
| 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 wenzelm parents: 
17539diff
changeset | 13 | val tracing: string -> unit | 
| 
216692feebab
removed special ERROR handling stuff (transform_error etc.);
 wenzelm parents: 
17539diff
changeset | 14 | val warning: string -> unit | 
| 22826 | 15 | val tolerate_legacy_features: bool ref | 
| 16 | val legacy_feature: string -> unit | |
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 17 | val cond_timeit: bool -> string -> (unit -> 'a) -> 'a | 
| 14815 | 18 | val timeit: (unit -> 'a) -> 'a | 
| 19 |   val timeap: ('a -> 'b) -> 'a -> 'b
 | |
| 20 |   val timeap_msg: string -> ('a -> 'b) -> 'a -> 'b
 | |
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 21 | val timing: bool ref | 
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 22 |   val time_accumulator: string -> ('a -> 'b) -> 'a -> 'b
 | 
| 14815 | 23 | end; | 
| 24 | ||
| 25 | signature OUTPUT = | |
| 26 | sig | |
| 27 | include BASIC_OUTPUT | |
| 23660 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 28 | val default_output: string -> output * int | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 29 | val default_escape: output -> string | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 30 | val add_mode: string -> (string -> output * int) -> (output -> string) -> unit | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 31 | val output_width: string -> output * int | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 32 | val output: string -> output | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 33 | val escape: output -> string | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 34 | val std_output: output -> unit | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 35 | val std_error: output -> unit | 
| 22585 | 36 | val immediate_output: string -> unit | 
| 23660 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 37 | val writeln_default: output -> unit | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 38 | val writeln_fn: (output -> unit) ref | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 39 | val priority_fn: (output -> unit) ref | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 40 | val tracing_fn: (output -> unit) ref | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 41 | val warning_fn: (output -> unit) ref | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 42 | val error_fn: (output -> unit) ref | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 43 | val debug_fn: (output -> unit) ref | 
| 25845 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 wenzelm parents: 
25686diff
changeset | 44 | val prompt_fn: (output -> unit) ref | 
| 27605 | 45 | val status_fn: (output -> unit) ref | 
| 25845 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 wenzelm parents: 
25686diff
changeset | 46 | val error_msg: string -> unit | 
| 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 wenzelm parents: 
25686diff
changeset | 47 | val prompt: string -> unit | 
| 27605 | 48 | val status: string -> unit | 
| 22585 | 49 | val debugging: bool ref | 
| 50 |   val no_warnings: ('a -> 'b) -> 'a -> 'b
 | |
| 22130 | 51 | val debug: (unit -> string) -> unit | 
| 24652 | 52 | val ml_output: (string -> unit) * (string -> 'a) | 
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 53 | val accumulated_time: unit -> unit | 
| 14815 | 54 | end; | 
| 55 | ||
| 56 | structure Output: OUTPUT = | |
| 57 | struct | |
| 58 | ||
| 23616 | 59 | (** print modes **) | 
| 14881 | 60 | |
| 23660 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 61 | type output = string; (*raw system output*) | 
| 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 62 | |
| 23616 | 63 | fun default_output s = (s, size s); | 
| 23660 
18765718cf62
type output = string indicates raw system output;
 wenzelm parents: 
23616diff
changeset | 64 | fun default_escape (s: output) = s; | 
| 14815 | 65 | |
| 23616 | 66 | local | 
| 67 |   val default = {output = default_output, escape = default_escape};
 | |
| 68 |   val modes = ref (Symtab.make [("", default)]);
 | |
| 69 | in | |
| 23922 
707639e9497d
marked some CRITICAL sections (for multithreading);
 wenzelm parents: 
23862diff
changeset | 70 | fun add_mode name output escape = CRITICAL (fn () => | 
| 
707639e9497d
marked some CRITICAL sections (for multithreading);
 wenzelm parents: 
23862diff
changeset | 71 |     change modes (Symtab.update_new (name, {output = output, escape = escape})));
 | 
| 23616 | 72 | fun get_mode () = | 
| 24612 | 73 | the_default default (Library.get_first (Symtab.lookup (! modes)) (print_mode_value ())); | 
| 23616 | 74 | end; | 
| 14815 | 75 | |
| 19265 | 76 | fun output_width x = #output (get_mode ()) x; | 
| 14815 | 77 | val output = #1 o output_width; | 
| 23727 | 78 | |
| 23616 | 79 | fun escape x = #escape (get_mode ()) x; | 
| 14815 | 80 | |
| 81 | ||
| 82 | ||
| 83 | (** output channels **) | |
| 84 | ||
| 14984 | 85 | (* output primitives -- normally NOT used directly!*) | 
| 86 | ||
| 24058 | 87 | fun std_output s = NAMED_CRITICAL "IO" (fn () => | 
| 23922 
707639e9497d
marked some CRITICAL sections (for multithreading);
 wenzelm parents: 
23862diff
changeset | 88 | (TextIO.output (TextIO.stdOut, s); TextIO.flushOut TextIO.stdOut)); | 
| 
707639e9497d
marked some CRITICAL sections (for multithreading);
 wenzelm parents: 
23862diff
changeset | 89 | |
| 24058 | 90 | fun std_error s = NAMED_CRITICAL "IO" (fn () => | 
| 23922 
707639e9497d
marked some CRITICAL sections (for multithreading);
 wenzelm parents: 
23862diff
changeset | 91 | (TextIO.output (TextIO.stdErr, s); TextIO.flushOut TextIO.stdErr)); | 
| 14815 | 92 | |
| 14984 | 93 | val immediate_output = std_output o output; | 
| 27605 | 94 | |
| 95 | fun writeln_default "" = () | |
| 96 | | writeln_default s = std_output (suffix "\n" s); | |
| 14815 | 97 | |
| 14984 | 98 | |
| 99 | (* Isabelle output channels *) | |
| 100 | ||
| 14815 | 101 | val writeln_fn = ref writeln_default; | 
| 102 | val priority_fn = ref (fn s => ! writeln_fn s); | |
| 103 | val tracing_fn = ref (fn s => ! writeln_fn s); | |
| 104 | val warning_fn = ref (std_output o suffix "\n" o prefix_lines "### "); | |
| 105 | val error_fn = ref (std_output o suffix "\n" o prefix_lines "*** "); | |
| 15190 | 106 | val debug_fn = ref (std_output o suffix "\n" o prefix_lines "::: "); | 
| 25845 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 wenzelm parents: 
25686diff
changeset | 107 | val prompt_fn = ref std_output; | 
| 27605 | 108 | val status_fn = ref (fn s => ! writeln_fn s); | 
| 14815 | 109 | |
| 110 | fun writeln s = ! writeln_fn (output s); | |
| 111 | fun priority s = ! priority_fn (output s); | |
| 112 | fun tracing s = ! tracing_fn (output s); | |
| 113 | fun warning s = ! warning_fn (output s); | |
| 25845 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 wenzelm parents: 
25686diff
changeset | 114 | fun error_msg s = ! error_fn (output s); | 
| 
c448a5f15f31
added explicit prompt channel (prompt_fn/prompt);
 wenzelm parents: 
25686diff
changeset | 115 | fun prompt s = ! prompt_fn (output s); | 
| 27605 | 116 | fun status s = ! status_fn (output s); | 
| 15190 | 117 | |
| 22826 | 118 | val tolerate_legacy_features = ref true; | 
| 119 | fun legacy_feature s = | |
| 26291 | 120 |   (if ! tolerate_legacy_features then warning else error) ("Legacy feature! " ^ s);
 | 
| 22826 | 121 | |
| 16191 | 122 | fun no_warnings f = setmp warning_fn (K ()) f; | 
| 123 | ||
| 22130 | 124 | val debugging = ref false; | 
| 125 | fun debug s = if ! debugging then ! debug_fn (output (s ())) else () | |
| 15190 | 126 | |
| 24652 | 127 | val ml_output = (writeln, error); | 
| 20926 | 128 | |
| 14815 | 129 | |
| 130 | ||
| 131 | (** timing **) | |
| 132 | ||
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 133 | (*conditional timing with message*) | 
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 134 | fun cond_timeit flag msg e = | 
| 14815 | 135 | if flag then | 
| 23862 | 136 | let | 
| 137 | val start = start_timing (); | |
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 138 | val result = Exn.capture e (); | 
| 25682 | 139 | val end_msg = end_timing start; | 
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 140 | val _ = warning (if msg = "" then end_msg else msg ^ "\n" ^ end_msg); | 
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 141 | in Exn.release result end | 
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 142 | else e (); | 
| 25667 | 143 | |
| 23862 | 144 | (*unconditional timing*) | 
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 145 | fun timeit e = cond_timeit true "" e; | 
| 14815 | 146 | |
| 147 | (*timed application function*) | |
| 148 | fun timeap f x = timeit (fn () => f x); | |
| 25686 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 149 | fun timeap_msg msg f x = cond_timeit true msg (fn () => f x); | 
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 150 | |
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 151 | |
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 152 | (*global timing mode*) | 
| 
bfa774974b6c
cond_timeit: added message argument, use Exn.capture/release;
 wenzelm parents: 
25682diff
changeset | 153 | val timing = ref false; | 
| 14815 | 154 | |
| 14978 | 155 | |
| 156 | (* accumulated timing *) | |
| 157 | ||
| 158 | local | |
| 159 | ||
| 160 | datatype time_info = TI of | |
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 161 |   {name: string,
 | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 162 | timer: Timer.cpu_timer, | 
| 14978 | 163 | sys: Time.time, | 
| 164 | usr: Time.time, | |
| 165 | gc: Time.time, | |
| 166 | count: int}; | |
| 167 | ||
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 168 | fun time_init name = ref (TI | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 169 |  {name = name,
 | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 170 | timer = Timer.startCPUTimer (), | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 171 | sys = Time.zeroTime, | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 172 | usr = Time.zeroTime, | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 173 | gc = Time.zeroTime, | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 174 | count = 0}); | 
| 14978 | 175 | |
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 176 | fun time_reset (r as ref (TI {name, ...})) = r := ! (time_init name);
 | 
| 14978 | 177 | |
| 178 | fun time_check (ref (TI r)) = r; | |
| 179 | ||
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 180 | fun time_add ti f x = | 
| 14978 | 181 | let | 
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 182 | fun add_diff time time1 time2 = | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 183 | Time.+ (time, Time.- (time2, time1) handle Time.Time => Time.zeroTime); | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 184 |     val {name, timer, sys, usr, gc, count} = time_check ti;
 | 
| 21295 
63552bc99cfb
tuned names of start_timing,/end_timing/check_timer;
 wenzelm parents: 
20926diff
changeset | 185 | val (sys1, usr1, gc1) = check_timer timer; | 
| 23963 
c2ee97a963db
moved exception capture/release to structure Exn;
 wenzelm parents: 
23939diff
changeset | 186 | val result = Exn.capture f x; | 
| 21295 
63552bc99cfb
tuned names of start_timing,/end_timing/check_timer;
 wenzelm parents: 
20926diff
changeset | 187 | val (sys2, usr2, gc2) = check_timer timer; | 
| 14978 | 188 | in | 
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 189 | ti := TI | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 190 |      {name = name,
 | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 191 | timer = timer, | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 192 | sys = add_diff sys sys1 sys2, | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 193 | usr = add_diff usr usr1 usr2, | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 194 | gc = add_diff gc gc1 gc2, | 
| 14978 | 195 | count = count + 1}; | 
| 23963 
c2ee97a963db
moved exception capture/release to structure Exn;
 wenzelm parents: 
23939diff
changeset | 196 | Exn.release result | 
| 14978 | 197 | end; | 
| 198 | ||
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 199 | fun time_finish ti = | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 200 | let | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 201 | fun secs prfx time = prfx ^ Time.toString time; | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 202 |     val {name, timer, sys, usr, gc, count} = time_check ti;
 | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 203 | in | 
| 22585 | 204 |     warning ("Total of " ^ quote name ^ ": " ^
 | 
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 205 | secs "User " usr ^ secs " GC " gc ^ secs " All " (Time.+ (sys, Time.+ (usr, gc))) ^ | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 206 | " secs in " ^ string_of_int count ^ " calls"); | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 207 | time_reset ti | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 208 | end; | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 209 | |
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 210 | val time_finish_hooks = ref ([]: (unit -> unit) list); | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 211 | |
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 212 | in | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 213 | |
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 214 | fun time_accumulator name = | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 215 | let val ti = time_init name in | 
| 23939 | 216 | CRITICAL (fn () => change time_finish_hooks (cons (fn () => time_finish ti))); | 
| 16726 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 217 | time_add ti | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 218 | end; | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 219 | |
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 220 | fun accumulated_time () = List.app (fn f => f ()) (! time_finish_hooks); | 
| 
4399016bf13e
added time_accumulator and accumulated_time supercede
 wenzelm parents: 
16683diff
changeset | 221 | |
| 14978 | 222 | end; | 
| 223 | ||
| 14815 | 224 | end; | 
| 225 | ||
| 226 | structure BasicOutput: BASIC_OUTPUT = Output; | |
| 227 | open BasicOutput; |