z3 0.0.20220828 → 0.0.20230107

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94779e8d2fdaee7a213640164c8113fee96135e5247d9dc161d02dae87da6e94
4
- data.tar.gz: d11a1326c693216fe857b436460d63176b466cc8b9927378940fc5543506a02e
3
+ metadata.gz: f5369c721ea50477790661ac8975e9c66104028450d4a73a2916eac046633380
4
+ data.tar.gz: 713374dddd23a82e7a22ec32e60964288182306201ef6e3e212e17b8d25c7a06
5
5
  SHA512:
6
- metadata.gz: 5282dc961ae5f4f9dbe08c3f0e225ad3e8849522d5f0f7de7deaa233463479197498c91327dc8e6455478ee4469cbec660f6c278a45b09218a45e3d3d8f5736d
7
- data.tar.gz: b884d26fb02ec6714d5ff54e862cbe5dccec2853b4ebcdda84410ccda65fc7693428e163b390a7d71b741a538d5ef9e0c5aac365d8709ff301e0344bb7bd8880
6
+ metadata.gz: 22d87abcdc1c5b8570bb0c52db0a0086185336bba84092666b010de0504cfa15e9973073d0ca1fa0ac5cb2eb448b2e9ae6da1ba5f7f807255fbbb91e573c42cf
7
+ data.tar.gz: cc3527b80fd35db96b1dd6cf2fde3511f97cc94316f76c507e8c7ded6f6fef1b122fdc477a043870a15acd7bf76a87e6884f3e6d502998c762315b3732d14023
@@ -40,6 +40,26 @@ module Z3
40
40
  sort.new(LowLevel.mk_unary_minus(self))
41
41
  end
42
42
 
43
+ def zero?
44
+ self == 0
45
+ end
46
+
47
+ def nonzero?
48
+ self != 0
49
+ end
50
+
51
+ def positive?
52
+ self > 0
53
+ end
54
+
55
+ def negative?
56
+ self < 0
57
+ end
58
+
59
+ def abs
60
+ (self < 0).ite(-self, self)
61
+ end
62
+
43
63
  # Recast so 1 + x:Float
44
64
  # is: (+ 1.0 x)
45
65
  # not: (+ (to_real 1) x)
@@ -1,5 +1,25 @@
1
1
  module Z3
2
2
  class ArrayExpr < Expr
3
3
  public_class_method :new
4
+
5
+ def key_sort
6
+ sort.key_sort
7
+ end
8
+
9
+ def value_sort
10
+ sort.value_sort
11
+ end
12
+
13
+ def store(key, value)
14
+ sort.new LowLevel.mk_store(self, key_sort.cast(key), value_sort.cast(value))
15
+ end
16
+
17
+ def select(key)
18
+ sort.value_sort.new LowLevel.mk_select(self, key_sort.cast(key))
19
+ end
20
+
21
+ def [](key)
22
+ select(key)
23
+ end
4
24
  end
5
25
  end
@@ -246,6 +246,26 @@ module Z3
246
246
  BitvecExpr.UnsignedLe(self, other)
247
247
  end
248
248
 
249
+ def zero?
250
+ self == 0
251
+ end
252
+
253
+ def nonzero?
254
+ self != 0
255
+ end
256
+
257
+ def positive?
258
+ self.signed_gt 0
259
+ end
260
+
261
+ def negative?
262
+ self.signed_lt 0
263
+ end
264
+
265
+ def abs
266
+ self.negative?.ite(-self, self)
267
+ end
268
+
249
269
  def coerce(other)
250
270
  other_sort = Expr.sort_for_const(other)
251
271
  max_sort = [sort, other_sort].max
@@ -81,6 +81,10 @@ module Z3
81
81
  BoolSort.new.new LowLevel.mk_fpa_is_zero(self)
82
82
  end
83
83
 
84
+ def nonzero?
85
+ Z3.And(~zero?, ~nan?)
86
+ end
87
+
84
88
  def max(other)
85
89
  FloatExpr.Max(self, other)
86
90
  end
data/lib/z3/interface.rb CHANGED
@@ -72,6 +72,10 @@ module Z3
72
72
  LowLevel.get_version.join(".")
73
73
  end
74
74
 
75
+ def version_at_least?(a, b=0, c=0, d=0)
76
+ (LowLevel.get_version <=> [a, b, c, d]) >= 0
77
+ end
78
+
75
79
  def set_param(k,v)
76
80
  LowLevel.global_param_set(k,v)
77
81
  end
@@ -4,7 +4,9 @@ module Z3
4
4
  let(:a) { sort.var("a") }
5
5
  let(:b) { sort.var("b") }
6
6
  let(:c) { sort.var("c") }
7
- let(:x) { Z3::Bool("x") }
7
+ let(:x) { Z3::Int("x") }
8
+ let(:y) { Z3::Int("y") }
9
+ let(:z) { Z3::Int("z") }
8
10
 
9
11
  # TODO: Formatting is dreadful
10
12
  it "== and !=" do
@@ -14,5 +16,35 @@ module Z3
14
16
  c => "const(0)",
15
17
  )
16
18
  end
19
+
20
+ it "select" do
21
+ expect([a.select(10) == 20]).to have_solution(
22
+ a => "const(20)",
23
+ )
24
+ expect([a[10] == 20]).to have_solution(
25
+ a => "const(20)",
26
+ )
27
+ expect([a[x] == 10, a[y] == 20]).to have_solution(
28
+ a => "store(const(10), 3, 20)",
29
+ x => "2",
30
+ y => "3",
31
+ )
32
+ end
33
+
34
+ it "store" do
35
+ expect([a == b.store(10, 20), x == a.select(10)]).to have_solution(
36
+ x => 20,
37
+ )
38
+ expect([a == b.store(10, 20), x == a[10]]).to have_solution(
39
+ x => 20,
40
+ )
41
+ expect([a == b.store(10, 20), x == a[y], y == 10]).to have_solution(
42
+ x => 20,
43
+ )
44
+ expect([a == b.store(10, 20), x == a[y], x == 20]).to have_solution(
45
+ x => 20,
46
+ y => 10,
47
+ )
48
+ end
17
49
  end
18
50
  end
@@ -1,7 +1,7 @@
1
1
  module Z3
2
2
  describe ArraySort do
3
- let(:int_int_array) { ArraySort.new(IntSort.new, IntSort.new) }
4
- let(:int_real_array) { ArraySort.new(IntSort.new, RealSort.new) }
3
+ let(:int_int_array) { ArraySort.new(IntSort.new, IntSort.new) }
4
+ let(:int_real_array) { ArraySort.new(IntSort.new, RealSort.new) }
5
5
 
6
6
  it "can instantiate variables" do
7
7
  expect(int_int_array.var("a").inspect).to eq("Array(Int, Int)<a>")
@@ -231,5 +231,38 @@ module Z3
231
231
  expect([a == 0b0101_0110, e == 0b1101, d == a.concat(e)]).to have_solution(d => 0b0101_0110_1101)
232
232
  expect([a == 0b0101_0110, e == 0b1101, d == e.concat(a)]).to have_solution(d => 0b1101_0101_0110)
233
233
  end
234
+
235
+ it "zero?" do
236
+ expect([a == 0, x == a.zero?]).to have_solution(x => true)
237
+ expect([a == 100, x == a.zero?]).to have_solution(x => false)
238
+ expect([a == 200, x == a.zero?]).to have_solution(x => false)
239
+ end
240
+
241
+ it "nonzero?" do
242
+ expect([a == 0, x == a.nonzero?]).to have_solution(x => false)
243
+ expect([a == 100, x == a.nonzero?]).to have_solution(x => true)
244
+ expect([a == 200, x == a.nonzero?]).to have_solution(x => true)
245
+ end
246
+
247
+ # Inherently signed
248
+ it "positive?" do
249
+ expect([a == 0, x == a.positive?]).to have_solution(x => false)
250
+ expect([a == 100, x == a.positive?]).to have_solution(x => true)
251
+ expect([a == 200, x == a.positive?]).to have_solution(x => false)
252
+ end
253
+
254
+ # Inherently signed
255
+ it "negative?" do
256
+ expect([a == 0, x == a.negative?]).to have_solution(x => false)
257
+ expect([a == 100, x == a.negative?]).to have_solution(x => false)
258
+ expect([a == 200, x == a.negative?]).to have_solution(x => true)
259
+ end
260
+
261
+ # Inherently signed
262
+ it "abs" do
263
+ expect([a == 0, b == a.abs]).to have_solution(b => 0)
264
+ expect([a == 100, b == a.abs]).to have_solution(b => 100)
265
+ expect([a == 200, b == a.abs]).to have_solution(b => 56)
266
+ end
234
267
  end
235
268
  end
@@ -102,8 +102,9 @@ module Z3
102
102
  expect(positive_infinity.to_s).to eq("+oo")
103
103
  expect(negative_infinity.to_s).to eq("-oo")
104
104
  expect(nan.to_s).to eq("NaN")
105
+
105
106
  # Denormals changed
106
- if Z3.version >= '4.5'
107
+ if Z3.version_at_least?(4, 6)
107
108
  expect(float_double.from_const(1234 * 0.5**1040).to_s).to eq("0.00470733642578125B-1022")
108
109
  expect(float_single.from_const(1234 * 0.5**136).to_s).to eq("1.205078125B-126")
109
110
  # This is what we get, all of these are wrong, by a lot:
@@ -128,6 +129,17 @@ module Z3
128
129
  expect([x == nan.zero?]).to have_solution(x => false)
129
130
  end
130
131
 
132
+ # Same as positive or negative
133
+ # +0, -0, and NaN are all false
134
+ it "nonzero?" do
135
+ expect([x == positive_zero.nonzero?]).to have_solution(x => false)
136
+ expect([x == negative_zero.nonzero?]).to have_solution(x => false)
137
+ expect([x == positive_infinity.nonzero?]).to have_solution(x => true)
138
+ expect([x == negative_infinity.nonzero?]).to have_solution(x => true)
139
+ expect([x == float_double.from_const(1.5).nonzero?]).to have_solution(x => true)
140
+ expect([x == nan.nonzero?]).to have_solution(x => false)
141
+ end
142
+
131
143
  it "infinite?" do
132
144
  expect([x == positive_zero.infinite?]).to have_solution(x => false)
133
145
  expect([x == positive_infinity.infinite?]).to have_solution(x => true)
@@ -178,5 +190,28 @@ module Z3
178
190
  expect([x == float_double.from_const(-1.5).negative?]).to have_solution(x => true)
179
191
  expect([x == nan.negative?]).to have_solution(x => false)
180
192
  end
193
+
194
+ # We can't simply do have_solution(b => positive_zero)
195
+ # as positive_zero == negative_zero
196
+ it "abs" do
197
+ expect([a == positive_zero, b == a.abs]).to have_solution(a.abs => positive_zero)
198
+ expect([a == negative_zero, b == a.abs]).to have_solution(a.abs => positive_zero)
199
+ expect([a == positive_infinity, b == a.abs]).to have_solution(b => positive_infinity)
200
+ expect([a == negative_infinity, b == a.abs]).to have_solution(b => positive_infinity)
201
+ expect([a == float_double.from_const(1.5), b == a.abs]).to have_solution(b => float_double.from_const(1.5))
202
+ expect([a == float_double.from_const(-1.5), b == a.abs]).to have_solution(b => float_double.from_const(1.5))
203
+ expect([a == nan, b == a.abs]).to have_no_solution
204
+ end
205
+
206
+ # This means you need to be extra careful when using Z3::Float
207
+ # as == means something else on them than mathematical ==
208
+ #
209
+ # Also have_solutions helper doesn't work as it relies on ==
210
+ it "zeroes" do
211
+ expect([a == positive_zero, b == a, b.positive?]).to have_solution(b => positive_zero)
212
+ expect([a == negative_zero, b == a, b.negative?]).to have_solution(b => negative_zero)
213
+ expect([a == positive_zero, b == a, b.positive?]).to have_solution(b => positive_zero)
214
+ expect([a == negative_zero, b == a, b.negative?]).to have_solution(b => negative_zero)
215
+ end
181
216
  end
182
217
  end
@@ -81,6 +81,36 @@ module Z3
81
81
  expect([a == 3, b == -a]).to have_solution(b => -3)
82
82
  end
83
83
 
84
+ it "zero?" do
85
+ expect([a == 0, x == a.zero?]).to have_solution(x => true)
86
+ expect([a == 100, x == a.zero?]).to have_solution(x => false)
87
+ expect([a == -200, x == a.zero?]).to have_solution(x => false)
88
+ end
89
+
90
+ it "nonzero?" do
91
+ expect([a == 0, x == a.nonzero?]).to have_solution(x => false)
92
+ expect([a == 100, x == a.nonzero?]).to have_solution(x => true)
93
+ expect([a == -200, x == a.nonzero?]).to have_solution(x => true)
94
+ end
95
+
96
+ it "positive?" do
97
+ expect([a == 0, x == a.positive?]).to have_solution(x => false)
98
+ expect([a == 100, x == a.positive?]).to have_solution(x => true)
99
+ expect([a == -200, x == a.positive?]).to have_solution(x => false)
100
+ end
101
+
102
+ it "negative?" do
103
+ expect([a == 0, x == a.negative?]).to have_solution(x => false)
104
+ expect([a == 100, x == a.negative?]).to have_solution(x => false)
105
+ expect([a == -200, x == a.negative?]).to have_solution(x => true)
106
+ end
107
+
108
+ it "abs" do
109
+ expect([a == 3, b == 2, c == (a - b).abs]).to have_solution(c => 1)
110
+ expect([a == 2, b == 3, c == (a - b).abs]).to have_solution(c => 1)
111
+ expect([a == 2, b == 2, c == (a - b).abs]).to have_solution(c => 0)
112
+ end
113
+
84
114
  it "simplify" do
85
115
  a = Z3.Const(5)
86
116
  b = Z3.Const(3)
@@ -0,0 +1,90 @@
1
+ Solved
2
+ State 0:
3
+ bbb.
4
+ xbxw
5
+ ..ww
6
+ x.xw
7
+ w: 3,3 -> 1,2
8
+
9
+ State 1:
10
+ bbb.
11
+ xbxw
12
+ .www
13
+ x.x.
14
+ b: 1,1 -> 3,0
15
+
16
+ State 2:
17
+ bbbb
18
+ x.xw
19
+ .www
20
+ x.x.
21
+ w: 3,2 -> 1,1
22
+
23
+ State 3:
24
+ bbbb
25
+ xwxw
26
+ .ww.
27
+ x.x.
28
+ b: 2,0 -> 3,2
29
+
30
+ State 4:
31
+ bb.b
32
+ xwxw
33
+ .wwb
34
+ x.x.
35
+ w: 1,2 -> 2,0
36
+
37
+ State 5:
38
+ bbwb
39
+ xwxw
40
+ ..wb
41
+ x.x.
42
+ b: 0,0 -> 1,2
43
+
44
+ State 6:
45
+ .bwb
46
+ xwxw
47
+ .bwb
48
+ x.x.
49
+ b: 1,2 -> 3,3
50
+
51
+ State 7:
52
+ .bwb
53
+ xwxw
54
+ ..wb
55
+ x.xb
56
+ w: 3,1 -> 1,2
57
+
58
+ State 8:
59
+ .bwb
60
+ xwx.
61
+ .wwb
62
+ x.xb
63
+ b: 1,0 -> 3,1
64
+
65
+ State 9:
66
+ ..wb
67
+ xwxb
68
+ .wwb
69
+ x.xb
70
+ w: 2,2 -> 1,0
71
+
72
+ State 10:
73
+ .wwb
74
+ xwxb
75
+ .w.b
76
+ x.xb
77
+ b: 3,0 -> 2,2
78
+
79
+ State 11:
80
+ .ww.
81
+ xwxb
82
+ .wbb
83
+ x.xb
84
+ w: 1,2 -> 0,0
85
+
86
+ State 12:
87
+ www.
88
+ xwxb
89
+ ..bb
90
+ x.xb
@@ -0,0 +1,90 @@
1
+ Solved
2
+ State 0:
3
+ bbb.
4
+ xbxw
5
+ ..ww
6
+ x.xw
7
+ b: 0,0 -> 1,2
8
+
9
+ State 1:
10
+ .bb.
11
+ xbxw
12
+ .bww
13
+ x.xw
14
+ w: 2,2 -> 3,0
15
+
16
+ State 2:
17
+ .bbw
18
+ xbxw
19
+ .b.w
20
+ x.xw
21
+ b: 1,0 -> 2,2
22
+
23
+ State 3:
24
+ ..bw
25
+ xbxw
26
+ .bbw
27
+ x.xw
28
+ w: 3,1 -> 1,0
29
+
30
+ State 4:
31
+ .wbw
32
+ xbx.
33
+ .bbw
34
+ x.xw
35
+ b: 1,2 -> 3,1
36
+
37
+ State 5:
38
+ .wbw
39
+ xbxb
40
+ ..bw
41
+ x.xw
42
+ w: 3,3 -> 1,2
43
+
44
+ State 6:
45
+ .wbw
46
+ xbxb
47
+ .wbw
48
+ x.x.
49
+ w: 1,2 -> 0,0
50
+
51
+ State 7:
52
+ wwbw
53
+ xbxb
54
+ ..bw
55
+ x.x.
56
+ b: 2,0 -> 1,2
57
+
58
+ State 8:
59
+ ww.w
60
+ xbxb
61
+ .bbw
62
+ x.x.
63
+ b: 1,2 -> 3,3
64
+
65
+ State 9:
66
+ ww.w
67
+ xbxb
68
+ ..bw
69
+ x.xb
70
+ w: 3,2 -> 2,0
71
+
72
+ State 10:
73
+ wwww
74
+ xbxb
75
+ ..b.
76
+ x.xb
77
+ b: 1,1 -> 3,2
78
+
79
+ State 11:
80
+ wwww
81
+ x.xb
82
+ ..bb
83
+ x.xb
84
+ w: 3,0 -> 1,1
85
+
86
+ State 12:
87
+ www.
88
+ xwxb
89
+ ..bb
90
+ x.xb
@@ -64,6 +64,36 @@ module Z3
64
64
  expect([a == 81, b == 0.25, c == (a ** b)]).to have_solution(c => 3)
65
65
  end
66
66
 
67
+ it "zero?" do
68
+ expect([a == 0, x == a.zero?]).to have_solution(x => true)
69
+ expect([a == 100, x == a.zero?]).to have_solution(x => false)
70
+ expect([a == -200, x == a.zero?]).to have_solution(x => false)
71
+ end
72
+
73
+ it "nonzero?" do
74
+ expect([a == 0, x == a.nonzero?]).to have_solution(x => false)
75
+ expect([a == 100, x == a.nonzero?]).to have_solution(x => true)
76
+ expect([a == -200, x == a.nonzero?]).to have_solution(x => true)
77
+ end
78
+
79
+ it "positive?" do
80
+ expect([a == 0, x == a.positive?]).to have_solution(x => false)
81
+ expect([a == 100, x == a.positive?]).to have_solution(x => true)
82
+ expect([a == -200, x == a.positive?]).to have_solution(x => false)
83
+ end
84
+
85
+ it "negative?" do
86
+ expect([a == 0, x == a.negative?]).to have_solution(x => false)
87
+ expect([a == 100, x == a.negative?]).to have_solution(x => false)
88
+ expect([a == -200, x == a.negative?]).to have_solution(x => true)
89
+ end
90
+
91
+ it "abs" do
92
+ expect([a == 3, b == 2, c == (a - b).abs]).to have_solution(c => 1)
93
+ expect([a == 2, b == 3, c == (a - b).abs]).to have_solution(c => 1)
94
+ expect([a == 2, b == 2, c == (a - b).abs]).to have_solution(c => 0)
95
+ end
96
+
67
97
  it "unary -" do
68
98
  expect([a == 3, b == -a]).to have_solution(b => -3)
69
99
  expect([a == 0, b == -a]).to have_solution(b => 0)
@@ -17,7 +17,7 @@ module Z3
17
17
  )
18
18
  end
19
19
 
20
- if Z3.version >= "4.5"
20
+ if Z3.version_at_least?(4, 5)
21
21
  # Only works in z3 4.5, 4.4 (like on Ubuntu) returns bad stuff
22
22
  it "union" do
23
23
  expect([
data/spec/solver_spec.rb CHANGED
@@ -43,7 +43,7 @@ module Z3
43
43
  # This is a very simple example of unknown satisfiablity
44
44
  # so we might need more complex one in the future
45
45
  # This is now satisfiable in 4.6.0
46
- if Z3.version >= "4.6"
46
+ if Z3.version_at_least?(4, 6)
47
47
  it "unknown satisfiability (until 4.6 fix)" do
48
48
  solver.assert a**3 == a
49
49
  expect(solver.check).to eq(:sat)
data/spec/spec_helper.rb CHANGED
@@ -155,3 +155,22 @@ RSpec::Matchers.define :have_solutions do |expected|
155
155
  end
156
156
  end
157
157
  end
158
+
159
+ RSpec::Matchers.define :have_no_solution do
160
+ match do |asts|
161
+ solver = setup_solver(asts)
162
+ !solver.satisfiable?
163
+ end
164
+
165
+ failure_message do |asts|
166
+ "expected #{asts.inspect} to have no solutions, but solution found"
167
+ end
168
+
169
+ def setup_solver(asts)
170
+ Z3::Solver.new.tap do |solver|
171
+ asts.each do |ast|
172
+ solver.assert ast
173
+ end
174
+ end
175
+ end
176
+ end
data/spec/z3_spec.rb CHANGED
@@ -2,4 +2,14 @@ describe Z3 do
2
2
  it "#version return version number of Z3 library" do
3
3
  expect(Z3.version).to match(/\A\d+\.\d+\.\d+\.\d+\z/)
4
4
  end
5
+
6
+ it "#version_at_least return if version matches" do
7
+ version = Z3.version.split(".").map(&:to_i)
8
+ expect(Z3.version_at_least?(*version)).to eq(true)
9
+ expect(Z3.version_at_least?(*version[0,2])).to eq(true)
10
+ expect(Z3.version_at_least?(*version[0,1])).to eq(true)
11
+ expect(Z3.version_at_least?(version[0])).to eq(true)
12
+ expect(Z3.version_at_least?(*version[0,2], 999)).to eq(false)
13
+ expect(Z3.version_at_least?(999)).to eq(false)
14
+ end
5
15
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: z3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20220828
4
+ version: 0.0.20230107
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-28 00:00:00.000000000 Z
11
+ date: 2023-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -287,6 +287,8 @@ files:
287
287
  - spec/integration/examples/knights_puzzle-1.txt
288
288
  - spec/integration/examples/knights_puzzle-2.txt
289
289
  - spec/integration/examples/knights_puzzle-3.txt
290
+ - spec/integration/examples/knights_puzzle-4.txt
291
+ - spec/integration/examples/knights_puzzle-5.txt
290
292
  - spec/integration/four_hackers_puzzle_spec.rb
291
293
  - spec/integration/futoshiki_spec.rb
292
294
  - spec/integration/geometry_problem_spec.rb