summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jib/jib_smt.ml32
1 files changed, 17 insertions, 15 deletions
diff --git a/src/jib/jib_smt.ml b/src/jib/jib_smt.ml
index ee2e7fc9..230e9e07 100644
--- a/src/jib/jib_smt.ml
+++ b/src/jib/jib_smt.ml
@@ -55,6 +55,7 @@ open Jib
open Jib_util
open Smtlib
+module IntSet = Set.Make(struct type t = int let compare = compare end)
module IntMap = Map.Make(struct type t = int let compare = compare end)
let zencode_upper_id id = Util.zencode_upper_string (string_of_id id)
@@ -74,6 +75,8 @@ type ctx = {
We need to take care that vector_index is large enough for all generic vectors. *)
vector_index : int;
register_map : id list CTMap.t;
+ (* Keep track of all the tuple sizes we need to genenerate types for *)
+ mutable tuple_sizes : IntSet.t;
tc_env : Type_check.Env.t;
pragma_l : Ast.l;
arg_stack : (int * string) Stack.t;
@@ -93,6 +96,7 @@ let initial_ctx () = {
lint_size = !opt_default_lint_size;
vector_index = !opt_default_vector_index;
register_map = CTMap.empty;
+ tuple_sizes = IntSet.empty;
tc_env = Type_check.initial_env;
pragma_l = Parse_ast.Unknown;
arg_stack = Stack.create ();
@@ -133,7 +137,9 @@ let rec smt_ctyp ctx = function
mk_record (zencode_upper_id id) (List.map (fun (id, ctyp) -> (zencode_id id, smt_ctyp ctx ctyp)) fields)
| CT_variant (id, ctors) ->
mk_variant (zencode_upper_id id) (List.map (fun (id, ctyp) -> (zencode_id id, smt_ctyp ctx ctyp)) ctors)
- | CT_tup ctyps -> Tuple (List.map (smt_ctyp ctx) ctyps)
+ | CT_tup ctyps ->
+ ctx.tuple_sizes <- IntSet.add (List.length ctyps) ctx.tuple_sizes;
+ Tuple (List.map (smt_ctyp ctx) ctyps)
| CT_vector (_, ctyp) -> Array (Bitvec !vector_index, smt_ctyp ctx ctyp)
| CT_string -> Bitvec 64
| CT_ref ctyp ->
@@ -254,6 +260,7 @@ let rec smt_cval ctx cval =
| _ -> failwith "Struct does not have struct type"
end
| V_tuple_member (frag, len, n) ->
+ ctx.tuple_sizes <- IntSet.add len ctx.tuple_sizes;
Fn (Printf.sprintf "tup_%d_%d" len n, [smt_cval ctx frag])
| V_ref (Name (id, _), _) ->
let rmap = CTMap.filter (fun ctyp regs -> List.exists (fun reg -> Id.compare reg id = 0) regs) ctx.register_map in
@@ -1403,20 +1410,15 @@ let optimize_smt stack =
(** [smt_header stack cdefs] pushes all the type declarations required
for cdefs onto the SMT stack *)
-let smt_header ctx stack cdefs =
- push_smt_defs stack
- [declare_datatypes (mk_enum "Unit" ["unit"]);
- Declare_tuple 2;
- Declare_tuple 3;
- Declare_tuple 4;
- Declare_tuple 5;
- Declare_tuple 6;
- declare_datatypes (mk_record "Bits" [("len", Bitvec ctx.lbits_index);
+let smt_header ctx cdefs =
+ let smt_ctype_defs = List.concat (generate_ctype_defs ctx cdefs) in
+ [declare_datatypes (mk_enum "Unit" ["unit"])]
+ @ (IntSet.elements ctx.tuple_sizes |> List.map (fun n -> Declare_tuple n))
+ @ [declare_datatypes (mk_record "Bits" [("len", Bitvec ctx.lbits_index);
("contents", Bitvec (lbits_size ctx))])
- ];
- let smt_type_defs = List.concat (generate_ctype_defs ctx cdefs) in
- push_smt_defs stack smt_type_defs
+ ]
+ @ smt_ctype_defs
(* For generating SMT when we have a reg_deref(r : register(t))
function, we have to expand it into a if-then-else cascade that
@@ -1480,8 +1482,6 @@ let smt_cdef props lets name_file ctx all_cdefs = function
let stack = Stack.create () in
- smt_header ctx stack all_cdefs;
-
Stack.clear overflow_checks;
let ctx = { ctx with pragma_l = pragma_l; arg_stack = Stack.create () } in
@@ -1536,6 +1536,8 @@ let smt_cdef props lets name_file ctx all_cdefs = function
output_string out_chan "(set-option :produce-models true)\n";
output_string out_chan "(set-logic QF_AUFBVDT)\n";
+ List.iter (fun def -> output_string out_chan (string_of_smt_def def); output_string out_chan "\n") (smt_header ctx all_cdefs);
+
let queue = optimize_smt stack in
Queue.iter (fun def -> output_string out_chan (string_of_smt_def def); output_string out_chan "\n") queue;