z3 0.0.20160330 → 0.0.20160427

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -0
  3. data/examples/{bridges_solver → bridges} +5 -12
  4. data/examples/bridges-1.txt +7 -0
  5. data/examples/{clogic_puzzle_solver → clogic_puzzle} +0 -0
  6. data/examples/four_hackers_puzzle +2 -1
  7. data/examples/{kakuro_solver → kakuro} +5 -15
  8. data/examples/kakuro-1.txt +10 -0
  9. data/examples/{knights_puzzle_solver → knights_puzzle} +4 -4
  10. data/examples/{letter_connections_solver → letter_connections} +6 -15
  11. data/examples/letter_connections-1.txt +10 -0
  12. data/examples/{light_up_solver → light_up} +5 -12
  13. data/examples/light_up-1.txt +7 -0
  14. data/examples/{minisudoku_solver → minisudoku} +8 -11
  15. data/examples/minisudoku-1.txt +6 -0
  16. data/examples/nonogram +152 -0
  17. data/examples/{selfref_solver → selfref} +0 -0
  18. data/examples/{sudoku_solver → sudoku} +9 -14
  19. data/examples/sudoku-1.txt +9 -0
  20. data/lib/z3.rb +10 -6
  21. data/lib/z3/ast.rb +33 -0
  22. data/lib/z3/{value/arith_value.rb → expr/arith_expr.rb} +3 -3
  23. data/lib/z3/{value/bitvec_value.rb → expr/bitvec_expr.rb} +1 -1
  24. data/lib/z3/{value/bool_value.rb → expr/bool_expr.rb} +5 -1
  25. data/lib/z3/{value/value.rb → expr/expr.rb} +7 -13
  26. data/lib/z3/expr/int_expr.rb +15 -0
  27. data/lib/z3/{value/int_value.rb → expr/real_expr.rb} +2 -2
  28. data/lib/z3/func_decl.rb +33 -23
  29. data/lib/z3/interface.rb +52 -30
  30. data/lib/z3/low_level.rb +10 -1
  31. data/lib/z3/low_level_auto.rb +83 -83
  32. data/lib/z3/model.rb +6 -5
  33. data/lib/z3/printer.rb +26 -0
  34. data/lib/z3/solver.rb +1 -5
  35. data/lib/z3/sort/bitvec_sort.rb +3 -3
  36. data/lib/z3/sort/bool_sort.rb +4 -4
  37. data/lib/z3/sort/int_sort.rb +2 -2
  38. data/lib/z3/sort/real_sort.rb +5 -5
  39. data/lib/z3/sort/sort.rb +22 -7
  40. data/lib/z3/very_low_level.rb +1 -1
  41. data/spec/bitvec_expr_spec.rb +55 -0
  42. data/spec/bitvec_sort_spec.rb +34 -0
  43. data/spec/bool_expr_spec.rb +65 -0
  44. data/spec/bool_sort_spec.rb +20 -0
  45. data/spec/{value_spec.rb → expr_spec.rb} +3 -3
  46. data/spec/int_expr_spec.rb +78 -0
  47. data/spec/int_sort_spec.rb +18 -0
  48. data/spec/integration/algebra_problems_spec.rb +19 -20
  49. data/spec/integration/basic_int_math_spec.rb +4 -5
  50. data/spec/integration/basic_logic_spec.rb +3 -4
  51. data/spec/integration/bit_tricks_spec.rb +2 -3
  52. data/spec/integration/bridges_spec.rb +2 -3
  53. data/spec/integration/four_hackers_puzzle_spec.rb +26 -0
  54. data/spec/integration/geometry_problem_spec.rb +10 -11
  55. data/spec/integration/kakuro_spec.rb +2 -3
  56. data/spec/integration/kinematics_problems_spec.rb +36 -37
  57. data/spec/integration/knights_puzzle_spec.rb +96 -0
  58. data/spec/integration/letter_connections_spec.rb +2 -3
  59. data/spec/integration/light_up_spec.rb +3 -4
  60. data/spec/integration/minisudoku_spec.rb +2 -3
  61. data/spec/integration/nonogram_spec.rb +26 -0
  62. data/spec/integration/selfref_spec.rb +2 -3
  63. data/spec/integration/sudoku_spec.rb +2 -3
  64. data/spec/integration/verbal_arithmetic_spec.rb +2 -3
  65. data/spec/model_spec.rb +13 -6
  66. data/spec/printer_spec.rb +22 -0
  67. data/spec/real_expr_spec.rb +64 -0
  68. data/spec/real_sort_spec.rb +24 -0
  69. data/spec/solver_spec.rb +11 -0
  70. data/spec/spec_helper.rb +39 -64
  71. metadata +81 -18
  72. data/lib/z3/value/real_value.rb +0 -7
@@ -11,7 +11,9 @@ class Z3::Model
11
11
  end
12
12
 
13
13
  def consts
14
- (0...num_consts).map{|i| Z3::FuncDecl.new(Z3::LowLevel.model_get_const_decl(self, i)) }
14
+ (0...num_consts).map do |i|
15
+ Z3::FuncDecl.new(Z3::LowLevel.model_get_const_decl(self, i))
16
+ end
15
17
  end
16
18
 
17
19
  def num_sorts
@@ -23,7 +25,7 @@ class Z3::Model
23
25
  end
24
26
 
25
27
  def model_eval(ast, model_completion=false)
26
- Z3::Value.new_from_pointer(Z3::LowLevel.model_eval(self, ast, model_completion))
28
+ Z3::Expr.new_from_pointer(Z3::LowLevel.model_eval(self, ast, model_completion))
27
29
  end
28
30
 
29
31
  def [](ast)
@@ -40,10 +42,9 @@ class Z3::Model
40
42
 
41
43
  def each
42
44
  consts.sort_by(&:name).each do |c|
43
- _ast = Z3::LowLevel.model_get_const_interp(self, c)
44
45
  yield(
45
- c.name,
46
- Z3::Value.new_from_pointer(_ast)
46
+ c.range.var(c.name),
47
+ Z3::Expr.new_from_pointer(Z3::LowLevel.model_get_const_interp(self, c))
47
48
  )
48
49
  end
49
50
  end
@@ -0,0 +1,26 @@
1
+ module Z3
2
+ class Printer
3
+ def format(a)
4
+ case a.ast_kind
5
+ when :numeral
6
+ format_numeral(a)
7
+ when :app
8
+ a.sexpr
9
+ when :var
10
+ a.sexpr
11
+ when :quantifier
12
+ a.sexpr
13
+ when :func_decl
14
+ a.sexpr
15
+ when :unknown
16
+ a.sexpr
17
+ else
18
+ raise Z3::Exception, "Unknown AST kind #{a.ast_kind}"
19
+ end
20
+ end
21
+
22
+ def format_numeral(a)
23
+ Z3::LowLevel.get_numeral_string(a)
24
+ end
25
+ end
26
+ end
@@ -34,11 +34,7 @@ module Z3
34
34
 
35
35
  def assertions
36
36
  _ast_vector = Z3::LowLevel.solver_get_assertions(self)
37
- n = Z3::VeryLowLevel.Z3_ast_vector_size(Z3::LowLevel._ctx_pointer, _ast_vector)
38
- (0...n).map{|i|
39
- _ast = Z3::VeryLowLevel.Z3_ast_vector_get(Z3::LowLevel._ctx_pointer, _ast_vector, i)
40
- Z3::Value.new_from_pointer(_ast)
41
- }
37
+ Z3::LowLevel.unpack_ast_vector(_ast_vector)
42
38
  end
43
39
 
44
40
  def prove!(ast)
@@ -4,12 +4,12 @@ module Z3
4
4
  super LowLevel.mk_bv_sort(n)
5
5
  end
6
6
 
7
- def value_class
8
- BitvecValue
7
+ def expr_class
8
+ BitvecExpr
9
9
  end
10
10
 
11
11
  def from_const(val)
12
- if val.is_a?(Integer) or val.is_a?(Float)
12
+ if val.is_a?(Integer)
13
13
  new LowLevel.mk_numeral(val.to_s, self)
14
14
  else
15
15
  raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
@@ -4,15 +4,15 @@ module Z3
4
4
  super LowLevel.mk_bool_sort
5
5
  end
6
6
 
7
- def value_class
8
- BoolValue
7
+ def expr_class
8
+ BoolExpr
9
9
  end
10
10
 
11
11
  def from_const(val)
12
12
  if val == true
13
- BoolValue.new(LowLevel.mk_true, self)
13
+ BoolExpr.new(LowLevel.mk_true, self)
14
14
  elsif val == false
15
- BoolValue.new(LowLevel.mk_false, self)
15
+ BoolExpr.new(LowLevel.mk_false, self)
16
16
  else
17
17
  raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
18
18
  end
@@ -4,8 +4,8 @@ module Z3
4
4
  super LowLevel.mk_int_sort
5
5
  end
6
6
 
7
- def value_class
8
- IntValue
7
+ def expr_class
8
+ IntExpr
9
9
  end
10
10
 
11
11
  def from_const(val)
@@ -4,12 +4,12 @@ module Z3
4
4
  super LowLevel.mk_real_sort
5
5
  end
6
6
 
7
- def value_class
8
- RealValue
7
+ def expr_class
8
+ RealExpr
9
9
  end
10
10
 
11
11
  def from_const(val)
12
- if val.is_a?(Integer) or val.is_a?(Float)
12
+ if val.is_a?(Integer) or (val.is_a?(Float) and val.finite?)
13
13
  new LowLevel.mk_numeral(val.to_s, self)
14
14
  else
15
15
  raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
@@ -17,9 +17,9 @@ module Z3
17
17
  end
18
18
 
19
19
  def from_value(val)
20
- if val.is_a?(IntValue)
20
+ if val.is_a?(IntExpr)
21
21
  new LowLevel.mk_int2real(val)
22
- elsif val.is_a?(RealValue)
22
+ elsif val.is_a?(RealExpr)
23
23
  val
24
24
  else
25
25
  raise Z3::Exception, "Cannot convert #{val.class} to #{self.class}"
@@ -1,13 +1,13 @@
1
1
  module Z3
2
- class Sort
3
- attr_reader :_sort
4
- def initialize(_sort)
5
- @_sort = _sort
2
+ class Sort < AST
3
+ def initialize(_ast)
4
+ super(_ast)
5
+ raise Z3::Exception, "Sorts must have AST kind sort" unless ast_kind == :sort
6
6
  end
7
7
 
8
8
  include Comparable
9
9
  def ==(other)
10
- other.is_a?(Sort) and @_sort == other._sort
10
+ other.is_a?(Sort) and @_ast == other._ast
11
11
  end
12
12
 
13
13
  def >(other)
@@ -59,7 +59,7 @@ module Z3
59
59
 
60
60
  # We pretend to be a class, sort of
61
61
  def new(_ast)
62
- value_class.new(_ast, self)
62
+ expr_class.new(_ast, self)
63
63
  end
64
64
 
65
65
  def value_class
@@ -71,6 +71,21 @@ module Z3
71
71
  raise Z3::Exception, "Can't convert #{v.sort} into #{self}"
72
72
  end
73
73
 
74
- private_class_method :new
74
+ def self.from_pointer(_sort)
75
+ kind = Z3::VeryLowLevel.Z3_get_sort_kind(Z3::LowLevel._ctx_pointer, _sort)
76
+ case kind
77
+ when 1
78
+ BoolSort.new
79
+ when 2
80
+ IntSort.new
81
+ when 3
82
+ RealSort.new
83
+ when 4
84
+ n = Z3::VeryLowLevel.Z3_get_bv_sort_size(Z3::LowLevel._ctx_pointer, _sort)
85
+ BitvecSort.new(n)
86
+ else
87
+ raise "Unknown sort kind #{kind}"
88
+ end
89
+ end
75
90
  end
76
91
  end
@@ -29,7 +29,7 @@ module Z3::VeryLowLevel
29
29
  callback :error_handler, [:pointer, :int], :void
30
30
  attach_function :Z3_get_version, [:pointer, :pointer, :pointer, :pointer], :void
31
31
  attach_function :Z3_set_error_handler, [:ctx_pointer, :error_handler], :void
32
- attach_function :Z3_mk_context, [], :ctx_pointer
32
+ attach_function :Z3_mk_context, [:config_pointer], :ctx_pointer
33
33
  attach_function :Z3_model_eval, [:ctx_pointer, :model_pointer, :ast_pointer, :bool, :pointer], :int
34
34
  attach_function :Z3_mk_and, [:ctx_pointer, :int, :pointer], :ast_pointer
35
35
  attach_function :Z3_mk_or, [:ctx_pointer, :int, :pointer], :ast_pointer
@@ -0,0 +1,55 @@
1
+ describe Z3::BitvecExpr do
2
+ let(:a) { Z3::Bitvec("a", 8) }
3
+ let(:b) { Z3::Bitvec("b", 8) }
4
+ let(:c) { Z3::Bitvec("c", 8) }
5
+ let(:x) { Z3::Bool("x") }
6
+
7
+ it "==" do
8
+ expect([a == 2, b == -254, x == (a == b)]).to have_solution(x => true)
9
+ expect([a == 2, b == 2, x == (a == b)]).to have_solution(x => true)
10
+ expect([a == 2, b == 3, x == (a == b)]).to have_solution(x => false)
11
+ end
12
+
13
+ it "!=" do
14
+ expect([a == 2, b == -254, x == (a != b)]).to have_solution(x => false)
15
+ expect([a == 2, b == 2, x == (a != b)]).to have_solution(x => false)
16
+ expect([a == 2, b == 3, x == (a != b)]).to have_solution(x => true)
17
+ end
18
+
19
+ it "+" do
20
+ expect([a == 2, b == 40, c == (a + b)]).to have_solution(c => 42)
21
+ expect([a == 200, b == 40, c == (a + b)]).to have_solution(c => 240)
22
+ expect([a == -1, b == -1, c == (a + b)]).to have_solution(c => 254)
23
+ end
24
+
25
+ it "-" do
26
+ expect([a == 50, b == 8, c == (a - b)]).to have_solution(c => 42)
27
+ expect([a == 200, b == 40, c == (a - b)]).to have_solution(c => 160)
28
+ expect([a == 40, b == 200, c == (a - b)]).to have_solution(c => 96)
29
+ end
30
+
31
+ it "*" do
32
+ expect([a == 3, b == 40, c == (a * b)]).to have_solution(c => 120)
33
+ expect([a == 30, b == 42, c == (a * b)]).to have_solution(c => 236)
34
+ end
35
+
36
+ it "&" do
37
+ expect([a == 50, b == 27, c == (a & b)]).to have_solution(c => 18)
38
+ end
39
+
40
+ it "|" do
41
+ expect([a == 50, b == 27, c == (a | b)]).to have_solution(c => 59)
42
+ end
43
+
44
+ it "^" do
45
+ expect([a == 50, b == 27, c == (a ^ b)]).to have_solution(c => 41)
46
+ end
47
+
48
+ it "unary -" do
49
+ expect([a == 50, b == -a]).to have_solution(b => 206)
50
+ end
51
+
52
+ it "~" do
53
+ expect([a == 50, b == ~a]).to have_solution(b => 205)
54
+ end
55
+ end
@@ -0,0 +1,34 @@
1
+ describe Z3::BitvecSort do
2
+ let(:bv3) { Z3::BitvecSort.new(3) }
3
+ let(:bv8) { Z3::BitvecSort.new(8) }
4
+ let(:bv32) { Z3::BitvecSort.new(32) }
5
+
6
+ it "can instantiate constants - 32 bit" do
7
+ expect(bv32.from_const(0).inspect).to eq("Bitvec(32)<0>")
8
+ expect(bv32.from_const(42).inspect).to eq("Bitvec(32)<42>")
9
+ expect(bv32.from_const(0x1234_5678_9abc).inspect).to eq("Bitvec(32)<1450744508>")
10
+ expect(bv32.from_const(-0x1234_5678_9abc).inspect).to eq("Bitvec(32)<2844222788>")
11
+ end
12
+
13
+ it "can instantiate constants - 8 bit" do
14
+ expect(bv8.from_const(0).inspect).to eq("Bitvec(8)<0>")
15
+ expect(bv8.from_const(42).inspect).to eq("Bitvec(8)<42>")
16
+ expect(bv8.from_const(0x1234_5678_9abc).inspect).to eq("Bitvec(8)<188>")
17
+ expect(bv8.from_const(-0x1234_5678_9abc).inspect).to eq("Bitvec(8)<68>")
18
+ end
19
+
20
+ it "can instantiate constants - 3 bit" do
21
+ expect(bv3.from_const(-1).inspect).to eq("Bitvec(3)<7>")
22
+ end
23
+
24
+ it "raisesbv32 exception when trying to convert constants of wrong type" do
25
+ expect{ bv32.from_const(true) }.to raise_error(Z3::Exception)
26
+ expect{ bv32.from_const(false) }.to raise_error(Z3::Exception)
27
+ expect{ bv32.from_const(0.0) }.to raise_error(Z3::Exception)
28
+ end
29
+
30
+ it "can instantiate variables" do
31
+ expect(Z3.Bitvec("a", 8).inspect).to eq("Bitvec(8)<a>")
32
+ expect(Z3.Bitvec("a", 32).inspect).to eq("Bitvec(32)<a>")
33
+ end
34
+ end
@@ -0,0 +1,65 @@
1
+ describe Z3::BoolExpr do
2
+ let(:a) { Z3::Bool("a") }
3
+ let(:b) { Z3::Bool("b") }
4
+ let(:c) { Z3::Bool("c") }
5
+ let(:x) { Z3::Int("x") }
6
+
7
+ it "&" do
8
+ expect([a == true, b == true, c == (a & b)]).to have_solution(c => true)
9
+ expect([a == true, b == false, c == (a & b)]).to have_solution(c => false)
10
+ expect([a == false, b == true, c == (a & b)]).to have_solution(c => false)
11
+ expect([a == false, b == false, c == (a & b)]).to have_solution(c => false)
12
+ end
13
+
14
+ it "|" do
15
+ expect([a == true, b == true, c == (a | b)]).to have_solution(c => true)
16
+ expect([a == true, b == false, c == (a | b)]).to have_solution(c => true)
17
+ expect([a == false, b == true, c == (a | b)]).to have_solution(c => true)
18
+ expect([a == false, b == false, c == (a | b)]).to have_solution(c => false)
19
+ end
20
+
21
+ it "^" do
22
+ expect([a == true, b == true, c == (a ^ b)]).to have_solution(c => false)
23
+ expect([a == true, b == false, c == (a ^ b)]).to have_solution(c => true)
24
+ expect([a == false, b == true, c == (a ^ b)]).to have_solution(c => true)
25
+ expect([a == false, b == false, c == (a ^ b)]).to have_solution(c => false)
26
+ end
27
+
28
+ it "!=" do
29
+ expect([a == true, b == true, c == (a != b)]).to have_solution(c => false)
30
+ expect([a == true, b == false, c == (a != b)]).to have_solution(c => true)
31
+ expect([a == false, b == true, c == (a != b)]).to have_solution(c => true)
32
+ expect([a == false, b == false, c == (a != b)]).to have_solution(c => false)
33
+ end
34
+
35
+ it "implies" do
36
+ expect([a == true, b == true, c == a.implies(b)]).to have_solution(c => true)
37
+ expect([a == true, b == false, c == a.implies(b)]).to have_solution(c => false)
38
+ expect([a == false, b == true, c == a.implies(b)]).to have_solution(c => true)
39
+ expect([a == false, b == false, c == a.implies(b)]).to have_solution(c => true)
40
+ end
41
+
42
+ it "iff" do
43
+ expect([a == true, b == true, c == a.iff(b)]).to have_solution(c => true)
44
+ expect([a == true, b == false, c == a.iff(b)]).to have_solution(c => false)
45
+ expect([a == false, b == true, c == a.iff(b)]).to have_solution(c => false)
46
+ expect([a == false, b == false, c == a.iff(b)]).to have_solution(c => true)
47
+ end
48
+
49
+ it "==" do
50
+ expect([a == true, b == true, c == (a == b)]).to have_solution(c => true)
51
+ expect([a == true, b == false, c == (a == b)]).to have_solution(c => false)
52
+ expect([a == false, b == true, c == (a == b)]).to have_solution(c => false)
53
+ expect([a == false, b == false, c == (a == b)]).to have_solution(c => true)
54
+ end
55
+
56
+ it "~" do
57
+ expect([a == true, b == ~a]).to have_solution(b => false)
58
+ expect([a == false, b == ~a]).to have_solution(b => true)
59
+ end
60
+
61
+ it "if then else" do
62
+ expect([a == true, x == a.ite(2, 3)]).to have_solution(x => 2)
63
+ expect([a == false, x == a.ite(2, 3)]).to have_solution(x => 3)
64
+ end
65
+ end
@@ -0,0 +1,20 @@
1
+ describe Z3::BoolSort do
2
+ it "can instantiate constants" do
3
+ expect(subject.from_const(true).inspect).to eq("Bool<true>")
4
+ expect(subject.from_const(false).inspect).to eq("Bool<false>")
5
+ end
6
+
7
+ it "raises exception when trying to convert constants of wrong type" do
8
+ expect{ subject.from_const(0) }.to raise_error(Z3::Exception)
9
+ expect{ subject.from_const(0.0) }.to raise_error(Z3::Exception)
10
+ end
11
+
12
+ it "interface constructors" do
13
+ expect(Z3.True.inspect).to eq("Bool<true>")
14
+ expect(Z3.False.inspect).to eq("Bool<false>")
15
+ end
16
+
17
+ it "can instantiate variables" do
18
+ expect(Z3.Bool("a").inspect).to eq("Bool<a>")
19
+ end
20
+ end
@@ -1,4 +1,4 @@
1
- describe Z3::Value do
1
+ describe Z3::Expr do
2
2
  let(:a) { Z3.Int("a") }
3
3
  let(:b) { Z3.Int("b") }
4
4
  let(:c) { Z3.Bool("c") }
@@ -17,8 +17,8 @@ describe Z3::Value do
17
17
  end
18
18
 
19
19
  it "#inspect" do
20
- expect(a.inspect).to eq("Value<a :: Int>")
21
- expect((e+f).inspect).to eq("Value<(+ e f) :: Real>")
20
+ expect(a.inspect).to eq("Int<a>")
21
+ expect((e+f).inspect).to eq("Real<(+ e f)>")
22
22
  end
23
23
 
24
24
  describe "#~" do
@@ -0,0 +1,78 @@
1
+ describe Z3::IntExpr do
2
+ let(:a) { Z3::Int("a") }
3
+ let(:b) { Z3::Int("b") }
4
+ let(:c) { Z3::Int("c") }
5
+ let(:x) { Z3::Bool("x") }
6
+
7
+ it "+" do
8
+ expect([a == 2, b == 4, c == a + b]).to have_solution(c => 6)
9
+ end
10
+
11
+ it "-" do
12
+ expect([a == 2, b == 4, c == a - b]).to have_solution(c => -2)
13
+ end
14
+
15
+ it "*" do
16
+ expect([a == 2, b == 4, c == a * b]).to have_solution(c => 8)
17
+ end
18
+
19
+ it "/" do
20
+ expect([a == 10, b == 3, c == a / b]).to have_solution(c => 3)
21
+ expect([a == -10, b == 3, c == a / b]).to have_solution(c => -4)
22
+ expect([a == 10, b == -3, c == a / b]).to have_solution(c => -3)
23
+ expect([a == -10, b == -3, c == a / b]).to have_solution(c => 4)
24
+ end
25
+
26
+ # Can't say these make much sense, but let's document what Z3 actually does
27
+ it "rem" do
28
+ expect([a == 10, b == 3, c == a.rem(b)]).to have_solution(c => 10 - 3 * 3)
29
+ expect([a == -10, b == 3, c == a.rem(b)]).to have_solution(c =>-10 - 3 * -4)
30
+ expect([a == 10, b == -3, c == a.rem(b)]).to have_solution(c =>-( 10 - -3 * -3))
31
+ expect([a == -10, b == -3, c == a.rem(b)]).to have_solution(c =>-(-10 - -3 * 4))
32
+ end
33
+
34
+ it "mod" do
35
+ expect([a == 10, b == 3, c == a.mod(b)]).to have_solution(c => 1)
36
+ expect([a == 10, b == -3, c == a.mod(b)]).to have_solution(c => 1)
37
+ expect([a == -10, b == 3, c == a.mod(b)]).to have_solution(c => 2)
38
+ expect([a == -10, b == -3, c == a.mod(b)]).to have_solution(c => 2)
39
+ end
40
+
41
+ it "==" do
42
+ expect([a == 2, b == 2, x == (a == b)]).to have_solution(x => true)
43
+ expect([a == 2, b == 3, x == (a == b)]).to have_solution(x => false)
44
+ end
45
+
46
+ it "!=" do
47
+ expect([a == 2, b == 2, x == (a != b)]).to have_solution(x => false)
48
+ expect([a == 2, b == 3, x == (a != b)]).to have_solution(x => true)
49
+ end
50
+
51
+ it ">" do
52
+ expect([a == 3, b == 2, x == (a > b)]).to have_solution(x => true)
53
+ expect([a == 2, b == 2, x == (a > b)]).to have_solution(x => false)
54
+ expect([a == 1, b == 2, x == (a > b)]).to have_solution(x => false)
55
+ end
56
+
57
+ it ">=" do
58
+ expect([a == 3, b == 2, x == (a >= b)]).to have_solution(x => true)
59
+ expect([a == 2, b == 2, x == (a >= b)]).to have_solution(x => true)
60
+ expect([a == 1, b == 2, x == (a >= b)]).to have_solution(x => false)
61
+ end
62
+
63
+ it "<" do
64
+ expect([a == 3, b == 2, x == (a < b)]).to have_solution(x => false)
65
+ expect([a == 2, b == 2, x == (a < b)]).to have_solution(x => false)
66
+ expect([a == 1, b == 2, x == (a < b)]).to have_solution(x => true)
67
+ end
68
+
69
+ it "<=" do
70
+ expect([a == 3, b == 2, x == (a <= b)]).to have_solution(x => false)
71
+ expect([a == 2, b == 2, x == (a <= b)]).to have_solution(x => true)
72
+ expect([a == 1, b == 2, x == (a <= b)]).to have_solution(x => true)
73
+ end
74
+
75
+ it "**" do
76
+ expect([a == 3, b == 4, c == (a ** b)]).to have_solution(c => 81)
77
+ end
78
+ end