z3 0.0.20161008 → 0.0.20161010

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
  SHA1:
3
- metadata.gz: f77923728739173352acc32c2b86d15d158df0aa
4
- data.tar.gz: 6d14bf2597324dfaeb56fef62126466a80312b59
3
+ metadata.gz: 6cae47eadb8b6cb435ab68a3c1d5e64e7ab7ef10
4
+ data.tar.gz: 59e4479e128bad8ea7588b8de42ef9c6ad9af4e5
5
5
  SHA512:
6
- metadata.gz: 5c298ac6d9809173f284ac05ae13e19a52cebd56cff557f36894a6b8e5168f68bcfee71e1652ae3848d7009a2572bcdc3663e858e66f808b8c8a112f8a1a25bf
7
- data.tar.gz: cf216b75b22a6c172f06613972a8d1c0644efee56ea1462df24d040aa189b58558d594d84156ba1e3ebc3e23b24fc4371faa661f519aecd8e2fa0afe47c98da9
6
+ metadata.gz: 9e3a0cf9fff6457c318ad086e987029fad72a292080572ea0ddc204cf5c054881c95b515977456aed9a07bb57a86718d85c8ac03e4144c5379c7417a1c667696
7
+ data.tar.gz: 3bf40c2ff99cb57ef7b623415ddf50605bbdde75d524c05c40223ca38d81e3cd58d122d39a1b51dc490bc2575dde884823e24cd2fc06a8568d5ee42f4a4cb216
@@ -10,7 +10,7 @@ class AlgebraProblem
10
10
 
11
11
  def print_solution!(number)
12
12
  puts("Solution to problem %s:" % number)
13
- if @solver.check() == :sat
13
+ if @solver.satisfiable?
14
14
  @solver.model.each do |n,v|
15
15
  puts "* #{n} = #{v}"
16
16
  end
data/examples/bridges CHANGED
@@ -61,7 +61,7 @@ class Bridges
61
61
  end
62
62
  end
63
63
 
64
- if @solver.check == :sat
64
+ if @solver.satisfiable?
65
65
  @model = @solver.model
66
66
  print_answer!
67
67
  else
@@ -82,8 +82,8 @@ class Bridges
82
82
 
83
83
  @data.each do |(x,y),v|
84
84
  if v == nil
85
- u = @model[@vars[[x,y,"u"]]].to_s.to_i
86
- l = @model[@vars[[x,y,"l"]]].to_s.to_i
85
+ u = @model[@vars[[x,y,"u"]]].to_i
86
+ l = @model[@vars[[x,y,"l"]]].to_i
87
87
  if u > 0
88
88
  picture[y*3+1][x*3+1] = " |\u2016"[u]
89
89
  elsif l > 0
@@ -97,10 +97,10 @@ class Bridges
97
97
  end
98
98
 
99
99
  @data.each do |(x,y),_|
100
- u = @model[@vars[[x,y,"u"]]].to_s.to_i
101
- d = @model[@vars[[x,y,"d"]]].to_s.to_i
102
- l = @model[@vars[[x,y,"l"]]].to_s.to_i
103
- r = @model[@vars[[x,y,"r"]]].to_s.to_i
100
+ u = @model[@vars[[x,y,"u"]]].to_i
101
+ d = @model[@vars[[x,y,"d"]]].to_i
102
+ l = @model[@vars[[x,y,"l"]]].to_i
103
+ r = @model[@vars[[x,y,"r"]]].to_i
104
104
 
105
105
  picture[y*3+1][x*3 ] = " -="[l]
106
106
  picture[y*3+1][x*3+2] = " -="[r]
@@ -71,7 +71,7 @@ class CircuitProblem
71
71
  private
72
72
 
73
73
  def with_solved_model
74
- if @solver.check == :sat
74
+ if @solver.satisfiable?
75
75
  yield @solver.model
76
76
  else
77
77
  puts "Can't solve the problem"
@@ -85,13 +85,13 @@ class CLogicPuzzleSolver
85
85
 
86
86
  key = %W[iw hu fv lu dv cy og lc gy fq od lo fq is ig gu hs hi ds cy oo os iu fs gu lh dq lv gu iw hv gu di hs cy oc iw gc]
87
87
 
88
- if solver.check == :sat
88
+ if solver.satisfiable?
89
89
  model = solver.model
90
90
  model_vars = {}
91
91
  model.each do |k,v|
92
92
  v = v.to_s.sub(/\A#x/, "").to_i(16)
93
93
  model_vars[k] = v
94
- puts "#{k.to_s}=#{v.to_s}"
94
+ puts "#{k}=#{v}"
95
95
  end
96
96
  result = key.map do |ab|
97
97
  a,b = ab.chars
@@ -60,11 +60,11 @@ class LogicPuzzle
60
60
 
61
61
  def solve!
62
62
  add_assertions!
63
- if @solver.check == :sat
63
+ if @solver.satisfiable?
64
64
  @solver.model.each do |k,v|
65
65
  k = k.to_s.gsub("|", "")
66
66
  i, name = k.split("-", 2)
67
- puts "#{k} = #{@dict[name][v.to_s.to_i]}"
67
+ puts "#{k} = #{@dict[name][v.to_i]}"
68
68
  end
69
69
  else
70
70
  puts "Puzzle has no solutions"
@@ -30,7 +30,7 @@ solver.assert(b_d == 20)
30
30
 
31
31
  solver.assert(a_c**2 == (ax-cx)**2 + (ay-cy)**2)
32
32
 
33
- if solver.check == :sat
33
+ if solver.satisfiable?
34
34
  model = solver.model
35
35
  model.each do |n,v|
36
36
  puts "* #{n} = #{v}"
data/examples/kakuro CHANGED
@@ -38,7 +38,7 @@ class Kakuro
38
38
  end
39
39
  end
40
40
 
41
- if @solver.check() == :sat
41
+ if @solver.satisfiable?
42
42
  @model = @solver.model
43
43
  print_board!
44
44
  else
@@ -58,7 +58,7 @@ class Kakuro
58
58
  cell = @data[[x,y]]
59
59
  if cell == nil
60
60
  if @model and @cells.has_key?([x,y])
61
- a = @model[@cells[[x,y]]].to_s
61
+ a = @model[@cells[[x,y]]]
62
62
  print(" [#{a}] ")
63
63
  else
64
64
  print(" _ ")
@@ -16,7 +16,7 @@ class KinematicsProblem
16
16
 
17
17
  def print_solution!(number)
18
18
  puts("Solution to problem %s:" % number)
19
- if @solver.check() == :sat
19
+ if @solver.satisfiable?
20
20
  @solver.model.each do |n,v|
21
21
  puts "* #{n} = #{v}"
22
22
  end
@@ -29,18 +29,18 @@ class KnightsPuzzle
29
29
 
30
30
  def print_board(t)
31
31
  puts "State #{t}:"
32
- puts @boards[t].transpose.map{|row| row.map{|c| ".wbx"[@model[c].to_s.to_i]}.join }.join("\n")
32
+ puts @boards[t].transpose.map{|row| row.map{|c| ".wbx"[@model[c].to_i]}.join }.join("\n")
33
33
  end
34
34
 
35
35
  def print_move(t)
36
- move = Hash[@moves[t].map{|k,v| [k,@model[v].to_s.to_i]}]
36
+ move = Hash[@moves[t].map{|k,v| [k,@model[v].to_i]}]
37
37
  figure = " wbx"[move[:figure]]
38
38
  puts "#{figure}: #{move[:start_x]},#{move[:start_y]} -> #{move[:end_x]},#{move[:end_y]}"
39
39
  puts ""
40
40
  end
41
41
 
42
42
  def solve!
43
- if @solver.check == :sat
43
+ if @solver.satisfiable?
44
44
  @model = @solver.model
45
45
  puts "Solved"
46
46
  @num_moves.times do |t|
@@ -116,7 +116,7 @@ class LetterConnections
116
116
  )
117
117
  end
118
118
  end
119
- if @solver.check == :sat
119
+ if @solver.satisfiable?
120
120
  @model = @solver.model
121
121
  print_answer!
122
122
  else
@@ -170,9 +170,9 @@ class LetterConnections
170
170
  def print_answer!
171
171
  (0...@ysize).each do |y|
172
172
  (0...@xsize).each do |x|
173
- li = @model[@line[[x,y]]].to_s.to_i
173
+ li = @model[@line[[x,y]]].to_i
174
174
  l = @rletters[li]
175
- d = @model[@dir[[x,y]]].to_s.to_i
175
+ d = @model[@dir[[x,y]]].to_i
176
176
  if [x,y] == @starts[l]
177
177
  print("\u2190\u2191\u2192\u2193"[d]+l+" ")
178
178
  elsif [x,y] == @ends[l]
data/examples/light_up CHANGED
@@ -39,7 +39,7 @@ class LightUp
39
39
  end
40
40
  end
41
41
 
42
- if @solver.check == :sat
42
+ if @solver.satisfiable?
43
43
  @model = @solver.model
44
44
  print_answer!
45
45
  else
@@ -76,7 +76,7 @@ class LightUp
76
76
  (0...@xsize).each do |x|
77
77
  if @data[[x,y]] != "."
78
78
  print(@data[[x,y]])
79
- elsif @model[@lamps[[x,y]]].to_s == "1"
79
+ elsif @model[@lamps[[x,y]]].to_i == 1
80
80
  print("*")
81
81
  else
82
82
  print(" ")
data/examples/minisudoku CHANGED
@@ -32,7 +32,7 @@ class MiniSudokuSolver
32
32
  end
33
33
  end
34
34
 
35
- if @solver.check == :sat
35
+ if @solver.satisfiable?
36
36
  @model = @solver.model
37
37
  print_answer!
38
38
  else
data/examples/nonogram CHANGED
@@ -15,7 +15,7 @@ class Nonogram
15
15
  @ysize.times do |y|
16
16
  @xsize.times do |x|
17
17
  v = @model[@cells[y][x]]
18
- if v.to_s == "true"
18
+ if v.to_b
19
19
  print "\u2588"
20
20
  else
21
21
  print "\u00b7"
@@ -26,7 +26,7 @@ class Nonogram
26
26
  end
27
27
 
28
28
  def print_all_answers!
29
- if @solver.check == :sat
29
+ if @solver.satisfiable?
30
30
  @model = @solver.model
31
31
  print_answer!
32
32
  current_solution = []
@@ -36,7 +36,7 @@ class Nonogram
36
36
  # current_solution << (@model[var] != val)
37
37
  # end
38
38
  # @solver.assert Z3.Or(*current_solution)
39
- # if @solver.check == :sat
39
+ # if @solver.satisfiable?
40
40
  # puts "solution is not unique"
41
41
  # print_answer!
42
42
  # else
data/examples/selfref CHANGED
@@ -192,10 +192,10 @@ class SelfRefPuzzleSolver
192
192
  assert q[20] == 5
193
193
 
194
194
  # Print solutions
195
- if @solver.check == :sat
195
+ if @solver.satisfiable?
196
196
  model = @solver.model
197
197
  (1..20).each do |i|
198
- a = model[q[i]].to_s.to_i
198
+ a = model[q[i]].to_i
199
199
  puts "Q%2d: %s" % [i, " ABCDE"[a]]
200
200
  end
201
201
  else
data/examples/sudoku CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
-
4
3
  require "pathname"
5
4
  require_relative "../lib/z3"
6
5
 
@@ -33,7 +32,7 @@ class SudokuSolver
33
32
  end
34
33
  end
35
34
 
36
- if @solver.check == :sat
35
+ if @solver.satisfiable?
37
36
  @model = @solver.model
38
37
  print_answer!
39
38
  else
@@ -23,7 +23,7 @@ class VerbalArithmetic
23
23
  @solver.assert word_value(@a) + word_value(@b) == word_value(@c)
24
24
  @solver.assert Z3.Distinct(*@vars.values)
25
25
 
26
- if @solver.check == :sat
26
+ if @solver.satisfiable?
27
27
  @model = @solver.model
28
28
  print_answer!
29
29
  else
@@ -39,7 +39,7 @@ class VerbalArithmetic
39
39
 
40
40
  def print_answer!
41
41
  [@a,@b,@c].each do |word|
42
- p word.map{|v| [v.to_s, @model[v].to_s.to_i]}
42
+ p word.map{|v| [v.to_s, @model[v].to_i]}
43
43
  end
44
44
  end
45
45
  end
Binary file
@@ -28,6 +28,21 @@ module Z3
28
28
  BoolExpr.IfThenElse(self, a, b)
29
29
  end
30
30
 
31
+ def to_b
32
+ s = to_s
33
+ if ast_kind == :app and (s == "true" or s == "false")
34
+ s == "true"
35
+ else
36
+ obj = simplify
37
+ s = obj.to_s
38
+ if ast_kind == :app and (s == "true" or s == "false")
39
+ s == "true"
40
+ else
41
+ raise Z3::Exception, "Can't convert expression #{to_s} to Boolean"
42
+ end
43
+ end
44
+ end
45
+
31
46
  public_class_method :new
32
47
 
33
48
  class << self
@@ -8,6 +8,19 @@ module Z3
8
8
  IntExpr.Rem(self, other)
9
9
  end
10
10
 
11
+ def to_i
12
+ if ast_kind == :numeral
13
+ LowLevel.get_numeral_string(self).to_i
14
+ else
15
+ obj = simplify
16
+ if obj.ast_kind == :numeral
17
+ LowLevel.get_numeral_string(obj).to_i
18
+ else
19
+ raise Z3::Exception, "Can't convert expression #{to_s} to Integer"
20
+ end
21
+ end
22
+ end
23
+
11
24
  public_class_method :new
12
25
  class << self
13
26
  def coerce_to_same_int_sort(*args)
data/lib/z3/solver.rb CHANGED
@@ -4,32 +4,50 @@ module Z3
4
4
  def initialize
5
5
  @_solver = LowLevel.mk_solver
6
6
  LowLevel.solver_inc_ref(self)
7
+ reset_model!
7
8
  end
8
9
 
9
10
  def push
11
+ reset_model!
10
12
  LowLevel.solver_push(self)
11
13
  end
12
14
 
13
15
  def pop(n=1)
16
+ reset_model!
14
17
  LowLevel.solver_pop(self, n)
15
18
  end
16
19
 
17
20
  def reset
21
+ reset_model!
18
22
  LowLevel.solver_reset(self)
19
23
  end
20
24
 
21
25
  def assert(ast)
26
+ reset_model!
22
27
  LowLevel.solver_assert(self, ast)
23
28
  end
24
29
 
25
30
  def check
26
- check_sat_results(LowLevel.solver_check(self))
31
+ reset_model!
32
+ result = check_sat_results(LowLevel.solver_check(self))
33
+ @has_model = true if result == :sat
34
+ result
35
+ end
36
+
37
+ def satisfiable?
38
+ check == :sat
39
+ end
40
+
41
+ def unsatisfiable?
42
+ check == :unsat
27
43
  end
28
44
 
29
45
  def model
30
- Z3::Model.new(
31
- LowLevel.solver_get_model(self)
32
- )
46
+ if @has_model
47
+ @model ||= Z3::Model.new(LowLevel.solver_get_model(self))
48
+ else
49
+ raise Z3::Exception, "You need to check that it's satisfiable before asking for the model"
50
+ end
33
51
  end
34
52
 
35
53
  def assertions
@@ -43,6 +61,7 @@ module Z3
43
61
  end
44
62
 
45
63
  def prove!(ast)
64
+ @has_model = false
46
65
  push
47
66
  assert(~ast)
48
67
  case check
@@ -64,6 +83,11 @@ module Z3
64
83
 
65
84
  private
66
85
 
86
+ def reset_model!
87
+ @has_model = false
88
+ @model = nil
89
+ end
90
+
67
91
  def check_sat_results(r)
68
92
  {
69
93
  -1 => :unsat,
Binary file
data/spec/.DS_Store ADDED
Binary file
@@ -57,11 +57,18 @@ module Z3
57
57
  it "~" do
58
58
  expect([a == true, b == ~a]).to have_solution(b => false)
59
59
  expect([a == false, b == ~a]).to have_solution(b => true)
60
- end
60
+ end
61
+
62
+ it "if then else" do
63
+ expect([a == true, x == a.ite(2, 3)]).to have_solution(x => 2)
64
+ expect([a == false, x == a.ite(2, 3)]).to have_solution(x => 3)
65
+ end
61
66
 
62
- it "if then else" do
63
- expect([a == true, x == a.ite(2, 3)]).to have_solution(x => 2)
64
- expect([a == false, x == a.ite(2, 3)]).to have_solution(x => 3)
65
- end
67
+ it "to_b" do
68
+ expect{Z3.Bool("a").to_b}.to raise_error(Z3::Exception)
69
+ expect(Z3.Const(true).to_b).to eq(true)
70
+ expect(Z3.Const(false).to_b).to eq(false)
71
+ expect((Z3.Const(true) & Z3.Const(false)).to_b).to eq(false)
72
+ end
66
73
  end
67
74
  end
@@ -87,5 +87,11 @@ module Z3
87
87
  expect((a+b).inspect).to eq("Int<5 + 3>")
88
88
  expect((a+b).simplify.inspect).to eq("Int<8>")
89
89
  end
90
+
91
+ it "to_i" do
92
+ expect{Z3.Int("a").to_i}.to raise_error(Z3::Exception)
93
+ expect(Z3.Const(2).to_i).to eq(2)
94
+ expect((Z3.Const(2) + Z3.Const(40)).to_i).to eq(42)
95
+ end
90
96
  end
91
97
  end
data/spec/model_spec.rb CHANGED
@@ -10,7 +10,7 @@ module Z3
10
10
  it "knows how many variables are in the model" do
11
11
  solver.assert(a == 2)
12
12
  solver.assert(b == a+2)
13
- expect(solver.check).to eq(:sat)
13
+ expect(solver).to be_satisfiable
14
14
  expect(model.num_consts).to eq(2)
15
15
  expect(model.num_funcs).to eq(0)
16
16
  expect(model.num_sorts).to eq(0)
@@ -19,7 +19,7 @@ module Z3
19
19
  it "can evaluate variables" do
20
20
  solver.assert(a == 2)
21
21
  solver.assert(b == a+2)
22
- expect(solver.check).to eq(:sat)
22
+ expect(solver).to be_satisfiable
23
23
  expect(model.model_eval(a)).to be_same_as(Z3.Const(2))
24
24
  expect(model.model_eval(b)).to be_same_as(Z3.Const(4))
25
25
  expect(model.model_eval(c)).to be_same_as(c)
@@ -31,14 +31,14 @@ module Z3
31
31
  it "#to_a" do
32
32
  solver.assert(a == 2)
33
33
  solver.assert(b == a+2)
34
- expect(solver.check).to eq(:sat)
34
+ expect(solver).to be_satisfiable
35
35
  expect(model.to_a).to be_same_as([[Z3.Int("a"), Z3.Const(2)], [Z3.Int("b"), Z3.Const(4)]])
36
36
  end
37
37
 
38
38
  it "#to_s" do
39
39
  solver.assert(a == 2)
40
40
  solver.assert(b == a+2)
41
- expect(solver.check).to eq(:sat)
41
+ expect(solver).to be_satisfiable
42
42
  expect(model.to_s).to eq("Z3::Model<a=2, b=4>")
43
43
  expect(model.inspect).to eq("Z3::Model<a=2, b=4>")
44
44
  end
data/spec/solver_spec.rb CHANGED
@@ -7,18 +7,18 @@ module Z3
7
7
 
8
8
  it "basic functionality" do
9
9
  solver.assert(a == b)
10
- expect(solver.check).to eq(:sat)
10
+ expect(solver).to be_satisfiable
11
11
  solver.assert(a != b)
12
- expect(solver.check).to eq(:unsat)
12
+ expect(solver).to be_unsatisfiable
13
13
  end
14
14
 
15
15
  it "push/pop" do
16
16
  solver.assert(a == b)
17
17
  solver.push
18
18
  solver.assert(a != b)
19
- expect(solver.check).to eq(:unsat)
19
+ expect(solver).to be_unsatisfiable
20
20
  solver.pop
21
- expect(solver.check).to eq(:sat)
21
+ expect(solver).to be_satisfiable
22
22
  end
23
23
 
24
24
  it "#assertions" do
data/spec/spec_helper.rb CHANGED
@@ -74,12 +74,12 @@ end
74
74
  RSpec::Matchers.define :have_solution do |expected|
75
75
  match do |asts|
76
76
  solver = setup_solver(asts)
77
- solver.check == :sat and expected.all?{|var,val| solver.model[var].to_s == val.to_s}
77
+ solver.satisfiable? and expected.all?{|var,val| solver.model[var].to_s == val.to_s}
78
78
  end
79
79
 
80
80
  failure_message do |asts|
81
81
  solver = setup_solver(asts)
82
- if solver.check == :sat
82
+ if solver.satisfiable?
83
83
  "expected #{asts.inspect} to have solution #{expected.inspect}, instead got #{solver.model}"
84
84
  else
85
85
  "expected #{asts.inspect} to have solution #{expected.inspect}, instead not solvable"
@@ -112,7 +112,7 @@ RSpec::Matchers.define :have_solutions do |expected|
112
112
  vars = vars[0]
113
113
  solver = setup_solver(asts)
114
114
  solutions = []
115
- while solver.check == :sat
115
+ while solver.satisfiable?
116
116
  model = solver.model
117
117
  solution = Hash[vars.map{|v| [v, model.model_eval(v, true)] }]
118
118
  solutions << solution
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.20161008
4
+ version: 0.0.20161010
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-08 00:00:00.000000000 Z
11
+ date: 2016-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -118,6 +118,7 @@ files:
118
118
  - lib/z3/ast.rb
119
119
  - lib/z3/context.rb
120
120
  - lib/z3/exception.rb
121
+ - lib/z3/expr/.DS_Store
121
122
  - lib/z3/expr/arith_expr.rb
122
123
  - lib/z3/expr/array_expr.rb
123
124
  - lib/z3/expr/bitvec_expr.rb
@@ -137,6 +138,7 @@ files:
137
138
  - lib/z3/printer.rb
138
139
  - lib/z3/probe.rb
139
140
  - lib/z3/solver.rb
141
+ - lib/z3/sort/.DS_Store
140
142
  - lib/z3/sort/array_sort.rb
141
143
  - lib/z3/sort/bitvec_sort.rb
142
144
  - lib/z3/sort/bool_sort.rb
@@ -149,6 +151,7 @@ files:
149
151
  - lib/z3/tactic.rb
150
152
  - lib/z3/very_low_level.rb
151
153
  - lib/z3/very_low_level_auto.rb
154
+ - spec/.DS_Store
152
155
  - spec/array_expr_spec.rb
153
156
  - spec/array_sort_spec.rb
154
157
  - spec/bitvec_expr_spec.rb