gecoder 0.3.0 → 0.4.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 (56) hide show
  1. data/CHANGES +17 -2
  2. data/README +7 -1
  3. data/Rakefile +4 -0
  4. data/lib/gecoder/interface/constraints/bool/boolean.rb +1 -4
  5. data/lib/gecoder/interface/constraints/int/arithmetic.rb +77 -0
  6. data/lib/gecoder/interface/constraints/int/domain.rb +50 -0
  7. data/lib/gecoder/interface/constraints/int/linear.rb +12 -44
  8. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
  9. data/lib/gecoder/interface/constraints/int_enum/channel.rb +32 -0
  10. data/lib/gecoder/interface/constraints/int_enum/count.rb +90 -0
  11. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +3 -8
  12. data/lib/gecoder/interface/constraints/int_enum/element.rb +75 -0
  13. data/lib/gecoder/interface/constraints/int_enum/equality.rb +31 -0
  14. data/lib/gecoder/interface/constraints/int_enum/sort.rb +104 -0
  15. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +6 -0
  16. data/lib/gecoder/interface/constraints/int_var_constraints.rb +2 -0
  17. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +21 -0
  18. data/lib/gecoder/interface/constraints.rb +57 -6
  19. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  20. data/lib/gecoder/interface/enum_wrapper.rb +33 -5
  21. data/lib/gecoder/interface/model.rb +36 -6
  22. data/lib/gecoder/interface.rb +1 -0
  23. data/lib/gecoder/version.rb +4 -0
  24. data/lib/gecoder.rb +1 -0
  25. data/specs/binding_changes.rb +72 -0
  26. data/specs/bool_var.rb +20 -0
  27. data/specs/branch.rb +104 -0
  28. data/specs/constraints/arithmetic.rb +227 -0
  29. data/specs/constraints/boolean.rb +132 -0
  30. data/specs/constraints/channel.rb +55 -0
  31. data/specs/constraints/constraint_helper.rb +48 -0
  32. data/specs/constraints/constraints.rb +28 -0
  33. data/specs/constraints/count.rb +99 -0
  34. data/specs/constraints/distinct.rb +99 -0
  35. data/specs/constraints/domain.rb +56 -0
  36. data/specs/constraints/element.rb +128 -0
  37. data/specs/constraints/equality.rb +30 -0
  38. data/specs/constraints/linear.rb +166 -0
  39. data/specs/constraints/reification_sugar.rb +92 -0
  40. data/specs/constraints/relation.rb +72 -0
  41. data/specs/constraints/sort.rb +173 -0
  42. data/specs/enum_matrix.rb +43 -0
  43. data/specs/enum_wrapper.rb +100 -0
  44. data/specs/int_var.rb +108 -0
  45. data/specs/model.rb +84 -0
  46. data/specs/search.rb +157 -0
  47. data/specs/spec_helper.rb +63 -0
  48. data/specs/tmp +135 -0
  49. data/tasks/all_tasks.rb +1 -0
  50. data/tasks/distribution.rake +64 -0
  51. data/tasks/rcov.rake +17 -0
  52. data/tasks/specs.rake +16 -0
  53. data/tasks/svn.rake +11 -0
  54. data/tasks/website.rake +58 -0
  55. data/vendor/rust/include/rust_conversions.hh +1 -2
  56. metadata +53 -2
@@ -0,0 +1,56 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ describe Gecode::Constraints::Int::Domain do
5
+ before do
6
+ @model = Gecode::Model.new
7
+ @domain = 0..3
8
+ @x = @model.int_var(@domain)
9
+ @range_domain = 1..2
10
+ @three_dot_range_domain = 1...2
11
+ @non_range_domain = [1, 3]
12
+
13
+ @invoke_options = lambda do |hash|
14
+ @x.must_be.in(@non_range_domain, hash)
15
+ @model.solve!
16
+ end
17
+ @expect_options = lambda do |strength, reif_var|
18
+ if reif_var.nil?
19
+ Gecode::Raw.should_receive(:dom).once.with(@model.active_space,
20
+ @x.bind, an_instance_of(Gecode::Raw::IntSet), strength)
21
+ else
22
+ Gecode::Raw.should_receive(:dom).once.with(@model.active_space,
23
+ @x.bind, an_instance_of(Gecode::Raw::IntSet),
24
+ an_instance_of(Gecode::Raw::BoolVar), strength)
25
+ end
26
+ end
27
+ end
28
+
29
+ it 'should translate domain constraints with range domains' do
30
+ Gecode::Raw.should_receive(:dom).once.with(@model.active_space,
31
+ @x.bind, @range_domain.first, @range_domain.last, Gecode::Raw::ICL_DEF)
32
+ @x.must_be.in @range_domain
33
+ @model.solve!
34
+ end
35
+
36
+ it 'should translate domain constraints with three dot range domains' do
37
+ Gecode::Raw.should_receive(:dom).once.with(@model.active_space,
38
+ @x.bind, @three_dot_range_domain.first, @three_dot_range_domain.last,
39
+ Gecode::Raw::ICL_DEF)
40
+ @x.must_be.in @three_dot_range_domain
41
+ @model.solve!
42
+ end
43
+
44
+ it 'should translate domain constraints with non-range domains' do
45
+ @expect_options.call(Gecode::Raw::ICL_DEF, nil)
46
+ @invoke_options.call({})
47
+ end
48
+
49
+ it 'should handle negation' do
50
+ @x.must_not_be.in @range_domain
51
+ @model.solve!
52
+ @x.should have_domain(@domain.to_a - @range_domain.to_a)
53
+ end
54
+
55
+ it_should_behave_like 'constraint with options'
56
+ end
@@ -0,0 +1,128 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ class ElementSampleProblem < Gecode::Model
5
+ attr :prices
6
+ attr :store
7
+ attr :price
8
+ attr :fixnum_prices
9
+
10
+ def initialize
11
+ prices = [17, 63, 45, 63]
12
+ @fixnum_prices = wrap_enum(prices)
13
+ @prices = int_var_array(4, *prices)
14
+ @store = int_var(0...prices.size)
15
+ @price = int_var(*prices)
16
+ branch_on wrap_enum([@store])
17
+ end
18
+ end
19
+
20
+ describe Gecode::Constraints::IntEnum::Element do
21
+ before do
22
+ @model = ElementSampleProblem.new
23
+ @prices = @model.prices
24
+ @price = @model.price
25
+ @store = @model.store
26
+ @fixnum_prices = @model.fixnum_prices
27
+
28
+ # For constraint option spec.
29
+ @invoke_options = lambda do |hash|
30
+ @prices[@store].must_be.greater_than(@price, hash)
31
+ @model.solve!
32
+ end
33
+ @expect_options = lambda do |strength, reif_var|
34
+ if reif_var.nil?
35
+ Gecode::Raw.should_receive(:element).once.with(@model.active_space,
36
+ an_instance_of(Gecode::Raw::IntVarArray),
37
+ an_instance_of(Gecode::Raw::IntVar),
38
+ an_instance_of(Gecode::Raw::IntVar), an_instance_of(Fixnum))
39
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
40
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR,
41
+ an_instance_of(Gecode::Raw::IntVar), strength)
42
+ else
43
+ Gecode::Raw.should_receive(:element).once.with(@model.active_space,
44
+ an_instance_of(Gecode::Raw::IntVarArray),
45
+ an_instance_of(Gecode::Raw::IntVar),
46
+ an_instance_of(Gecode::Raw::IntVar), an_instance_of(Fixnum))
47
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
48
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR,
49
+ an_instance_of(Gecode::Raw::IntVar),
50
+ an_instance_of(Gecode::Raw::BoolVar), strength)
51
+ end
52
+ end
53
+ end
54
+
55
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
56
+ it "should translate #{relation} with variable right hand side" do
57
+ Gecode::Raw.should_receive(:element).once.with(@model.active_space,
58
+ an_instance_of(Gecode::Raw::IntVarArray),
59
+ an_instance_of(Gecode::Raw::IntVar),
60
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
61
+ unless type == Gecode::Raw::IRT_EQ
62
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
63
+ an_instance_of(Gecode::Raw::IntVar), type,
64
+ an_instance_of(Gecode::Raw::IntVar), an_instance_of(Fixnum))
65
+ end
66
+ @prices[@store].must.send(relation, @price)
67
+ @model.solve!
68
+ end
69
+ end
70
+
71
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
72
+ it "should translate negated #{relation} with variable right hand side" do
73
+ Gecode::Raw.should_receive(:element).once.with(@model.active_space,
74
+ an_instance_of(Gecode::Raw::IntVarArray),
75
+ an_instance_of(Gecode::Raw::IntVar),
76
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
77
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
78
+ an_instance_of(Gecode::Raw::IntVar), type,
79
+ an_instance_of(Gecode::Raw::IntVar), an_instance_of(Fixnum))
80
+ @prices[@store].must_not.send(relation, @price)
81
+ @model.solve!
82
+ end
83
+ end
84
+
85
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
86
+ it "should translate #{relation} with constant right hand side" do
87
+ Gecode::Raw.should_receive(:element).once.with(@model.active_space,
88
+ an_instance_of(Gecode::Raw::IntVarArray),
89
+ an_instance_of(Gecode::Raw::IntVar),
90
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
91
+ unless type == Gecode::Raw::IRT_EQ
92
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
93
+ an_instance_of(Gecode::Raw::IntVar), type, 5, an_instance_of(Fixnum))
94
+ end
95
+ @prices[@store].must.send(relation, 5)
96
+ @model.solve!
97
+ end
98
+ end
99
+
100
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
101
+ it "should translate negated #{relation} with constant right hand side" do
102
+ Gecode::Raw.should_receive(:element).once.with(@model.active_space,
103
+ an_instance_of(Gecode::Raw::IntVarArray),
104
+ an_instance_of(Gecode::Raw::IntVar),
105
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
106
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
107
+ an_instance_of(Gecode::Raw::IntVar), type, 5, an_instance_of(Fixnum))
108
+ @prices[@store].must_not.send(relation, 5)
109
+ @model.solve!
110
+ end
111
+ end
112
+
113
+ it 'should not disturb normal array access' do
114
+ @fixnum_prices[2].should_not be_nil
115
+ @prices[2].should_not be_nil
116
+ end
117
+
118
+ it 'should handle fixnum enums as enumeration' do
119
+ @fixnum_prices[@store].must == @fixnum_prices[2]
120
+ @model.solve!.store.val.should equal(2)
121
+ end
122
+
123
+ it 'should raise error on right hand sides of the wrong type' do
124
+ lambda{ @prices[@store].must == 'hello' }.should raise_error(TypeError)
125
+ end
126
+
127
+ it_should_behave_like 'constraint with options'
128
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ describe Gecode::Constraints::IntEnum::Equality do
5
+ before do
6
+ @model = Gecode::Model.new
7
+ @vars = @model.int_var_array(4, -2..2)
8
+ @invoke_options = lambda do |hash|
9
+ @vars.must_be.equal(hash)
10
+ @model.solve!
11
+ end
12
+ @expect_options = lambda do |strength, reif_var|
13
+ Gecode::Raw.should_receive(:eq).once.with(@model.active_space,
14
+ anything, strength)
15
+ end
16
+ end
17
+
18
+ it 'should translate equality constraints' do
19
+ @expect_options.call(Gecode::Raw::ICL_DEF, nil)
20
+ @invoke_options.call({})
21
+ @vars.must_be.equal
22
+ end
23
+
24
+ it 'should not allow negation' do
25
+ lambda{ @vars.must_not_be.equal }.should raise_error(
26
+ Gecode::MissingConstraintError)
27
+ end
28
+
29
+ it_should_behave_like 'constraint with strength option'
30
+ end
@@ -0,0 +1,166 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ class LinearSampleProblem < Gecode::Model
5
+ attr :x
6
+ attr :y
7
+ attr :z
8
+
9
+ def initialize(x_dom, y_dom, z_dom)
10
+ @x = self.int_var(x_dom)
11
+ @y = self.int_var(y_dom)
12
+ @z = self.int_var(z_dom)
13
+ branch_on wrap_enum([@x, @y, @z])
14
+ end
15
+ end
16
+
17
+ describe Gecode::Constraints::Int::Linear do
18
+ before do
19
+ @x_dom = 0..2
20
+ @y_dom = -3..3
21
+ @z_dom = 0..10
22
+ @model = LinearSampleProblem.new(@x_dom, @y_dom, @z_dom)
23
+ @x = @model.x
24
+ @y = @model.y
25
+ @z = @model.z
26
+
27
+ # For constraint option spec.
28
+ @invoke_options = lambda do |hash|
29
+ (@x + @y).must_be.greater_than(@z, hash)
30
+ @model.solve!
31
+ end
32
+ @expect_options = lambda do |strength, reif_var|
33
+ # TODO: this is hard to spec from this level.
34
+ end
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.val
41
+ y = sol.y.val
42
+ (x + y).should be_zero
43
+ end
44
+
45
+ it 'should handle addition with multiple variables' do
46
+ (@x + @y + @z).must == 0
47
+ sol = @model.solve!
48
+ x = sol.x.val
49
+ y = sol.y.val
50
+ z = sol.z.val
51
+ (x + y + z).should be_zero
52
+ end
53
+
54
+ it 'should handle subtraction with a variable' do
55
+ (@x - @y).must == 0
56
+ sol = @model.solve!
57
+ x = sol.x.val
58
+ y = sol.y.val
59
+ (x - y).should be_zero
60
+ end
61
+
62
+ it 'should handle non-zero constants as right hand side' do
63
+ (@x + @y).must == 1
64
+ sol = @model.solve!
65
+ x = sol.x.val
66
+ y = sol.y.val
67
+ (x + y).should equal(1)
68
+ end
69
+
70
+ it 'should handle variables as right hand side' do
71
+ (@x + @y).must == @z
72
+ sol = @model.solve!
73
+ x = sol.x.val
74
+ y = sol.y.val
75
+ z = sol.z.val
76
+ (x + y).should equal(z)
77
+ end
78
+
79
+ it 'should handle linear expressions as right hand side' do
80
+ (@x + @y).must == @z + @y
81
+ sol = @model.solve!
82
+ x = sol.x.val
83
+ y = sol.y.val
84
+ z = sol.z.val
85
+ (x + y).should equal(z + y)
86
+ end
87
+
88
+ it 'should raise error on invalid right hand sides' do
89
+ lambda{ ((@x + @y).must == 'z') }.should raise_error(TypeError)
90
+ end
91
+
92
+ it 'should handle coefficients other than 1' do
93
+ (@x * 2 + @y).must == 0
94
+ sol = @model.solve!
95
+ x = sol.x.val
96
+ y = sol.y.val
97
+ (2*x + y).should equal(0)
98
+ end
99
+
100
+ it 'should handle addition with constants' do
101
+ (@y + 2).must == 1
102
+ sol = @model.solve!
103
+ y = sol.y.val
104
+ (y + 2).should equal(1)
105
+ end
106
+
107
+ it 'should handle subtraction with a constant' do
108
+ (@x - 2).must == 0
109
+ sol = @model.solve!
110
+ x = sol.x.val
111
+ (x - 2).should be_zero
112
+ end
113
+
114
+ it 'should a single variable as left hande side' do
115
+ @x.must == @y + @z
116
+ sol = @model.solve!
117
+ x = sol.x.val
118
+ y = sol.y.val
119
+ z = sol.z.val
120
+ x.should equal(y + z)
121
+ end
122
+
123
+ it 'should handle parenthesis' do
124
+ (@x - (@y + @z)).must == 1
125
+ sol = @model.solve!
126
+ x = sol.x.val
127
+ y = sol.y.val
128
+ z = sol.z.val
129
+ (x - (y + z)).should equal(1)
130
+ end
131
+
132
+ it 'should handle multiplication of parenthesis' do
133
+ (((@x + @y*10)*10 + @z)*10).must == 0
134
+ sol = @model.solve!
135
+ x = sol.x.val
136
+ y = sol.y.val
137
+ z = sol.z.val
138
+ (((x + y*10)*10 + z)*10).should equal(0)
139
+ end
140
+
141
+ relations = ['>', '>=', '<', '<=', '==']
142
+
143
+ relations.each do |relation|
144
+ it "should handle #{relation} with constant integers" do
145
+ (@x + @y).must.send(relation, 1)
146
+ sol = @model.solve!
147
+ sol.should_not be_nil
148
+ (sol.x.val + sol.y.val).should.send(relation, 1)
149
+ end
150
+ end
151
+
152
+ relations.each do |relation|
153
+ it "should handle negated #{relation} with constant integers" do
154
+ (@x + @y).must_not.send(relation, 1)
155
+ sol = @model.solve!
156
+ sol.should_not be_nil
157
+ (sol.x.val + sol.y.val).should_not.send(relation, 1)
158
+ end
159
+ end
160
+
161
+ it 'should not interfere with other defined multiplication methods' do
162
+ (@x * :foo).should be_nil
163
+ end
164
+
165
+ it_should_behave_like 'constraint with options'
166
+ end
@@ -0,0 +1,92 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class ReifSugarSampleProblem < Gecode::Model
4
+ attr :x
5
+ attr :y
6
+ attr :z
7
+
8
+ def initialize
9
+ @x = int_var(0..1)
10
+ @y = int_var(1..2)
11
+ @z = int_var(3..4)
12
+ branch_on wrap_enum([@x, @y, @z])
13
+ end
14
+ end
15
+
16
+ describe Gecode::Constraints::ReifiableConstraint do
17
+ before do
18
+ @model = ReifSugarSampleProblem.new
19
+ @x = @model.x
20
+ @y = @model.y
21
+ @z = @model.z
22
+ end
23
+
24
+ it 'should fail disjunctions if neither side can be satisfied' do
25
+ (@x.must == 3) | (@y.must == 3)
26
+ @model.solve!.should be_nil
27
+ end
28
+
29
+ it 'should translate disjunctions' do
30
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
31
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, 0,
32
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
33
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
34
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_EQ, 3,
35
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
36
+ (@x.must > 0) | (@y.must == 3)
37
+ sol = @model.solve!
38
+ end
39
+
40
+ it 'should solve disjunctions' do
41
+ (@x.must > 0) | (@y.must == 3)
42
+ sol = @model.solve!
43
+ sol.should_not be_nil
44
+ sol.x.should have_domain([1])
45
+ end
46
+
47
+ it 'should fail conjunctions if one side can\'t be satisfied' do
48
+ (@x.must > 3) & (@y.must == 3)
49
+ @model.solve!.should be_nil
50
+ end
51
+
52
+ it 'should translate conjunctions' do
53
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
54
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, 0,
55
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
56
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
57
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_EQ, 2,
58
+ an_instance_of(Gecode::Raw::BoolVar), Gecode::Raw::ICL_DEF)
59
+ (@x.must > 0) & (@y.must == 2)
60
+ sol = @model.solve!
61
+ end
62
+
63
+ it 'should solve conjunctions' do
64
+ (@x.must > 0) & (@y.must == 2)
65
+ sol = @model.solve!
66
+ sol.should_not be_nil
67
+ sol.x.should have_domain([1])
68
+ sol.y.should have_domain([2])
69
+ end
70
+
71
+ it 'should handle the same variable being used multiple times' do
72
+ (@z.must == 4) | (@z.must == 4)
73
+ sol = @model.solve!
74
+ sol.should_not be_nil
75
+ sol.z.should have_domain([4])
76
+ end
77
+
78
+ it 'should handle nested operations' do
79
+ ((@x.must > 3) & (@y.must == 2)) | (@z.must == 4) | (
80
+ (@x.must == 0) & (@z.must == 4))
81
+ sol = @model.solve!
82
+ sol.should_not be_nil
83
+ sol.x.should have_domain([0])
84
+ sol.z.should have_domain([4])
85
+ end
86
+
87
+ it 'should handle negations' do
88
+ (@z.must_not == 4) & (@z.must == 4)
89
+ sol = @model.solve!
90
+ sol.should be_nil
91
+ end
92
+ end
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require File.dirname(__FILE__) + '/constraint_helper'
3
+
4
+ describe Gecode::Constraints::Int::Linear, ' (simple ones)' do
5
+ before do
6
+ @model = Gecode::Model.new
7
+ @x = @model.int_var(1..2)
8
+ @int = 4
9
+ @y = @model.int_var(1..2)
10
+
11
+ # For constraint option spec.
12
+ @invoke_options = lambda do |hash|
13
+ @x.must_be.greater_than(3, hash)
14
+ @model.solve!
15
+ end
16
+ @expect_options = lambda do |strength, reif_var|
17
+ if reif_var.nil?
18
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
19
+ anything, Gecode::Raw::IRT_GR, anything,
20
+ strength)
21
+ else
22
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
23
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, anything,
24
+ an_instance_of(Gecode::Raw::BoolVar), strength)
25
+ end
26
+ end
27
+ end
28
+
29
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
30
+ it "should translate #{relation} with constant to simple relation" do
31
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
32
+ an_instance_of(Gecode::Raw::IntVar), type, @int, Gecode::Raw::ICL_DEF)
33
+ @x.must.send(relation, @int)
34
+ @model.solve!
35
+ end
36
+ end
37
+
38
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
39
+ it "should translate negated #{relation} with constant to simple relation" do
40
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
41
+ an_instance_of(Gecode::Raw::IntVar), type, @int, Gecode::Raw::ICL_DEF)
42
+ @x.must_not.send(relation, @int)
43
+ @model.solve!
44
+ end
45
+ end
46
+
47
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
48
+ it "should translate #{relation} with variables to simple relation" do
49
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
50
+ an_instance_of(Gecode::Raw::IntVar), type,
51
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
52
+ @x.must.send(relation, @y)
53
+ @model.solve!
54
+ end
55
+ end
56
+
57
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
58
+ it "should translate negated #{relation} with variable to simple relation" do
59
+ Gecode::Raw.should_receive(:rel).once.with(@model.active_space,
60
+ an_instance_of(Gecode::Raw::IntVar), type,
61
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
62
+ @x.must_not.send(relation, @y)
63
+ @model.solve!
64
+ end
65
+ end
66
+
67
+ it 'should raise error on arguments of the wrong type' do
68
+ lambda{ @x.must == 'hello' }.should raise_error(TypeError)
69
+ end
70
+
71
+ it_should_behave_like 'constraint with options'
72
+ end