Theory Trace_Timing

theory Trace_Timing
  imports Refine_Imperative_HOL.Sepref
begin

datatype time = Time int

definition now :: "unit  time" where
  "now _ = undefined"

instantiation time :: minus
begin

definition "minus_time (_ :: time) (_ :: time) = (undefined :: time)"

instance ..

end

definition time_to_string :: "time  String.literal" where
  "time_to_string _ = undefined"

code_printing
  constant "now"  (SML) "Time.now _"

code_printing
  constant "time_to_string"  (SML) "(fn x => Time.toString x) _"

code_printing
  constant "(-) :: time  time  time"  (SML) "(fn x => fn y => Time.- (x, y)) _ _"

code_printing code_module "Timing"  (SML)
‹
structure Timing : sig
  val start_timer: unit -> unit
  val save_time: string -> unit
  val get_timings: unit -> (string * Time.time) list
end = struct
  val t = Unsynchronized.ref Time.zeroTime;
  val timings = Unsynchronized.ref [];
  fun start_timer () = (t := Time.now ());
  fun get_elapsed () = Time.- (Time.now (), !t);
  fun save_time s = (timings := ((s, get_elapsed ()) :: !timings));
  fun get_timings () = !timings;
end
›

definition start_timer :: "unit  unit" where
  "start_timer _ = ()"

definition save_time :: "String.literal  unit" where
  "save_time s = ()"

code_reserved (SML) Timing

code_printing
  constant start_timer  (SML) "Timing.start'_timer _"

code_printing
  constant save_time  (SML) "Timing.save'_time _"

definition "test  let _ = start_timer (); _ = save_time STR ''test'' in ()"

export_code test checking SML

hide_const test

paragraph ‹Setup for Sepref›

lemma [sepref_import_param]:
  "(start_timer, start_timer)  Id  Id"
  "(save_time, save_time)  Id  Id"
  by simp+

definition
  "START_TIMER = RETURN o start_timer"

definition
  "start_timer_impl = return o start_timer"

definition
  "SAVE_TIME = RETURN o save_time"

definition
  "save_time_impl = return o save_time"

lemma start_timer_hnr:
  "hn_refine (hn_val Id x' x) (start_timer_impl x) (hn_val Id x' x) unit_assn (START_TIMER $ x')"
  unfolding START_TIMER_def start_timer_impl_def by sepref_to_hoare sep_auto

lemma save_time_hnr:
  "(save_time_impl, SAVE_TIME)  id_assnk a unit_assn"
  unfolding SAVE_TIME_def save_time_impl_def by sepref_to_hoare sep_auto

sepref_register START_TIMER SAVE_TIME

lemmas [sepref_fr_rules] = start_timer_hnr save_time_hnr

definition
  "time_it s f = (let _ = start_timer (); r = f (); _ = save_time s in r)"

lemma time_it:
  "e = time_it s (λ_. e)"
  unfolding Let_def time_it_def ..

method time_it for s :: String.literal and t = (subst time_it[where s = s and e = t])

end