gecoder 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/CHANGES +7 -0
  2. data/README +10 -1
  3. data/example/sudoku-set.rb +16 -13
  4. data/ext/extconf.rb +26 -9
  5. data/ext/missing.cpp +1 -1
  6. data/ext/missing.h +1 -1
  7. data/ext/vararray.h +4 -4
  8. data/lib/gecoder/bindings.rb +21 -1
  9. data/lib/gecoder/bindings/bindings.rb +408 -731
  10. data/lib/gecoder/interface/binding_changes.rb +1 -1
  11. data/lib/gecoder/interface/branch.rb +25 -25
  12. data/lib/gecoder/interface/constraints.rb +47 -4
  13. data/lib/gecoder/interface/constraints/bool/boolean.rb +18 -16
  14. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +13 -11
  15. data/lib/gecoder/interface/constraints/int/arithmetic.rb +5 -4
  16. data/lib/gecoder/interface/constraints/int/domain.rb +8 -9
  17. data/lib/gecoder/interface/constraints/int/linear.rb +10 -8
  18. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +4 -4
  19. data/lib/gecoder/interface/constraints/int_enum/channel.rb +2 -2
  20. data/lib/gecoder/interface/constraints/int_enum/count.rb +4 -5
  21. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +7 -2
  22. data/lib/gecoder/interface/constraints/int_enum/element.rb +2 -2
  23. data/lib/gecoder/interface/constraints/int_enum/equality.rb +6 -3
  24. data/lib/gecoder/interface/constraints/int_enum/sort.rb +17 -5
  25. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +0 -36
  26. data/lib/gecoder/interface/constraints/set_var_constraints.rb +5 -0
  27. data/lib/gecoder/interface/model.rb +3 -3
  28. data/lib/gecoder/interface/search.rb +5 -4
  29. data/lib/gecoder/version.rb +1 -1
  30. data/specs/branch.rb +27 -27
  31. data/specs/constraints/arithmetic.rb +48 -30
  32. data/specs/constraints/bool_enum.rb +39 -19
  33. data/specs/constraints/boolean.rb +10 -10
  34. data/specs/constraints/cardinality.rb +12 -9
  35. data/specs/constraints/channel.rb +6 -6
  36. data/specs/constraints/connection.rb +22 -26
  37. data/specs/constraints/constraint_helper.rb +125 -41
  38. data/specs/constraints/count.rb +22 -15
  39. data/specs/constraints/distinct.rb +10 -64
  40. data/specs/constraints/element.rb +14 -12
  41. data/specs/constraints/equality.rb +4 -4
  42. data/specs/constraints/int_domain.rb +8 -7
  43. data/specs/constraints/int_relation.rb +12 -8
  44. data/specs/constraints/linear.rb +4 -4
  45. data/specs/constraints/reification_sugar.rb +22 -4
  46. data/specs/constraints/selection.rb +2 -2
  47. data/specs/constraints/set_domain.rb +7 -3
  48. data/specs/constraints/set_operation.rb +2 -2
  49. data/specs/constraints/set_relation.rb +2 -6
  50. data/specs/constraints/sort.rb +20 -16
  51. data/specs/distribution.rb +14 -0
  52. data/specs/model.rb +4 -4
  53. data/tasks/dependencies.txt +21 -0
  54. data/tasks/distribution.rake +81 -8
  55. data/tasks/svn.rake +6 -3
  56. data/vendor/rust/include/rust_checks.hh +2 -1
  57. data/vendor/rust/include/rust_conversions.hh +2 -2
  58. data/vendor/rust/rust/attribute.rb +2 -2
  59. data/vendor/rust/rust/class.rb +2 -2
  60. data/vendor/rust/rust/cxxclass.rb +0 -2
  61. data/vendor/rust/rust/function.rb +2 -2
  62. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +1 -1
  63. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +1 -1
  64. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +1 -1
  65. data/vendor/rust/rust/type.rb +1 -1
  66. metadata +159 -157
@@ -79,17 +79,27 @@ describe Gecode::Constraints::BoolEnum, ' (conjunction)' do
79
79
  @bools.conjunction.must_be.equal_to(true, hash)
80
80
  @model.solve!
81
81
  end
82
- @expect_options = lambda do |strength, reif_var|
82
+ @expect_options = option_expectation do |strength, kind, reif_var|
83
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),
84
+ if reif_var.nil?
85
+ Gecode::Raw.should_receive(:rel).once.with(
86
+ an_instance_of(Gecode::Raw::Space),
87
+ Gecode::Raw::BOT_AND,
88
+ an_instance_of(Gecode::Raw::BoolVarArray),
91
89
  an_instance_of(Gecode::Raw::BoolVar),
92
- an_instance_of(Gecode::Raw::BoolVar), true, strength)
90
+ strength, kind)
91
+ else
92
+ Gecode::Raw.should_receive(:rel).once.with(
93
+ an_instance_of(Gecode::Raw::Space),
94
+ an_instance_of(Gecode::Raw::BoolVar),
95
+ anything,
96
+ an_instance_of(Gecode::Raw::BoolVar),
97
+ anything, anything, anything)
98
+ Gecode::Raw.should_receive(:rel).once.with(
99
+ an_instance_of(Gecode::Raw::Space),
100
+ Gecode::Raw::BOT_AND,
101
+ an_instance_of(Gecode::Raw::BoolVarArray),
102
+ reif_var, strength, kind)
93
103
  end
94
104
  end
95
105
  end
@@ -100,7 +110,7 @@ describe Gecode::Constraints::BoolEnum, ' (conjunction)' do
100
110
  end
101
111
 
102
112
  it_should_behave_like 'bool enum constraint'
103
- it_should_behave_like 'constraint with options'
113
+ it_should_behave_like 'reifiable constraint'
104
114
  end
105
115
 
106
116
  describe Gecode::Constraints::BoolEnum, ' (disjunction)' do
@@ -115,17 +125,27 @@ describe Gecode::Constraints::BoolEnum, ' (disjunction)' do
115
125
  @bools.disjunction.must_be.equal_to(true, hash)
116
126
  @model.solve!
117
127
  end
118
- @expect_options = lambda do |strength, reif_var|
128
+ @expect_options = option_expectation do |strength, kind, reif_var|
119
129
  @model.allow_space_access do
120
- Gecode::Raw.should_receive(:bool_or).once.with(
121
- an_instance_of(Gecode::Raw::Space),
122
- an_instance_of(Gecode::Raw::BoolVarArray),
123
- an_instance_of(Gecode::Raw::BoolVar), strength)
124
- unless reif_var.nil?
125
- Gecode::Raw.should_receive(:bool_eqv).once.with(
130
+ if reif_var.nil?
131
+ Gecode::Raw.should_receive(:rel).once.with(
126
132
  an_instance_of(Gecode::Raw::Space),
133
+ Gecode::Raw::BOT_OR,
134
+ an_instance_of(Gecode::Raw::BoolVarArray),
127
135
  an_instance_of(Gecode::Raw::BoolVar),
128
- an_instance_of(Gecode::Raw::BoolVar), true, strength)
136
+ strength, kind)
137
+ else
138
+ Gecode::Raw.should_receive(:rel).once.with(
139
+ an_instance_of(Gecode::Raw::Space),
140
+ an_instance_of(Gecode::Raw::BoolVar),
141
+ anything,
142
+ an_instance_of(Gecode::Raw::BoolVar),
143
+ anything, anything, anything)
144
+ Gecode::Raw.should_receive(:rel).once.with(
145
+ an_instance_of(Gecode::Raw::Space),
146
+ Gecode::Raw::BOT_OR,
147
+ an_instance_of(Gecode::Raw::BoolVarArray),
148
+ reif_var, strength, kind)
129
149
  end
130
150
  end
131
151
  end
@@ -136,5 +156,5 @@ describe Gecode::Constraints::BoolEnum, ' (disjunction)' do
136
156
  end
137
157
 
138
158
  it_should_behave_like 'bool enum constraint'
139
- it_should_behave_like 'constraint with options'
159
+ it_should_behave_like 'reifiable constraint'
140
160
  end
@@ -25,19 +25,20 @@ describe Gecode::Constraints::Bool do
25
25
  (@b1 | @b2).must_be.equal_to(true, hash)
26
26
  @model.solve!
27
27
  end
28
- @expect_options = lambda do |strength, reif_var|
28
+ @expect_options = option_expectation do |strength, kind, reif_var|
29
29
  @model.allow_space_access do
30
- Gecode::Raw.should_receive(:bool_or).once.with(
30
+ Gecode::Raw.should_receive(:rel).once.with(
31
31
  an_instance_of(Gecode::Raw::Space),
32
+ an_instance_of(Gecode::Raw::BoolVar),
33
+ Gecode::Raw::BOT_OR,
32
34
  an_instance_of(Gecode::Raw::BoolVar),
33
- an_instance_of(Gecode::Raw::BoolVar),
34
- an_instance_of(Gecode::Raw::BoolVar),
35
- Gecode::Raw::ICL_DEF)
35
+ an_instance_of(Gecode::Raw::BoolVar),
36
+ Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF)
36
37
  unless reif_var.nil?
37
- Gecode::Raw.should_receive(:bool_eqv).once.with(
38
+ Gecode::Raw.should_receive(:rel).once.with(
38
39
  an_instance_of(Gecode::Raw::Space),
39
- an_instance_of(Gecode::Raw::BoolVar),
40
- an_instance_of(Gecode::Raw::BoolVar), true, strength)
40
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::BOT_EQV,
41
+ an_instance_of(Gecode::Raw::BoolVar), 1, strength, kind)
41
42
  end
42
43
  end
43
44
  end
@@ -227,6 +228,5 @@ describe Gecode::Constraints::Bool do
227
228
  sol.b3.value.should be_true
228
229
  end
229
230
 
230
-
231
- it_should_behave_like 'constraint with options'
231
+ it_should_behave_like 'reifiable constraint'
232
232
  end
@@ -49,11 +49,13 @@ describe Gecode::Constraints::Set::Cardinality, ' (range)' do
49
49
  it 'should not shadow the integer variable domain constrain' do
50
50
  Gecode::Raw.should_receive(:dom).with(
51
51
  an_instance_of(Gecode::Raw::Space),
52
- an_instance_of(Gecode::Raw::IntVar), 0, 11, Gecode::Raw::ICL_DEF)
52
+ an_instance_of(Gecode::Raw::IntVar), 0, 11, Gecode::Raw::ICL_DEF,
53
+ Gecode::Raw::PK_DEF)
53
54
  Gecode::Raw.should_receive(:dom).with(
54
55
  an_instance_of(Gecode::Raw::Space),
55
56
  an_instance_of(Gecode::Raw::IntVar), an_instance_of(Gecode::Raw::IntSet),
56
- an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
57
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF,
58
+ Gecode::Raw::PK_DEF)
57
59
  @set.size.must_not_be.in [1,3]
58
60
  @model.solve!
59
61
  end
@@ -73,7 +75,7 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
73
75
  @set.size.must == rhs
74
76
  @model.solve!
75
77
  end
76
- @expect = lambda do |relation, rhs, strength, reif_var, negated|
78
+ @expect = lambda do |relation, rhs, strength, kind, reif_var, negated|
77
79
  @model.allow_space_access do
78
80
  rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
79
81
  if reif_var.nil?
@@ -91,7 +93,7 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
91
93
  Gecode::Raw.should_receive(:rel).once.with(
92
94
  an_instance_of(Gecode::Raw::Space),
93
95
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
94
- strength)
96
+ strength, kind)
95
97
  end
96
98
  else
97
99
  Gecode::Raw.should_receive(:cardinality).once.with(
@@ -102,7 +104,7 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
102
104
  an_instance_of(Gecode::Raw::Space),
103
105
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
104
106
  an_instance_of(Gecode::Raw::BoolVar),
105
- strength)
107
+ strength, kind)
106
108
  end
107
109
  end
108
110
  end
@@ -117,7 +119,8 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
117
119
  @model.solve!
118
120
  end
119
121
  @expect_relation = lambda do |relation, target, negated|
120
- @expect.call(relation, target, Gecode::Raw::ICL_DEF, nil, negated)
122
+ @expect.call(relation, target, Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF,
123
+ nil, negated)
121
124
  end
122
125
 
123
126
  # For options spec.
@@ -125,8 +128,8 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
125
128
  @set.size.must_be.less_than_or_equal_to(17, hash)
126
129
  @model.solve!
127
130
  end
128
- @expect_options = lambda do |strength, reif_var|
129
- @expect.call(Gecode::Raw::IRT_LQ, 17, strength, reif_var, false)
131
+ @expect_options = option_expectation do |strength, kind, reif_var|
132
+ @expect.call(Gecode::Raw::IRT_LQ, 17, strength, kind, reif_var, false)
130
133
  end
131
134
  end
132
135
 
@@ -149,6 +152,6 @@ describe Gecode::Constraints::Set::Cardinality, ' (composite)' do
149
152
  @set.value.size.should == 2
150
153
  end
151
154
 
152
- it_should_behave_like 'constraint with options'
155
+ it_should_behave_like 'reifiable constraint'
153
156
  it_should_behave_like 'composite constraint'
154
157
  end
@@ -25,18 +25,18 @@ describe Gecode::Constraints::IntEnum::Channel, ' (two int enums)' do
25
25
  @positions.must.channel @elements, hash
26
26
  @model.solve!
27
27
  end
28
- @expect_options = lambda do |strength, reif_var|
28
+ @expect_options = option_expectation do |strength, kind, reif_var|
29
29
  Gecode::Raw.should_receive(:channel).once.with(
30
30
  an_instance_of(Gecode::Raw::Space),
31
31
  an_instance_of(Gecode::Raw::IntVarArray),
32
- an_instance_of(Gecode::Raw::IntVarArray), strength)
32
+ an_instance_of(Gecode::Raw::IntVarArray), strength, kind)
33
33
  end
34
34
  end
35
35
 
36
36
  it 'should translate into a channel constraint' do
37
37
  Gecode::Raw.should_receive(:channel).once.with(
38
38
  an_instance_of(Gecode::Raw::Space),
39
- anything, anything, Gecode::Raw::ICL_DEF)
39
+ anything, anything, Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF)
40
40
  @invoke_options.call({})
41
41
  end
42
42
 
@@ -59,7 +59,7 @@ describe Gecode::Constraints::IntEnum::Channel, ' (two int enums)' do
59
59
  lambda{ @elements.must.channel 'hello' }.should raise_error(TypeError)
60
60
  end
61
61
 
62
- it_should_behave_like 'constraint with strength option'
62
+ it_should_behave_like 'reifiable constraint'
63
63
  end
64
64
 
65
65
  describe Gecode::Constraints::IntEnum::Channel, ' (one int enum and one set enum)' do
@@ -99,7 +99,7 @@ describe Gecode::Constraints::SetEnum, ' (channel with set as left hand side)' d
99
99
  @sets.must.channel @positions, hash
100
100
  @model.solve!
101
101
  end
102
- @expect_options = lambda do |strength, reif_var|
102
+ @expect_options = option_expectation do |strength, kind, reif_var|
103
103
  Gecode::Raw.should_receive(:channel).once.with(
104
104
  an_instance_of(Gecode::Raw::Space),
105
105
  an_instance_of(Gecode::Raw::IntVarArray),
@@ -108,7 +108,7 @@ describe Gecode::Constraints::SetEnum, ' (channel with set as left hand side)' d
108
108
  end
109
109
 
110
110
  it 'should translate into a channel constraint' do
111
- @expect_options.call(Gecode::Raw::ICL_DEF, nil)
111
+ @expect_options.call({})
112
112
  @sets.must.channel @positions
113
113
  @model.solve!
114
114
  end
@@ -19,7 +19,8 @@ describe 'connection constraint', :shared => true do
19
19
  @model.solve!
20
20
  end
21
21
  @expect_relation = lambda do |relation, target, negated|
22
- @expect.call(relation, target, Gecode::Raw::ICL_DEF, nil, negated)
22
+ @expect.call(relation, target, Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF,
23
+ nil, negated)
23
24
  end
24
25
 
25
26
  # For options spec.
@@ -27,12 +28,12 @@ describe 'connection constraint', :shared => true do
27
28
  @stub.must_be.less_than_or_equal_to(17, hash)
28
29
  @model.solve!
29
30
  end
30
- @expect_options = lambda do |strength, reif_var|
31
- @expect.call(Gecode::Raw::IRT_LQ, 17, strength, reif_var, false)
31
+ @expect_options = option_expectation do |strength, kind, reif_var|
32
+ @expect.call(Gecode::Raw::IRT_LQ, 17, strength, kind, reif_var, false)
32
33
  end
33
34
  end
34
35
 
35
- it_should_behave_like 'constraint with options'
36
+ it_should_behave_like 'reifiable constraint'
36
37
  it_should_behave_like 'composite constraint'
37
38
  end
38
39
 
@@ -44,7 +45,7 @@ describe Gecode::Constraints::Set::Connection, ' (min)' do
44
45
  @model.branch_on @model.wrap_enum([@set])
45
46
  @stub = @set.min
46
47
 
47
- @expect = lambda do |relation, rhs, strength, reif_var, negated|
48
+ @expect = lambda do |relation, rhs, strength, kind, reif_var, negated|
48
49
  @model.allow_space_access do
49
50
  rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
50
51
  if reif_var.nil?
@@ -62,7 +63,7 @@ describe Gecode::Constraints::Set::Connection, ' (min)' do
62
63
  Gecode::Raw.should_receive(:rel).once.with(
63
64
  an_instance_of(Gecode::Raw::Space),
64
65
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
65
- strength)
66
+ strength, kind)
66
67
  end
67
68
  else
68
69
  Gecode::Raw.should_receive(:min).once.with(
@@ -72,8 +73,7 @@ describe Gecode::Constraints::Set::Connection, ' (min)' do
72
73
  Gecode::Raw.should_receive(:rel).once.with(
73
74
  an_instance_of(Gecode::Raw::Space),
74
75
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
75
- an_instance_of(Gecode::Raw::BoolVar),
76
- strength)
76
+ reif_var, strength, kind)
77
77
  end
78
78
  end
79
79
  end
@@ -96,7 +96,7 @@ describe Gecode::Constraints::Set::Connection, ' (max)' do
96
96
  @model.branch_on @model.wrap_enum([@set])
97
97
  @stub = @set.max
98
98
 
99
- @expect = lambda do |relation, rhs, strength, reif_var, negated|
99
+ @expect = lambda do |relation, rhs, strength, kind, reif_var, negated|
100
100
  @model.allow_space_access do
101
101
  rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
102
102
  if reif_var.nil?
@@ -114,7 +114,7 @@ describe Gecode::Constraints::Set::Connection, ' (max)' do
114
114
  Gecode::Raw.should_receive(:rel).once.with(
115
115
  an_instance_of(Gecode::Raw::Space),
116
116
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
117
- strength)
117
+ strength, kind)
118
118
  end
119
119
  else
120
120
  Gecode::Raw.should_receive(:max).once.with(
@@ -124,8 +124,7 @@ describe Gecode::Constraints::Set::Connection, ' (max)' do
124
124
  Gecode::Raw.should_receive(:rel).once.with(
125
125
  an_instance_of(Gecode::Raw::Space),
126
126
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
127
- an_instance_of(Gecode::Raw::BoolVar),
128
- strength)
127
+ reif_var, strength, kind)
129
128
  end
130
129
  end
131
130
  end
@@ -148,7 +147,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum)' do
148
147
  @model.branch_on @model.wrap_enum([@set])
149
148
  @stub = @set.sum
150
149
 
151
- @expect = lambda do |relation, rhs, strength, reif_var, negated|
150
+ @expect = lambda do |relation, rhs, strength, kind, reif_var, negated|
152
151
  @model.allow_space_access do
153
152
  rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
154
153
  if reif_var.nil?
@@ -167,7 +166,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum)' do
167
166
  Gecode::Raw.should_receive(:rel).once.with(
168
167
  an_instance_of(Gecode::Raw::Space),
169
168
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
170
- strength)
169
+ strength, kind)
171
170
  end
172
171
  else
173
172
  Gecode::Raw.should_receive(:weights).once.with(
@@ -177,8 +176,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum)' do
177
176
  Gecode::Raw.should_receive(:rel).once.with(
178
177
  an_instance_of(Gecode::Raw::Space),
179
178
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
180
- an_instance_of(Gecode::Raw::BoolVar),
181
- strength)
179
+ reif_var, strength, kind)
182
180
  end
183
181
  end
184
182
  end
@@ -214,7 +212,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum with weights)' do
214
212
  @weights = Hash[*(0..9).zip((-9..-0).to_a.reverse).flatten]
215
213
  @stub = @set.sum(:weights => @weights)
216
214
 
217
- @expect = lambda do |relation, rhs, strength, reif_var, negated|
215
+ @expect = lambda do |relation, rhs, strength, kind, reif_var, negated|
218
216
  @model.allow_space_access do
219
217
  rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
220
218
  if reif_var.nil?
@@ -232,7 +230,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum with weights)' do
232
230
  Gecode::Raw.should_receive(:rel).once.with(
233
231
  an_instance_of(Gecode::Raw::Space),
234
232
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
235
- strength)
233
+ strength, kind)
236
234
  end
237
235
  else
238
236
  Gecode::Raw.should_receive(:weights).once.with(
@@ -242,8 +240,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum with weights)' do
242
240
  Gecode::Raw.should_receive(:rel).once.with(
243
241
  an_instance_of(Gecode::Raw::Space),
244
242
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
245
- an_instance_of(Gecode::Raw::BoolVar),
246
- strength)
243
+ reif_var, strength, kind)
247
244
  end
248
245
  end
249
246
  end
@@ -275,7 +272,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum with substitutions)' do
275
272
  @subs = Hash[*(0..9).zip((-9..-0).to_a.reverse).flatten]
276
273
  @stub = @set.sum(:substitutions => @subs)
277
274
 
278
- @expect = lambda do |relation, rhs, strength, reif_var, negated|
275
+ @expect = lambda do |relation, rhs, strength, kind, reif_var, negated|
279
276
  @model.allow_space_access do
280
277
  rhs = an_instance_of(Gecode::Raw::IntVar) if rhs.respond_to? :bind
281
278
  if reif_var.nil?
@@ -293,7 +290,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum with substitutions)' do
293
290
  Gecode::Raw.should_receive(:rel).once.with(
294
291
  an_instance_of(Gecode::Raw::Space),
295
292
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
296
- strength)
293
+ strength, kind)
297
294
  end
298
295
  else
299
296
  Gecode::Raw.should_receive(:weights).once.with(
@@ -303,8 +300,7 @@ describe Gecode::Constraints::Set::Connection, ' (sum with substitutions)' do
303
300
  Gecode::Raw.should_receive(:rel).once.with(
304
301
  an_instance_of(Gecode::Raw::Space),
305
302
  an_instance_of(Gecode::Raw::IntVar), relation, rhs,
306
- an_instance_of(Gecode::Raw::BoolVar),
307
- strength)
303
+ reif_var, strength, kind)
308
304
  end
309
305
  end
310
306
  end
@@ -339,7 +335,7 @@ describe Gecode::Constraints::Set::Connection, ' (include)' do
339
335
  end
340
336
  end
341
337
 
342
- @expect_options = lambda do |strength, reif_var|
338
+ @expect_options = option_expectation do |strength, kind, reif_var|
343
339
  @expect.call(@array, strength, reif_var)
344
340
  end
345
341
  @invoke_options = lambda do |hash|
@@ -349,7 +345,7 @@ describe Gecode::Constraints::Set::Connection, ' (include)' do
349
345
  end
350
346
 
351
347
  it 'should translate to a match constraint' do
352
- @expect_options.call(Gecode::Raw::ICL_DEF, nil)
348
+ @expect_options.call({})
353
349
  @set.must.include @array
354
350
  @model.solve!
355
351
  end
@@ -1,7 +1,28 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
- # This requires that the constraint spec has instance variables @invoke_options
4
- # and @expect_options .
3
+ # Several of these shared specs requires one or more of the following instance
4
+ # variables to be used:
5
+ # [@expect_options] A method that creates an expectation on the aspect to be
6
+ # tested, using the provided hash of Gecode values. The hash
7
+ # can have values for the keys :icl (ICL_*), :pk (PK_*), and
8
+ # :bool (bound reification variable). Any values not
9
+ # provided are assumed to be default values (nil in the case
10
+ # of :bool).
11
+ # [@invoke_options] A method that invokes the aspect to be tested, with the
12
+ # provided hash of options (with at most the keys :strength,
13
+ # :kind and :reify).
14
+ # [@model] The model instance that contains the aspects being tested.
15
+ # [@expect_relation] A method that takes a relation, right hand side, and
16
+ # whether it's negated, as arguments and sets up the
17
+ # corresponding expectations.
18
+ # [@invoke_relation] A method that takes a relation, right hand side, and
19
+ # whether it's negated, as arguments and adds the
20
+ # corresponding constraint and invokes it.
21
+ # [@target] A legal right hand side that can be used as argument to
22
+ # the above two methods.
23
+
24
+
25
+ # Requires @invoke_options and @expect_options.
5
26
  describe 'constraint with strength option', :shared => true do
6
27
  { :default => Gecode::Raw::ICL_DEF,
7
28
  :value => Gecode::Raw::ICL_VAL,
@@ -9,49 +30,92 @@ describe 'constraint with strength option', :shared => true do
9
30
  :domain => Gecode::Raw::ICL_DOM
10
31
  }.each_pair do |name, gecode_value|
11
32
  it "should translate propagation strength #{name}" do
12
- @expect_options.call(gecode_value, nil)
33
+ @expect_options.call(:icl => gecode_value)
13
34
  @invoke_options.call(:strength => name)
14
35
  end
15
36
  end
16
37
 
17
38
  it 'should default to using default as propagation strength' do
18
- @expect_options.call(Gecode::Raw::ICL_DEF, nil)
39
+ @expect_options.call({})
19
40
  @invoke_options.call({})
20
41
  end
21
42
 
22
- it 'should raise errors for unrecognized options' do
23
- lambda{ @invoke_options.call(:does_not_exist => :foo) }.should(
24
- raise_error(ArgumentError))
43
+ it 'should raise errors for unrecognized propagation strengths' do
44
+ lambda do
45
+ @invoke_options.call(:strength => :does_not_exist)
46
+ end.should raise_error(ArgumentError)
47
+ end
48
+ end
49
+
50
+ # Requires @invoke_options and @expect_options.
51
+ describe 'constraint with kind option', :shared => true do
52
+ { :default => Gecode::Raw::PK_DEF,
53
+ :speed => Gecode::Raw::PK_SPEED,
54
+ :memory => Gecode::Raw::PK_MEMORY
55
+ }.each_pair do |name, gecode_value|
56
+ it "should translate propagation kind #{name}" do
57
+ @expect_options.call(:pk => gecode_value)
58
+ @invoke_options.call(:kind => name)
59
+ end
25
60
  end
26
61
 
27
- it 'should raise errors for unrecognized propagation strengths' do
28
- lambda{ @invoke_options.call(:strength => :does_not_exist) }.should(
29
- raise_error(ArgumentError))
62
+ it 'should default to using default as propagation kind' do
63
+ @expect_options.call({})
64
+ @invoke_options.call({})
30
65
  end
31
66
 
32
- it 'should raise errors for reification variables of incorrect type' do
33
- lambda{ @invoke_options.call(:reify => 'foo') }.should(
34
- raise_error(TypeError))
67
+ it 'should raise errors for unrecognized propagation kinds' do
68
+ lambda do
69
+ @invoke_options.call(:kind => :does_not_exist)
70
+ end.should raise_error(ArgumentError)
35
71
  end
36
72
  end
37
73
 
38
- # This requires that the constraint spec has instance variables @invoke_options
39
- # and @expect_options .
40
- describe 'constraint with options', :shared => true do
74
+
75
+ # Requires @invoke_options and @expect_options.
76
+ describe 'constraint with reification option', :shared => true do
41
77
  it 'should translate reification' do
42
78
  var = @model.bool_var
43
- @expect_options.call(Gecode::Raw::ICL_DEF, var)
79
+ @expect_options.call(:bool => var)
44
80
  @invoke_options.call(:reify => var)
45
81
  end
46
82
 
83
+ it 'should raise errors for reification variables of incorrect type' do
84
+ lambda do
85
+ @invoke_options.call(:reify => 'foo')
86
+ end.should raise_error(TypeError)
87
+ end
88
+ end
89
+
90
+ # Requires @invoke_options and @expect_options.
91
+ describe 'reifiable constraint', :shared => true do
92
+ it_should_behave_like 'constraint with default options'
93
+ it_should_behave_like 'constraint with reification option'
94
+ end
95
+
96
+ # Requires @invoke_options, @expect_options and @model.
97
+ describe 'non-reifiable constraint', :shared => true do
98
+ it 'should raise errors if reification is used' do
99
+ lambda do
100
+ @invoke_options.call(:reify => @model.bool_var)
101
+ end.should raise_error(ArgumentError)
102
+ end
103
+
104
+ it_should_behave_like 'constraint with default options'
105
+ end
106
+
107
+ # Requires @invoke_options and @expect_options.
108
+ describe 'constraint with default options', :shared => true do
109
+ it 'should raise errors for unrecognized options' do
110
+ lambda{ @invoke_options.call(:does_not_exist => :foo) }.should(
111
+ raise_error(ArgumentError))
112
+ end
113
+
47
114
  it_should_behave_like 'constraint with strength option'
115
+ it_should_behave_like 'constraint with kind option'
48
116
  end
49
117
 
50
- # This requires that the constraint spec has the instance variable
51
- # @expect_relation which takes a relation, right hand side and whether it's
52
- # negated as arguments and sets up the corresponding expectations. It also
53
- # requires @invoke_relation with the same arguments. The spec is also required
54
- # to provide a variable @target.
118
+ # Requires @expect_relation, @invoke_relation and @target.
55
119
  describe 'composite constraint', :shared => true do
56
120
  Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
57
121
  it "should translate #{relation} with constant target" do
@@ -88,11 +152,7 @@ describe 'composite constraint', :shared => true do
88
152
  end
89
153
  end
90
154
 
91
- # This requires that the constraint spec has the instance variable
92
- # @expect_relation which takes a relation, right hand side and whether it's
93
- # negated as arguments and sets up the corresponding expectations. It also
94
- # requires @invoke_relation with the same arguments. The spec is also required
95
- # to provide a variable @target.
155
+ # Requires @expect_relation, @invoke_relation and @target.
96
156
  describe 'composite set constraint', :shared => true do
97
157
  Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |relation, type|
98
158
  it "should translate #{relation} with constant target" do
@@ -129,35 +189,42 @@ describe 'composite set constraint', :shared => true do
129
189
  end
130
190
  end
131
191
 
132
- # Requires @invoke_options and @model.
133
- describe 'non-reifiable set constraint', :shared => true do
192
+ describe 'set constraint', :shared => true do
134
193
  it 'should not accept strength option' do
135
194
  lambda do
136
195
  @invoke_options.call(:strength => :default)
137
196
  end.should raise_error(ArgumentError)
138
197
  end
139
198
 
199
+ it 'should not accept kind option' do
200
+ lambda do
201
+ @invoke_options.call(:kind => :default)
202
+ end.should raise_error(ArgumentError)
203
+ end
204
+
205
+ it 'should raise errors for unrecognized options' do
206
+ lambda do
207
+ @invoke_options.call(:does_not_exist => :foo)
208
+ end.should raise_error(ArgumentError)
209
+ end
210
+ end
211
+
212
+ # Requires @invoke_options and @model.
213
+ describe 'non-reifiable set constraint', :shared => true do
140
214
  it 'should not accept reification option' do
141
215
  bool = @model.bool_var
142
216
  lambda do
143
217
  @invoke_options.call(:reify => bool)
144
218
  end.should raise_error(ArgumentError)
145
219
  end
220
+
221
+ it_should_behave_like 'set constraint'
146
222
  end
147
223
 
148
224
  # Requires @invoke_options, @expect_options and @model.
149
225
  describe 'reifiable set constraint', :shared => true do
150
- it 'should not accept strength option' do
151
- lambda do
152
- @invoke_options.call(:strength => :default)
153
- end.should raise_error(ArgumentError)
154
- end
155
-
156
- it 'should accept reification option' do
157
- bool = @model.bool_var
158
- @expect_options.call(nil, bool)
159
- @invoke_options.call(:reify => bool)
160
- end
226
+ it_should_behave_like 'set constraint'
227
+ it_should_behave_like 'constraint with reification option'
161
228
  end
162
229
 
163
230
  # Help methods for the GecodeR specs.
@@ -177,4 +244,21 @@ module GecodeR::Specs
177
244
  end
178
245
  end
179
246
  end
180
- end
247
+ end
248
+
249
+ # Helper for creating @expect_option. Creates a method which takes a hash that
250
+ # may have values for the keys :icl (ICL_*), :pk (PK_*), and :bool (reification
251
+ # variable). Expectations corresponding to the hash values are given to the
252
+ # specified block in the order of icl, pk and bool. Default values are provided
253
+ # if the hash doesn't specify anything else.
254
+ def option_expectation(&block)
255
+ lambda do |hash|
256
+ bool = hash[:bool]
257
+ # We loosen the expectation some to avoid practical problems with expecting
258
+ # specific variables not under our control.
259
+ bool = an_instance_of(Gecode::Raw::BoolVar) unless bool.nil?
260
+ yield(hash[:icl] || Gecode::Raw::ICL_DEF,
261
+ hash[:pk] || Gecode::Raw::PK_DEF,
262
+ bool)
263
+ end
264
+ end