gecoder 0.8.3 → 0.9.0

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.
Files changed (142) hide show
  1. data/CHANGES +15 -0
  2. data/README +6 -2
  3. data/example/equation_system.rb +15 -0
  4. data/example/magic_sequence.rb +7 -7
  5. data/example/money.rb +36 -0
  6. data/example/queens.rb +7 -8
  7. data/example/send_most_money.rb +1 -1
  8. data/example/square_tiling.rb +2 -2
  9. data/example/sudoku-set.rb +11 -12
  10. data/example/sudoku.rb +40 -45
  11. data/ext/extconf.rb +0 -0
  12. data/lib/gecoder/bindings.rb +42 -0
  13. data/lib/gecoder/bindings/bindings.rb +16 -0
  14. data/lib/gecoder/interface.rb +2 -1
  15. data/lib/gecoder/interface/branch.rb +16 -9
  16. data/lib/gecoder/interface/constraints.rb +410 -451
  17. data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
  18. data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
  19. data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
  20. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
  21. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
  22. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
  23. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
  24. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
  25. data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
  26. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  27. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  28. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  29. data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
  30. data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
  31. data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
  32. data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
  33. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  34. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
  35. data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
  36. data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
  37. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
  38. data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
  39. data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
  40. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
  41. data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
  42. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
  43. data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
  44. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
  45. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  46. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  47. data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
  48. data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
  49. data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
  50. data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
  51. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  52. data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
  53. data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
  54. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  55. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  56. data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
  57. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
  58. data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
  59. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  60. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
  61. data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
  62. data/lib/gecoder/interface/enum_matrix.rb +4 -4
  63. data/lib/gecoder/interface/enum_wrapper.rb +71 -22
  64. data/lib/gecoder/interface/model.rb +167 -12
  65. data/lib/gecoder/interface/model_sugar.rb +84 -0
  66. data/lib/gecoder/interface/search.rb +30 -18
  67. data/lib/gecoder/interface/variables.rb +103 -33
  68. data/lib/gecoder/version.rb +2 -2
  69. data/specs/bool_var.rb +19 -12
  70. data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
  71. data/specs/constraints/bool/boolean_properties.rb +51 -0
  72. data/specs/constraints/bool/linear.rb +213 -0
  73. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  74. data/specs/constraints/bool_enum/channel.rb +102 -0
  75. data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
  76. data/specs/constraints/constraint_helper.rb +149 -179
  77. data/specs/constraints/constraint_receivers.rb +103 -0
  78. data/specs/constraints/constraints.rb +6 -63
  79. data/specs/constraints/fixnum_enum/element.rb +58 -0
  80. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  81. data/specs/constraints/int/arithmetic.rb +149 -0
  82. data/specs/constraints/int/channel.rb +101 -0
  83. data/specs/constraints/int/domain.rb +106 -0
  84. data/specs/constraints/int/linear.rb +183 -0
  85. data/specs/constraints/int/linear_properties.rb +97 -0
  86. data/specs/constraints/int/relation.rb +84 -0
  87. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  88. data/specs/constraints/int_enum/channel.rb +57 -0
  89. data/specs/constraints/int_enum/count.rb +72 -0
  90. data/specs/constraints/int_enum/distinct.rb +80 -0
  91. data/specs/constraints/int_enum/element.rb +61 -0
  92. data/specs/constraints/int_enum/equality.rb +29 -0
  93. data/specs/constraints/int_enum/extensional.rb +224 -0
  94. data/specs/constraints/int_enum/sort.rb +167 -0
  95. data/specs/constraints/operands.rb +264 -0
  96. data/specs/constraints/property_helper.rb +443 -0
  97. data/specs/constraints/reification_sugar.rb +4 -5
  98. data/specs/constraints/selected_set/select.rb +56 -0
  99. data/specs/constraints/selected_set/select_properties.rb +157 -0
  100. data/specs/constraints/set/cardinality.rb +58 -0
  101. data/specs/constraints/set/cardinality_properties.rb +46 -0
  102. data/specs/constraints/set/channel.rb +77 -0
  103. data/specs/constraints/set/connection.rb +176 -0
  104. data/specs/constraints/set/domain.rb +197 -0
  105. data/specs/constraints/set/include.rb +36 -0
  106. data/specs/constraints/set/operation.rb +132 -0
  107. data/specs/constraints/set/relation.rb +117 -0
  108. data/specs/constraints/set_elements/relation.rb +84 -0
  109. data/specs/constraints/set_enum/channel.rb +80 -0
  110. data/specs/constraints/set_enum/distinct.rb +59 -0
  111. data/specs/constraints/set_enum/operation.rb +111 -0
  112. data/specs/constraints/set_enum/select.rb +73 -0
  113. data/specs/enum_wrapper.rb +53 -3
  114. data/specs/int_var.rb +44 -25
  115. data/specs/model.rb +58 -1
  116. data/specs/model_sugar.rb +30 -0
  117. data/specs/search.rb +24 -5
  118. data/specs/selected_set.rb +39 -0
  119. data/specs/set_elements.rb +34 -0
  120. data/specs/set_var.rb +22 -8
  121. data/specs/spec_helper.rb +206 -6
  122. data/tasks/distribution.rake +22 -7
  123. data/tasks/svn.rake +3 -1
  124. metadata +218 -134
  125. data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
  126. data/specs/constraints/arithmetic.rb +0 -351
  127. data/specs/constraints/bool_enum_relation.rb +0 -160
  128. data/specs/constraints/cardinality.rb +0 -157
  129. data/specs/constraints/channel.rb +0 -454
  130. data/specs/constraints/connection.rb +0 -369
  131. data/specs/constraints/count.rb +0 -146
  132. data/specs/constraints/distinct.rb +0 -164
  133. data/specs/constraints/element.rb +0 -108
  134. data/specs/constraints/equality.rb +0 -31
  135. data/specs/constraints/int_domain.rb +0 -70
  136. data/specs/constraints/int_relation.rb +0 -82
  137. data/specs/constraints/linear.rb +0 -340
  138. data/specs/constraints/selection.rb +0 -292
  139. data/specs/constraints/set_domain.rb +0 -185
  140. data/specs/constraints/set_operation.rb +0 -285
  141. data/specs/constraints/set_relation.rb +0 -197
  142. data/specs/constraints/sort.rb +0 -179
@@ -1,5 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
2
- require File.dirname(__FILE__) + '/constraint_helper'
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
3
2
 
4
3
  class BoolSampleProblem < Gecode::Model
5
4
  attr :b1
@@ -13,29 +12,114 @@ class BoolSampleProblem < Gecode::Model
13
12
  end
14
13
  end
15
14
 
16
- describe Gecode::Constraints::Bool do
17
- before do
18
- @model = BoolSampleProblem.new
19
- @b1 = @model.b1
20
- @b2 = @model.b2
21
- @b3 = @model.b3
22
-
23
- # For constraint option spec.
24
- @invoke_options = lambda do |hash|
25
- (@b1 | @b2).must_be.true(hash)
26
- @model.solve!
27
- end
28
- @expect_options = option_expectation do |strength, kind, reif_var|
29
- @model.allow_space_access do
15
+ [:true, :false].each do |type|
16
+ describe Gecode::Bool, " (must be #{type})" do
17
+ before do
18
+ @model = Gecode::Model.new
19
+ @bool = @model.bool_var
20
+
21
+ @types = [:bool]
22
+ @invoke = lambda do |receiver, hash|
23
+ receiver.method(type).call(hash)
24
+ @model.solve!
25
+ end
26
+ @expect = lambda do |var, opts, reif_var|
30
27
  # We only test the non-MiniModel parts.
31
28
  unless reif_var.nil?
32
29
  Gecode::Raw.should_receive(:rel).once.with(
33
30
  an_instance_of(Gecode::Raw::Space),
34
- an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::IRT_EQ,
35
- an_instance_of(Gecode::Raw::BoolVar), strength, kind)
31
+ an_instance_of(Gecode::Raw::BoolVar),
32
+ (type == :true) ? Gecode::Raw::IRT_EQ : Gecode::Raw::IRT_NQ,
33
+ reif_var, *opts)
36
34
  end
37
35
  end
38
36
  end
37
+
38
+ it "should constrain variables to be #{type}" do
39
+ @bool.must.method(type).call
40
+ @model.solve!
41
+ @bool.value.should == (type == :true)
42
+ end
43
+
44
+ it "should make negation constrain variables to not be #{type}" do
45
+ @bool.must_not.method(type).call
46
+ @model.solve!
47
+ @bool.value.should == (type != :true)
48
+ end
49
+
50
+ it_should_behave_like 'reifiable constraint'
51
+ end
52
+ end
53
+
54
+ describe Gecode::Bool, " (implies)" do
55
+ before do
56
+ @model = Gecode::Model.new
57
+ @b1 = @model.bool_var
58
+ @b2 = @model.bool_var
59
+ @model.branch_on @model.wrap_enum([@b1, @b2])
60
+
61
+ @types = [:bool, :bool]
62
+ @invoke = lambda do |receiver, op, hash|
63
+ receiver.imply(op, hash)
64
+ @model.solve!
65
+ end
66
+ @expect = lambda do |var1, var2, opts, reif_var|
67
+ end
68
+ end
69
+
70
+ it "should constrain variables to imply each other" do
71
+ @b1.must.imply @b2
72
+ @model.solve!
73
+ (!@b1.value || @b2.value).should be_true
74
+ end
75
+
76
+ it "should, when negated, constrain variables to not imply each other" do
77
+ @b1.must_not.imply @b2
78
+ @model.solve!
79
+ @b1.value.should be_true
80
+ @b2.value.should_not be_true
81
+ end
82
+
83
+ it_should_behave_like 'reifiable constraint'
84
+ end
85
+
86
+ describe Gecode::Bool, " (equality)" do
87
+ before do
88
+ @model = Gecode::Model.new
89
+ @b1 = @model.bool_var
90
+ @b2 = @model.bool_var
91
+ @model.branch_on @model.wrap_enum([@b1, @b2])
92
+
93
+ @types = [:bool, :bool]
94
+ @invoke = lambda do |receiver, op, hash|
95
+ receiver.equal(op, hash)
96
+ @model.solve!
97
+ end
98
+ @expect = lambda do |var1, var2, opts, reif_var|
99
+ end
100
+ end
101
+
102
+ it "should constrain variables to equal each other" do
103
+ @b1.must == @b2
104
+ @model.solve!
105
+ @b1.value.should == @b2.value
106
+ end
107
+
108
+ it "should, when negated, constrain variables to not equal each other" do
109
+ @b1.must_not == @b2
110
+ @model.solve!
111
+ @b1.value.should_not == @b2.value
112
+ end
113
+
114
+ it_should_behave_like 'reifiable constraint'
115
+ end
116
+
117
+ describe Gecode::Bool do
118
+ before do
119
+ @model = BoolSampleProblem.new
120
+ @b1 = @model.b1
121
+ @b2 = @model.b2
122
+ @b3 = @model.b3
39
123
  end
40
124
 
41
125
  it 'should handle single variables constrainted to be true' do
@@ -229,14 +313,5 @@ describe Gecode::Constraints::Bool do
229
313
  sol = @model.solve!
230
314
  sol.b3.value.should be_true
231
315
  end
232
-
233
- it 'should raise error on right hand sides of incorrect type given to #==' do
234
- lambda{ @b1.must == 'hello' }.should raise_error(TypeError)
235
- end
236
-
237
- it 'should raise error on right hand sides of incorrect type given to #imply' do
238
- lambda{ @b1.must.imply 'hello' }.should raise_error(TypeError)
239
- end
240
-
241
- it_should_behave_like 'reifiable constraint'
242
316
  end
317
+
@@ -0,0 +1,51 @@
1
+ require File.dirname(__FILE__) + '/../property_helper'
2
+
3
+ [:&, :|, :^].each do |property|
4
+ describe Gecode::Bool, " (#{property} property)" do
5
+ before do
6
+ @model = Gecode::Model.new
7
+ @b1 = @model.bool_var
8
+ @b2 = @model.bool_var
9
+ @model.branch_on @model.wrap_enum([@b1, @b2])
10
+
11
+ # For bool operand producing property spec.
12
+ @property_types = [:bool, :bool]
13
+ @select_property = lambda do |bool1, bool2|
14
+ bool1.method(property).call bool2
15
+ end
16
+ @selected_property = @b1.method(property).call @b2
17
+ end
18
+
19
+ it 'should constrain the conjunction/disjunction/exclusive disjunction' do
20
+ (@b1.method(property).call @b2).must_be.true
21
+ @model.solve!
22
+ @b1.value.method(property).call(@b2.value).should be_true
23
+ end
24
+
25
+ it_should_behave_like 'property that produces bool operand'
26
+ end
27
+ end
28
+
29
+ describe Gecode::Bool, ' (#implies property)' do
30
+ before do
31
+ @model = Gecode::Model.new
32
+ @b1 = @model.bool_var
33
+ @b2 = @model.bool_var
34
+ @model.branch_on @model.wrap_enum([@b1, @b2])
35
+
36
+ # For bool operand producing property spec.
37
+ @property_types = [:bool, :bool]
38
+ @select_property = lambda do |bool1, bool2|
39
+ bool1.implies bool2
40
+ end
41
+ @selected_property = @b1.implies @b2
42
+ end
43
+
44
+ it 'should constrain the implication' do
45
+ (@b1.implies @b2).must_be.true
46
+ @model.solve!
47
+ (!@b1.value | @b2.value).should be_true
48
+ end
49
+
50
+ it_should_behave_like 'property that produces bool operand'
51
+ end
@@ -0,0 +1,213 @@
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
2
+
3
+ class BoolLinearSampleProblem < Gecode::Model
4
+ attr :x
5
+ attr :y
6
+ attr :z
7
+
8
+ def initialize
9
+ @x = self.bool_var
10
+ @y = self.bool_var
11
+ @z = self.bool_var
12
+ branch_on wrap_enum([@x, @y, @z])
13
+ end
14
+ end
15
+
16
+ class TrueClass
17
+ def to_i
18
+ 1
19
+ end
20
+ end
21
+
22
+ class FalseClass
23
+ def to_i
24
+ 0
25
+ end
26
+ end
27
+
28
+ describe Gecode::Int::Linear, '(with booleans)' do
29
+ before do
30
+ @model = BoolLinearSampleProblem.new
31
+ @x = @model.x
32
+ @y = @model.y
33
+ @z = @model.z
34
+ @operand = @x + @y
35
+ end
36
+
37
+ it 'should handle addition with a variable' do
38
+ (@x + @y).must == 0
39
+ sol = @model.solve!
40
+ x = sol.x.value.to_i
41
+ y = sol.y.value.to_i
42
+ (x + y).should be_zero
43
+ end
44
+
45
+ it 'should handle reification (1)' do
46
+ bool = @model.bool_var
47
+ (@x + @y).must.equal(0, :reify => bool)
48
+ bool.must_be.false
49
+ sol = @model.solve!
50
+ x = sol.x.value.to_i
51
+ y = sol.y.value.to_i
52
+ (x + y).should_not be_zero
53
+ end
54
+
55
+ it 'should handle reification (2)' do
56
+ bool = @model.bool_var
57
+ (@x + @y).must.equal(0, :reify => bool)
58
+ bool.must_be.true
59
+ sol = @model.solve!
60
+ x = sol.x.value.to_i
61
+ y = sol.y.value.to_i
62
+ (x + y).should be_zero
63
+ end
64
+
65
+ it 'should handle addition with multiple variables' do
66
+ (@x + @y + @z).must == 0
67
+ sol = @model.solve!
68
+ x = sol.x.value.to_i
69
+ y = sol.y.value.to_i
70
+ z = sol.z.value.to_i
71
+ (x + y + z).should be_zero
72
+ end
73
+
74
+ it 'should handle subtraction with a variable' do
75
+ (@x - @y).must == 0
76
+ sol = @model.solve!
77
+ x = sol.x.value.to_i
78
+ y = sol.y.value.to_i
79
+ (x - y).should be_zero
80
+ end
81
+
82
+ it 'should handle non-zero constants as right hand side' do
83
+ (@x + @y).must == 1
84
+ sol = @model.solve!
85
+ x = sol.x.value.to_i
86
+ y = sol.y.value.to_i
87
+ (x + y).should equal(1)
88
+ end
89
+
90
+ it 'should handle single booleans as left hand side' do
91
+ @x.must == @y + 1
92
+ sol = @model.solve!
93
+ x = sol.x.value.to_i
94
+ y = sol.y.value.to_i
95
+ x.should equal(y + 1)
96
+ end
97
+
98
+ it 'should handle single booleans as left hand side (2)' do
99
+ @x.must == @y + @z
100
+ sol = @model.solve!
101
+ x = sol.x.value.to_i
102
+ y = sol.y.value.to_i
103
+ z = sol.z.value.to_i
104
+ x.should equal(y + z)
105
+ end
106
+
107
+ it 'should handle single booleans as left hand side (3)' do
108
+ bool = @model.bool_var
109
+ @x.must.equal(@y + @z, :reify => bool)
110
+ bool.must_be.false
111
+ sol = @model.solve!
112
+ x = sol.x.value.to_i
113
+ y = sol.y.value.to_i
114
+ z = sol.z.value.to_i
115
+ x.should_not equal(y + z)
116
+ end
117
+
118
+ it 'should handle variables as right hand side' do
119
+ (@x + @y).must == @z
120
+ sol = @model.solve!
121
+ x = sol.x.value.to_i
122
+ y = sol.y.value.to_i
123
+ z = sol.z.value.to_i
124
+ (x + y).should equal(z)
125
+ end
126
+
127
+ it 'should handle linear expressions as right hand side' do
128
+ (@x + @y).must == @z + @y
129
+ sol = @model.solve!
130
+ x = sol.x.value.to_i
131
+ y = sol.y.value.to_i
132
+ z = sol.z.value.to_i
133
+ (x + y).should equal(z + y)
134
+ end
135
+
136
+ it 'should raise error on invalid right hand sides' do
137
+ lambda do
138
+ (@x + @y).must == 'z'
139
+ end.should raise_error(TypeError)
140
+ end
141
+
142
+ it 'should raise error if a fixnum is not used in multiplication' do
143
+ lambda do
144
+ (@x * @y).must == 0
145
+ end.should raise_error(TypeError)
146
+ end
147
+
148
+ it 'should raise error if bools are combined with integer variables' do
149
+ lambda do
150
+ (@x + @model.int_var).must == 0
151
+ end.should raise_error(TypeError)
152
+ end
153
+
154
+ it 'should handle coefficients other than 1' do
155
+ (@x * 2 + @y).must == 0
156
+ sol = @model.solve!
157
+ x = sol.x.value.to_i
158
+ y = sol.y.value.to_i
159
+ (2*x + y).should equal(0)
160
+ end
161
+
162
+ it 'should handle addition with constants' do
163
+ (@y + 1).must == 1
164
+ sol = @model.solve!
165
+ y = sol.y.value.to_i
166
+ (y + 1).should equal(1)
167
+ end
168
+
169
+ it 'should handle subtraction with a constant' do
170
+ (@x - 1).must == 0
171
+ sol = @model.solve!
172
+ x = sol.x.value.to_i
173
+ (x - 1).should be_zero
174
+ end
175
+
176
+ it 'should handle parenthesis' do
177
+ (@x - (@y + @z)).must == 1
178
+ sol = @model.solve!
179
+ x = sol.x.value.to_i
180
+ y = sol.y.value.to_i
181
+ z = sol.z.value.to_i
182
+ (x - (y + z)).should equal(1)
183
+ end
184
+
185
+ it 'should handle multiplication of parenthesis' do
186
+ (((@x + @y*10)*10 + @z)*10).must == 0
187
+ sol = @model.solve!
188
+ x = sol.x.value.to_i
189
+ y = sol.y.value.to_i
190
+ z = sol.z.value.to_i
191
+ (((x + y*10)*10 + z)*10).should equal(0)
192
+ end
193
+
194
+ relations = ['>', '>=', '<', '<=', '==']
195
+
196
+ relations.each do |relation|
197
+ it "should handle #{relation} with constant integers" do
198
+ (@x + @y).must.send(relation, 1)
199
+ sol = @model.solve!
200
+ sol.should_not be_nil
201
+ (sol.x.value.to_i + sol.y.value.to_i).should.send(relation, 1)
202
+ end
203
+ end
204
+
205
+ relations.each do |relation|
206
+ it "should handle negated #{relation} with constant integers" do
207
+ (@x + @y).must_not.send(relation, 1)
208
+ sol = @model.solve!
209
+ sol.should_not be_nil
210
+ (sol.x.value.to_i + sol.y.value.to_i).should_not.send(relation, 1)
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,117 @@
1
+ require File.dirname(__FILE__) + '/../property_helper'
2
+
3
+ class BoolEnumSampleProblem < Gecode::Model
4
+ attr :bools
5
+ attr :b1
6
+ attr :b2
7
+
8
+ def initialize
9
+ @bools = bool_var_array(4)
10
+ @b1 = bool_var
11
+ @b2 = bool_var
12
+ branch_on @bools
13
+ branch_on wrap_enum([@b1, @b2])
14
+ end
15
+ end
16
+
17
+ # Expects @stub, which contains the started constraint and @compute_result
18
+ # which computes whether the left hand side is true or not.
19
+ describe 'bool enum relation constraint', :shared => true do
20
+ it 'should handle being constrained to be true' do
21
+ @stub.must_be.true
22
+ @model.solve!
23
+ @compute_result.call.should be_true
24
+ end
25
+
26
+ it 'should handle being constrained to be negated true' do
27
+ @stub.must_not_be.true
28
+ @model.solve!
29
+ @compute_result.call.should_not be_true
30
+ end
31
+
32
+ it 'should handle being constrained to be false' do
33
+ @stub.must_be.false
34
+ @model.solve!
35
+ @compute_result.call.should_not be_true
36
+ end
37
+
38
+ it 'should handle being constrained to be negated false' do
39
+ @stub.must_not_be.false
40
+ @model.solve!
41
+ @compute_result.call.should be_true
42
+ end
43
+
44
+ it 'should handle being constrained to be equal to a variable' do
45
+ @stub.must_be == @b1
46
+ @model.solve!
47
+ @compute_result.call.should == @b1.value
48
+ end
49
+
50
+ it 'should handle being constrained to not be equal to a variable' do
51
+ @stub.must_not_be == @b1
52
+ @model.solve!
53
+ @compute_result.call.should_not == @b1.value
54
+ end
55
+
56
+ it 'should handle being constrained to be equal to be a nested expression' do
57
+ @stub.must_be == (@b1 | @b2) & @b1
58
+ @model.solve!
59
+ @compute_result.call.should == (@b1.value | @b2.value) & @b1.value
60
+ end
61
+
62
+ it 'should handle being constrained to not be equal to be a nested expression' do
63
+ @stub.must_not_be == (@b1 | @b2) & @b1
64
+ @model.solve!
65
+ @compute_result.call.should_not == (@b1.value | @b2.value) & @b1.value
66
+ end
67
+ end
68
+
69
+ describe Gecode::BoolEnum::Relation, ' (conjunction)' do
70
+ before do
71
+ @model = BoolEnumSampleProblem.new
72
+ @bools = @model.bools
73
+ @b1 = @model.b1
74
+ @b2 = @model.b2
75
+
76
+ # For property spec.
77
+ @property_types = [:bool_enum]
78
+ @select_property = lambda do |bool_enum|
79
+ bool_enum.conjunction
80
+ end
81
+ @selected_property = @bools.conjunction
82
+ @constraint_class = Gecode::BlockConstraint
83
+
84
+ # For bool enum spec.
85
+ @stub = @selected_property
86
+ @compute_result = lambda{ @bools.all?{ |b| b.value } }
87
+ end
88
+
89
+ it_should_behave_like 'bool enum relation constraint'
90
+ it_should_behave_like(
91
+ 'property that produces bool operand by short circuiting equality')
92
+ end
93
+
94
+ describe Gecode::BoolEnum::Relation, ' (disjunction)' do
95
+ before do
96
+ @model = BoolEnumSampleProblem.new
97
+ @bools = @model.bools
98
+ @b1 = @model.b1
99
+ @b2 = @model.b2
100
+
101
+ # For constraint option spec.
102
+ @property_types = [:bool_enum]
103
+ @select_property = lambda do |bool_enum|
104
+ bool_enum.disjunction
105
+ end
106
+ @selected_property = @bools.disjunction
107
+ @constraint_class = Gecode::BlockConstraint
108
+
109
+ # For bool enum spec.
110
+ @stub = @selected_property
111
+ @compute_result = lambda{ @bools.any?{ |b| b.value } }
112
+ end
113
+
114
+ it_should_behave_like 'bool enum relation constraint'
115
+ it_should_behave_like(
116
+ 'property that produces bool operand by short circuiting equality')
117
+ end