summaryrefslogtreecommitdiff
path: root/compiler/InterpreterExpansion.ml
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/InterpreterExpansion.ml')
-rw-r--r--compiler/InterpreterExpansion.ml239
1 files changed, 98 insertions, 141 deletions
diff --git a/compiler/InterpreterExpansion.ml b/compiler/InterpreterExpansion.ml
index e47fbfbe..39c9bd4a 100644
--- a/compiler/InterpreterExpansion.ml
+++ b/compiler/InterpreterExpansion.ml
@@ -191,8 +191,8 @@ let replace_symbolic_values (meta : Meta.meta) (at_most_once : bool)
ctx
let apply_symbolic_expansion_non_borrow (config : config) (meta : Meta.meta)
- (original_sv : symbolic_value) (expansion : symbolic_expansion)
- (ctx : eval_ctx) : eval_ctx =
+ (original_sv : symbolic_value) (ctx : eval_ctx)
+ (expansion : symbolic_expansion) : eval_ctx =
(* Apply the expansion to non-abstraction values *)
let nv = symbolic_expansion_non_borrow_to_value meta original_sv expansion in
let at_most_once = false in
@@ -288,7 +288,7 @@ let compute_expanded_symbolic_adt_value (meta : Meta.meta)
let expand_symbolic_value_shared_borrow (config : config) (meta : Meta.meta)
(original_sv : symbolic_value) (original_sv_place : SA.mplace option)
(ref_ty : rty) : cm_fun =
- fun cf ctx ->
+ fun ctx ->
(* First, replace the projectors on borrows.
* The important point is that the symbolic value to expand may appear
* several times, if it has been copied. In this case, we need to introduce
@@ -395,17 +395,16 @@ let expand_symbolic_value_shared_borrow (config : config) (meta : Meta.meta)
apply_symbolic_expansion_to_avalues config meta allow_reborrows original_sv
see ctx
in
- (* Call the continuation *)
- let expr = cf ctx in
- (* Update the synthesized program *)
- S.synthesize_symbolic_expansion_no_branching meta original_sv
- original_sv_place see expr
+ ( ctx,
+ (* Update the synthesized program *)
+ S.synthesize_symbolic_expansion_no_branching meta original_sv
+ original_sv_place see )
(** TODO: simplify and merge with the other expansion function *)
let expand_symbolic_value_borrow (config : config) (meta : Meta.meta)
(original_sv : symbolic_value) (original_sv_place : SA.mplace option)
(region : region) (ref_ty : rty) (rkind : ref_kind) : cm_fun =
- fun cf ctx ->
+ fun ctx ->
sanity_check __FILE__ __LINE__ (region <> RErased) meta;
(* Check that we are allowed to expand the reference *)
sanity_check __FILE__ __LINE__
@@ -435,99 +434,47 @@ let expand_symbolic_value_borrow (config : config) (meta : Meta.meta)
original_sv see ctx
in
(* Apply the continuation *)
- let expr = cf ctx in
- (* Update the synthesized program *)
- S.synthesize_symbolic_expansion_no_branching meta original_sv
- original_sv_place see expr
+ ( ctx,
+ fun e ->
+ (* Update the synthesized program *)
+ S.synthesize_symbolic_expansion_no_branching meta original_sv
+ original_sv_place see e )
| RShared ->
expand_symbolic_value_shared_borrow config meta original_sv
- original_sv_place ref_ty cf ctx
-
-(** A small helper.
-
- Apply a branching symbolic expansion to a context and execute all the
- branches. Note that the expansion is optional for every branch (this is
- used for integer expansion: see {!expand_symbolic_int}).
-
- [see_cf_l]: list of pairs (optional symbolic expansion, continuation).
- We use [None] for the symbolic expansion for the [_] (default) case of the
- integer expansions.
- The continuation are used to execute the content of the branches, but not
- what comes after.
-
- [cf_after_join]: this continuation is called *after* the branches have been evaluated.
- We need this continuation separately (i.e., we can't compose it with the
- continuations in [see_cf_l]) because we perform a join *before* calling it.
-*)
-let apply_branching_symbolic_expansions_non_borrow (config : config)
- (meta : Meta.meta) (sv : symbolic_value) (sv_place : SA.mplace option)
- (see_cf_l : (symbolic_expansion option * st_cm_fun) list)
- (cf_after_join : st_m_fun) : m_fun =
- fun ctx ->
- sanity_check __FILE__ __LINE__ (see_cf_l <> []) meta;
- (* Apply the symbolic expansion in the context and call the continuation *)
- let resl =
- List.map
- (fun (see_opt, cf_br) ->
- (* Remember the initial context for printing purposes *)
- let ctx0 = ctx in
- (* Expansion *)
- let ctx =
- match see_opt with
- | None -> ctx
- | Some see ->
- apply_symbolic_expansion_non_borrow config meta sv see ctx
- in
- (* Debug *)
- log#ldebug
- (lazy
- ("apply_branching_symbolic_expansions_non_borrow: "
- ^ symbolic_value_to_string ctx0 sv
- ^ "\n\n- original context:\n"
- ^ eval_ctx_to_string ~meta:(Some meta) ctx0
- ^ "\n\n- new context:\n"
- ^ eval_ctx_to_string ~meta:(Some meta) ctx
- ^ "\n"));
- (* Continuation *)
- cf_br cf_after_join ctx)
- see_cf_l
- in
- (* Collect the result: either we computed no subterm, or we computed all
- * of them *)
- let subterms =
- match resl with
- | Some _ :: _ -> Some (List.map Option.get resl)
- | None :: _ ->
- List.iter
- (fun res -> sanity_check __FILE__ __LINE__ (res = None) meta)
- resl;
- None
- | _ -> craise __FILE__ __LINE__ meta "Unreachable"
- in
- (* Synthesize and return *)
- let seel = List.map fst see_cf_l in
- S.synthesize_symbolic_expansion meta sv sv_place seel subterms
+ original_sv_place ref_ty ctx
let expand_symbolic_bool (config : config) (meta : Meta.meta)
- (sv : symbolic_value) (sv_place : SA.mplace option) (cf_true : st_cm_fun)
- (cf_false : st_cm_fun) (cf_after_join : st_m_fun) : m_fun =
+ (sv : symbolic_value) (sv_place : SA.mplace option) :
+ eval_ctx ->
+ (eval_ctx * eval_ctx)
+ * ((SymbolicAst.expression * SymbolicAst.expression) option -> eval_result)
+ =
fun ctx ->
(* Compute the expanded value *)
let original_sv = sv in
- let original_sv_place = sv_place in
let rty = original_sv.sv_ty in
sanity_check __FILE__ __LINE__ (rty = TLiteral TBool) meta;
(* Expand the symbolic value to true or false and continue execution *)
let see_true = SeLiteral (VBool true) in
let see_false = SeLiteral (VBool false) in
- let seel = [ (Some see_true, cf_true); (Some see_false, cf_false) ] in
- (* Apply the symbolic expansion (this also outputs the updated symbolic AST) *)
- apply_branching_symbolic_expansions_non_borrow config meta original_sv
- original_sv_place seel cf_after_join ctx
+ let seel = [ Some see_true; Some see_false ] in
+ (* Apply the symbolic expansion *)
+ let apply_expansion =
+ apply_symbolic_expansion_non_borrow config meta sv ctx
+ in
+ let ctx_true = apply_expansion see_true in
+ let ctx_false = apply_expansion see_false in
+ (* Compute the continuation to build the expression *)
+ let cf e =
+ let el = match e with Some (a, b) -> Some [ a; b ] | None -> None in
+ S.synthesize_symbolic_expansion meta sv sv_place seel el
+ in
+ (* Return *)
+ ((ctx_true, ctx_false), cf)
let expand_symbolic_value_no_branching (config : config) (meta : Meta.meta)
(sv : symbolic_value) (sv_place : SA.mplace option) : cm_fun =
- fun cf ctx ->
+ fun ctx ->
(* Debug *)
log#ldebug
(lazy
@@ -539,8 +486,7 @@ let expand_symbolic_value_no_branching (config : config) (meta : Meta.meta)
let original_sv = sv in
let original_sv_place = sv_place in
let rty = original_sv.sv_ty in
- let cc : cm_fun =
- fun cf ctx ->
+ let ctx, cc =
match rty with
(* ADTs *)
| TAdt (adt_id, generics) ->
@@ -554,45 +500,43 @@ let expand_symbolic_value_no_branching (config : config) (meta : Meta.meta)
let see = Collections.List.to_cons_nil seel in
(* Apply in the context *)
let ctx =
- apply_symbolic_expansion_non_borrow config meta original_sv see ctx
+ apply_symbolic_expansion_non_borrow config meta original_sv ctx see
in
- (* Call the continuation *)
- let expr = cf ctx in
- (* Update the synthesized program *)
- S.synthesize_symbolic_expansion_no_branching meta original_sv
- original_sv_place see expr
+ (* Return*)
+ ( ctx,
+ (* Update the synthesized program *)
+ S.synthesize_symbolic_expansion_no_branching meta original_sv
+ original_sv_place see )
(* Borrows *)
| TRef (region, ref_ty, rkind) ->
expand_symbolic_value_borrow config meta original_sv original_sv_place
- region ref_ty rkind cf ctx
+ region ref_ty rkind ctx
| _ ->
craise __FILE__ __LINE__ meta
("expand_symbolic_value_no_branching: unexpected type: "
^ show_rty rty)
in
(* Debug *)
- let cc =
- comp_unit cc (fun ctx ->
- log#ldebug
- (lazy
- ("expand_symbolic_value_no_branching: "
- ^ symbolic_value_to_string ctx0 sv
- ^ "\n\n- original context:\n"
- ^ eval_ctx_to_string ~meta:(Some meta) ctx0
- ^ "\n\n- new context:\n"
- ^ eval_ctx_to_string ~meta:(Some meta) ctx
- ^ "\n"));
- (* Sanity check: the symbolic value has disappeared *)
- sanity_check __FILE__ __LINE__
- (not (symbolic_value_id_in_ctx original_sv.sv_id ctx))
- meta)
- in
- (* Continue *)
- cc cf ctx
+ log#ldebug
+ (lazy
+ ("expand_symbolic_value_no_branching: "
+ ^ symbolic_value_to_string ctx0 sv
+ ^ "\n\n- original context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx0
+ ^ "\n\n- new context:\n"
+ ^ eval_ctx_to_string ~meta:(Some meta) ctx
+ ^ "\n"));
+ (* Sanity check: the symbolic value has disappeared *)
+ sanity_check __FILE__ __LINE__
+ (not (symbolic_value_id_in_ctx original_sv.sv_id ctx))
+ meta;
+ (* Return *)
+ (ctx, cc)
let expand_symbolic_adt (config : config) (meta : Meta.meta)
- (sv : symbolic_value) (sv_place : SA.mplace option)
- (cf_branches : st_cm_fun) (cf_after_join : st_m_fun) : m_fun =
+ (sv : symbolic_value) (sv_place : SA.mplace option) :
+ eval_ctx ->
+ eval_ctx list * (SymbolicAst.expression list option -> eval_result) =
fun ctx ->
(* Debug *)
log#ldebug (lazy ("expand_symbolic_adt:" ^ symbolic_value_to_string ctx sv));
@@ -612,17 +556,24 @@ let expand_symbolic_adt (config : config) (meta : Meta.meta)
ctx
in
(* Apply *)
- let seel = List.map (fun see -> (Some see, cf_branches)) seel in
- apply_branching_symbolic_expansions_non_borrow config meta original_sv
- original_sv_place seel cf_after_join ctx
+ let ctx_branches =
+ List.map (apply_symbolic_expansion_non_borrow config meta sv ctx) seel
+ in
+ ( ctx_branches,
+ S.synthesize_symbolic_expansion meta sv original_sv_place
+ (List.map (fun el -> Some el) seel) )
| _ ->
craise __FILE__ __LINE__ meta
("expand_symbolic_adt: unexpected type: " ^ show_rty rty)
let expand_symbolic_int (config : config) (meta : Meta.meta)
(sv : symbolic_value) (sv_place : SA.mplace option)
- (int_type : integer_type) (tgts : (scalar_value * st_cm_fun) list)
- (otherwise : st_cm_fun) (cf_after_join : st_m_fun) : m_fun =
+ (int_type : integer_type) (tgts : scalar_value list) :
+ eval_ctx ->
+ (eval_ctx list * eval_ctx)
+ * ((SymbolicAst.expression list * SymbolicAst.expression) option ->
+ eval_result) =
+ fun ctx ->
(* Sanity check *)
sanity_check __FILE__ __LINE__ (sv.sv_ty = TLiteral (TInteger int_type)) meta;
(* For all the branches of the switch, we expand the symbolic value
@@ -630,17 +581,23 @@ let expand_symbolic_int (config : config) (meta : Meta.meta)
* For the otherwise branch, we leave the symbolic value as it is
* (because this branch doesn't precisely define which should be the
* value of the scrutinee...) and simply execute the otherwise statement.
- *
- * First, generate the list of pairs:
- * (optional expansion, statement to execute)
*)
- let seel =
- List.map (fun (v, cf) -> (Some (SeLiteral (VScalar v)), cf)) tgts
+ (* Substitute the symbolic values to generate the contexts in the branches *)
+ let seel = List.map (fun v -> SeLiteral (VScalar v)) tgts in
+ let ctx_branches =
+ List.map (apply_symbolic_expansion_non_borrow config meta sv ctx) seel
in
- let seel = List.append seel [ (None, otherwise) ] in
- (* Then expand and evaluate - this generates the proper symbolic AST *)
- apply_branching_symbolic_expansions_non_borrow config meta sv sv_place seel
- cf_after_join
+ let ctx_otherwise = ctx in
+ (* Update the symbolic ast *)
+ let cf e =
+ match e with
+ | None -> None
+ | Some (el, e) ->
+ let seel = List.map (fun x -> Some x) seel in
+ S.synthesize_symbolic_expansion meta sv sv_place (seel @ [ None ])
+ (Some (el @ [ e ]))
+ in
+ ((ctx_branches, ctx_otherwise), cf)
(** Expand all the symbolic values which contain borrows.
Allows us to restrict ourselves to a simpler model for the projectors over
@@ -652,7 +609,7 @@ let expand_symbolic_int (config : config) (meta : Meta.meta)
*)
let greedy_expand_symbolics_with_borrows (config : config) (meta : Meta.meta) :
cm_fun =
- fun cf ctx ->
+ fun ctx ->
(* The visitor object, to look for symbolic values in the concrete environment *)
let obj =
object
@@ -669,20 +626,20 @@ let greedy_expand_symbolics_with_borrows (config : config) (meta : Meta.meta) :
in
let rec expand : cm_fun =
- fun cf ctx ->
+ fun ctx ->
try
(* We reverse the environment before exploring it - this way the values
get expanded in a more "logical" order (this is only for convenience) *)
obj#visit_env () (List.rev ctx.env);
(* Nothing to expand: continue *)
- cf ctx
+ (ctx, fun e -> e)
with FoundSymbolicValue sv ->
(* Expand and recheck the environment *)
log#ldebug
(lazy
("greedy_expand_symbolics_with_borrows: about to expand: "
^ symbolic_value_to_string ctx sv));
- let cc : cm_fun =
+ let ctx, cc =
match sv.sv_ty with
| TAdt (TAdtId def_id, _) ->
(* {!expand_symbolic_value_no_branching} checks if there are branchings,
@@ -706,10 +663,10 @@ let greedy_expand_symbolics_with_borrows (config : config) (meta : Meta.meta) :
("Attempted to greedily expand a recursive definition (option \
[greedy_expand_symbolics_with_borrows] of [config]): "
^ name_to_string ctx def.name)
- else expand_symbolic_value_no_branching config meta sv None
+ else expand_symbolic_value_no_branching config meta sv None ctx
| TAdt ((TTuple | TAssumed TBox), _) | TRef (_, _, _) ->
(* Ok *)
- expand_symbolic_value_no_branching config meta sv None
+ expand_symbolic_value_no_branching config meta sv None ctx
| TAdt (TAssumed (TArray | TSlice | TStr), _) ->
(* We can't expand those *)
craise __FILE__ __LINE__ meta
@@ -718,15 +675,15 @@ let greedy_expand_symbolics_with_borrows (config : config) (meta : Meta.meta) :
craise __FILE__ __LINE__ meta "Unreachable"
in
(* Compose and continue *)
- comp cc expand cf ctx
+ comp cc (expand ctx)
in
(* Apply *)
- expand cf ctx
+ expand ctx
let greedy_expand_symbolic_values (config : config) (meta : Meta.meta) : cm_fun
=
- fun cf ctx ->
+ fun ctx ->
if Config.greedy_expand_symbolics_with_borrows then (
log#ldebug (lazy "greedy_expand_symbolic_values");
- greedy_expand_symbolics_with_borrows config meta cf ctx)
- else cf ctx
+ greedy_expand_symbolics_with_borrows config meta ctx)
+ else (ctx, fun e -> e)