diff options
| -rw-r--r-- | src/jib/jib_smt.ml | 290 | ||||
| -rw-r--r-- | src/sail.ml | 6 | ||||
| -rw-r--r-- | src/smtlib.ml | 8 | ||||
| -rw-r--r-- | test/smt/arith.unsat.sail | 33 | ||||
| -rw-r--r-- | test/smt/arith_C128FL.unsat.sail | 34 | ||||
| -rw-r--r-- | test/smt/arith_C64C32CB.unsat.sail | 25 | ||||
| -rw-r--r-- | test/smt/arith_FFL_1.unsat.sail | 12 | ||||
| -rw-r--r-- | test/smt/arith_FFL_2.unsat.sail | 21 | ||||
| -rw-r--r-- | test/smt/arith_FFL_3.unsat.sail | 19 | ||||
| -rw-r--r-- | test/smt/arith_FFL_4.unsat.sail | 12 | ||||
| -rw-r--r-- | test/smt/arith_LC32L.unsat.sail | 27 | ||||
| -rw-r--r-- | test/smt/arith_LCBL.unsat.sail | 33 | ||||
| -rw-r--r-- | test/smt/arith_LFL.unsat.sail | 33 | ||||
| -rwxr-xr-x | test/smt/run_tests.py | 2 | ||||
| -rw-r--r-- | test/smt/rv_add_0.sat.sail | 2 | ||||
| -rw-r--r-- | test/smt/rv_add_0.unsat.sail | 2 |
16 files changed, 435 insertions, 124 deletions
diff --git a/src/jib/jib_smt.ml b/src/jib/jib_smt.ml index af2c7284..35a5bcb8 100644 --- a/src/jib/jib_smt.ml +++ b/src/jib/jib_smt.ml @@ -55,6 +55,8 @@ open Jib open Jib_util open Smtlib +let ignore_overflow = ref false + let zencode_upper_id id = Util.zencode_upper_string (string_of_id id) let zencode_id id = Util.zencode_string (string_of_id id) let zencode_name id = string_of_name ~deref_current_exception:false ~zencode:true id @@ -68,12 +70,15 @@ let lint_size = ref 128 let smt_unit = mk_enum "Unit" ["Unit"] let smt_lbits = mk_record "Bits" [("size", Bitvec !lbits_index); ("bits", Bitvec (lbits_size ()))] -let rec required_width n = - if Big_int.equal n Big_int.zero then - 1 - else - 1 + required_width (Big_int.shift_right n 1) - +let required_width n = + let rec required_width' n = + if Big_int.equal n Big_int.zero then + 1 + else + 1 + required_width' (Big_int.shift_right n 1) + in + required_width' (Big_int.abs n) + let rec smt_ctyp = function | CT_constant n -> Bitvec (required_width n) | CT_fint n -> Bitvec n @@ -95,7 +100,7 @@ let rec smt_ctyp = function | CT_string -> Bitvec 64 | ctyp -> failwith ("Unhandled ctyp: " ^ string_of_ctyp ctyp) -let bvint sz x = +let bvpint sz x = if Big_int.less_equal Big_int.zero x && Big_int.less_equal x (Big_int.of_int max_int) then ( let open Sail_lib in let x = Big_int.to_int x in @@ -111,19 +116,29 @@ let bvint sz x = Bin (padding ^ bin) ) else if Big_int.greater x (Big_int.of_int max_int) then ( let open Sail_lib in - let x = ref x in + let y = ref x in let bin = ref [] in - while (not (Big_int.equal !x Big_int.zero)) do - let (q, m) = Big_int.quomod !x (Big_int.of_int 2) in + while (not (Big_int.equal !y Big_int.zero)) do + let (q, m) = Big_int.quomod !y (Big_int.of_int 2) in bin := (if Big_int.equal m Big_int.zero then B0 else B1) :: !bin; - x := q + y := q done; let bin = String.concat "" (List.map string_of_bit !bin) in + let padding_size = sz - String.length bin in + if padding_size < 0 then + raise (Reporting.err_general Parse_ast.Unknown + (Printf.sprintf "Count not create a %d-bit integer with value %s.\nTry increasing the maximum integer size" + sz (Big_int.to_string x))); let padding = String.make (sz - String.length bin) '0' in Bin (padding ^ bin) - ) else - failwith "Invalid bvint" + ) else failwith "Invalid bvpint" +let bvint sz x = + if Big_int.less x Big_int.zero then + Fn ("bvadd", [Fn ("bvnot", [bvpint sz (Big_int.abs x)]); bvpint sz (Big_int.of_int 1)]) + else + bvpint sz x + let smt_value vl ctyp = let open Value2 in match vl, ctyp with @@ -179,8 +194,117 @@ let rec smt_cval env cval = let overflow_checks = Stack.create () let overflow_check smt = - Stack.push (Define_const ("overflow" ^ string_of_int (Stack.length overflow_checks), Bool, Fn ("not", [smt]))) overflow_checks + if not !ignore_overflow then ( + Util.warn "Adding overflow check in generated SMT"; + Stack.push (Define_const ("overflow" ^ string_of_int (Stack.length overflow_checks), Bool, Fn ("not", [smt]))) overflow_checks + ) + +let builtin_type_error fn cvals = + let args = Util.string_of_list ", " (fun cval -> string_of_ctyp (cval_ctyp cval)) cvals in + function + | Some ret_ctyp -> + Reporting.unreachable Parse_ast.Unknown __POS__ + (Printf.sprintf "%s : (%s) -> %s" fn args (string_of_ctyp ret_ctyp)) + | None -> + Reporting.unreachable Parse_ast.Unknown __POS__ (Printf.sprintf "%s : (%s)" fn args) +(* ***** Basic comparisons: lib/flow.sail ***** *) + +let builtin_int_comparison fn big_int_fn env v1 v2 = + match cval_ctyp v1, cval_ctyp v2 with + | CT_lint, CT_lint -> + Fn (fn, [smt_cval env v1; smt_cval env v2]) + | CT_fint sz1, CT_fint sz2 -> + if sz1 == sz2 then + Fn (fn, [smt_cval env v1; smt_cval env v2]) + else if sz1 > sz2 then + Fn (fn, [smt_cval env v1; SignExtend (sz1 - sz2, smt_cval env v2)]) + else + Fn (fn, [SignExtend (sz2 - sz1, smt_cval env v1); smt_cval env v2]) + | CT_constant c, CT_fint sz -> + Fn (fn, [bvint sz c; smt_cval env v2]) + | CT_constant c, CT_lint -> + Fn (fn, [bvint !lint_size c; smt_cval env v2]) + | CT_fint sz, CT_constant c -> + Fn (fn, [smt_cval env v1; bvint sz c]) + | CT_lint, CT_constant c -> + Fn (fn, [smt_cval env v1; bvint !lint_size c]) + | CT_constant c1, CT_constant c2 -> + Bool_lit (big_int_fn c1 c2) + | _, _ -> builtin_type_error fn [v1; v2] None + +let builtin_eq_int = builtin_int_comparison "=" Big_int.equal + +let builtin_lt = builtin_int_comparison "bvslt" Big_int.less +let builtin_lteq = builtin_int_comparison "bvsle" Big_int.less_equal +let builtin_gt = builtin_int_comparison "bvsgt" Big_int.greater +let builtin_gteq = builtin_int_comparison "bvsge" Big_int.greater_equal + +(* ***** Arithmetic operations: lib/arith.sail ***** *) + +(** [force_size n m exp] takes a smt expression assumed to be a + integer (signed bitvector) of length m and forces it to be length n + by either sign extending it or truncating it as required *) +let force_size n m smt = + if n = m then + smt + else if n > m then + SignExtend (n - m, smt) + else + let check = + (* If the top bit of the truncated number is one *) + Ite (Fn ("=", [Extract (n - 1, n - 1, smt); Bin "1"]), + (* Then we have an overflow, unless all bits we truncated were also one *) + Fn ("not", [Fn ("=", [Extract (m - 1, n, smt); bvones (m - n)])]), + (* Otherwise, all the top bits must be zero *) + Fn ("not", [Fn ("=", [Extract (m - 1, n, smt); bvzero (m - n)])])) + in + overflow_check check; + Extract (n - 1, 0, smt) + +let int_size = function + | CT_constant n -> required_width n + | CT_fint sz -> sz + | CT_lint -> !lint_size + | _ -> Reporting.unreachable Parse_ast.Unknown __POS__ "Argument to int_size must be an integer type" + +let builtin_arith fn big_int_fn padding env v1 v2 ret_ctyp = + let padding = if !ignore_overflow then (fun x -> x) else padding in + match cval_ctyp v1, cval_ctyp v2, ret_ctyp with + | _, _, CT_constant c -> + bvint (required_width c) c + | CT_constant c1, CT_constant c2, _ -> + bvint (int_size ret_ctyp) (big_int_fn c1 c2) + + | ctyp, CT_constant c, _ -> + let n = int_size ctyp in + force_size (int_size ret_ctyp) n (Fn (fn, [smt_cval env v1; bvint n c])) + | CT_constant c, ctyp, _ -> + let n = int_size ctyp in + force_size (int_size ret_ctyp) n (Fn (fn, [bvint n c; smt_cval env v2])) + + | ctyp1, ctyp2, _ -> + let ret_sz = int_size ret_ctyp in + let smt1 = smt_cval env v1 in + let smt2 = smt_cval env v2 in + force_size ret_sz (padding ret_sz) (Fn (fn, [force_size (padding ret_sz) (int_size ctyp1) smt1; + force_size (padding ret_sz) (int_size ctyp2) smt2])) + +let builtin_add_int = builtin_arith "bvadd" Big_int.add (fun x -> x + 1) +let builtin_sub_int = builtin_arith "bvsub" Big_int.sub (fun x -> x + 1) +let builtin_mult_int = builtin_arith "bvmul" Big_int.mul (fun x -> x * 2) + +let builtin_negate_int env v ret_ctyp = + match cval_ctyp v, ret_ctyp with + | _, CT_constant c -> + bvint (required_width c) c + | CT_constant c, _ -> + bvint (int_size ret_ctyp) (Big_int.negate c) + | ctyp, _ -> + let smt = force_size (int_size ret_ctyp) (int_size ctyp) (smt_cval env v) in + overflow_check (Fn ("=", [smt; Bin ("1" ^ String.make (int_size ret_ctyp - 1) '0')])); + Fn ("bvneg", [smt]) + let builtin_zeros env cval = function | CT_fbits (n, _) -> bvzero n | CT_lbits _ -> Fn ("Bits", [extract (!lbits_index - 1) 0 (smt_cval env cval); bvzero (lbits_size ())]) @@ -205,12 +329,6 @@ let builtin_sign_extend env vbits vlen ret_ctyp = Ite (top_bit_one, Fn ("concat", [bvones (m - n); bv]), Fn ("concat", [bvzero (m - n); bv])) | _ -> failwith "Cannot compile zero_extend" -let int_size = function - | CT_constant n -> required_width n - | CT_fint sz -> sz - | CT_lint -> lbits_size () - | _ -> failwith "Argument to int_size must be an integer" - (* [bvzeint esz cval] (BitVector Zero Extend INTeger), takes a cval which must be an integer type (either CT_fint, or CT_lint), and produces a bitvector which is either zero extended or truncated to @@ -343,45 +461,6 @@ let builtin_unsigned env v ret_ctyp = | ctyp, _ -> failwith (Printf.sprintf "Cannot compile unsigned : %s -> %s" (string_of_ctyp ctyp) (string_of_ctyp ret_ctyp)) -let builtin_eq_int env v1 v2 = - match cval_ctyp v1, cval_ctyp v2 with - | CT_fint m, CT_constant c -> - Fn ("=", [smt_cval env v1; bvint m c]) - - | CT_lint, CT_constant c -> - Fn ("=", [smt_cval env v1; bvint !lint_size c]) - - | CT_lint, CT_lint -> - Fn ("=", [smt_cval env v1; smt_cval env v2]) - - | _ -> failwith "Cannot compile eq_int" - -let builtin_add_int env v1 v2 ret_ctyp = - match cval_ctyp v1, cval_ctyp v2, ret_ctyp with - | CT_fint n, CT_constant c, CT_fint m when n = m -> - Fn ("bvadd", [smt_cval env v1; bvint n c]) - - | _ -> failwith "Cannot compile add_int" - -let builtin_sub_int env v1 v2 ret_ctyp = - match cval_ctyp v1, cval_ctyp v2, ret_ctyp with - | CT_fint n, CT_constant c, CT_fint m when n = m -> - Fn ("bvadd", [smt_cval env v1; Fn ("bvneg", [bvint n c])]) - - | CT_fint n, CT_fint m, CT_fint o when n = m && m = o -> - Fn ("bvadd", [smt_cval env v1; Fn ("bvneg", [smt_cval env v2])]) - - | _ -> failwith "Cannot compile add_int" - -let builtin_neg_int env v ret_ctyp = - match cval_ctyp v, ret_ctyp with - | CT_lint, CT_lint -> - let smt = smt_cval env v in - overflow_check (Fn ("=", [smt; Bin ("1" ^ String.make (!lint_size - 1) '0')])); - Fn ("bvneg", [smt]) - - | _ -> failwith "Cannot compile neg_int" - let builtin_add_bits env v1 v2 ret_ctyp = match cval_ctyp v1, cval_ctyp v2, ret_ctyp with | CT_fbits (n, _), CT_fbits (m, _), CT_fbits (o, _) -> @@ -435,69 +514,33 @@ let builtin_sail_truncateLSB env v1 v2 ret_ctyp = | _ -> failwith "Cannot compile sail_truncate" -let builtin_lt env v1 v2 = - match cval_ctyp v1, cval_ctyp v2 with - | CT_lint, CT_lint -> - Fn ("bvslt", [smt_cval env v1; smt_cval env v2]) - - | CT_constant c, CT_fint sz -> - Fn ("bvslt", [bvint sz c; smt_cval env v2]) - | CT_constant c, CT_lint -> - Fn ("bvslt", [bvint !lint_size c; smt_cval env v2]) - - | CT_fint sz, CT_constant c -> - Fn ("bvslt", [smt_cval env v1; bvint sz c]) - | CT_lint, CT_constant c -> - Fn ("bvslt", [smt_cval env v1; bvint !lint_size c]) - - | t1, t2 -> failwith (Printf.sprintf "Cannot compile lt (%s, %s)" (string_of_ctyp t1) (string_of_ctyp t2)) - -let builtin_lteq env v1 v2 = - match cval_ctyp v1, cval_ctyp v2 with - | CT_lint, CT_lint -> - (* Use or rather than v1 < v2 + 1 to avoid overflow *) - Fn ("or", [Fn ("=", [smt_cval env v1; smt_cval env v2]); - Fn ("bvslt", [smt_cval env v1; smt_cval env v2])]) - - | CT_constant c, CT_fint sz when Big_int.greater c Big_int.zero -> - Fn ("bvslt", [bvint sz (Big_int.pred c); smt_cval env v2]) - - | CT_lint, CT_constant c when Big_int.greater c Big_int.zero -> - Fn ("bvslt", [smt_cval env v1; bvint !lint_size (Big_int.pred c)]) - - | t1, t2 -> failwith (Printf.sprintf "Cannot compile lteq (%s, %s)" (string_of_ctyp t1) (string_of_ctyp t2)) +let builtin_count_leading_zeros env v ret_ctyp = + match cval_ctyp v, ret_ctyp with + | _, _ -> failwith "CLZ" -let builtin_gt env v1 v2 = builtin_lt env v2 v1 +let smt_builtin env name args ret_ctyp = + match name, args, ret_ctyp with + | "eq_bits", [v1; v2], _ -> Fn ("=", [smt_cval env v1; smt_cval env v2]) + | "eq_anything", [v1; v2], CT_bool -> Fn ("=", [smt_cval env v1; smt_cval env v2]) -let builtin_gteq env v1 v2 = builtin_lteq env v2 v1 + (* lib/flow.sail *) + | "eq_bit", [v1; v2], CT_bool -> Fn ("=", [smt_cval env v1; smt_cval env v2]) + | "eq_bool", [v1; v2], CT_bool -> Fn ("=", [smt_cval env v1; smt_cval env v2]) + | "eq_unit", [v1; v2], CT_bool -> Fn ("=", [smt_cval env v1; smt_cval env v2]) -let smt_primop env name args ret_ctyp = - match name, args, ret_ctyp with - | "eq_bits", [v1; v2], _ -> - let smt1 = smt_cval env v1 in - let smt2 = smt_cval env v2 in - Fn ("=", [smt1; smt2]) - | "eq_bit", [v1; v2], _ -> - let smt1 = smt_cval env v1 in - let smt2 = smt_cval env v2 in - Fn ("=", [smt1; smt2]) - | "eq_bool", [v1; v2], _ -> - let smt1 = smt_cval env v1 in - let smt2 = smt_cval env v2 in - Fn ("=", [smt1; smt2]) - | "eq_anything", [v1; v2], _ -> - let smt1 = smt_cval env v1 in - let smt2 = smt_cval env v2 in - Fn ("=", [smt1; smt2]) + | "eq_int", [v1; v2], CT_bool -> builtin_eq_int env v1 v2 | "not", [v], _ -> Fn ("not", [smt_cval env v]) - | "lt", [v1; v2], _ -> builtin_lt env v1 v2 + | "lt", [v1; v2], _ -> builtin_lt env v1 v2 | "lteq", [v1; v2], _ -> builtin_lteq env v1 v2 - | "gt", [v1; v2], _ -> builtin_gt env v1 v2 + | "gt", [v1; v2], _ -> builtin_gt env v1 v2 | "gteq", [v1; v2], _ -> builtin_gteq env v1 v2 + + (* lib/arith.sail *) | "add_int", [v1; v2], _ -> builtin_add_int env v1 v2 ret_ctyp | "sub_int", [v1; v2], _ -> builtin_sub_int env v1 v2 ret_ctyp - | "neg_int", [v], _ -> builtin_neg_int env v ret_ctyp + | "mult_int", [v1; v2], _ -> builtin_mult_int env v1 v2 ret_ctyp + | "neg_int", [v], _ -> builtin_negate_int env v ret_ctyp | "zeros", [v1], _ -> builtin_zeros env v1 ret_ctyp | "zero_extend", [v1; v2], _ -> builtin_zero_extend env v1 v2 ret_ctyp @@ -519,7 +562,7 @@ let smt_primop env name args ret_ctyp = | "replicate_bits", [v1; v2], ret_ctyp -> builtin_replicate_bits env v1 v2 ret_ctyp | "eq_int", [v1; v2], _ -> builtin_eq_int env v1 v2 - | _ -> failwith ("Bad primop " ^ name ^ " " ^ Util.string_of_list ", " string_of_ctyp (List.map cval_ctyp args) ^ " -> " ^ string_of_ctyp ret_ctyp) + | _ -> failwith ("Bad builtin " ^ name ^ " " ^ Util.string_of_list ", " string_of_ctyp (List.map cval_ctyp args) ^ " -> " ^ string_of_ctyp ret_ctyp) let rec smt_conversion from_ctyp to_ctyp x = match from_ctyp, to_ctyp with @@ -825,7 +868,7 @@ let smt_instr env = | I_aux (I_funcall (CL_id (id, ret_ctyp), _, function_id, args), _) -> if Env.is_extern function_id env "c" then let name = Env.get_extern function_id env "c" in - let value = smt_primop env name args ret_ctyp in + let value = smt_builtin env name args ret_ctyp in [define_const id ret_ctyp value] else let smt_args = List.map (smt_cval env) args in @@ -844,10 +887,13 @@ let smt_instr env = [declare_const id ctyp] | I_aux (I_end id, _) -> - let checks = - Stack.fold (fun checks -> function (Define_const (name, _, _) as def) -> (name, def) :: checks | _ -> assert false) [] overflow_checks - in - List.map snd checks @ [Assert (Fn ("and", Fn ("not", [Var (zencode_name id)]) :: List.map (fun check -> Var (fst check)) checks))] + if !ignore_overflow then + [Assert (Fn ("not", [Var (zencode_name id)]))] + else + let checks = + Stack.fold (fun checks -> function (Define_const (name, _, _) as def) -> (name, def) :: checks | _ -> assert false) [] overflow_checks + in + List.map snd checks @ [Assert (Fn ("and", Fn ("not", [Var (zencode_name id)]) :: List.map (fun check -> Var (fst check)) checks))] | I_aux (I_clear _, _) -> [] @@ -894,7 +940,7 @@ let optimize_smt stack = List.iter uses_in_exp exps | Ite (cond, t, e) -> uses_in_exp cond; uses_in_exp t; uses_in_exp e - | Extract (_, _, exp) | Tester (_, exp) -> + | Extract (_, _, exp) | Tester (_, exp) | SignExtend (_, exp) -> uses_in_exp exp in @@ -983,8 +1029,8 @@ let smt_cdef props name_file env all_cdefs = function |> remove_pointless_goto in - (* let str = Pretty_print_sail.to_string PPrint.(separate_map hardline Jib_util.pp_instr instrs) in - prerr_endline str; *) + let str = Pretty_print_sail.to_string PPrint.(separate_map hardline Jib_util.pp_instr instrs) in + prerr_endline str; let open Jib_ssa in let start, cfg = ssa instrs in diff --git a/src/sail.ml b/src/sail.ml index 179c1a67..6f3833da 100644 --- a/src/sail.ml +++ b/src/sail.ml @@ -127,6 +127,12 @@ let options = Arg.align ([ ( "-smt", set_target "smt", " print SMT translated version of input"); + ( "-smt_ignore_overflow", + Arg.Set Jib_smt.ignore_overflow, + " ignore integer overflow in generated SMT"); + ( "-smt_int_size", + Arg.String (fun n -> Jib_smt.lint_size := int_of_string n), + " set a bound on the maximum integer bitwidth"); ( "-c", Arg.Tuple [set_target "c"; Arg.Set Initial_check.opt_undefined_gen], " output a C translated version of the input"); diff --git a/src/smtlib.ml b/src/smtlib.ml index 95047627..aa7a4e19 100644 --- a/src/smtlib.ml +++ b/src/smtlib.ml @@ -89,6 +89,7 @@ type smt_exp = | Var of string | Fn of string * smt_exp list | Ite of smt_exp * smt_exp * smt_exp + | SignExtend of int * smt_exp | Extract of int * int * smt_exp | Tester of string * smt_exp @@ -143,6 +144,9 @@ let rec simp_smt_exp vars = function | Tester (str, exp) -> let exp = simp_smt_exp vars exp in Tester (str, exp) + | SignExtend (i, exp) -> + let exp = simp_smt_exp vars exp in + SignExtend (i, exp) type smt_def = | Define_fun of string * (string * smt_typ) list * smt_typ * smt_exp @@ -174,7 +178,9 @@ let rec pp_smt_exp = parens (string (Printf.sprintf "(_ extract %d %d)" i j) ^^ space ^^ pp_smt_exp exp) | Tester (kind, exp) -> parens (string (Printf.sprintf "(_ is %s)" kind) ^^ space ^^ pp_smt_exp exp) - + | SignExtend (i, exp) -> + parens (string (Printf.sprintf "(_ sign_extend %d)" i) ^^ space ^^ pp_smt_exp exp) + let rec pp_smt_typ = let open PPrint in function diff --git a/test/smt/arith.unsat.sail b/test/smt/arith.unsat.sail new file mode 100644 index 00000000..20892ce6 --- /dev/null +++ b/test/smt/arith.unsat.sail @@ -0,0 +1,33 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow + +$property +function prop(x: int, y: int, z: int) -> bool = { + let lo = -100000000000; + let hi = 100000000000; + if lo >= x | x >= hi | lo >= y | y >= hi | lo >= z | z >= hi then { + return(true) + }; + + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_comm & add_assoc & add_id + & mul_comm & mul_assoc & mul_zero + & add_mul_distrib + & add_neg_zero & add_neg_sub & neg_neg +}
\ No newline at end of file diff --git a/test/smt/arith_C128FL.unsat.sail b/test/smt/arith_C128FL.unsat.sail new file mode 100644 index 00000000..3a323452 --- /dev/null +++ b/test/smt/arith_C128FL.unsat.sail @@ -0,0 +1,34 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow + +$property +function prop forall 'n, 0 <= 'n <= 128. (x: int(128), y: int('n), z: int) -> bool = { + let lo = -100000000000; + let hi = 100000000000; + if lo >= x | x >= hi | lo >= y | y >= hi | lo >= z | z >= hi then { + return(true) + }; + + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_assoc + /* add_comm & add_assoc & add_id + & mul_comm & mul_assoc & mul_zero + & add_mul_distrib + & add_neg_zero & add_neg_sub & neg_neg */ +}
\ No newline at end of file diff --git a/test/smt/arith_C64C32CB.unsat.sail b/test/smt/arith_C64C32CB.unsat.sail new file mode 100644 index 00000000..49e0ac59 --- /dev/null +++ b/test/smt/arith_C64C32CB.unsat.sail @@ -0,0 +1,25 @@ +default Order dec + +$include <prelude.sail> + +$property +function prop(x: int(64), y: int(32), z: int(1823473425924535349753247394723984324344634534)) -> bool = { + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_comm & add_assoc & add_id + & mul_comm & mul_assoc & mul_zero + & add_mul_distrib + & add_neg_zero & add_neg_sub & neg_neg +}
\ No newline at end of file diff --git a/test/smt/arith_FFL_1.unsat.sail b/test/smt/arith_FFL_1.unsat.sail new file mode 100644 index 00000000..d6ba31e3 --- /dev/null +++ b/test/smt/arith_FFL_1.unsat.sail @@ -0,0 +1,12 @@ +default Order dec + +$include <prelude.sail> + +$property +function prop forall 'n 'm, 0 <= 'n <= 128 & 0 <= 'm <= 64. (x: int('m), y: int('n), z: int) -> bool = { + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + add_comm & add_assoc & add_id +}
\ No newline at end of file diff --git a/test/smt/arith_FFL_2.unsat.sail b/test/smt/arith_FFL_2.unsat.sail new file mode 100644 index 00000000..1b095e99 --- /dev/null +++ b/test/smt/arith_FFL_2.unsat.sail @@ -0,0 +1,21 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow +$option -smt_int_size 256 + +$property +function prop forall 'n 'm, 0 <= 'n <= 128 & 0 <= 'm <= 64. (x: int('m), y: int('n), z: int) -> bool = { + let lo = -1000; + let hi = 1000; + if lo >= z | z >= hi then { + return(true) + }; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + mul_comm & mul_assoc /* & mul_zero */ +} diff --git a/test/smt/arith_FFL_3.unsat.sail b/test/smt/arith_FFL_3.unsat.sail new file mode 100644 index 00000000..87dbc498 --- /dev/null +++ b/test/smt/arith_FFL_3.unsat.sail @@ -0,0 +1,19 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow +$option -smt_int_size 256 + +$property +function prop forall 'n 'm, 0 <= 'n <= 128 & 0 <= 'm <= 64. (x: int('m), y: int('n), z: int) -> bool = { + let lo = -100000000000; + let hi = 100000000000; + if lo >= z | z >= hi then { + return(true) + }; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + add_mul_distrib +}
\ No newline at end of file diff --git a/test/smt/arith_FFL_4.unsat.sail b/test/smt/arith_FFL_4.unsat.sail new file mode 100644 index 00000000..29902af6 --- /dev/null +++ b/test/smt/arith_FFL_4.unsat.sail @@ -0,0 +1,12 @@ +default Order dec + +$include <prelude.sail> + +$property +function prop forall 'n 'm, 0 <= 'n <= 128 & 0 <= 'm <= 64. (x: int('m), y: int('n), z: int) -> bool = { + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_neg_zero & add_neg_sub & neg_neg +}
\ No newline at end of file diff --git a/test/smt/arith_LC32L.unsat.sail b/test/smt/arith_LC32L.unsat.sail new file mode 100644 index 00000000..547a5cb1 --- /dev/null +++ b/test/smt/arith_LC32L.unsat.sail @@ -0,0 +1,27 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow + +$property +function prop(x: int, y: int(32), z: int) -> bool = { + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_comm & add_assoc & add_id + & mul_comm & mul_assoc & mul_zero + & add_mul_distrib + & add_neg_zero & add_neg_sub & neg_neg +}
\ No newline at end of file diff --git a/test/smt/arith_LCBL.unsat.sail b/test/smt/arith_LCBL.unsat.sail new file mode 100644 index 00000000..879217fc --- /dev/null +++ b/test/smt/arith_LCBL.unsat.sail @@ -0,0 +1,33 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow + +$property +function prop(x: int, y: int(248534734259245353247394723984172394), z: int) -> bool = { + let lo = -100000000000; + let hi = 100000000000; + if lo >= x | x >= hi | lo >= z | z >= hi then { + return(true) + }; + + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_comm & add_assoc & add_id + & mul_comm & mul_assoc & mul_zero + & add_mul_distrib + & add_neg_zero & add_neg_sub & neg_neg +}
\ No newline at end of file diff --git a/test/smt/arith_LFL.unsat.sail b/test/smt/arith_LFL.unsat.sail new file mode 100644 index 00000000..3fdcd0fd --- /dev/null +++ b/test/smt/arith_LFL.unsat.sail @@ -0,0 +1,33 @@ +default Order dec + +$include <prelude.sail> + +$option -smt_ignore_overflow + +$property +function prop forall 'n, 0 <= 'n <= 128. (x: int, y: int('n), z: int) -> bool = { + let lo = -100000000000; + let hi = 100000000000; + if lo >= x | x >= hi | lo >= y | y >= hi | lo >= z | z >= hi then { + return(true) + }; + + let add_comm = x + y == y + x; + let add_assoc = (x + y) + z == x + (y + z); + let add_id = x + 0 == x; + + let mul_comm = x * y == y * x; + let mul_assoc = (x * y) * z == x * (y * z); + let mul_zero = x * 0 == 0; + + let add_mul_distrib = x * (y + z) == (x * y) + (x * z); + + let add_neg_zero = x + negate(x) == 0; + let add_neg_sub = x + negate(y) == x - y; + let neg_neg = negate(negate(x)) == x; + + add_comm & add_assoc & add_id + & mul_comm & mul_assoc & mul_zero + & add_mul_distrib + & add_neg_zero & add_neg_sub & neg_neg +}
\ No newline at end of file diff --git a/test/smt/run_tests.py b/test/smt/run_tests.py index fb5a0ebd..c9cadec3 100755 --- a/test/smt/run_tests.py +++ b/test/smt/run_tests.py @@ -23,7 +23,7 @@ def test_smt(name, solver, sail_opts): tests[filename] = os.fork() if tests[filename] == 0: step('sail {} -smt {} -o {}'.format(sail_opts, filename, basename)) - step('{} {}_prop.smt2 1> {}.out'.format(solver, basename, basename)) + step('timeout 20s {} {}_prop.smt2 1> {}.out'.format(solver, basename, basename)) if re.match('.+\.sat\.sail$', filename): step('grep -q ^sat$ {}.out'.format(basename)) else: diff --git a/test/smt/rv_add_0.sat.sail b/test/smt/rv_add_0.sat.sail index d0e8a5f5..4f1a28c5 100644 --- a/test/smt/rv_add_0.sat.sail +++ b/test/smt/rv_add_0.sat.sail @@ -2,6 +2,8 @@ default Order dec $include <prelude.sail> +$option -smt_ignore_overflow + type xlen : Int = 32 type xlen_bytes : Int = 4 type xlenbits : Type = bits(xlen) diff --git a/test/smt/rv_add_0.unsat.sail b/test/smt/rv_add_0.unsat.sail index cddc5c7a..ed45112e 100644 --- a/test/smt/rv_add_0.unsat.sail +++ b/test/smt/rv_add_0.unsat.sail @@ -2,6 +2,8 @@ default Order dec $include <prelude.sail> +$option -smt_ignore_overflow + type xlen : Int = 32 type xlen_bytes : Int = 4 type xlenbits : Type = bits(xlen) |
