summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--compiler/Contexts.ml6
-rw-r--r--compiler/Interpreter.ml55
-rw-r--r--compiler/InterpreterBorrows.ml8
-rw-r--r--compiler/InterpreterLoops.ml12
-rw-r--r--compiler/Print.ml72
-rw-r--r--compiler/PrintPure.ml10
-rw-r--r--compiler/SymbolicToPure.ml3
7 files changed, 127 insertions, 39 deletions
diff --git a/compiler/Contexts.ml b/compiler/Contexts.ml
index 3d09b58a..f2fa36c5 100644
--- a/compiler/Contexts.ml
+++ b/compiler/Contexts.ml
@@ -491,6 +491,12 @@ let ctx_subst_abs (ctx : eval_ctx) (abs_id : V.AbstractionId.id) (nabs : V.abs)
let env, abs_opt = env_subst_abs ctx.env abs_id nabs in
({ ctx with env }, abs_opt)
+let ctx_set_abs_can_end (ctx : eval_ctx) (abs_id : V.AbstractionId.id)
+ (can_end : bool) : eval_ctx =
+ let abs = ctx_lookup_abs ctx abs_id in
+ let abs = { abs with can_end } in
+ fst (ctx_subst_abs ctx abs_id abs)
+
let ctx_type_decl_is_rec (ctx : eval_ctx) (id : TypeDeclId.id) : bool =
let decl_group = TypeDeclId.Map.find id ctx.type_context.type_decls_groups in
match decl_group with Rec _ -> true | NonRec _ -> false
diff --git a/compiler/Interpreter.ml b/compiler/Interpreter.ml
index d5032756..85da809e 100644
--- a/compiler/Interpreter.ml
+++ b/compiler/Interpreter.ml
@@ -96,7 +96,7 @@ let initialize_symbolic_context_for_fun (type_context : C.type_context)
in
(ctx, avalues)
in
- let region_can_end _ = true in
+ let region_can_end _ = false in
let ctx =
create_push_abstractions_from_abs_region_groups
(fun rg_id -> V.SynthInput rg_id)
@@ -134,6 +134,17 @@ let evaluate_function_symbolic_synthesize_backward_from_return
(config : C.config) (fdef : A.fun_decl) (inst_sg : A.inst_fun_sig)
(back_id : T.RegionGroupId.id) (loop_id : V.LoopId.id option)
(inside_loop : bool) (ctx : C.eval_ctx) : SA.expression option =
+ log#ldebug
+ (lazy
+ ("evaluate_function_symbolic_synthesize_backward_from_return:"
+ ^ "\n- back_id: "
+ ^ T.RegionGroupId.to_string back_id
+ ^ "\n- loop_id: "
+ ^ Print.option_to_string V.LoopId.to_string loop_id
+ ^ "\n- inside_loop: "
+ ^ Print.bool_to_string inside_loop
+ ^ "\n- ctx:\n"
+ ^ Print.Contexts.eval_ctx_to_string_gen true true ctx));
let entered_loop = Option.is_some loop_id in
(* We need to instantiate the function signature - to retrieve
* the return type. Note that it is important to re-generate
@@ -200,7 +211,7 @@ let evaluate_function_symbolic_synthesize_backward_from_return
else ctx
in
- (* Set the proper loop abstractions as endable *)
+ (* Set the proper abstractions as endable *)
let ctx =
let visit_loop_abs =
object
@@ -208,10 +219,28 @@ let evaluate_function_symbolic_synthesize_backward_from_return
method! visit_abs _ abs =
match abs.kind with
- | V.Loop (_, rg_id', _) ->
+ | V.Loop (loop_id', rg_id', V.LoopSynthInput) ->
+ (* We only allow to end the loop synth input abs for the region
+ group [rg_id] *)
+ assert (
+ if Option.is_some loop_id then loop_id = Some loop_id'
+ else true);
+ (* Loop abstractions *)
let rg_id' = Option.get rg_id' in
- if rg_id' = back_id then { abs with can_end = true } else abs
- | _ -> abs
+ if rg_id' = back_id && inside_loop then
+ { abs with can_end = true }
+ else abs
+ | V.Loop (loop_id', _, V.LoopCall) ->
+ (* We can end all the loop call abstractions *)
+ assert (loop_id = Some loop_id');
+ { abs with can_end = true }
+ | V.SynthInput rg_id' ->
+ if rg_id' = back_id && not inside_loop then
+ { abs with can_end = true }
+ else abs
+ | _ ->
+ (* Other abstractions *)
+ abs
end
in
visit_loop_abs#visit_eval_ctx () ctx
@@ -247,6 +276,11 @@ let evaluate_function_symbolic_synthesize_backward_from_return
let abs = Option.get (C.ctx_find_abs ctx pred) in
abs.abs_id
in
+ log#ldebug
+ (lazy
+ ("evaluate_function_symbolic_synthesize_backward_from_return: ending \
+ input abstraction: "
+ ^ V.AbstractionId.to_string current_abs_id));
let target_abs_ids = List.append parent_input_abs_ids [ current_abs_id ] in
let cf_end_target_abs cf =
List.fold_left
@@ -296,7 +330,7 @@ let evaluate_function_symbolic (synthesize : bool)
^ Cps.show_statement_eval_res res));
match res with
- | Return | LoopReturn ->
+ | Return | LoopReturn _ ->
if synthesize then
(* We have to "play different endings":
* - one execution for the forward function
@@ -326,16 +360,17 @@ let evaluate_function_symbolic (synthesize : bool)
abstractions to consume the return value, then end all the
abstractions up to the one in which we are interested.
*)
- let inside_loop =
+ let loop_id =
match res with
- | Return -> false
- | LoopReturn -> true
+ | Return -> None
+ | LoopReturn loop_id -> Some loop_id
| _ -> raise (Failure "Unreachable")
in
+ let inside_loop = Option.is_some loop_id in
let finish_back_eval back_id =
Option.get
(evaluate_function_symbolic_synthesize_backward_from_return config
- fdef inst_sg back_id None inside_loop ctx)
+ fdef inst_sg back_id loop_id inside_loop ctx)
in
let back_el =
T.RegionGroupId.mapi
diff --git a/compiler/InterpreterBorrows.ml b/compiler/InterpreterBorrows.ml
index 208918af..0b7b4be5 100644
--- a/compiler/InterpreterBorrows.ml
+++ b/compiler/InterpreterBorrows.ml
@@ -1005,7 +1005,13 @@ and end_abstraction_aux (config : C.config) (chain : borrow_or_abs_ids)
let abs = C.ctx_lookup_abs ctx abs_id in
(* Check that we can end the abstraction *)
- assert abs.can_end;
+ if abs.can_end then ()
+ else
+ raise
+ (Failure
+ ("Can't end abstraction "
+ ^ V.AbstractionId.to_string abs.abs_id
+ ^ " as it is set as non-endable"));
(* End the parent abstractions first *)
let cc = end_abstractions_aux config chain abs.parents in
diff --git a/compiler/InterpreterLoops.ml b/compiler/InterpreterLoops.ml
index 7a72f8e3..96f6e7b5 100644
--- a/compiler/InterpreterLoops.ml
+++ b/compiler/InterpreterLoops.ml
@@ -2323,8 +2323,11 @@ let compute_loop_entry_fixed_point (config : C.config) (loop_id : V.LoopId.id)
let abs_id =
V.AbstractionId.of_int (T.RegionGroupId.to_int rg_id)
in
- let abs = C.ctx_lookup_abs ctx abs_id in
- assert (abs.kind = V.SynthInput rg_id);
+ (* By default, the [SynthInput] abs can't end *)
+ let ctx = C.ctx_set_abs_can_end ctx abs_id true in
+ assert (
+ let abs = C.ctx_lookup_abs ctx abs_id in
+ abs.kind = V.SynthInput rg_id);
(* End this abstraction *)
let ctx =
InterpreterBorrows.end_abstraction_no_synth config abs_id ctx
@@ -3171,7 +3174,10 @@ let eval_loop_symbolic (config : C.config) (eval_loop_body : st_cm_fun) :
let cf_loop : st_m_fun =
fun res ctx ->
match res with
- | Return | Panic -> cf res ctx
+ | Return ->
+ (* We replace the [Return] with a [LoopReturn] *)
+ cf (LoopReturn loop_id) ctx
+ | Panic -> cf res ctx
| Break i ->
(* Break out of the loop by calling the continuation *)
let res = if i = 0 then Unit else Break (i - 1) in
diff --git a/compiler/Print.ml b/compiler/Print.ml
index e2bc3777..d040680f 100644
--- a/compiler/Print.ml
+++ b/compiler/Print.ml
@@ -10,6 +10,8 @@ module Expressions = Charon.PrintExpressions
let list_to_string (to_string : 'a -> string) (ls : 'a list) : string =
"[" ^ String.concat "; " (List.map to_string ls) ^ "]"
+let bool_to_string (b : bool) : string = if b then "true" else "false"
+
(** Pretty-printing for values *)
module Values = struct
type value_formatter = {
@@ -292,16 +294,41 @@ module Values = struct
^ abstract_shared_borrows_to_string fmt sb
^ ")"
- let abs_to_string (fmt : value_formatter) (indent : string)
+ let loop_abs_kind_to_string (kind : V.loop_abs_kind) : string =
+ match kind with
+ | LoopSynthInput -> "LoopSynthInput"
+ | LoopCall -> "LoopCall"
+
+ let abs_kind_to_string (kind : V.abs_kind) : string =
+ match kind with
+ | V.FunCall (fid, rg_id) ->
+ "FunCall(fid:" ^ V.FunCallId.to_string fid ^ ", rg_id:"
+ ^ T.RegionGroupId.to_string rg_id
+ ^ ")"
+ | SynthInput rg_id ->
+ "SynthInput(rg_id:" ^ T.RegionGroupId.to_string rg_id ^ ")"
+ | SynthRet rg_id ->
+ "SynthRet(rg_id:" ^ T.RegionGroupId.to_string rg_id ^ ")"
+ | Loop (lp_id, rg_id, abs_kind) ->
+ "Loop(loop_id:" ^ V.LoopId.to_string lp_id ^ ", rg_id:"
+ ^ option_to_string T.RegionGroupId.to_string rg_id
+ ^ ", loop abs kind: "
+ ^ loop_abs_kind_to_string abs_kind
+ ^ ")"
+
+ let abs_to_string (fmt : value_formatter) (verbose : bool) (indent : string)
(indent_incr : string) (abs : V.abs) : string =
let indent2 = indent ^ indent_incr in
let avs =
List.map (fun av -> indent2 ^ typed_avalue_to_string fmt av) abs.avalues
in
let avs = String.concat ",\n" avs in
+ let kind =
+ if verbose then "[kind:" ^ abs_kind_to_string abs.kind ^ "]" else ""
+ in
indent ^ "abs@"
^ V.AbstractionId.to_string abs.abs_id
- ^ "{parents="
+ ^ kind ^ "{parents="
^ V.AbstractionId.Set.to_string None abs.parents
^ "}" ^ "{regions="
^ T.RegionId.Set.to_string None abs.regions
@@ -325,20 +352,21 @@ module Contexts = struct
| VarBinder b -> var_binder_to_string b
| DummyBinder bid -> dummy_var_id_to_string bid
- let env_elem_to_string (fmt : PV.value_formatter) (indent : string)
- (indent_incr : string) (ev : C.env_elem) : string =
+ let env_elem_to_string (fmt : PV.value_formatter) (verbose : bool)
+ (indent : string) (indent_incr : string) (ev : C.env_elem) : string =
match ev with
| Var (var, tv) ->
let bv = binder_to_string var in
indent ^ bv ^ " -> " ^ PV.typed_value_to_string fmt tv ^ " ;"
- | Abs abs -> PV.abs_to_string fmt indent indent_incr abs
+ | Abs abs -> PV.abs_to_string fmt verbose indent indent_incr abs
| Frame -> raise (Failure "Can't print a Frame element")
- let opt_env_elem_to_string (fmt : PV.value_formatter) (indent : string)
- (indent_incr : string) (ev : C.env_elem option) : string =
+ let opt_env_elem_to_string (fmt : PV.value_formatter) (verbose : bool)
+ (indent : string) (indent_incr : string) (ev : C.env_elem option) : string
+ =
match ev with
| None -> indent ^ "..."
- | Some ev -> env_elem_to_string fmt indent indent_incr ev
+ | Some ev -> env_elem_to_string fmt verbose indent indent_incr ev
(** Filters "dummy" bindings from an environment, to gain space and clarity/
See [env_to_string]. *)
@@ -376,14 +404,16 @@ module Contexts = struct
allows to filter them when printing, replacing groups of such bindings with
"..." to gain space and clarity.
*)
- let env_to_string (filter : bool) (fmt : PV.value_formatter) (env : C.env) :
- string =
+ let env_to_string (filter : bool) (fmt : PV.value_formatter) (verbose : bool)
+ (env : C.env) : string =
let env =
if filter then filter_env env else List.map (fun ev -> Some ev) env
in
"{\n"
^ String.concat "\n"
- (List.map (fun ev -> opt_env_elem_to_string fmt " " " " ev) env)
+ (List.map
+ (fun ev -> opt_env_elem_to_string fmt verbose " " " " ev)
+ env)
^ "\n}"
type ctx_formatter = PV.value_formatter
@@ -486,8 +516,8 @@ module Contexts = struct
let frames = split_aux [] [] env in
frames
- let fmt_eval_ctx_to_string_gen (fmt : ctx_formatter) (filter : bool)
- (ctx : C.eval_ctx) : string =
+ let fmt_eval_ctx_to_string_gen (fmt : ctx_formatter) (verbose : bool)
+ (filter : bool) (ctx : C.eval_ctx) : string =
let ended_regions = T.RegionId.Set.to_string None ctx.ended_regions in
let frames = split_env_according_to_frames ctx.env in
let num_frames = List.length frames in
@@ -509,21 +539,23 @@ module Contexts = struct
^ string_of_int !num_bindings
^ "\n- dummy bindings: " ^ string_of_int !num_dummies
^ "\n- abstractions: " ^ string_of_int !num_abs ^ "\n"
- ^ env_to_string filter fmt f ^ "\n")
+ ^ env_to_string filter fmt verbose f
+ ^ "\n")
frames
in
"# Ended regions: " ^ ended_regions ^ "\n" ^ "# " ^ string_of_int num_frames
^ " frame(s)\n" ^ String.concat "" frames
- let eval_ctx_to_string_gen (filter : bool) (ctx : C.eval_ctx) : string =
+ let eval_ctx_to_string_gen (verbose : bool) (filter : bool) (ctx : C.eval_ctx)
+ : string =
let fmt = eval_ctx_to_ctx_formatter ctx in
- fmt_eval_ctx_to_string_gen fmt filter ctx
+ fmt_eval_ctx_to_string_gen fmt verbose filter ctx
let eval_ctx_to_string (ctx : C.eval_ctx) : string =
- eval_ctx_to_string_gen true ctx
+ eval_ctx_to_string_gen false true ctx
let eval_ctx_to_string_no_filter (ctx : C.eval_ctx) : string =
- eval_ctx_to_string_gen false ctx
+ eval_ctx_to_string_gen false false ctx
end
module PC = Contexts (* local module *)
@@ -593,10 +625,10 @@ module EvalCtxLlbcAst = struct
let env_elem_to_string (ctx : C.eval_ctx) (indent : string)
(indent_incr : string) (ev : C.env_elem) : string =
let fmt = PC.eval_ctx_to_ctx_formatter ctx in
- PC.env_elem_to_string fmt indent indent_incr ev
+ PC.env_elem_to_string fmt false indent indent_incr ev
let abs_to_string (ctx : C.eval_ctx) (indent : string) (indent_incr : string)
(abs : V.abs) : string =
let fmt = PC.eval_ctx_to_ctx_formatter ctx in
- PV.abs_to_string fmt indent indent_incr abs
+ PV.abs_to_string fmt false indent indent_incr abs
end
diff --git a/compiler/PrintPure.ml b/compiler/PrintPure.ml
index c83858b3..b19e0be6 100644
--- a/compiler/PrintPure.ml
+++ b/compiler/PrintPure.ml
@@ -619,14 +619,16 @@ and switch_to_string (fmt : ast_formatter) (indent : string)
and loop_to_string (fmt : ast_formatter) (indent : string)
(indent_incr : string) (loop : loop) : string =
let indent1 = indent ^ indent_incr in
+ let indent2 = indent1 ^ indent_incr in
let fun_end =
- texpression_to_string fmt false indent1 indent_incr loop.fun_end
+ texpression_to_string fmt false indent2 indent_incr loop.fun_end
in
let loop_body =
- texpression_to_string fmt false indent1 indent_incr loop.loop_body
+ texpression_to_string fmt false indent2 indent_incr loop.loop_body
in
- "loop {\n" ^ indent1 ^ "fun_end: " ^ fun_end ^ "\n" ^ indent1 ^ "loop_body:"
- ^ loop_body ^ "\n" ^ indent ^ "}"
+ "loop {\n" ^ indent1 ^ "fun_end: {\n" ^ indent2 ^ fun_end ^ "\n" ^ indent1
+ ^ "}\n" ^ indent1 ^ "loop_body: {\n" ^ indent2 ^ loop_body ^ "\n" ^ indent1
+ ^ "}\n" ^ indent ^ "}"
and meta_to_string (fmt : ast_formatter) (meta : meta) : string =
let meta =
diff --git a/compiler/SymbolicToPure.ml b/compiler/SymbolicToPure.ml
index f06e6542..3488b334 100644
--- a/compiler/SymbolicToPure.ml
+++ b/compiler/SymbolicToPure.ml
@@ -284,9 +284,10 @@ let fun_decl_to_string (ctx : bs_ctx) (def : Pure.fun_decl) : string =
let abs_to_string (ctx : bs_ctx) (abs : V.abs) : string =
let fmt = bs_ctx_to_ast_formatter ctx in
let fmt = Print.Contexts.ast_to_value_formatter fmt in
+ let verbose = false in
let indent = "" in
let indent_incr = " " in
- Print.Values.abs_to_string fmt indent indent_incr abs
+ Print.Values.abs_to_string fmt verbose indent indent_incr abs
let get_instantiated_fun_sig (fun_id : A.fun_id)
(back_id : T.RegionGroupId.id option) (tys : ty list) (ctx : bs_ctx) :