diff --git a/dolmen b/dolmen index 7cd59bbeaa536056d19facdbdc724b104e891732..365eeab891d19457e8cc8cc103ce21d3e50b33dc 160000 --- a/dolmen +++ b/dolmen @@ -1 +1 @@ -Subproject commit 7cd59bbeaa536056d19facdbdc724b104e891732 +Subproject commit 365eeab891d19457e8cc8cc103ce21d3e50b33dc diff --git a/src_colibri2/stdlib/std.ml b/src_colibri2/stdlib/std.ml index 2ef6d9b9e8be09ca77027f09dd0bae1f8e769e6c..b2d2b158674aeeb7ba71ae40eb748ac4dac46ae6 100644 --- a/src_colibri2/stdlib/std.ml +++ b/src_colibri2/stdlib/std.ml @@ -110,6 +110,9 @@ module Q = struct let is_integer q = Z.equal Z.one q.Q.den + let is_unsigned_integer size q = + is_integer q && Int.(Z.sign q.Q.num >= 0) && Int.(Z.numbits q.Q.num <= size) + let floor x = Q.of_bigint (Z.fdiv x.Q.num x.Q.den) let ceil x = Q.of_bigint (Z.cdiv x.Q.num x.Q.den) diff --git a/src_colibri2/stdlib/std.mli b/src_colibri2/stdlib/std.mli index ac11078198b9447ee7b1238ebb4e888eb3927c54..54ec732367da2c1307d5ed48242aacb94548b7b8 100644 --- a/src_colibri2/stdlib/std.mli +++ b/src_colibri2/stdlib/std.mli @@ -68,6 +68,10 @@ module Q : sig val is_integer : t -> bool + val is_unsigned_integer : int -> t -> bool + (** [is_unsigned_integer size q] checks that [q] is an integer that fits in + [size] bits *) + val none_zero : t -> t option (** return None if the input is zero otherwise Some of the value *) diff --git a/src_colibri2/tests/solve/smt_bv/sat/bigHex.smt2 b/src_colibri2/tests/solve/smt_bv/sat/bigHex.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..b8ae738d44128a37228cfdeef0d8b332df7d90ea --- /dev/null +++ b/src_colibri2/tests/solve/smt_bv/sat/bigHex.smt2 @@ -0,0 +1,12 @@ +(set-info :smt-lib-version 2.6) +(set-logic QF_BV) +(set-info :source | + Constructed by Trevor Hansen to test that #x and #b literals are working. Allocation of big constants. + With explicit explicit constant added. +|) +(set-info :category "check") +(set-info :status sat) +(assert (= #b1111 #xf)) +(assert (= (_ bv114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029375 2000) (bvnot (_ bv0 2000)))) +(check-sat) +(exit) diff --git a/src_colibri2/tests/solve/smt_bv/sat/dune b/src_colibri2/tests/solve/smt_bv/sat/dune new file mode 100644 index 0000000000000000000000000000000000000000..87aec8cee7b54a9b5770453bb688a103592210ab --- /dev/null +++ b/src_colibri2/tests/solve/smt_bv/sat/dune @@ -0,0 +1,12 @@ +(include dune.inc) + +(rule + (alias runtest) + (deps + (glob_files *.cnf) + (glob_files *.smt2)) + (action + (with-stdout-to + dune.inc + (run %{exe:../../../generate_tests/generate_dune_tests.exe} . sat))) + (mode promote)) diff --git a/src_colibri2/tests/solve/smt_bv/sat/dune.inc b/src_colibri2/tests/solve/smt_bv/sat/dune.inc new file mode 100644 index 0000000000000000000000000000000000000000..59264bcbe717ae6ff954e43682c49f27c31809cb --- /dev/null +++ b/src_colibri2/tests/solve/smt_bv/sat/dune.inc @@ -0,0 +1,6 @@ +(rule (alias runtest) (action (run %{bin:colibri2} --size=50M --time=30s --max-steps 3500 --check-status sat +--dont-print-result %{dep:bigHex.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=50M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:bigHex.smt2}))) +(rule (alias runtest) (action (run %{bin:colibri2} --size=50M --time=30s --max-steps 3500 --check-status sat +--dont-print-result %{dep:unit_test.smt2}))) +(rule (alias runtest-learning) (action (run %{bin:colibri2} --size=50M --time=30s --max-steps 3500 --check-status sat --learning --dont-print-result %{dep:unit_test.smt2}))) diff --git a/src_colibri2/tests/solve/smt_bv/sat/unit_test.smt2 b/src_colibri2/tests/solve/smt_bv/sat/unit_test.smt2 new file mode 100644 index 0000000000000000000000000000000000000000..0cd82ae2a394a347ab1b4bed51d5d6ec10c17440 --- /dev/null +++ b/src_colibri2/tests/solve/smt_bv/sat/unit_test.smt2 @@ -0,0 +1,102 @@ +(set-logic QF_BV) + +(assert (= (bvnot #b1010) #b0101)) +(assert (= (bvand #b1010 #b0001) #b0000)) +(assert (= (bvor #b1010 #b0001) #b1011)) +(assert (= (bvnand #b1010 #b0001) #b1111)) +(assert (= (bvnor #b1010 #b0001) #b0100)) +(assert (= (bvxor #b1010 #b1001) #b0011)) +(assert (= (bvxnor #b1010 #b1001) #b1100)) + +(assert (= (bvneg (_ bv4 3)) (_ bv4 3))) +(assert (= (bvneg (_ bv3 3)) (_ bv5 3))) + +(assert (= (bvcomp (_ bv3 3) (_ bv5 3)) #b0)) +(assert (= (bvcomp (_ bv4 3) (_ bv4 3)) #b1)) + +(assert (= (bvadd (_ bv3 2) (_ bv2 2)) (_ bv1 2))) +(assert (= (bvmul (_ bv3 2) (_ bv2 2)) (_ bv2 2))) + + +(assert (= (bvudiv (_ bv3 2) (_ bv2 2)) (_ bv1 2))) +(assert (= (bvsdiv (_ bv3 2) (_ bv2 2)) (_ bv0 2))) + +(assert (= (bvudiv (_ bv7 3) (_ bv0 3)) (_ bv7 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv1 3)) (_ bv7 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv2 3)) (_ bv3 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv3 3)) (_ bv2 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv4 3)) (_ bv1 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv5 3)) (_ bv1 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv6 3)) (_ bv1 3))) +(assert (= (bvudiv (_ bv7 3) (_ bv7 3)) (_ bv1 3))) + +(assert (= (bvurem (_ bv7 3) (_ bv0 3)) (_ bv7 3))) +(assert (= (bvurem (_ bv7 3) (_ bv1 3)) (_ bv0 3))) +(assert (= (bvurem (_ bv7 3) (_ bv2 3)) (_ bv1 3))) +(assert (= (bvurem (_ bv7 3) (_ bv3 3)) (_ bv1 3))) +(assert (= (bvurem (_ bv7 3) (_ bv4 3)) (_ bv3 3))) +(assert (= (bvurem (_ bv7 3) (_ bv5 3)) (_ bv2 3))) +(assert (= (bvurem (_ bv7 3) (_ bv6 3)) (_ bv1 3))) +(assert (= (bvurem (_ bv7 3) (_ bv7 3)) (_ bv0 3))) + +(assert (= (bvsdiv (_ bv7 3) (_ bv0 3)) (_ bv1 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv1 3)) (_ bv7 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv2 3)) (_ bv0 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv3 3)) (_ bv0 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv4 3)) (_ bv0 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv5 3)) (_ bv0 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv6 3)) (_ bv0 3))) +(assert (= (bvsdiv (_ bv7 3) (_ bv7 3)) (_ bv1 3))) + +(assert (= (bvsdiv (_ bv4 3) (_ bv0 3)) (_ bv1 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv1 3)) (_ bv4 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv2 3)) (_ bv6 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv3 3)) (_ bv7 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv4 3)) (_ bv1 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv5 3)) (_ bv1 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv6 3)) (_ bv2 3))) +(assert (= (bvsdiv (_ bv4 3) (_ bv7 3)) (_ bv4 3))) + +(assert (= (bvsrem (_ bv4 3) (_ bv0 3)) (_ bv4 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv1 3)) (_ bv0 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv2 3)) (_ bv0 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv3 3)) (_ bv7 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv4 3)) (_ bv0 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv5 3)) (_ bv7 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv6 3)) (_ bv0 3))) +(assert (= (bvsrem (_ bv4 3) (_ bv7 3)) (_ bv0 3))) + +(assert (= (bvsmod (_ bv4 3) (_ bv0 3)) (_ bv4 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv1 3)) (_ bv0 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv2 3)) (_ bv0 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv3 3)) (_ bv2 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv4 3)) (_ bv0 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv5 3)) (_ bv7 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv6 3)) (_ bv0 3))) +(assert (= (bvsmod (_ bv4 3) (_ bv7 3)) (_ bv0 3))) + +(assert (= (bvshl #b100 #b001) #b000)) +(assert (= (bvlshr #b100 #b001) #b010)) +(assert (= (bvashr #b000 #b001) #b000)) +(assert (= (bvashr #b010 #b001) #b001)) +(assert (= (bvashr #b100 #b001) #b110)) +(assert (= (bvashr #b110 #b001) #b111)) + +(assert (= ((_ sign_extend 1) #b1000) #b11000)) +(assert (= ((_ sign_extend 1) #b0100) #b00100)) +(assert (= ((_ zero_extend 1) #b1000) #b01000)) +(assert (= ((_ zero_extend 1) #b0100) #b00100)) + +(assert (= ((_ repeat 1) #b1011) #b1011)) +(assert (= ((_ repeat 2) #b1011) #b10111011)) + +(assert (= ((_ extract 3 2) #b1011) #b10)) +(assert (= ((_ extract 3 1) #b1011) #b101)) + +(assert (= ((_ rotate_left 2) #b1011) #b1110)) +(assert (= ((_ rotate_right 2) #b1011) #b1110)) +(assert (= ((_ rotate_left 1) #b1011) #b0111)) +(assert (= ((_ rotate_right 1) #b1011) #b1101)) + +(check-sat) +(exit) diff --git a/src_colibri2/tests/solve/smt_bv/unsat/dune b/src_colibri2/tests/solve/smt_bv/unsat/dune new file mode 100644 index 0000000000000000000000000000000000000000..959922d115ac3b89aec38904a6221b2730b37e08 --- /dev/null +++ b/src_colibri2/tests/solve/smt_bv/unsat/dune @@ -0,0 +1,12 @@ +(include dune.inc) + +(rule + (alias runtest) + (deps + (glob_files *.cnf) + (glob_files *.smt2)) + (action + (with-stdout-to + dune.inc + (run %{exe:../../../generate_tests/generate_dune_tests.exe} . unsat))) + (mode promote)) diff --git a/src_colibri2/tests/solve/smt_bv/unsat/dune.inc b/src_colibri2/tests/solve/smt_bv/unsat/dune.inc new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src_colibri2/theories/LRA/realValue.ml b/src_colibri2/theories/LRA/realValue.ml index bc8acb837e3b4e68ba836339dec317d3aec442fd..197eb6a1890256df90f3f7b1de210063db918a04 100644 --- a/src_colibri2/theories/LRA/realValue.ml +++ b/src_colibri2/theories/LRA/realValue.ml @@ -100,18 +100,46 @@ let init_ty d = else Yield (nodevalue (cst' v), Q.S.add v s)) in Some seq + | { app = { builtin = Expr.Bitv n; _ }; _ } -> + let open Base.Sequence.Generator in + let rec loop i = + if Z.numbits i <= n then + yield (nodevalue (cst' (Q.of_bigint i))) >>= fun () -> + loop (Z.succ i) + else return () + in + let seq = Interp.SeqLim.of_seq d (run (loop Z.zero)) in + Some seq | _ -> None) module Check = struct let interp d n = Opt.get_exn Impossible (Egraph.get_value d n) + exception Wrong_arg + let compute_ground d t = let ( !> ) t = RealValue.value (RealValue.coerce_nodevalue (interp d t)) in + let bitv n t = + let t = !>t in + if not (Q.is_unsigned_integer n t) then raise Wrong_arg; + t.Q.num + in + let signed_bitv n t = Z.signed_extract (bitv n t) 0 n in let ( !< ) v = `Some (RealValue.nodevalue (RealValue.index v)) in let ( !<< ) b = let r = if b then Boolean.values_true else Boolean.values_false in `Some r in + let extract n t = !<(Q.of_bigint (Z.extract t 0 n)) in + let from_bitv n t = + let t' = Q.of_bigint t in + if not (Q.is_unsigned_integer n t') then + Fmt.epr "@[[BV] %s(%a) is not of size %i@]@." + (Z.format (Fmt.str "%%0+#%ib" n) t) + Z.pp_print t n; + assert (Q.is_unsigned_integer n t'); + !<t' + in match Ground.sem t with | { app = { builtin = Expr.Coercion }; @@ -171,27 +199,182 @@ module Check = struct -> let a = IArray.extract1_exn args in !<(Q.abs !>a) + | { app = { builtin = Expr.Bitvec s }; tyargs = []; args; ty = _ } -> + assert (IArray.is_empty args); + from_bitv (String.length s) (Z.of_string_base 2 s) + | { app = { builtin = Expr.Bitv_concat (n, m) }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + from_bitv (n + m) (Z.logor (Z.shift_left (bitv n a) m) (bitv m b)) + | { app = { builtin = Expr.Bitv_extract (n, i, j) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + from_bitv (i - j + 1) (Z.extract (bitv n a) j (i - j + 1)) + | { app = { builtin = Expr.Bitv_repeat (n, k) }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + let rec loop n k acc z = + if k = 0 then acc + else + let acc = Z.logor (Z.shift_left acc n) z in + loop n (k - 1) acc z + in + let a = bitv n a in + from_bitv (n * k) (loop n k Z.zero a) + | { app = { builtin = Expr.Bitv_zero_extend (n, k) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + from_bitv (n + k) (bitv n a) + | { app = { builtin = Expr.Bitv_sign_extend (n, k) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + let a = bitv n a in + if Z.testbit a (n - 1) then + extract (n + k) (Z.logor (Z.shift_left Z.minus_one n) a) + else from_bitv (n + k) a + | { app = { builtin = Expr.Bitv_rotate_left (n, k) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + let a = bitv n a in + let k = k mod n in + extract n (Z.logor (Z.shift_left a k) (Z.extract a (n - k) k)) + | { + app = { builtin = Expr.Bitv_rotate_right (n, k) }; + tyargs = []; + args; + _; + } -> + let a = IArray.extract1_exn args in + let a = bitv n a in + let k = k mod n in + extract n (Z.logor (Z.shift_left a (n - k)) (Z.shift_right a k)) + | { app = { builtin = Expr.Bitv_not n }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + extract n (Z.lognot (bitv n a)) + | { app = { builtin = Expr.Bitv_and n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + from_bitv n (Z.logand (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_or n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + from_bitv n (Z.logor (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_nand n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + extract n (Z.lognot (Z.logand (bitv n a) (bitv n b))) + | { app = { builtin = Expr.Bitv_nor n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + extract n (Z.lognot (Z.logor (bitv n a) (bitv n b))) + | { app = { builtin = Expr.Bitv_xor n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + extract n (Z.logxor (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_xnor n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + extract n (Z.logxor (bitv n a) (Z.lognot (bitv n b))) + | { app = { builtin = Expr.Bitv_comp n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + if Z.equal (bitv n a) (bitv n b) then extract 1 Z.minus_one + else from_bitv 1 Z.zero + | { app = { builtin = Expr.Bitv_neg n }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + from_bitv n (Z.sub (Z.shift_left Z.one n) (bitv n a)) + | { app = { builtin = Expr.Bitv_add n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + extract n (Z.add (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_mul n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + extract n (Z.mul (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_udiv n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = bitv n b in + if Z.equal b Z.zero then extract n Z.minus_one + else extract n (Z.div (bitv n a) b) + | { app = { builtin = Expr.Bitv_urem n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = bitv n b in + if Z.equal b Z.zero then from_bitv n (bitv n a) + else extract n (Z.rem (bitv n a) b) + | { app = { builtin = Expr.Bitv_sdiv n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = signed_bitv n b in + if Z.equal b Z.zero then extract n Z.one + else extract n (Z.div (signed_bitv n a) b) + | { app = { builtin = Expr.Bitv_srem n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = signed_bitv n b in + if Z.equal b Z.zero then from_bitv n (bitv n a) + else extract n (Z.rem (signed_bitv n a) b) + | { app = { builtin = Expr.Bitv_smod n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = signed_bitv n b in + let a = signed_bitv n a in + if Z.equal b Z.zero then `Uninterp + else extract n (Z.sub a (Z.mul (Z.fdiv a b) b)) + | { app = { builtin = Expr.Bitv_shl n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = bitv n b in + if Z.leq (Z.of_int n) b then from_bitv n Z.zero + else extract n (Z.shift_left (bitv n a) (Z.to_int b)) + | { app = { builtin = Expr.Bitv_lshr n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = bitv n b in + if Z.leq (Z.of_int n) b then from_bitv n Z.zero + else extract n (Z.shift_right (bitv n a) (Z.to_int b)) + | { app = { builtin = Expr.Bitv_ashr n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + let b = bitv n b in + let b = if Z.leq (Z.of_int n) b then n else Z.to_int b in + extract n (Z.shift_right (signed_bitv n a) b) + | { app = { builtin = Expr.Bitv_ult n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.lt (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_ule n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.leq (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_ugt n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.gt (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_uge n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.geq (bitv n a) (bitv n b)) + | { app = { builtin = Expr.Bitv_slt n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.lt (signed_bitv n a) (signed_bitv n b)) + | { app = { builtin = Expr.Bitv_sle n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.leq (signed_bitv n a) (signed_bitv n b)) + | { app = { builtin = Expr.Bitv_sgt n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.gt (signed_bitv n a) (signed_bitv n b)) + | { app = { builtin = Expr.Bitv_sge n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + !<<(Z.geq (signed_bitv n a) (signed_bitv n b)) | _ -> `None let init d = Interp.Register.check d (fun d t -> - if - Ground.Ty.equal Ground.Ty.int (Ground.sem t).ty - && Base.Option.for_all - ~f:(fun q -> not (Q.is_integer (RealValue.value q))) - (RealValue.of_nodevalue (interp d (Ground.node t))) - then Wrong - else - let check r = Value.equal r (interp d (Ground.node t)) in - match compute_ground d t with - | `None -> NA - | `Some v -> Interp.check_of_bool (check v) - | `Uninterp -> - Interp.check_of_bool - (Colibri2_theories_quantifiers.Uninterp.On_uninterpreted_domain - .check d t)); + match + ( (Ground.sem t).ty.app, + RealValue.of_nodevalue (interp d (Ground.node t)) ) + with + | { builtin = Expr.Int; _ }, None -> Wrong + | { builtin = Expr.Int; _ }, Some v + when not (Q.is_integer (RealValue.value v)) -> + Wrong + | { builtin = Expr.Bitv _; _ }, None -> Wrong + | { builtin = Expr.Bitv n; _ }, Some v + when not (Q.is_unsigned_integer n (RealValue.value v)) -> + Wrong + | _ -> ( + let check r = Value.equal r (interp d (Ground.node t)) in + match compute_ground d t with + | exception Wrong_arg -> Wrong + | `None -> NA + | `Some v -> Interp.check_of_bool (check v) + | `Uninterp -> + Interp.check_of_bool + (Colibri2_theories_quantifiers.Uninterp + .On_uninterpreted_domain + .check d t))); Interp.Register.compute d (fun d t -> match compute_ground d t with + | exception Wrong_arg -> raise Impossible | `None -> NA | `Some v -> Value v | `Uninterp -> @@ -201,6 +384,7 @@ module Check = struct let attach d g = let f d g = match compute_ground d g with + | exception Wrong_arg -> Egraph.contradiction d | `None -> raise Impossible | `Some v -> Egraph.set_value d (Ground.node g) v | `Uninterp -> @@ -353,6 +537,175 @@ let converter d (f : Ground.t) = let a = IArray.extract1_exn args in reg a; Check.attach d f + | { app = { builtin = Expr.Bitvec s }; tyargs = []; args; ty = _ } -> + assert (IArray.is_empty args); + merge (cst (Q.of_bigint (Z.of_string_base 2 s))) + | { app = { builtin = Expr.Bitv_concat (_n, _m) }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_extract (_n, _i, _j) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_repeat (_n, _k) }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_zero_extend (_n, _k) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_sign_extend (_n, _k) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_rotate_left (_n, _k) }; tyargs = []; args; _ } + -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { + app = { builtin = Expr.Bitv_rotate_right (_n, _k) }; + tyargs = []; + args; + _; + } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_not _n }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_and _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_or _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_nand _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_nor _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_xnor _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_comp _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_neg _n }; tyargs = []; args; _ } -> + let a = IArray.extract1_exn args in + reg a; + Check.attach d f + | { app = { builtin = Expr.Bitv_add _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_mul _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_udiv _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_urem _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_sdiv _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_srem _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_smod _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_shl _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_lshr _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_ashr _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_ult _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_ule _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_ugt _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_uge _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_slt _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_sle _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_sgt _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f + | { app = { builtin = Expr.Bitv_sge _n }; tyargs = []; args; _ } -> + let a, b = IArray.extract2_exn args in + reg a; + reg b; + Check.attach d f | _ -> () let init env =