z3 0.0.20220828 → 0.0.20230107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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