gecoder 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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