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