WIP: autocorres: make trace results available again
This changes the interface to access traces, making the underlying symtabs explicit.
This commit is contained in:
parent
cc1329c232
commit
6b72212597
|
@ -581,17 +581,27 @@ let
|
|||
| SOME s => s
|
||||
in fn f => prefix ^ f ^ suffix end
|
||||
|
||||
(* Initialise database for traces.
|
||||
* Currently, this is implemented by mutating a global table.
|
||||
* While slightly ugly, it does simplify adding more tracing to AutoCorres
|
||||
* without cluttering the return types of existing code. *)
|
||||
val trace_db: AutoCorresData.Trace Symtab.table (* type *) Symtab.table (* func *) Synchronized.var =
|
||||
Synchronized.var "AutoCorres traces" Symtab.empty
|
||||
fun add_trace f_name trace_name trace =
|
||||
Synchronized.change trace_db
|
||||
(Symtab.map_default (f_name, Symtab.empty) (Symtab.update_new (trace_name, trace)))
|
||||
|
||||
(* Do the translation. *)
|
||||
val l1_results =
|
||||
SimplConv2.translate
|
||||
filename prog_info simpl_info existing_simpl_info existing_l1_info
|
||||
(!(#no_c_termination opt) <> SOME true)
|
||||
do_opt trace_opt (prefix "l1_" o make_function_name) lthy
|
||||
do_opt trace_opt add_trace (prefix "l1_" o make_function_name) lthy
|
||||
|
||||
val l2_results =
|
||||
LocalVarExtract2.translate
|
||||
filename prog_info l1_results existing_l1_info existing_l2_info
|
||||
do_opt trace_opt (prefix "l2_" o make_function_name)
|
||||
do_opt trace_opt add_trace (prefix "l2_" o make_function_name)
|
||||
|
||||
val skip_heap_abs = !(#skip_heap_abs opt) = SOME true
|
||||
val hl_results =
|
||||
|
@ -606,7 +616,7 @@ let
|
|||
filename prog_info l2_results' existing_l2_info existing_hl_info
|
||||
HL_setup no_heap_abs force_heap_abs
|
||||
heap_abs_syntax keep_going
|
||||
(these (!(#trace_heap_lift opt))) do_opt trace_opt
|
||||
(these (!(#trace_heap_lift opt))) do_opt trace_opt add_trace
|
||||
(prefix "hl_" o make_function_name)
|
||||
end
|
||||
|
||||
|
@ -616,14 +626,14 @@ let
|
|||
else WordAbstract2.translate
|
||||
filename prog_info hl_results existing_hl_info existing_wa_info
|
||||
unsigned_word_abs no_signed_word_abs
|
||||
(these (!(#trace_word_abs opt))) do_opt trace_opt
|
||||
(these (!(#trace_word_abs opt))) do_opt trace_opt add_trace
|
||||
(prefix "wa_" o make_function_name)
|
||||
|
||||
val ts_results =
|
||||
TypeStrengthen2.translate
|
||||
ts_rules ts_force filename prog_info
|
||||
wa_results existing_wa_info existing_ts_info
|
||||
make_function_name keep_going do_opt
|
||||
make_function_name keep_going do_opt add_trace
|
||||
|
||||
(* Collect final translation results. *)
|
||||
val l1_info = FSeq.list_of l1_results |> map snd |> Utils.symtab_merge false;
|
||||
|
@ -708,6 +718,16 @@ let
|
|||
val lthy = Local_Theory.background_theory (
|
||||
AutoCorresFunctionInfo2.map (fn tbl =>
|
||||
Symtab.update (filename, new_results) tbl)) lthy
|
||||
(* All traces should be available at this point. Archive them. *)
|
||||
|
||||
val traces = Synchronized.value trace_db;
|
||||
val _ = if Symtab.is_empty traces then () else
|
||||
tracing "Saving translation traces to AutoCorresData.Traces."
|
||||
val lthy = lthy |> Local_Theory.background_theory (
|
||||
AutoCorresData.Traces.map
|
||||
(Symtab.map_default (filename, Symtab.empty)
|
||||
(fn old_traces => Utils.symtab_merge_with snd (old_traces, traces))));
|
||||
|
||||
in
|
||||
(* Exit context. *)
|
||||
Named_Target.exit lthy
|
||||
|
|
|
@ -22,6 +22,8 @@ sig
|
|||
RuleTrace of thm AutoCorresTrace.RuleTrace
|
||||
| SimpTrace of AutoCorresTrace.SimpTrace
|
||||
|
||||
structure Traces: THEORY_DATA
|
||||
|
||||
val add_trace: string -> string -> string -> Trace -> theory -> theory
|
||||
val get_trace: theory -> string -> string -> string -> Trace option
|
||||
|
||||
|
@ -74,6 +76,19 @@ structure Terms = Theory_Data(
|
|||
}
|
||||
)
|
||||
|
||||
(* Function translation traces.
|
||||
* These are for informational or debugging usage. *)
|
||||
structure Traces = Theory_Data (
|
||||
type T = Trace Symtab.table (* trace type *)
|
||||
Symtab.table (* func name *)
|
||||
Symtab.table (* file *);
|
||||
val empty = Symtab.empty;
|
||||
val extend = I;
|
||||
(* We need a deep merge due to incremental translations (which can span
|
||||
* multiple theories). snd is arbitrary. *)
|
||||
val merge = Utils.symtab_merge_with (Utils.symtab_merge_with (Utils.symtab_merge_with snd));
|
||||
)
|
||||
|
||||
(* Fetch a trace. *)
|
||||
fun get_trace thy filename module fn_name =
|
||||
Terms.get thy
|
||||
|
@ -119,7 +134,6 @@ fun debug thy = Terms.get thy |> dest_ac_data |> (fn x => (Symtab3.dest (#proofs
|
|||
|
||||
end (* structure AutoCorresData *)
|
||||
|
||||
|
||||
(* Function translation information.
|
||||
* This is needed for resuming incremental translations. *)
|
||||
structure AutoCorresFunctionInfo2 = Theory_Data(
|
||||
|
@ -127,6 +141,5 @@ structure AutoCorresFunctionInfo2 = Theory_Data(
|
|||
FunctionInfo2.Phasetab.table Symtab.table;
|
||||
val empty = Symtab.empty;
|
||||
val extend = I;
|
||||
fun merge (l, r) =
|
||||
Symtab.merge (fn _ => true) (l, r);
|
||||
val merge = Symtab.merge (K true);
|
||||
)
|
||||
|
|
|
@ -437,6 +437,8 @@ fun par_convert
|
|||
(existing_infos: FunctionInfo2.function_info Symtab.table)
|
||||
(* Functions from previous phase *)
|
||||
(prev_results: FunctionInfo2.phase_results)
|
||||
(* Add traces from the conversion result. *)
|
||||
(add_trace: string -> string -> AutoCorresData.Trace -> unit)
|
||||
(* Return converted functions in recursive groups.
|
||||
* The groups are tagged with fn_infos from prev_results to identify them. *)
|
||||
: (FunctionInfo2.function_info Symtab.table * convert_result Symtab.table) FSeq.fseq =
|
||||
|
@ -453,6 +455,9 @@ fun par_convert
|
|||
|> Par_List.map (fn (f, _) =>
|
||||
(f, convert lthy fn_infos_accum f))
|
||||
|> Symtab.make;
|
||||
val _ = app (fn (f, result) => app (fn (typ, trace) =>
|
||||
add_trace f typ trace) (#traces result))
|
||||
(Symtab.dest conv_results);
|
||||
in ((fn_infos, conv_results), fn_infos_accum) end)
|
||||
existing_infos prev_results;
|
||||
|
||||
|
|
|
@ -627,6 +627,7 @@ fun translate
|
|||
(trace_funcs : string list)
|
||||
(do_opt : bool)
|
||||
(trace_opt : bool)
|
||||
(add_trace: string -> string -> AutoCorresData.Trace -> unit)
|
||||
(hl_function_name : string -> string)
|
||||
: FunctionInfo2.phase_results =
|
||||
if FSeq.null l2_results then FSeq.empty () else
|
||||
|
@ -871,7 +872,7 @@ let
|
|||
in (new_infos, lthy') end;
|
||||
|
||||
(* Do conversions in parallel. *)
|
||||
val converted_groups = AutoCorresUtil2.par_convert convert existing_l2_infos l2_results;
|
||||
val converted_groups = AutoCorresUtil2.par_convert convert existing_l2_infos l2_results add_trace;
|
||||
|
||||
(* Sequence of new function_infos and intermediate lthys *)
|
||||
val def_results = FSeq.mk (fn _ =>
|
||||
|
|
|
@ -1622,6 +1622,7 @@ fun translate
|
|||
(existing_l2_infos: FunctionInfo2.function_info Symtab.table)
|
||||
(do_opt: bool)
|
||||
(trace_opt: bool)
|
||||
(add_trace: string -> string -> AutoCorresData.Trace -> unit)
|
||||
(l2_function_name: string -> string)
|
||||
: FunctionInfo2.phase_results =
|
||||
let;
|
||||
|
@ -1629,7 +1630,7 @@ let;
|
|||
val converted_groups =
|
||||
AutoCorresUtil2.par_convert
|
||||
(fn lthy => fn l1_infos => convert lthy prog_info l1_infos do_opt trace_opt l2_function_name)
|
||||
existing_l1_infos l1_results;
|
||||
existing_l1_infos l1_results add_trace;
|
||||
|
||||
(* Sequence of new function_infos and intermediate lthys *)
|
||||
val def_results = FSeq.mk (fn _ =>
|
||||
|
|
|
@ -561,6 +561,7 @@ fun translate
|
|||
(check_termination: bool)
|
||||
(do_opt: bool)
|
||||
(trace_opt: bool)
|
||||
(add_trace: string -> string -> AutoCorresData.Trace -> unit)
|
||||
(l1_function_name: string -> string)
|
||||
(lthy: local_theory)
|
||||
: FunctionInfo2.phase_results =
|
||||
|
@ -591,7 +592,7 @@ let
|
|||
(fn lthy => fn simpl_infos =>
|
||||
convert lthy prog_info simpl_infos const_to_function check_termination
|
||||
do_opt trace_opt l1_function_name)
|
||||
existing_simpl_infos initial_results;
|
||||
existing_simpl_infos initial_results add_trace;
|
||||
|
||||
(* Sequence of new function_infos and intermediate lthys *)
|
||||
val def_results = AutoCorresUtil2.define_funcs_sequence
|
||||
|
|
|
@ -25,26 +25,31 @@ autocorres [
|
|||
* These tend to be very large and detailed.
|
||||
*)
|
||||
|
||||
(* All traces are stored in the AutoCorresData.Traces theory data. *)
|
||||
ML {*
|
||||
val all_traces = the (Symtab.lookup (AutoCorresData.Traces.get @{theory}) "trace_demo.c")
|
||||
*}
|
||||
|
||||
(* Heap lifting trace. *)
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "HL" "incr"
|
||||
|> the |> (fn AutoCorresData.RuleTrace x => x)
|
||||
the (Symtab.lookup (the (Symtab.lookup all_traces "incr")) "HL")
|
||||
|> (fn AutoCorresData.RuleTrace x => x)
|
||||
|> AutoCorresTrace.print_ac_trace
|
||||
|> writeln
|
||||
*}
|
||||
|
||||
(* Word abstraction trace. *)
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "WA" "incr"
|
||||
|> the |> (fn AutoCorresData.RuleTrace x => x)
|
||||
the (Symtab.lookup (the (Symtab.lookup all_traces "incr")) "WA")
|
||||
|> (fn AutoCorresData.RuleTrace x => x)
|
||||
|> AutoCorresTrace.print_ac_trace
|
||||
|> writeln
|
||||
*}
|
||||
|
||||
(* To navigate a trace in jEdit, write it to a file: *)
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "HL" "incr"
|
||||
|> the |> (fn AutoCorresData.RuleTrace x => x)
|
||||
the (Symtab.lookup (the (Symtab.lookup all_traces "incr")) "HL")
|
||||
|> (fn AutoCorresData.RuleTrace x => x)
|
||||
|> AutoCorresTrace.print_ac_trace
|
||||
|> AutoCorresTrace.writeFile
|
||||
(Path.append (Resources.master_directory @{theory}) (Path.make ["trace_demo_incr.trace"]) |> Path.implode)
|
||||
|
@ -59,30 +64,30 @@ AutoCorresData.get_trace @{theory} "trace_demo.c" "HL" "incr"
|
|||
|
||||
(* Peephole optimisations (ie. rewrite rules). *)
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "L2 peephole opt" "incr"
|
||||
|> the |> (fn AutoCorresData.SimpTrace x => x)
|
||||
the (Symtab.lookup (the (Symtab.lookup all_traces "incr")) "L2 peephole opt")
|
||||
|> (fn AutoCorresData.SimpTrace x => x)
|
||||
*}
|
||||
(* Flow-sensitive optimisations. If you use the no_opt option, they will be disabled and there will be no trace. *)
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "L2 flow opt" "incr"
|
||||
Symtab.lookup (the (Symtab.lookup all_traces "incr")) "L2 flow opt"
|
||||
|> Option.map (fn AutoCorresData.SimpTrace x => x)
|
||||
*}
|
||||
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "HL peephole opt" "incr"
|
||||
|> the |> (fn AutoCorresData.SimpTrace x => x)
|
||||
the (Symtab.lookup (the (Symtab.lookup all_traces "incr")) "HL peephole opt")
|
||||
|> (fn AutoCorresData.SimpTrace x => x)
|
||||
*}
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "HL flow opt" "incr"
|
||||
Symtab.lookup (the (Symtab.lookup all_traces "incr")) "HL flow opt"
|
||||
|> Option.map (fn AutoCorresData.SimpTrace x => x)
|
||||
*}
|
||||
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "WA peephole opt" "incr"
|
||||
|> the |> (fn AutoCorresData.SimpTrace x => x)
|
||||
the (Symtab.lookup (the (Symtab.lookup all_traces "incr")) "WA peephole opt")
|
||||
|> (fn AutoCorresData.SimpTrace x => x)
|
||||
*}
|
||||
ML {*
|
||||
AutoCorresData.get_trace @{theory} "trace_demo.c" "WA flow opt" "incr"
|
||||
Symtab.lookup (the (Symtab.lookup all_traces "incr")) "WA flow opt"
|
||||
|> Option.map (fn AutoCorresData.SimpTrace x => x)
|
||||
*}
|
||||
|
||||
|
|
|
@ -577,6 +577,7 @@ fun translate
|
|||
(make_function_name : string -> string)
|
||||
(keep_going : bool)
|
||||
(do_opt : bool)
|
||||
(add_trace: string -> string -> AutoCorresData.Trace -> unit)
|
||||
: FunctionInfo2.phase_results =
|
||||
if FSeq.null l2_results then FSeq.empty () else
|
||||
let
|
||||
|
|
|
@ -1029,6 +1029,16 @@ fun symtab_merge allow_dups tabs =
|
|||
|> (if allow_dups then sort_distinct (fast_string_ord o apply2 fst) else I)
|
||||
|> Symtab.make;
|
||||
|
||||
(* Merge with custom merge operation. *)
|
||||
fun symtab_merge_with merge (tab1, tab2) =
|
||||
sort_distinct fast_string_ord (Symtab.keys tab1 @ Symtab.keys tab2)
|
||||
|> map (fn k => (k, case (Symtab.lookup tab1 k, Symtab.lookup tab2 k) of
|
||||
(SOME x1, SOME x2) => merge (x1, x2)
|
||||
| (SOME x1, NONE) => x1
|
||||
| (NONE, SOME x2) => x2
|
||||
(* (NONE, NONE) impossible *)))
|
||||
|> Symtab.make
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ fun translate
|
|||
(trace_funcs: string list)
|
||||
(do_opt: bool)
|
||||
(trace_opt: bool)
|
||||
(add_trace: string -> string -> AutoCorresData.Trace -> unit)
|
||||
(wa_function_name: string -> string)
|
||||
: FunctionInfo2.phase_results =
|
||||
if FSeq.null l2_results then FSeq.empty () else
|
||||
|
@ -451,7 +452,7 @@ let
|
|||
in (new_infos, lthy') end;
|
||||
|
||||
(* Do conversions in parallel. *)
|
||||
val converted_groups = AutoCorresUtil2.par_convert convert existing_l2_infos l2_results;
|
||||
val converted_groups = AutoCorresUtil2.par_convert convert existing_l2_infos l2_results add_trace;
|
||||
|
||||
(* Sequence of intermediate states: (lthy, new_defs) *)
|
||||
val def_results = FSeq.mk (fn _ =>
|
||||
|
|
Loading…
Reference in New Issue