summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jib/anf.ml2
-rw-r--r--src/jib/c_backend.ml74
-rw-r--r--src/jib/jib_compile.ml32
-rw-r--r--src/jib/jib_optimize.ml8
-rw-r--r--src/jib/jib_smt.ml24
-rw-r--r--src/jib/jib_ssa.ml8
-rw-r--r--src/jib/jib_util.ml133
-rw-r--r--src/property.ml2
-rw-r--r--src/smtlib.ml14
-rw-r--r--src/type_check.ml2
10 files changed, 168 insertions, 131 deletions
diff --git a/src/jib/anf.ml b/src/jib/anf.ml
index 331fed83..7c6eee3e 100644
--- a/src/jib/anf.ml
+++ b/src/jib/anf.ml
@@ -663,7 +663,7 @@ let rec anf (E_aux (e_aux, ((l, _) as exp_annot)) as exp) =
let aexp2 = anf exp2 in
let aval1, wrap1 = to_aval aexp1 in
let aval2, wrap2 = to_aval aexp2 in
- wrap1 (wrap2 (mk_aexp (AE_app (mk_id "__assert", [aval1; aval2], unit_typ))))
+ wrap1 (wrap2 (mk_aexp (AE_app (mk_id "sail_assert", [aval1; aval2], unit_typ))))
| E_cons (exp1, exp2) ->
let aexp1 = anf exp1 in
diff --git a/src/jib/c_backend.ml b/src/jib/c_backend.ml
index 1b9fa1dd..6b264a48 100644
--- a/src/jib/c_backend.ml
+++ b/src/jib/c_backend.ml
@@ -407,7 +407,7 @@ let analyze_primop' ctx id args typ =
c_debug (lazy ("Analyzing primop " ^ extern ^ "(" ^ Util.string_of_list ", " (fun aval -> Pretty_print_sail.to_string (pp_aval aval)) args ^ ")"));
match extern, args with
- (*
+ (*
| "eq_bits", [AV_cval (v1, _); AV_cval (v2, _)] ->
begin match cval_ctyp v1 with
| CT_fbits _ ->
@@ -444,9 +444,9 @@ let analyze_primop' ctx id args typ =
when string_of_id id = "bit" && Big_int.less_equal n (Big_int.of_int 64) ->
begin match cval_ctyp v1 with
| CT_fbits _ ->
- AE_val (AV_C_fragment (v1, typ, CT_fbits (Big_int.to_int n, true)))
+ AE_val (AV_cval (v1, typ, CT_fbits (Big_int.to_int n, true)))
| CT_sbits _ ->
- AE_val (AV_C_fragment (F_call ("fast_zero_extend", [v1; v_int (Big_int.to_int n)]), typ, CT_fbits (Big_int.to_int n, true)))
+ AE_val (AV_cval (F_call ("fast_zero_extend", [v1; v_int (Big_int.to_int n)]), typ, CT_fbits (Big_int.to_int n, true)))
end
| _ -> no_change
end
@@ -1142,18 +1142,76 @@ let rec sgen_ctyp_name = function
| CT_poly -> "POLY" (* c_error "Tried to generate code for non-monomorphic type" *)
| CT_constant _ -> "CONSTANT"
-let sgen_cval cval = string_of_cval cval
+let rec sgen_cval = function
+ | V_id (id, ctyp) -> string_of_name id
+ | V_ref (id, _) -> "&" ^ string_of_name id
+ | V_lit (vl, ctyp) -> string_of_value vl
+ | V_call (op, cvals) -> sgen_call op cvals
+ | V_field (f, field) ->
+ Printf.sprintf "%s.%s" (sgen_cval f) field
+ | V_tuple_member (f, _, n) ->
+ Printf.sprintf "%s.ztup%d" (sgen_cval f) n
+ | V_ctor_kind (f, ctor, [], _) ->
+ sgen_cval f ^ ".kind"
+ ^ " != Kind_" ^ Util.zencode_string (string_of_id ctor)
+ | V_ctor_kind (f, ctor, unifiers, _) ->
+ sgen_cval f ^ ".kind"
+ ^ " != Kind_" ^ Util.zencode_string (string_of_id ctor ^ "_" ^ Util.string_of_list "_" string_of_ctyp unifiers)
+ | V_ctor_unwrap (ctor, f, [], _) ->
+ Printf.sprintf "%s.%s" (sgen_cval f) (Util.zencode_string (string_of_id ctor))
+ | V_struct (fields, _) ->
+ Printf.sprintf "{%s}"
+ (Util.string_of_list ", " (fun (field, cval) -> string_of_id field ^ " = " ^ sgen_cval cval) fields)
+ | V_ctor_unwrap (ctor, f, unifiers, _) ->
+ Printf.sprintf "%s.%s"
+ (sgen_cval f)
+ (Util.zencode_string (string_of_id ctor ^ "_" ^ Util.string_of_list "_" string_of_ctyp unifiers))
+ | V_poly (f, _) -> sgen_cval f
+
+and sgen_call op cvals =
+ match op, cvals with
+ | Bnot, [v] -> "!(" ^ sgen_cval v ^ ")"
+ | List_hd, [v] ->
+ Printf.sprintf "(%s).hd" ("*" ^ sgen_cval v)
+ | List_tl, [v] ->
+ Printf.sprintf "(%s).tl" ("*" ^ sgen_cval v)
+ | Eq, [v1; v2] ->
+ Printf.sprintf "(%s == %s)" (sgen_cval v1) (sgen_cval v2)
+ | Neq, [v1; v2] ->
+ Printf.sprintf "(%s != %s)" (sgen_cval v1) (sgen_cval v2)
+ | Ilt, [v1; v2] ->
+ Printf.sprintf "(%s < %s)" (sgen_cval v1) (sgen_cval v2)
+ | Igt, [v1; v2] ->
+ Printf.sprintf "(%s > %s)" (sgen_cval v1) (sgen_cval v2)
+ | Ilteq, [v1; v2] ->
+ Printf.sprintf "(%s <= %s)" (sgen_cval v1) (sgen_cval v2)
+ | Igteq, [v1; v2] ->
+ Printf.sprintf "(%s >= %s)" (sgen_cval v1) (sgen_cval v2)
+ | Iadd, [v1; v2] ->
+ Printf.sprintf "(%s + %s)" (sgen_cval v1) (sgen_cval v2)
+ | Isub, [v1; v2] ->
+ Printf.sprintf "(%s - %s)" (sgen_cval v1) (sgen_cval v2)
+ | Bvand, [v1; v2] ->
+ Printf.sprintf "(%s & %s)" (sgen_cval v1) (sgen_cval v2)
+ | Bvor, [v1; v2] ->
+ Printf.sprintf "(%s | %s)" (sgen_cval v1) (sgen_cval v2)
+ | Zero_extend n, [v] ->
+ Printf.sprintf "fast_zero_extend(%d, %s)" n (sgen_cval v)
+ | Sign_extend n, [v] ->
+ Printf.sprintf "fast_sign_extend(%d, %s)" n (sgen_cval v)
+ | _, vs ->
+ Printf.sprintf "%s(%s)" (string_of_op op) (Util.string_of_list ", " sgen_cval cvals)
let sgen_cval_param cval =
match cval_ctyp cval with
| CT_lbits direction ->
- string_of_cval cval ^ ", " ^ string_of_bool direction
+ sgen_cval cval ^ ", " ^ string_of_bool direction
| CT_sbits (_, direction) ->
- string_of_cval cval ^ ", " ^ string_of_bool direction
+ sgen_cval cval ^ ", " ^ string_of_bool direction
| CT_fbits (len, direction) ->
- string_of_cval cval ^ ", UINT64_C(" ^ string_of_int len ^ ") , " ^ string_of_bool direction
+ sgen_cval cval ^ ", UINT64_C(" ^ string_of_int len ^ ") , " ^ string_of_bool direction
| _ ->
- string_of_cval cval
+ sgen_cval cval
let rec sgen_clexp = function
| CL_id (Have_exception _, _) -> "have_exception"
diff --git a/src/jib/jib_compile.ml b/src/jib/jib_compile.ml
index f7438b96..1a4b8b4b 100644
--- a/src/jib/jib_compile.ml
+++ b/src/jib/jib_compile.ml
@@ -342,10 +342,10 @@ let rec compile_aval l ctx = function
match cval with
| V_lit (VL_bit Sail2_values.B0, _) -> []
| V_lit (VL_bit Sail2_values.B1, _) ->
- [icopy l (CL_id (gs, ctyp)) (V_op (V_id (gs, ctyp), "|", V_lit (mask i, ctyp)))]
+ [icopy l (CL_id (gs, ctyp)) (V_call (Bvor, [V_id (gs, ctyp); V_lit (mask i, ctyp)]))]
| _ ->
(* FIXME: Make this work in C *)
- setup @ [iif (V_call ("bit_to_bool", [cval])) [icopy l (CL_id (gs, ctyp)) (V_op (V_id (gs, ctyp), "|", V_lit (mask i, ctyp)))] [] CT_unit] @ cleanup
+ setup @ [iif (V_call (Bit_to_bool, [cval])) [icopy l (CL_id (gs, ctyp)) (V_call (Bvor, [V_id (gs, ctyp); V_lit (mask i, ctyp)]))] [] CT_unit] @ cleanup
in
[idecl ctyp gs;
icopy l (CL_id (gs, ctyp)) (V_lit (VL_bits (Util.list_init 64 (fun _ -> Sail2_values.B0), direction), ctyp))]
@@ -472,7 +472,7 @@ let rec compile_match ctx (AP_aux (apat_aux, env, l)) cval case_label =
| AP_id (pid, _) when is_ct_enum ctyp ->
begin match Env.lookup_id pid ctx.tc_env with
| Unbound -> [idecl ctyp (name pid); icopy l (CL_id (name pid, ctyp)) cval], [], ctx
- | _ -> [ijump (V_op (V_id (name pid, ctyp), "!=", cval)) case_label], [], ctx
+ | _ -> [ijump (V_call (Neq, [V_id (name pid, ctyp); cval])) case_label], [], ctx
end
| AP_id (pid, typ) ->
@@ -525,7 +525,7 @@ let rec compile_match ctx (AP_aux (apat_aux, env, l)) cval case_label =
raise (Reporting.err_general l (Printf.sprintf "Variant constructor %s : %s matching against non-variant type %s : %s"
(string_of_id ctor)
(string_of_typ variant_typ)
- (string_of_cval ~zencode:false cval)
+ (string_of_cval cval)
(string_of_ctyp ctyp)))
end
@@ -534,14 +534,14 @@ let rec compile_match ctx (AP_aux (apat_aux, env, l)) cval case_label =
| AP_cons (hd_apat, tl_apat) ->
begin match ctyp with
| CT_list ctyp ->
- let hd_setup, hd_cleanup, ctx = compile_match ctx hd_apat (V_hd cval) case_label in
- let tl_setup, tl_cleanup, ctx = compile_match ctx tl_apat (V_tl cval) case_label in
- [ijump (V_op (cval, "==", V_lit (VL_null, CT_list ctyp))) case_label] @ hd_setup @ tl_setup, tl_cleanup @ hd_cleanup, ctx
+ let hd_setup, hd_cleanup, ctx = compile_match ctx hd_apat (V_call (List_hd, [cval])) case_label in
+ let tl_setup, tl_cleanup, ctx = compile_match ctx tl_apat (V_call (List_tl, [cval])) case_label in
+ [ijump (V_call (Eq, [cval; V_lit (VL_null, CT_list ctyp)])) case_label] @ hd_setup @ tl_setup, tl_cleanup @ hd_cleanup, ctx
| _ ->
raise (Reporting.err_general l "Tried to pattern match cons on non list type")
end
- | AP_nil _ -> [ijump (V_op (cval, "!=", V_lit (VL_null, ctyp))) case_label], [], ctx
+ | AP_nil _ -> [ijump (V_call (Neq, [cval; V_lit (VL_null, ctyp)])) case_label], [], ctx
let unit_cval = V_lit (VL_unit, CT_unit)
@@ -588,7 +588,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
destructure
@ (if not trivial_guard then
guard_setup @ [idecl CT_bool gs; guard_call (CL_id (gs, CT_bool))] @ guard_cleanup
- @ [iif (V_unary ("!", V_id (gs, CT_bool))) (destructure_cleanup @ [igoto case_label]) [] CT_unit]
+ @ [iif (V_call (Bnot, [V_id (gs, CT_bool)])) (destructure_cleanup @ [igoto case_label]) [] CT_unit]
else [])
@ body_setup @ [body_call (CL_id (case_return_id, ctyp))] @ body_cleanup @ destructure_cleanup
@ [igoto finish_match_label]
@@ -629,7 +629,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
destructure @ [icomment "end destructuring"]
@ (if not trivial_guard then
guard_setup @ [idecl CT_bool gs; guard_call (CL_id (gs, CT_bool))] @ guard_cleanup
- @ [ijump (V_unary ("!", V_id (gs, CT_bool))) try_label]
+ @ [ijump (V_call (Bnot, [V_id (gs, CT_bool)])) try_label]
@ [icomment "end guard"]
else [])
@ body_setup @ [body_call (CL_id (try_return_id, ctyp))] @ body_cleanup @ destructure_cleanup
@@ -640,7 +640,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
assert (ctyp_equal ctyp (ctyp_of_typ ctx typ));
[idecl ctyp try_return_id;
itry_block (aexp_setup @ [aexp_call (CL_id (try_return_id, ctyp))] @ aexp_cleanup);
- ijump (V_unary ("!", V_id (have_exception, CT_bool))) handled_exception_label]
+ ijump (V_call (Bnot, [V_id (have_exception, CT_bool)])) handled_exception_label]
@ List.concat (List.map compile_case cases)
@ [igoto fallthrough_label;
ilabel handled_exception_label;
@@ -762,7 +762,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let body_setup, body_call, body_cleanup = compile_aexp ctx body in
let gs = ngensym () in
let unit_gs = ngensym () in
- let loop_test = V_unary ("!", V_id (gs, CT_bool)) in
+ let loop_test = V_call (Bnot, [V_id (gs, CT_bool)]) in
[idecl CT_bool gs; idecl CT_unit unit_gs]
@ [ilabel loop_start_label]
@ [iblock (cond_setup
@@ -893,12 +893,12 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
icopy l (CL_id (loop_var, (CT_fint 64))) (V_id (from_gs, CT_fint 64));
idecl CT_unit body_gs;
iblock ([ilabel loop_start_label]
- @ [ijump (V_op (V_id (loop_var, CT_fint 64), (if is_inc then ">" else "<"), V_id (to_gs, CT_fint 64))) loop_end_label]
+ @ [ijump (V_call ((if is_inc then Igt else Ilt), [V_id (loop_var, CT_fint 64); V_id (to_gs, CT_fint 64)])) loop_end_label]
@ body_setup
@ [body_call (CL_id (body_gs, CT_unit))]
@ body_cleanup
@ [icopy l (CL_id (loop_var, (CT_fint 64)))
- (V_op (V_id (loop_var, CT_fint 64), (if is_inc then "+" else "-"), V_id (step_gs, CT_fint 64)))]
+ (V_call ((if is_inc then Iadd else Isub), [V_id (loop_var, CT_fint 64); V_id (step_gs, CT_fint 64)]))]
@ [igoto loop_start_label]);
ilabel loop_end_label])],
(fun clexp -> icopy l clexp unit_cval),
@@ -1497,8 +1497,8 @@ let sort_ctype_defs cdefs =
ctype_defs @ cdefs
let compile_ast ctx (Defs defs) =
- let assert_vs = Initial_check.extern_of_string (mk_id "__assert") "(bool, string) -> unit" in
- let exit_vs = Initial_check.extern_of_string (mk_id "__exit") "unit -> unit" in
+ let assert_vs = Initial_check.extern_of_string (mk_id "sail_assert") "(bool, string) -> unit" in
+ let exit_vs = Initial_check.extern_of_string (mk_id "sail_exit") "unit -> unit" in
let ctx = { ctx with tc_env = snd (Type_error.check ctx.tc_env (Defs [assert_vs; exit_vs])) } in
diff --git a/src/jib/jib_optimize.ml b/src/jib/jib_optimize.ml
index 331cf65e..0ec92b97 100644
--- a/src/jib/jib_optimize.ml
+++ b/src/jib/jib_optimize.ml
@@ -160,8 +160,6 @@ let rec cval_subst id subst = function
| V_id (id', ctyp) -> if Name.compare id id' = 0 then subst else V_id (id', ctyp)
| V_ref (reg_id, ctyp) -> V_ref (reg_id, ctyp)
| V_lit (vl, ctyp) -> V_lit (vl, ctyp)
- | V_op (cval1, op, cval2) -> V_op (cval_subst id subst cval1, op, cval_subst id subst cval2)
- | V_unary (op, cval) -> V_unary (op, cval_subst id subst cval)
| V_call (op, cvals) -> V_call (op, List.map (cval_subst id subst) cvals)
| V_field (cval, field) -> V_field (cval_subst id subst cval, field)
| V_tuple_member (cval, len, n) -> V_tuple_member (cval_subst id subst cval, len, n)
@@ -169,22 +167,16 @@ let rec cval_subst id subst = function
| V_ctor_unwrap (ctor, cval, unifiers, ctyp) -> V_ctor_unwrap (ctor, cval_subst id subst cval, unifiers, ctyp)
| V_struct (fields, ctyp) -> V_struct (List.map (fun (field, cval) -> field, cval_subst id subst cval) fields, ctyp)
| V_poly (cval, ctyp) -> V_poly (cval_subst id subst cval, ctyp)
- | V_hd cval -> V_hd (cval_subst id subst cval)
- | V_tl cval -> V_tl (cval_subst id subst cval)
let rec cval_map_id f = function
| V_id (id, ctyp) -> V_id (f id, ctyp)
| V_ref (id, ctyp) -> V_ref (f id, ctyp)
| V_lit (vl, ctyp) -> V_lit (vl, ctyp)
| V_call (call, cvals) -> V_call (call, List.map (cval_map_id f) cvals)
- | V_op (cval1, op, cval2) -> V_op (cval_map_id f cval1, op, cval_map_id f cval2)
- | V_unary (op, cval) -> V_unary (op, cval_map_id f cval)
| V_field (cval, field) -> V_field (cval_map_id f cval, field)
| V_tuple_member (cval, len, n) -> V_tuple_member (cval_map_id f cval, len, n)
| V_ctor_kind (cval, ctor, unifiers, ctyp) -> V_ctor_kind (cval_map_id f cval, ctor, unifiers, ctyp)
| V_ctor_unwrap (ctor, cval, unifiers, ctyp) -> V_ctor_unwrap (ctor, cval_map_id f cval, unifiers, ctyp)
- | V_hd cval -> V_hd (cval_map_id f cval)
- | V_tl cval -> V_tl (cval_map_id f cval)
| V_struct (fields, ctyp) ->
V_struct (List.map (fun (field, cval) -> field, cval_map_id f cval) fields, ctyp)
| V_poly (cval, ctyp) -> V_poly (cval_map_id f cval, ctyp)
diff --git a/src/jib/jib_smt.ml b/src/jib/jib_smt.ml
index 719f0b53..c6fd9d8d 100644
--- a/src/jib/jib_smt.ml
+++ b/src/jib/jib_smt.ml
@@ -250,13 +250,13 @@ let rec smt_cval ctx cval =
| _ -> Var (zencode_name ssa_id)
end
| V_id (ssa_id, _) -> Var (zencode_name ssa_id)
- | V_op (frag1, "!=", frag2) ->
- Fn ("not", [Fn ("=", [smt_cval ctx frag1; smt_cval ctx frag2])])
- | V_op (frag1, "|", frag2) ->
- Fn ("bvor", [smt_cval ctx frag1; smt_cval ctx frag2])
- | V_call ("bit_to_bool", [cval]) ->
+ | V_call (Neq, [cval1; cval2]) ->
+ Fn ("not", [Fn ("=", [smt_cval ctx cval1; smt_cval ctx cval2])])
+ | V_call (Bvor, [cval1; cval2]) ->
+ Fn ("bvor", [smt_cval ctx cval1; smt_cval ctx cval2])
+ | V_call (Bit_to_bool, [cval]) ->
Fn ("=", [smt_cval ctx cval; Bin "1"])
- | V_unary ("!", cval) ->
+ | V_call (Bnot, [cval]) ->
Fn ("not", [smt_cval ctx cval])
| V_ctor_kind (union, ctor_id, unifiers, _) ->
Fn ("not", [Tester (zencode_ctor ctor_id unifiers, smt_cval ctx union)])
@@ -296,7 +296,7 @@ let rec smt_cval ctx cval =
end
| _ -> assert false
end
- | cval -> failwith ("Unrecognised cval " ^ string_of_cval ~zencode:false cval)
+ | cval -> failwith ("Unrecognised cval " ^ string_of_cval cval)
let add_event ctx ev smt =
let stack = event_stack ctx ev in
@@ -1301,7 +1301,7 @@ let smt_instr ctx =
| _ ->
Reporting.unreachable l __POS__ "Bad arguments for internal_vector_update"
end
- else if string_of_id function_id = "__assert" then
+ else if string_of_id function_id = "sail_assert" then
begin match args with
| [assertion; _] ->
let smt = smt_cval ctx assertion in
@@ -1310,7 +1310,7 @@ let smt_instr ctx =
| _ ->
Reporting.unreachable l __POS__ "Bad arguments for assertion"
end
- else if string_of_id function_id = "__assume" then
+ else if string_of_id function_id = "sail_assume" then
begin match args with
| [assumption] ->
let smt = smt_cval ctx assumption in
@@ -1489,7 +1489,7 @@ let expand_reg_deref ctx = function
let end_label = label "end_reg_deref_" in
let try_reg r =
let next_label = label "next_reg_deref_" in
- [ijump (V_op (V_ref (name r, reg_ctyp), "!=", reg_ref)) next_label;
+ [ijump (V_call (Neq, [V_ref (name r, reg_ctyp); reg_ref])) next_label;
icopy l clexp (V_id (name r, reg_ctyp));
igoto end_label;
ilabel next_label]
@@ -1511,7 +1511,7 @@ let expand_reg_deref ctx = function
let end_label = label "end_reg_write_" in
let try_reg r =
let next_label = label "next_reg_write_" in
- [ijump (V_op (V_ref (name r, reg_ctyp), "!=", V_id (id, ctyp))) next_label;
+ [ijump (V_call (Neq, [V_ref (name r, reg_ctyp); V_id (id, ctyp)])) next_label;
icopy l (CL_id (name r, reg_ctyp)) cval;
igoto end_label;
ilabel next_label]
@@ -1634,7 +1634,7 @@ let smt_cdef props lets name_file ctx all_cdefs = function
| _ -> assert false
) arg_decls
in
- check_counterexample ctx.ast ctx.tc_env fname args arg_ctyps arg_smt_names
+ check_counterexample ctx.ast ctx.tc_env fname function_id args arg_ctyps arg_smt_names
);
| _ -> failwith "Bad function body"
diff --git a/src/jib/jib_ssa.ml b/src/jib/jib_ssa.ml
index ad2302de..19dff7b1 100644
--- a/src/jib/jib_ssa.ml
+++ b/src/jib/jib_ssa.ml
@@ -193,8 +193,6 @@ type cf_node =
| CF_guard of cval
| CF_start of ctyp NameMap.t
-let cval_not cval = V_unary ("!", cval)
-
let control_flow_graph instrs =
let module StringMap = Map.Make(String) in
let labels = ref StringMap.empty in
@@ -243,7 +241,7 @@ let control_flow_graph instrs =
| I_aux (I_jump (cval, label), _) :: after ->
let t = add_vertex ([], CF_guard cval) graph in
- let f = add_vertex ([], CF_guard (cval_not cval)) graph in
+ let f = add_vertex ([], CF_guard (V_call (Bnot, [cval]))) graph in
List.iter (fun p -> add_edge p t graph; add_edge p f graph) preds;
add_edge t (StringMap.find label !labels) graph;
cfg [f] after
@@ -504,8 +502,6 @@ let rename_variables graph root children =
let i = top_stack id in
V_ref (ssa_name i id, ctyp)
| V_lit (vl, ctyp) -> V_lit (vl, ctyp)
- | V_op (f1, op, f2) -> V_op (fold_cval f1, op, fold_cval f2)
- | V_unary (op, f) -> V_unary (op, fold_cval f)
| V_call (id, fs) -> V_call (id, List.map fold_cval fs)
| V_field (f, field) -> V_field (fold_cval f, field)
| V_tuple_member (f, len, n) -> V_tuple_member (fold_cval f, len, n)
@@ -685,7 +681,7 @@ let string_of_ssainstr = function
| Phi (id, ctyp, args) ->
string_of_name id ^ " : " ^ string_of_ctyp ctyp ^ " = &phi;(" ^ Util.string_of_list ", " string_of_name args ^ ")"
| Pi cvals ->
- "&pi;(" ^ Util.string_of_list ", " (fun v -> String.escaped (string_of_cval ~zencode:false v)) cvals ^ ")"
+ "&pi;(" ^ Util.string_of_list ", " (fun v -> String.escaped (string_of_cval v)) cvals ^ ")"
let string_of_phis = function
| [] -> ""
diff --git a/src/jib/jib_util.ml b/src/jib/jib_util.ml
index 575e1352..2825d466 100644
--- a/src/jib/jib_util.ml
+++ b/src/jib/jib_util.ml
@@ -161,14 +161,10 @@ let rec cval_rename from_id to_id = function
| V_ref (id, ctyp) -> V_ref (id, ctyp)
| V_lit (vl, ctyp) -> V_lit (vl, ctyp)
| V_call (call, cvals) -> V_call (call, List.map (cval_rename from_id to_id) cvals)
- | V_op (f1, op, f2) -> V_op (cval_rename from_id to_id f1, op, cval_rename from_id to_id f2)
- | V_unary (op, f) -> V_unary (op, cval_rename from_id to_id f)
| V_field (f, field) -> V_field (cval_rename from_id to_id f, field)
| V_tuple_member (f, len, n) -> V_tuple_member (cval_rename from_id to_id f, len, n)
| V_ctor_kind (f, ctor, unifiers, ctyp) -> V_ctor_kind (cval_rename from_id to_id f, ctor, unifiers, ctyp)
| V_ctor_unwrap (ctor, f, unifiers, ctyp) -> V_ctor_unwrap (ctor, cval_rename from_id to_id f, unifiers, ctyp)
- | V_hd cval -> V_hd (cval_rename from_id to_id cval)
- | V_tl cval -> V_tl (cval_rename from_id to_id cval)
| V_struct (fields, ctyp) ->
V_struct (List.map (fun (field, cval) -> field, cval_rename from_id to_id cval) fields, ctyp)
| V_poly (f, ctyp) -> V_poly (cval_rename from_id to_id f, ctyp)
@@ -279,46 +275,50 @@ let string_of_name ?deref_current_exception:(dce=true) ?zencode:(zencode=true) =
| Current_exception n ->
"current_exception" ^ ssa_num n
-let rec string_of_cval ?zencode:(zencode=true) = function
- | V_id (id, ctyp) -> string_of_name ~zencode:zencode id
- | V_ref (id, _) -> "&" ^ string_of_name ~zencode:zencode id
+let string_of_op = function
+ | Bnot -> "not"
+ | List_hd -> "hd"
+ | List_tl -> "tl"
+ | Bit_to_bool -> "bit_to_bool"
+ | Eq -> "eq"
+ | Neq -> "neq"
+ | Bvor -> "bvor"
+ | Bvand -> "bvand"
+ | Ilt -> "lt"
+ | Igt -> "gt"
+ | Ilteq -> "lteq"
+ | Igteq -> "gteq"
+ | Iadd -> "iadd"
+ | Isub -> "isub"
+ | Zero_extend n -> "zero_extend" ^ string_of_int n
+ | Sign_extend n -> "sign_extend" ^ string_of_int n
+
+let rec string_of_cval = function
+ | V_id (id, ctyp) -> string_of_name id
+ | V_ref (id, _) -> "&" ^ string_of_name id
| V_lit (vl, ctyp) -> string_of_value vl
- | V_call (str, cvals) ->
- Printf.sprintf "%s(%s)" str (Util.string_of_list ", " (string_of_cval ~zencode:zencode) cvals)
+ | V_call (op, cvals) ->
+ Printf.sprintf "%s(%s)" (string_of_op op) (Util.string_of_list ", " string_of_cval cvals)
| V_field (f, field) ->
- Printf.sprintf "%s.%s" (string_of_cval' ~zencode:zencode f) field
+ Printf.sprintf "%s.%s" (string_of_cval f) field
| V_tuple_member (f, _, n) ->
- Printf.sprintf "%s.ztup%d" (string_of_cval' ~zencode:zencode f) n
- | V_op (f1, op, f2) ->
- Printf.sprintf "%s %s %s" (string_of_cval' ~zencode:zencode f1) op (string_of_cval' ~zencode:zencode f2)
- | V_unary (op, f) ->
- op ^ string_of_cval' ~zencode:zencode f
- | V_hd f ->
- Printf.sprintf "(%s).hd" ("*" ^ string_of_cval' ~zencode:zencode f)
- | V_tl f ->
- Printf.sprintf "(%s).tl" ("*" ^ string_of_cval' ~zencode:zencode f)
+ Printf.sprintf "%s.ztup%d" (string_of_cval f) n
| V_ctor_kind (f, ctor, [], _) ->
- string_of_cval' ~zencode:zencode f ^ ".kind"
+ string_of_cval f ^ ".kind"
^ " != Kind_" ^ Util.zencode_string (string_of_id ctor)
| V_ctor_kind (f, ctor, unifiers, _) ->
- string_of_cval' ~zencode:zencode f ^ ".kind"
+ string_of_cval f ^ ".kind"
^ " != Kind_" ^ Util.zencode_string (string_of_id ctor ^ "_" ^ Util.string_of_list "_" string_of_ctyp unifiers)
| V_ctor_unwrap (ctor, f, [], _) ->
- Printf.sprintf "%s.%s"
- (string_of_cval' ~zencode:zencode f)
- (Util.zencode_string (string_of_id ctor))
+ Printf.sprintf "%s.%s" (string_of_cval f) (string_of_id ctor)
| V_struct (fields, _) ->
Printf.sprintf "{%s}"
- (Util.string_of_list ", " (fun (field, cval) -> string_of_id field ^ " = " ^ string_of_cval' ~zencode:zencode cval) fields)
+ (Util.string_of_list ", " (fun (field, cval) -> string_of_id field ^ " = " ^ string_of_cval cval) fields)
| V_ctor_unwrap (ctor, f, unifiers, _) ->
Printf.sprintf "%s.%s"
- (string_of_cval' ~zencode:zencode f)
+ (string_of_cval f)
(Util.zencode_string (string_of_id ctor ^ "_" ^ Util.string_of_list "_" string_of_ctyp unifiers))
- | V_poly (f, _) -> string_of_cval ~zencode:zencode f
-and string_of_cval' ?zencode:(zencode=true) f =
- match f with
- | V_op _ | V_unary _ -> "(" ^ string_of_cval ~zencode:zencode f ^ ")"
- | _ -> string_of_cval ~zencode:zencode f
+ | V_poly (f, _) -> string_of_cval f
(* String representation of ctyps here is only for debugging and
intermediate language pretty-printer. *)
@@ -535,8 +535,6 @@ let rec unpoly = function
| V_poly (cval, _) -> unpoly cval
| V_call (call, cvals) -> V_call (call, List.map unpoly cvals)
| V_field (cval, field) -> V_field (unpoly cval, field)
- | V_op (cval1, op, cval2) -> V_op (unpoly cval1, op, unpoly cval2)
- | V_unary (op, cval) -> V_unary (op, unpoly cval)
| cval -> cval
let rec is_polymorphic = function
@@ -560,7 +558,7 @@ let pp_keyword str =
string ((str |> Util.red |> Util.clear) ^ " ")
let pp_cval cval =
- string (string_of_cval ~zencode:false cval)
+ string (string_of_cval cval)
let rec pp_clexp = function
| CL_id (id, ctyp) -> pp_name id ^^ string " : " ^^ pp_ctyp ctyp
@@ -670,12 +668,10 @@ let pp_cdef = function
let rec cval_deps = function
| V_id (id, _) | V_ref (id, _) -> NameSet.singleton id
| V_lit _ -> NameSet.empty
- | V_field (cval, _) | V_unary (_, cval) | V_poly (cval, _) | V_tuple_member (cval, _, _) -> cval_deps cval
+ | V_field (cval, _) | V_poly (cval, _) | V_tuple_member (cval, _, _) -> cval_deps cval
| V_call (_, cvals) -> List.fold_left NameSet.union NameSet.empty (List.map cval_deps cvals)
- | V_op (cval1, _, cval2) -> NameSet.union (cval_deps cval1) (cval_deps cval2)
| V_ctor_kind (cval, _, _, _) -> cval_deps cval
| V_ctor_unwrap (_, cval, _, _) -> cval_deps cval
- | V_hd cval | V_tl cval -> cval_deps cval
| V_struct (fields, ctyp) -> List.fold_left (fun ns (_, cval) -> NameSet.union ns (cval_deps cval)) NameSet.empty fields
let rec clexp_deps = function
@@ -750,22 +746,15 @@ let rec map_cval_ctyp f = function
V_ctor_kind (map_cval_ctyp f cval, id, List.map f unifiers, f ctyp)
| V_ctor_unwrap (id, cval, unifiers, ctyp) ->
V_ctor_unwrap (id, map_cval_ctyp f cval, List.map f unifiers, f ctyp)
- | V_op (cval1, op, cval2) ->
- V_op (map_cval_ctyp f cval1, op, map_cval_ctyp f cval2)
| V_tuple_member (cval, i, j) ->
V_tuple_member (map_cval_ctyp f cval, i, j)
- | V_unary (op, cval) ->
- V_unary (op, map_cval_ctyp f cval)
| V_call (op, cvals) ->
V_call (op, List.map (map_cval_ctyp f) cvals)
| V_field (cval, field) ->
V_field (map_cval_ctyp f cval, field)
- | V_hd cval -> V_hd (map_cval_ctyp f cval)
- | V_tl cval -> V_tl (map_cval_ctyp f cval)
| V_struct (fields, ctyp) -> V_struct (List.map (fun (id, cval) -> id, map_cval_ctyp f cval) fields, f ctyp)
| V_poly (cval, ctyp) -> V_poly (map_cval_ctyp f cval, f ctyp)
-
let rec map_instr_ctyp f (I_aux (instr, aux)) =
let instr = match instr with
| I_decl (ctyp, id) -> I_decl (f ctyp, id)
@@ -890,26 +879,32 @@ let label str =
incr label_counter;
str
-let rec infer_unary v = function
- | "!" -> CT_bool
- | op -> Reporting.unreachable Parse_ast.Unknown __POS__ ("Could not infer unary " ^ op)
-
-and infer_op v1 v2 = function
- | "==" -> CT_bool
- | "!=" -> CT_bool
- | ">=" -> CT_bool
- | "<=" -> CT_bool
- | ">" -> CT_bool
- | "<" -> CT_bool
- | "+" -> cval_ctyp v1
- | "-" -> cval_ctyp v1
- | "|" -> cval_ctyp v1
- | "&" -> cval_ctyp v1
- | op -> Reporting.unreachable Parse_ast.Unknown __POS__ ("Cannot infer binary op: " ^ op)
-
-and infer_call vs = function
- | "bit_to_bool" -> CT_bool
- | op -> Reporting.unreachable Parse_ast.Unknown __POS__ ("Cannot infer call: " ^ op)
+let rec infer_call op vs =
+ match op, vs with
+ | Bit_to_bool, _ -> CT_bool
+ | Bnot, _ -> CT_bool
+ | List_hd, [v] ->
+ begin match cval_ctyp v with
+ | CT_list ctyp -> ctyp
+ | _ -> Reporting.unreachable Parse_ast.Unknown __POS__ "Invalid call to hd"
+ end
+ | List_tl, [v] ->
+ begin match cval_ctyp v with
+ | CT_list ctyp -> CT_list ctyp
+ | _ -> Reporting.unreachable Parse_ast.Unknown __POS__ "Invalid call to tl"
+ end
+ | (Eq | Neq), _ -> CT_bool
+ | (Bvor | Bvand), [v; _] -> cval_ctyp v
+ | (Ilt | Igt | Ilteq | Igteq), _ -> CT_bool
+ | (Iadd | Isub), _ -> CT_fint 64
+ | (Zero_extend n | Sign_extend n), [v] ->
+ begin match cval_ctyp v with
+ | CT_fbits (_, ord) | CT_sbits (_, ord) | CT_lbits ord ->
+ CT_fbits (n, ord)
+ | _ -> Reporting.unreachable Parse_ast.Unknown __POS__ "Invalid type for zero/sign_extend argument"
+ end
+ | _, _ ->
+ Reporting.unreachable Parse_ast.Unknown __POS__ ("Invalid call to function " ^ string_of_op op)
and cval_ctyp = function
| V_id (_, ctyp) -> ctyp
@@ -917,14 +912,6 @@ and cval_ctyp = function
| V_lit (vl, ctyp) -> ctyp
| V_ctor_kind _ -> CT_bool
| V_ctor_unwrap (ctor, cval, unifiers, ctyp) -> ctyp
- | V_hd v ->
- begin match cval_ctyp v with
- | CT_list ctyp -> ctyp
- | ctyp -> Reporting.unreachable Parse_ast.Unknown __POS__ ("Invalid list type " ^ full_string_of_ctyp ctyp)
- end
- | V_tl v -> cval_ctyp v
- | V_op (v1, op, v2) -> infer_op v1 v2 op
- | V_unary (op, v) -> infer_unary v op
| V_poly (_, ctyp) -> ctyp
| V_tuple_member (cval, _, n) ->
begin match cval_ctyp cval with
@@ -942,7 +929,7 @@ and cval_ctyp = function
| ctyp -> Reporting.unreachable Parse_ast.Unknown __POS__ ("Inavlid type for V_field " ^ full_string_of_ctyp ctyp)
end
| V_struct (fields, ctyp) -> ctyp
- | V_call (op, vs) -> infer_call vs op
+ | V_call (op, vs) -> infer_call op vs
let rec clexp_ctyp = function
| CL_id (_, ctyp) -> ctyp
diff --git a/src/property.ml b/src/property.ml
index 84e9d734..9ef546a2 100644
--- a/src/property.ml
+++ b/src/property.ml
@@ -80,7 +80,7 @@ let add_property_guards props (Defs defs) =
let add_constraints_to_funcl (FCL_aux (FCL_Funcl (id, Pat_aux (pexp, pexp_aux)), fcl_aux)) =
let add_guard exp =
(* FIXME: Use an assert *)
- let exp' = mk_exp (E_block [mk_exp (E_app (mk_id "__assume", [mk_exp (E_constraint (List.fold_left nc_and nc_true constraints))]));
+ let exp' = mk_exp (E_block [mk_exp (E_app (mk_id "sail_assume", [mk_exp (E_constraint (List.fold_left nc_and nc_true constraints))]));
strip_exp exp])
in
try Type_check.check_exp (env_of exp) exp' (typ_of exp) with
diff --git a/src/smtlib.ml b/src/smtlib.ml
index d17cb4d9..65e73791 100644
--- a/src/smtlib.ml
+++ b/src/smtlib.ml
@@ -373,13 +373,17 @@ let build_counterexample args arg_ctyps arg_smt_names model =
let rec run frame =
match frame with
- | Interpreter.Done (state, v) -> v
+ | Interpreter.Done (state, v) -> Some v
| Interpreter.Step (lazy_str, _, _, _) ->
run (Interpreter.eval_frame frame)
| Interpreter.Break frame ->
run (Interpreter.eval_frame frame)
+ | Interpreter.Fail (_, _, _, _, msg) ->
+ None
+ | Interpreter.Effect_request (out, state, stack, eff) ->
+ run (Interpreter.default_effect_interp state eff)
-let check_counterexample ast env fname args arg_ctyps arg_smt_names =
+let check_counterexample ast env fname function_id args arg_ctyps arg_smt_names =
let open Printf in
prerr_endline ("Checking counterexample: " ^ fname);
let in_chan = ksprintf Unix.open_process_in "cvc4 --lang=smt2.6 %s" fname in
@@ -402,15 +406,15 @@ let check_counterexample ast env fname args arg_ctyps arg_smt_names =
List.iter (fun (id, v) -> prerr_endline (" " ^ string_of_id id ^ " -> " ^ string_of_value v)) counterexample;
let istate = initial_state ast env primops in
let annot = (Parse_ast.Unknown, Type_check.mk_tannot env bool_typ no_effect) in
- let call = E_aux (E_app (mk_id "prop", List.map (fun (_, v) -> E_aux (E_internal_value v, (Parse_ast.Unknown, Type_check.empty_tannot))) counterexample), annot) in
+ let call = E_aux (E_app (function_id, List.map (fun (_, v) -> E_aux (E_internal_value v, (Parse_ast.Unknown, Type_check.empty_tannot))) counterexample), annot) in
let result = run (Step (lazy "", istate, return call, [])) in
begin match result with
- | V_bool false ->
+ | Some (V_bool false) | None ->
ksprintf prerr_endline "Replaying counterexample: %s" Util.("ok" |> green |> clear)
| _ -> ()
end
| _ ->
- prerr_endline "failure"
+ prerr_endline "Solver could not find counterexample"
end;
let status = Unix.close_process_in in_chan in
()
diff --git a/src/type_check.ml b/src/type_check.ml
index c0560a83..5fa2b377 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -5062,6 +5062,6 @@ let initial_env =
(app_typ (mk_id "itself") [mk_typ_arg (A_nexp (nvar (mk_kid "n")))]) no_effect)
(* __assume is used by property.ml to add guards for SMT generation,
but which don't affect flow-typing. *)
- |> Env.add_val_spec (mk_id "__assume")
+ |> Env.add_val_spec (mk_id "sail_assume")
(TypQ_aux (TypQ_no_forall, Parse_ast.Unknown),
function_typ [bool_typ] unit_typ no_effect)