gecoder 0.5.0 → 0.6.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 (61) hide show
  1. data/CHANGES +16 -3
  2. data/example/magic_sequence.rb +1 -1
  3. data/example/queens.rb +1 -1
  4. data/example/send_more_money.rb +1 -1
  5. data/example/sudoku.rb +1 -1
  6. data/ext/missing.cpp +18 -4
  7. data/ext/missing.h +8 -0
  8. data/lib/gecoder/bindings.rb +30 -3
  9. data/lib/gecoder/bindings/bindings.rb +22 -0
  10. data/lib/gecoder/interface/binding_changes.rb +81 -107
  11. data/lib/gecoder/interface/branch.rb +65 -14
  12. data/lib/gecoder/interface/constraints.rb +1 -0
  13. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +16 -12
  14. data/lib/gecoder/interface/constraints/int/arithmetic.rb +7 -3
  15. data/lib/gecoder/interface/constraints/int/linear.rb +19 -16
  16. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +8 -4
  17. data/lib/gecoder/interface/constraints/int_enum/channel.rb +14 -6
  18. data/lib/gecoder/interface/constraints/int_enum/element.rb +7 -5
  19. data/lib/gecoder/interface/constraints/int_enum/sort.rb +1 -4
  20. data/lib/gecoder/interface/constraints/set/cardinality.rb +6 -3
  21. data/lib/gecoder/interface/constraints/set/connection.rb +136 -0
  22. data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
  23. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +61 -0
  24. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +32 -0
  25. data/lib/gecoder/interface/constraints/set_var_constraints.rb +1 -0
  26. data/lib/gecoder/interface/enum_wrapper.rb +12 -3
  27. data/lib/gecoder/interface/model.rb +77 -56
  28. data/lib/gecoder/interface/search.rb +74 -5
  29. data/lib/gecoder/interface/variables.rb +117 -15
  30. data/lib/gecoder/version.rb +1 -1
  31. data/specs/binding_changes.rb +9 -5
  32. data/specs/bool_var.rb +8 -12
  33. data/specs/branch.rb +85 -19
  34. data/specs/constraints/arithmetic.rb +99 -71
  35. data/specs/constraints/bool_enum.rb +26 -18
  36. data/specs/constraints/boolean.rb +53 -49
  37. data/specs/constraints/cardinality.rb +33 -26
  38. data/specs/constraints/channel.rb +77 -6
  39. data/specs/constraints/connection.rb +352 -0
  40. data/specs/constraints/constraints.rb +10 -1
  41. data/specs/constraints/count.rb +79 -39
  42. data/specs/constraints/distinct.rb +128 -9
  43. data/specs/constraints/element.rb +26 -19
  44. data/specs/constraints/equality.rb +2 -1
  45. data/specs/constraints/int_domain.rb +19 -12
  46. data/specs/constraints/int_relation.rb +12 -6
  47. data/specs/constraints/linear.rb +30 -30
  48. data/specs/constraints/reification_sugar.rb +8 -4
  49. data/specs/constraints/set_domain.rb +24 -18
  50. data/specs/constraints/set_relation.rb +38 -23
  51. data/specs/constraints/sort.rb +12 -10
  52. data/specs/enum_wrapper.rb +9 -3
  53. data/specs/int_var.rb +8 -4
  54. data/specs/logging.rb +24 -0
  55. data/specs/model.rb +25 -7
  56. data/specs/search.rb +41 -1
  57. data/specs/set_var.rb +36 -7
  58. data/specs/spec_helper.rb +3 -10
  59. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +1 -1
  60. metadata +12 -3
  61. data/specs/tmp +0 -22
@@ -45,25 +45,25 @@ describe 'bool enum constraint', :shared => true do
45
45
  it 'should handle being constrained to be equal to a variable' do
46
46
  @stub.must_be == @b1
47
47
  @model.solve!
48
- @compute_result.call.should == @b1.true?
48
+ @compute_result.call.should == @b1.value
49
49
  end
50
50
 
51
51
  it 'should handle being constrained to not be equal to a variable' do
52
52
  @stub.must_not_be == @b1
53
53
  @model.solve!
54
- @compute_result.call.should_not == @b1.true?
54
+ @compute_result.call.should_not == @b1.value
55
55
  end
56
56
 
57
57
  it 'should handle being constrained to be equal to be a nested expression' do
58
58
  @stub.must_be == (@b1 | @b2) & @b1
59
59
  @model.solve!
60
- @compute_result.call.should == (@b1.true? | @b2.true?) & @b1.true?
60
+ @compute_result.call.should == (@b1.value | @b2.value) & @b1.value
61
61
  end
62
62
 
63
63
  it 'should handle being constrained to not be equal to be a nested expression' do
64
64
  @stub.must_not_be == (@b1 | @b2) & @b1
65
65
  @model.solve!
66
- @compute_result.call.should_not == (@b1.true? | @b2.true?) & @b1.true?
66
+ @compute_result.call.should_not == (@b1.value | @b2.value) & @b1.value
67
67
  end
68
68
  end
69
69
 
@@ -80,18 +80,22 @@ describe Gecode::Constraints::BoolEnum, ' (conjunction)' do
80
80
  @model.solve!
81
81
  end
82
82
  @expect_options = lambda do |strength, reif_var|
83
- Gecode::Raw.should_receive(:bool_and).once.with(@model.active_space,
84
- an_instance_of(Gecode::Raw::BoolVarArray),
85
- an_instance_of(Gecode::Raw::BoolVar), strength)
86
- unless reif_var.nil?
87
- Gecode::Raw.should_receive(:bool_eqv).once.with(@model.active_space,
88
- an_instance_of(Gecode::Raw::BoolVar), reif_var.bind, true, strength)
83
+ @model.allow_space_access do
84
+ Gecode::Raw.should_receive(:bool_and).once.with(
85
+ an_instance_of(Gecode::Raw::Space),
86
+ an_instance_of(Gecode::Raw::BoolVarArray),
87
+ an_instance_of(Gecode::Raw::BoolVar), strength)
88
+ unless reif_var.nil?
89
+ Gecode::Raw.should_receive(:bool_eqv).once.with(
90
+ an_instance_of(Gecode::Raw::Space),
91
+ an_instance_of(Gecode::Raw::BoolVar), reif_var.bind, true, strength)
92
+ end
89
93
  end
90
94
  end
91
95
 
92
96
  # For bool enum spec.
93
97
  @stub = @bools.conjunction
94
- @compute_result = lambda{ @bools.all?{ |b| b.true? } }
98
+ @compute_result = lambda{ @bools.all?{ |b| b.value } }
95
99
  end
96
100
 
97
101
  it_should_behave_like 'bool enum constraint'
@@ -111,18 +115,22 @@ describe Gecode::Constraints::BoolEnum, ' (disjunction)' do
111
115
  @model.solve!
112
116
  end
113
117
  @expect_options = lambda do |strength, reif_var|
114
- Gecode::Raw.should_receive(:bool_or).once.with(@model.active_space,
115
- an_instance_of(Gecode::Raw::BoolVarArray),
116
- an_instance_of(Gecode::Raw::BoolVar), strength)
117
- unless reif_var.nil?
118
- Gecode::Raw.should_receive(:bool_eqv).once.with(@model.active_space,
119
- an_instance_of(Gecode::Raw::BoolVar), reif_var.bind, true, strength)
118
+ @model.allow_space_access do
119
+ Gecode::Raw.should_receive(:bool_or).once.with(
120
+ an_instance_of(Gecode::Raw::Space),
121
+ an_instance_of(Gecode::Raw::BoolVarArray),
122
+ an_instance_of(Gecode::Raw::BoolVar), strength)
123
+ unless reif_var.nil?
124
+ Gecode::Raw.should_receive(:bool_eqv).once.with(
125
+ an_instance_of(Gecode::Raw::Space),
126
+ an_instance_of(Gecode::Raw::BoolVar), reif_var.bind, true, strength)
127
+ end
120
128
  end
121
129
  end
122
130
 
123
131
  # For bool enum spec.
124
132
  @stub = @bools.disjunction
125
- @compute_result = lambda{ @bools.any?{ |b| b.true? } }
133
+ @compute_result = lambda{ @bools.any?{ |b| b.value } }
126
134
  end
127
135
 
128
136
  it_should_behave_like 'bool enum constraint'
@@ -26,12 +26,16 @@ describe Gecode::Constraints::Bool do
26
26
  @model.solve!
27
27
  end
28
28
  @expect_options = lambda do |strength, reif_var|
29
- Gecode::Raw.should_receive(:bool_or).once.with(@model.active_space,
30
- @b1.bind, @b2.bind, an_instance_of(Gecode::Raw::BoolVar),
31
- Gecode::Raw::ICL_DEF)
32
- unless reif_var.nil?
33
- Gecode::Raw.should_receive(:bool_eqv).once.with(@model.active_space,
34
- an_instance_of(Gecode::Raw::BoolVar), reif_var.bind, true, strength)
29
+ @model.allow_space_access do
30
+ Gecode::Raw.should_receive(:bool_or).once.with(
31
+ an_instance_of(Gecode::Raw::Space),
32
+ @b1.bind, @b2.bind, an_instance_of(Gecode::Raw::BoolVar),
33
+ Gecode::Raw::ICL_DEF)
34
+ unless reif_var.nil?
35
+ Gecode::Raw.should_receive(:bool_eqv).once.with(
36
+ an_instance_of(Gecode::Raw::Space),
37
+ an_instance_of(Gecode::Raw::BoolVar), reif_var.bind, true, strength)
38
+ end
35
39
  end
36
40
  end
37
41
  end
@@ -40,148 +44,148 @@ describe Gecode::Constraints::Bool do
40
44
  @b1.must_be.true
41
45
  b1 = @model.solve!.b1
42
46
  b1.should be_assigned
43
- b1.true?.should be_true
47
+ b1.value.should be_true
44
48
  end
45
49
 
46
50
  it 'should handle single variables constrainted to be false' do
47
51
  @b1.must_be.false
48
52
  b1 = @model.solve!.b1
49
53
  b1.should be_assigned
50
- b1.true?.should_not be_true
54
+ b1.value.should_not be_true
51
55
  end
52
56
 
53
57
  it 'should handle single variables constrainted not to be false' do
54
58
  @b1.must_not_be.false
55
59
  b1 = @model.solve!.b1
56
60
  b1.should be_assigned
57
- b1.true?.should be_true
61
+ b1.value.should be_true
58
62
  end
59
63
 
60
64
  it 'should handle single variables constrainted not to be true' do
61
65
  @b1.must_not_be.true
62
66
  b1 = @model.solve!.b1
63
67
  b1.should be_assigned
64
- b1.true?.should_not be_true
68
+ b1.value.should_not be_true
65
69
  end
66
70
 
67
71
  it 'should handle disjunction' do
68
72
  @b1.must_be.false
69
73
  (@b1 | @b2).must_be.true
70
74
  sol = @model.solve!
71
- sol.b1.true?.should_not be_true
72
- sol.b2.true?.should be_true
75
+ sol.b1.value.should_not be_true
76
+ sol.b2.value.should be_true
73
77
  end
74
78
 
75
79
  it 'should handle negated disjunction' do
76
80
  @b1.must_be.false
77
81
  (@b1 | @b2).must_not_be.true
78
82
  sol = @model.solve!
79
- sol.b1.true?.should_not be_true
80
- sol.b2.true?.should_not be_true
83
+ sol.b1.value.should_not be_true
84
+ sol.b2.value.should_not be_true
81
85
  end
82
86
 
83
87
  it 'should handle conjunction' do
84
88
  (@b1 & @b2).must_be.true
85
89
  sol = @model.solve!
86
- sol.b1.true?.should be_true
87
- sol.b2.true?.should be_true
90
+ sol.b1.value.should be_true
91
+ sol.b2.value.should be_true
88
92
  end
89
93
 
90
94
  it 'should handle negated conjunction' do
91
95
  @b1.must_be.true
92
96
  (@b1 & @b2).must_not_be.true
93
97
  sol = @model.solve!
94
- sol.b1.true?.should be_true
95
- sol.b2.true?.should_not be_true
98
+ sol.b1.value.should be_true
99
+ sol.b2.value.should_not be_true
96
100
  end
97
101
 
98
102
  it 'should handle exclusive or' do
99
103
  @b1.must_be.false
100
104
  (@b1 ^ @b2).must_be.true
101
105
  sol = @model.solve!
102
- sol.b1.true?.should_not be_true
103
- sol.b2.true?.should be_true
106
+ sol.b1.value.should_not be_true
107
+ sol.b2.value.should be_true
104
108
  end
105
109
 
106
110
  it 'should handle negated exclusive or' do
107
111
  @b1.must_be.true
108
112
  (@b1 ^ @b2).must_not_be.true
109
113
  sol = @model.solve!
110
- sol.b1.true?.should be_true
111
- sol.b2.true?.should be_true
114
+ sol.b1.value.should be_true
115
+ sol.b2.value.should be_true
112
116
  end
113
117
 
114
118
  it 'should handle implication' do
115
119
  @b2.must_be.false
116
120
  (@b1.implies @b2).must_be.true
117
121
  sol = @model.solve!
118
- sol.b1.true?.should_not be_true
119
- sol.b2.true?.should_not be_true
122
+ sol.b1.value.should_not be_true
123
+ sol.b2.value.should_not be_true
120
124
  end
121
125
 
122
126
  it 'should handle negated implication' do
123
127
  @b1.must_be.true
124
128
  ((@b1 | @b2).implies @b2).must_not_be.true
125
129
  sol = @model.solve!
126
- sol.b1.true?.should be_true
127
- sol.b2.true?.should_not be_true
130
+ sol.b1.value.should be_true
131
+ sol.b2.value.should_not be_true
128
132
  end
129
133
 
130
134
  it 'should handle imply after must' do
131
135
  @b2.must_be.false
132
136
  @b1.must.imply @b2
133
137
  sol = @model.solve!
134
- sol.b1.true?.should_not be_true
135
- sol.b2.true?.should_not be_true
138
+ sol.b1.value.should_not be_true
139
+ sol.b2.value.should_not be_true
136
140
  end
137
141
 
138
142
  it 'should handle imply after must_not' do
139
143
  @b1.must_be.true
140
144
  @b1.must_not.imply @b2
141
145
  sol = @model.solve!
142
- sol.b1.true?.should be_true
143
- sol.b2.true?.should_not be_true
146
+ sol.b1.value.should be_true
147
+ sol.b2.value.should_not be_true
144
148
  end
145
149
 
146
150
  it 'should handle single variables as right hand side' do
147
151
  @b1.must == @b2
148
152
  @b2.must_be.false
149
153
  sol = @model.solve!
150
- sol.b1.true?.should_not be_true
151
- sol.b2.true?.should_not be_true
154
+ sol.b1.value.should_not be_true
155
+ sol.b2.value.should_not be_true
152
156
  end
153
157
 
154
158
  it 'should handle single variables with negation as right hand side' do
155
159
  @b1.must_not == @b2
156
160
  @b2.must_be.false
157
161
  sol = @model.solve!
158
- sol.b1.true?.should be_true
159
- sol.b2.true?.should_not be_true
162
+ sol.b1.value.should be_true
163
+ sol.b2.value.should_not be_true
160
164
  end
161
165
 
162
166
  it 'should handle expressions as right hand side' do
163
167
  @b1.must == (@b2 | @b3)
164
168
  @b2.must_be.true
165
169
  sol = @model.solve!
166
- sol.b1.true?.should be_true
167
- sol.b2.true?.should be_true
170
+ sol.b1.value.should be_true
171
+ sol.b2.value.should be_true
168
172
  end
169
173
 
170
174
  it 'should handle nested expressions as left hand side' do
171
175
  ((@b1 & @b2) | @b3 | (@b1 & @b3)).must_be.true
172
176
  @b1.must_be.false
173
177
  sol = @model.solve!
174
- sol.b1.true?.should_not be_true
175
- sol.b3.true?.should be_true
178
+ sol.b1.value.should_not be_true
179
+ sol.b3.value.should be_true
176
180
  end
177
181
 
178
182
  it 'should handle nested expressions on both side' do
179
183
  ((@b1 & @b1) | @b3).must == ((@b1 & @b3) & @b2)
180
184
  @b1.must_be.true
181
185
  sol = @model.solve!
182
- sol.b1.true?.should be_true
183
- sol.b2.true?.should be_true
184
- sol.b3.true?.should be_true
186
+ sol.b1.value.should be_true
187
+ sol.b2.value.should be_true
188
+ sol.b3.value.should be_true
185
189
  end
186
190
 
187
191
  it 'should handle nested expressions containing exclusive or' do
@@ -189,9 +193,9 @@ describe Gecode::Constraints::Bool do
189
193
  @b1.must_be.true
190
194
  @b2.must_be.false
191
195
  sol = @model.solve!
192
- sol.b1.true?.should be_true
193
- sol.b2.true?.should_not be_true
194
- sol.b3.true?.should_not be_true
196
+ sol.b1.value.should be_true
197
+ sol.b2.value.should_not be_true
198
+ sol.b3.value.should_not be_true
195
199
  end
196
200
 
197
201
  it 'should handle nested expressions on both sides with negation' do
@@ -199,9 +203,9 @@ describe Gecode::Constraints::Bool do
199
203
  @b1.must_be.true
200
204
  @b3.must_be.true
201
205
  sol = @model.solve!
202
- sol.b1.true?.should be_true
203
- sol.b2.true?.should_not be_true
204
- sol.b3.true?.should be_true
206
+ sol.b1.value.should be_true
207
+ sol.b2.value.should_not be_true
208
+ sol.b3.value.should be_true
205
209
  end
206
210
 
207
211
  it 'should translate reification with a variable right hand side' do
@@ -209,7 +213,7 @@ describe Gecode::Constraints::Bool do
209
213
  @b1.must_be.true
210
214
  @b2.must_be.false
211
215
  sol = @model.solve!
212
- sol.b3.true?.should_not be_true
216
+ sol.b3.value.should_not be_true
213
217
  end
214
218
 
215
219
  it 'should translate reification with a variable right hand side and negation' do
@@ -217,7 +221,7 @@ describe Gecode::Constraints::Bool do
217
221
  @b1.must_be.true
218
222
  @b2.must_be.false
219
223
  sol = @model.solve!
220
- sol.b3.true?.should be_true
224
+ sol.b3.value.should be_true
221
225
  end
222
226
 
223
227
 
@@ -18,8 +18,11 @@ describe Gecode::Constraints::Set::Cardinality, ' (range)' do
18
18
  @model.solve!
19
19
  end
20
20
  @expect = lambda do |rhs|
21
- Gecode::Raw.should_receive(:cardinality).once.with(@model.active_space,
22
- @set.bind, rhs.first, rhs.last)
21
+ @model.allow_space_access do
22
+ Gecode::Raw.should_receive(:cardinality).once.with(
23
+ an_instance_of(Gecode::Raw::Space),
24
+ @set.bind, rhs.first, rhs.last)
25
+ end
23
26
  end
24
27
  end
25
28
 
@@ -36,7 +39,7 @@ describe Gecode::Constraints::Set::Cardinality, ' (range)' do
36
39
  it 'should constrain the cardinality of a set' do
37
40
  @set.size.must_be.in @range
38
41
  @model.solve!
39
- @range.should include(@set.val_size)
42
+ @range.should include(@set.value.size)
40
43
  end
41
44
 
42
45
  it 'should raise error if the right hand side is not a range' do
@@ -44,10 +47,12 @@ describe Gecode::Constraints::Set::Cardinality, ' (range)' do
44
47
  end
45
48
 
46
49
  it 'should not shadow the integer variable domain constrain' do
47
- Gecode::Raw.should_receive(:dom).once.with(@model.active_space,
50
+ Gecode::Raw.should_receive(:dom).once.with(
51
+ an_instance_of(Gecode::Raw::Space),
48
52
  an_instance_of(Gecode::Raw::IntVar), an_instance_of(Gecode::Raw::IntSet),
49
- Gecode::Raw::ICL_DEF)
53
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
50
54
  @set.size.must_not_be.in [1,3]
55
+ @model.solve!
51
56
  end
52
57
 
53
58
  it_should_behave_like 'non-reifiable set constraint'
@@ -61,35 +66,37 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
61
66
  @model.branch_on @model.wrap_enum([@set])
62
67
  @model.branch_on @model.wrap_enum([@var])
63
68
 
64
- @invoke_options = lambda do |hash|
65
- @set.size.must_be.equal_to(@var, hash)
66
- end
67
-
68
69
  @invoke = lambda do |rhs|
69
70
  @set.size.must == rhs
70
71
  @model.solve!
71
72
  end
72
73
  @expect = lambda do |relation, rhs, strength, reif_var, negated|
73
- rhs = rhs.bind if rhs.respond_to? :bind
74
- if reif_var.nil?
75
- if !negated and relation == Gecode::Raw::IRT_EQ and
76
- rhs.kind_of? Gecode::Raw::IntVar
77
- Gecode::Raw.should_receive(:cardinality).once.with(
78
- @model.active_space, @set.bind, rhs)
79
- Gecode::Raw.should_receive(:rel).exactly(0).times
74
+ @model.allow_space_access do
75
+ rhs = rhs.bind if rhs.respond_to? :bind
76
+ if reif_var.nil?
77
+ if !negated and relation == Gecode::Raw::IRT_EQ and
78
+ rhs.kind_of? Gecode::Raw::IntVar
79
+ Gecode::Raw.should_receive(:cardinality).once.with(
80
+ an_instance_of(Gecode::Raw::Space), @set.bind, rhs)
81
+ Gecode::Raw.should_receive(:rel).exactly(0).times
82
+ else
83
+ Gecode::Raw.should_receive(:cardinality).once.with(
84
+ an_instance_of(Gecode::Raw::Space), @set.bind,
85
+ an_instance_of(Gecode::Raw::IntVar))
86
+ Gecode::Raw.should_receive(:rel).once.with(
87
+ an_instance_of(Gecode::Raw::Space),
88
+ an_instance_of(Gecode::Raw::IntVar), relation, rhs,
89
+ strength)
90
+ end
80
91
  else
81
92
  Gecode::Raw.should_receive(:cardinality).once.with(
82
- @model.active_space, @set.bind, an_instance_of(Gecode::Raw::IntVar))
83
- Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
84
- an_instance_of(Gecode::Raw::IntVar), relation, rhs,
93
+ an_instance_of(Gecode::Raw::Space),
94
+ @set.bind, an_instance_of(Gecode::Raw::IntVar))
95
+ Gecode::Raw.should_receive(:rel).once.with(
96
+ an_instance_of(Gecode::Raw::Space),
97
+ an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
85
98
  strength)
86
99
  end
87
- else
88
- Gecode::Raw.should_receive(:cardinality).once.with(@model.active_space,
89
- @set.bind, an_instance_of(Gecode::Raw::IntVar))
90
- Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
91
- an_instance_of(Gecode::Raw::IntVar), relation, rhs, reif_var.bind,
92
- strength)
93
100
  end
94
101
  end
95
102
 
@@ -119,7 +126,7 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
119
126
  it 'should constrain the cardinality of a set' do
120
127
  @set.size.must == @var
121
128
  @model.solve!
122
- @set.val_size.should == @var.val
129
+ @set.value.size.should == @var.value
123
130
  end
124
131
 
125
132
  it_should_behave_like 'constraint with options'
@@ -4,17 +4,19 @@ require File.dirname(__FILE__) + '/constraint_helper'
4
4
  class ChannelSampleProblem < Gecode::Model
5
5
  attr :elements
6
6
  attr :positions
7
+ attr :sets
7
8
 
8
9
  def initialize
9
10
  @elements = int_var_array(4, 0..3)
10
11
  @elements.must_be.distinct
11
12
  @positions = int_var_array(4, 0..3)
12
13
  @positions.must_be.distinct
13
- branch_on @elements
14
+ @sets = set_var_array(4, [], 0..3)
15
+ branch_on @positions
14
16
  end
15
17
  end
16
18
 
17
- describe Gecode::Constraints::IntEnum::Channel do
19
+ describe Gecode::Constraints::IntEnum::Channel, ' (two int enums)' do
18
20
  before do
19
21
  @model = ChannelSampleProblem.new
20
22
  @positions = @model.positions
@@ -24,14 +26,16 @@ describe Gecode::Constraints::IntEnum::Channel do
24
26
  @model.solve!
25
27
  end
26
28
  @expect_options = lambda do |strength, reif_var|
27
- Gecode::Raw.should_receive(:channel).once.with(@model.active_space,
29
+ Gecode::Raw.should_receive(:channel).once.with(
30
+ an_instance_of(Gecode::Raw::Space),
28
31
  an_instance_of(Gecode::Raw::IntVarArray),
29
32
  an_instance_of(Gecode::Raw::IntVarArray), strength)
30
33
  end
31
34
  end
32
35
 
33
36
  it 'should translate into a channel constraint' do
34
- Gecode::Raw.should_receive(:channel).once.with(@model.active_space,
37
+ Gecode::Raw.should_receive(:channel).once.with(
38
+ an_instance_of(Gecode::Raw::Space),
35
39
  anything, anything, Gecode::Raw::ICL_DEF)
36
40
  @invoke_options.call({})
37
41
  end
@@ -39,8 +43,8 @@ describe Gecode::Constraints::IntEnum::Channel do
39
43
  it 'should constrain variables to be channelled' do
40
44
  @elements.must.channel @positions
41
45
  @model.solve!
42
- elements = @model.elements.map{ |e| e.val }
43
- positions = @model.elements.map{ |p| p.val }
46
+ elements = @model.elements.values
47
+ positions = @model.elements.values
44
48
  elements.each_with_index do |element, i|
45
49
  element.should equal(positions.index(i))
46
50
  end
@@ -51,5 +55,72 @@ describe Gecode::Constraints::IntEnum::Channel do
51
55
  Gecode::MissingConstraintError)
52
56
  end
53
57
 
58
+ it 'should raise error for unsupported right hand sides' do
59
+ lambda{ @elements.must.channel 'hello' }.should raise_error(TypeError)
60
+ end
61
+
54
62
  it_should_behave_like 'constraint with strength option'
55
63
  end
64
+
65
+ describe Gecode::Constraints::IntEnum::Channel, ' (one int enum and one set enum)' do
66
+ before do
67
+ @model = ChannelSampleProblem.new
68
+ @positions = @model.positions
69
+ @sets = @model.sets
70
+ end
71
+
72
+ it 'should translate into a channel constraint' do
73
+ Gecode::Raw.should_receive(:channel).once.with(
74
+ an_instance_of(Gecode::Raw::Space),
75
+ an_instance_of(Gecode::Raw::IntVarArray),
76
+ an_instance_of(Gecode::Raw::SetVarArray))
77
+ @positions.must.channel @sets
78
+ @model.solve!
79
+ end
80
+
81
+ it 'should constrain variables to be channelled' do
82
+ @positions.must.channel @sets
83
+ @model.solve!
84
+ sets = @model.sets
85
+ positions = @model.positions.values
86
+ positions.each_with_index do |position, i|
87
+ sets[position].value.should include(i)
88
+ end
89
+ end
90
+ end
91
+
92
+ describe Gecode::Constraints::SetEnum, ' (channel with set as left hand side)' do
93
+ before do
94
+ @model = ChannelSampleProblem.new
95
+ @positions = @model.positions
96
+ @sets = @model.sets
97
+
98
+ @invoke_options = lambda do |hash|
99
+ @sets.must.channel @positions, hash
100
+ @model.solve!
101
+ end
102
+ @expect_options = lambda do |strength, reif_var|
103
+ Gecode::Raw.should_receive(:channel).once.with(
104
+ an_instance_of(Gecode::Raw::Space),
105
+ an_instance_of(Gecode::Raw::IntVarArray),
106
+ an_instance_of(Gecode::Raw::SetVarArray))
107
+ end
108
+ end
109
+
110
+ it 'should translate into a channel constraint' do
111
+ @expect_options.call(Gecode::Raw::ICL_DEF, nil)
112
+ @sets.must.channel @positions
113
+ @model.solve!
114
+ end
115
+
116
+ it 'should not allow negation' do
117
+ lambda{ @sets.must_not.channel @positions }.should raise_error(
118
+ Gecode::MissingConstraintError)
119
+ end
120
+
121
+ it 'should raise error for unsupported right hand sides' do
122
+ lambda{ @sets.must.channel 'hello' }.should raise_error(TypeError)
123
+ end
124
+
125
+ it_should_behave_like 'non-reifiable set constraint'
126
+ end