gecoder 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. data/CHANGES +15 -0
  2. data/README +6 -2
  3. data/example/equation_system.rb +15 -0
  4. data/example/magic_sequence.rb +7 -7
  5. data/example/money.rb +36 -0
  6. data/example/queens.rb +7 -8
  7. data/example/send_most_money.rb +1 -1
  8. data/example/square_tiling.rb +2 -2
  9. data/example/sudoku-set.rb +11 -12
  10. data/example/sudoku.rb +40 -45
  11. data/ext/extconf.rb +0 -0
  12. data/lib/gecoder/bindings.rb +42 -0
  13. data/lib/gecoder/bindings/bindings.rb +16 -0
  14. data/lib/gecoder/interface.rb +2 -1
  15. data/lib/gecoder/interface/branch.rb +16 -9
  16. data/lib/gecoder/interface/constraints.rb +410 -451
  17. data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
  18. data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
  19. data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
  20. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
  21. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
  22. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
  23. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
  24. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
  25. data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
  26. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  27. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  28. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  29. data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
  30. data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
  31. data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
  32. data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
  33. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  34. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
  35. data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
  36. data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
  37. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
  38. data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
  39. data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
  40. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
  41. data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
  42. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
  43. data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
  44. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
  45. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  46. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  47. data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
  48. data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
  49. data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
  50. data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
  51. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  52. data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
  53. data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
  54. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  55. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  56. data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
  57. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
  58. data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
  59. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  60. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
  61. data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
  62. data/lib/gecoder/interface/enum_matrix.rb +4 -4
  63. data/lib/gecoder/interface/enum_wrapper.rb +71 -22
  64. data/lib/gecoder/interface/model.rb +167 -12
  65. data/lib/gecoder/interface/model_sugar.rb +84 -0
  66. data/lib/gecoder/interface/search.rb +30 -18
  67. data/lib/gecoder/interface/variables.rb +103 -33
  68. data/lib/gecoder/version.rb +2 -2
  69. data/specs/bool_var.rb +19 -12
  70. data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
  71. data/specs/constraints/bool/boolean_properties.rb +51 -0
  72. data/specs/constraints/bool/linear.rb +213 -0
  73. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  74. data/specs/constraints/bool_enum/channel.rb +102 -0
  75. data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
  76. data/specs/constraints/constraint_helper.rb +149 -179
  77. data/specs/constraints/constraint_receivers.rb +103 -0
  78. data/specs/constraints/constraints.rb +6 -63
  79. data/specs/constraints/fixnum_enum/element.rb +58 -0
  80. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  81. data/specs/constraints/int/arithmetic.rb +149 -0
  82. data/specs/constraints/int/channel.rb +101 -0
  83. data/specs/constraints/int/domain.rb +106 -0
  84. data/specs/constraints/int/linear.rb +183 -0
  85. data/specs/constraints/int/linear_properties.rb +97 -0
  86. data/specs/constraints/int/relation.rb +84 -0
  87. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  88. data/specs/constraints/int_enum/channel.rb +57 -0
  89. data/specs/constraints/int_enum/count.rb +72 -0
  90. data/specs/constraints/int_enum/distinct.rb +80 -0
  91. data/specs/constraints/int_enum/element.rb +61 -0
  92. data/specs/constraints/int_enum/equality.rb +29 -0
  93. data/specs/constraints/int_enum/extensional.rb +224 -0
  94. data/specs/constraints/int_enum/sort.rb +167 -0
  95. data/specs/constraints/operands.rb +264 -0
  96. data/specs/constraints/property_helper.rb +443 -0
  97. data/specs/constraints/reification_sugar.rb +4 -5
  98. data/specs/constraints/selected_set/select.rb +56 -0
  99. data/specs/constraints/selected_set/select_properties.rb +157 -0
  100. data/specs/constraints/set/cardinality.rb +58 -0
  101. data/specs/constraints/set/cardinality_properties.rb +46 -0
  102. data/specs/constraints/set/channel.rb +77 -0
  103. data/specs/constraints/set/connection.rb +176 -0
  104. data/specs/constraints/set/domain.rb +197 -0
  105. data/specs/constraints/set/include.rb +36 -0
  106. data/specs/constraints/set/operation.rb +132 -0
  107. data/specs/constraints/set/relation.rb +117 -0
  108. data/specs/constraints/set_elements/relation.rb +84 -0
  109. data/specs/constraints/set_enum/channel.rb +80 -0
  110. data/specs/constraints/set_enum/distinct.rb +59 -0
  111. data/specs/constraints/set_enum/operation.rb +111 -0
  112. data/specs/constraints/set_enum/select.rb +73 -0
  113. data/specs/enum_wrapper.rb +53 -3
  114. data/specs/int_var.rb +44 -25
  115. data/specs/model.rb +58 -1
  116. data/specs/model_sugar.rb +30 -0
  117. data/specs/search.rb +24 -5
  118. data/specs/selected_set.rb +39 -0
  119. data/specs/set_elements.rb +34 -0
  120. data/specs/set_var.rb +22 -8
  121. data/specs/spec_helper.rb +206 -6
  122. data/tasks/distribution.rake +22 -7
  123. data/tasks/svn.rake +3 -1
  124. metadata +218 -134
  125. data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
  126. data/specs/constraints/arithmetic.rb +0 -351
  127. data/specs/constraints/bool_enum_relation.rb +0 -160
  128. data/specs/constraints/cardinality.rb +0 -157
  129. data/specs/constraints/channel.rb +0 -454
  130. data/specs/constraints/connection.rb +0 -369
  131. data/specs/constraints/count.rb +0 -146
  132. data/specs/constraints/distinct.rb +0 -164
  133. data/specs/constraints/element.rb +0 -108
  134. data/specs/constraints/equality.rb +0 -31
  135. data/specs/constraints/int_domain.rb +0 -70
  136. data/specs/constraints/int_relation.rb +0 -82
  137. data/specs/constraints/linear.rb +0 -340
  138. data/specs/constraints/selection.rb +0 -292
  139. data/specs/constraints/set_domain.rb +0 -185
  140. data/specs/constraints/set_operation.rb +0 -285
  141. data/specs/constraints/set_relation.rb +0 -197
  142. data/specs/constraints/sort.rb +0 -179
@@ -0,0 +1,84 @@
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
2
+
3
+ Gecode::Util::RELATION_TYPES.each_pair do |relation, rel_value|
4
+ describe Gecode::Int::Relation, " (#{relation} with int op)" do
5
+ before do
6
+ @model = Gecode::Model.new
7
+
8
+ # For constraint spec.
9
+ @types = [:int, :int]
10
+ @invoke = lambda do |receiver, op, hash|
11
+ receiver.method(relation).call(op, hash)
12
+ @model.solve!
13
+ end
14
+ @expect = lambda do |var1, var2, opts, reif_var|
15
+ if reif_var.nil?
16
+ Gecode::Raw.should_receive(:rel).once.with(
17
+ an_instance_of(Gecode::Raw::Space),
18
+ var1, rel_value, var2, *opts)
19
+ else
20
+ Gecode::Raw.should_receive(:rel).once.with(
21
+ an_instance_of(Gecode::Raw::Space),
22
+ var1, rel_value, var2, reif_var, *opts)
23
+ end
24
+ end
25
+ end
26
+
27
+ it "should constrain the #{relation} with an int operand" do
28
+ ints = @model.int_var_array(2, -5..5)
29
+ @model.branch_on ints
30
+ int1, int2 = ints
31
+ int1.must.method(relation).call(int2)
32
+ @model.solve!
33
+ int1.value.should.method(relation).call(int2.value)
34
+ end
35
+
36
+ it "should constrain the negated #{relation} with an int operand" do
37
+ ints = @model.int_var_array(2, -5..5)
38
+ @model.branch_on ints
39
+ int1, int2 = ints
40
+ int1.must_not.method(relation).call(int2)
41
+ @model.solve!
42
+ int1.value.should_not.method(relation).call(int2.value)
43
+ end
44
+
45
+ it_should_behave_like 'reifiable constraint'
46
+ end
47
+ end
48
+
49
+ Gecode::Util::RELATION_TYPES.each_pair do |relation, rel_value|
50
+ describe Gecode::Int::Relation, " (#{relation} with fixnum)" do
51
+ before do
52
+ @model = Gecode::Model.new
53
+
54
+ # For constraint spec.
55
+ @types = [:int]
56
+ @invoke = lambda do |receiver, hash|
57
+ receiver.method(relation).call(17, hash)
58
+ @model.solve!
59
+ end
60
+ @expect = lambda do |var, opts, reif_var|
61
+ if reif_var.nil?
62
+ Gecode::Raw.should_receive(:rel).once.with(
63
+ an_instance_of(Gecode::Raw::Space),
64
+ var, rel_value, 17, *opts)
65
+ else
66
+ Gecode::Raw.should_receive(:rel).once.with(
67
+ an_instance_of(Gecode::Raw::Space),
68
+ var, rel_value, 17, reif_var, *opts)
69
+ end
70
+ end
71
+ end
72
+
73
+ it "should constrain the #{relation} with a fixnum" do
74
+ int = @model.int_var(-5..5)
75
+ @model.branch_on int
76
+ int.must.method(relation).call(3)
77
+ @model.solve!
78
+ int.value.should.method(relation).call(3)
79
+ end
80
+
81
+ it_should_behave_like 'reifiable constraint'
82
+ end
83
+ end
84
+
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/../property_helper'
2
+
3
+ class IntEnumArithmeticSampleProblem < Gecode::Model
4
+ attr :numbers
5
+ attr :var
6
+
7
+ def initialize
8
+ @numbers = int_var_array(4, 0..9)
9
+ @var = int_var(-9..9)
10
+ branch_on @numbers
11
+ branch_on @var
12
+ end
13
+ end
14
+
15
+ describe Gecode::IntEnum::Arithmetic, ' (max)' do
16
+ before do
17
+ @model = IntEnumArithmeticSampleProblem.new
18
+ @numbers = @model.numbers
19
+ @var = @model.var
20
+
21
+ @property_types = [:int_enum]
22
+ @select_property = lambda do |int_enum|
23
+ int_enum.max
24
+ end
25
+ @selected_property = @numbers.max
26
+ @constraint_class = Gecode::BlockConstraint
27
+ end
28
+
29
+ it 'should constrain the maximum value' do
30
+ @numbers.max.must > 5
31
+ @model.solve!.numbers.values.max.should > 5
32
+ end
33
+
34
+ it 'should translate into a max constraint' do
35
+ Gecode::Raw.should_receive(:max)
36
+ @numbers.max.must == 5
37
+ @model.solve!
38
+ end
39
+
40
+ it_should_behave_like(
41
+ 'property that produces int operand by short circuiting equality')
42
+ end
43
+
44
+ describe Gecode::IntEnum::Arithmetic, ' (min)' do
45
+ before do
46
+ @model = IntEnumArithmeticSampleProblem.new
47
+ @numbers = @model.numbers
48
+ @var = @model.var
49
+
50
+ @property_types = [:int_enum]
51
+ @select_property = lambda do |int_enum|
52
+ int_enum.min
53
+ end
54
+ @selected_property = @numbers.min
55
+ @constraint_class = Gecode::BlockConstraint
56
+ end
57
+
58
+ it 'should constrain the minimum value' do
59
+ @numbers.min.must > 5
60
+ @model.solve!.numbers.values.min.should > 5
61
+ end
62
+
63
+ it 'should translate into a min constraint' do
64
+ Gecode::Raw.should_receive(:min)
65
+ @numbers.min.must == 5
66
+ @model.solve!
67
+ end
68
+
69
+ it_should_behave_like(
70
+ 'property that produces int operand by short circuiting equality')
71
+ end
72
+
@@ -0,0 +1,57 @@
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
2
+
3
+ class ChannelSampleProblem < Gecode::Model
4
+ attr :elements
5
+ attr :positions
6
+ attr :sets
7
+
8
+ def initialize
9
+ @elements = int_var_array(4, 0..3)
10
+ @elements.must_be.distinct
11
+ @positions = int_var_array(4, 0..3)
12
+ @positions.must_be.distinct
13
+ @sets = set_var_array(4, [], 0..3)
14
+ branch_on @positions
15
+ end
16
+ end
17
+
18
+ describe Gecode::IntEnum::Channel, ' (two int enums)' do
19
+ before do
20
+ @model = ChannelSampleProblem.new
21
+ @positions = @model.positions
22
+ @elements = @model.elements
23
+
24
+ @types = [:int_enum, :int_enum]
25
+ @invoke = lambda do |receiver, int_enum, hash|
26
+ receiver.channel(int_enum, hash)
27
+ @model.solve!
28
+ end
29
+ @expect = lambda do |var1, var2, opts, reif_var|
30
+ Gecode::Raw.should_receive(:channel).once.with(
31
+ an_instance_of(Gecode::Raw::Space),
32
+ var1, var2, *opts)
33
+ end
34
+ end
35
+
36
+ it 'should translate into a channel constraint' do
37
+ Gecode::Raw.should_receive(:channel).once.with(
38
+ an_instance_of(Gecode::Raw::Space),
39
+ anything, anything, Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF)
40
+ @positions.must.channel @elements
41
+ @model.solve!
42
+ end
43
+
44
+ it 'should constrain variables to be channelled' do
45
+ @elements.must.channel @positions
46
+ @model.solve!
47
+ elements = @model.elements.values
48
+ positions = @model.elements.values
49
+ elements.each_with_index do |element, i|
50
+ element.should equal(positions.index(i))
51
+ end
52
+ end
53
+
54
+ it_should_behave_like 'non-reifiable constraint'
55
+ it_should_behave_like 'non-negatable constraint'
56
+ end
57
+
@@ -0,0 +1,72 @@
1
+ require File.dirname(__FILE__) + '/../property_helper'
2
+
3
+ class CountSampleProblem < Gecode::Model
4
+ attr :list
5
+ attr :element
6
+ attr :target
7
+
8
+ def initialize
9
+ @list = int_var_array(4, 0..3)
10
+ @element = int_var(0..3)
11
+ @target = int_var(0..4)
12
+ branch_on @list
13
+ branch_on @element
14
+ end
15
+ end
16
+
17
+ describe Gecode::IntEnum::Count, ' (with int var)' do
18
+ before do
19
+ @model = CountSampleProblem.new
20
+ @list = @model.list
21
+ @element = @model.element
22
+ @target = @model.target
23
+
24
+ # For int operand producing property spec.
25
+ @property_types = [:int_enum, :int]
26
+ @select_property = lambda do |int_enum, int|
27
+ int_enum.count(int)
28
+ end
29
+ @selected_property = @list.count(@element)
30
+ @constraint_class =
31
+ Gecode::IntEnum::Count::CountConstraint
32
+ end
33
+
34
+ it 'should constrain the count' do
35
+ @list.count(@element).must == 2
36
+ @model.solve!
37
+ @list.values.map{ |x| x == @element.value }.inject(0) do |sum, b|
38
+ sum += b ? 1 : 0
39
+ end.should == 2
40
+ end
41
+
42
+ it_should_behave_like(
43
+ 'property that produces int operand by short circuiting relations')
44
+ end
45
+
46
+ describe Gecode::IntEnum::Count, ' (with fixnum)' do
47
+ before do
48
+ @model = CountSampleProblem.new
49
+ @list = @model.list
50
+ @target = @model.target
51
+
52
+ # For int operand producing property spec.
53
+ @property_types = [:int_enum]
54
+ @select_property = lambda do |int_enum|
55
+ int_enum.count(1)
56
+ end
57
+ @selected_property = @list.count(1)
58
+ @constraint_class =
59
+ Gecode::IntEnum::Count::CountConstraint
60
+ end
61
+
62
+ it 'should constrain the count' do
63
+ @list.count(1).must == 2
64
+ @model.solve!
65
+ @list.values.map{ |x| x == 1 }.inject(0) do |sum, b|
66
+ sum += b ? 1 : 0
67
+ end.should == 2
68
+ end
69
+
70
+ it_should_behave_like(
71
+ 'property that produces int operand by short circuiting relations')
72
+ end
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
2
+
3
+ class DistinctSampleProblem < Gecode::Model
4
+ def initialize
5
+ vars_is_an int_var_array(2, 0..1)
6
+ branch_on vars
7
+ end
8
+ end
9
+
10
+ describe Gecode::IntEnum::Distinct do
11
+ before do
12
+ @model = DistinctSampleProblem.new
13
+
14
+ @types = [:int_enum]
15
+ @invoke = lambda do |receiver, hash|
16
+ receiver.distinct(hash)
17
+ @model.solve!
18
+ end
19
+ @expect = lambda do |var, opts, reif_var|
20
+ Gecode::Raw.should_receive(:distinct).once.with(
21
+ an_instance_of(Gecode::Raw::Space),
22
+ var, *opts)
23
+ end
24
+ end
25
+
26
+ it 'should constrain variables to be distinct' do
27
+ @model.vars.must_be.distinct
28
+ @model.solve!
29
+ @model.vars[0].value.should_not == @model.vars[1].value
30
+ end
31
+
32
+ it_should_behave_like 'non-reifiable constraint'
33
+ it_should_behave_like 'non-negatable constraint'
34
+ end
35
+
36
+ describe Gecode::IntEnum::Distinct, ' (with offsets)' do
37
+ before do
38
+ @model = DistinctSampleProblem.new
39
+
40
+ @types = [:int_enum]
41
+ @invoke = lambda do |receiver, hash|
42
+ receiver.distinct hash.update(:offsets => [1,2])
43
+ @model.solve!
44
+ end
45
+ @expect = lambda do |var, opts, reif_var|
46
+ if reif_var.nil?
47
+ Gecode::Raw.should_receive(:distinct).once.with(
48
+ an_instance_of(Gecode::Raw::Space),
49
+ [1,2], var, *opts)
50
+ else
51
+ Gecode::Raw.should_receive(:distinct).once.with(
52
+ an_instance_of(Gecode::Raw::Space),
53
+ [1,2], var, reif_var, *opts)
54
+ end
55
+ end
56
+ end
57
+
58
+ it 'should constrain variables to be distinct' do
59
+ @model.vars.must_be.distinct(:offsets => [-1, 0])
60
+ x, y = @model.solve!.vars
61
+ (x.value - 1).should_not == y.value
62
+ end
63
+
64
+ # This tests two distinct in conjunction. It's here because of a bug found.
65
+ it 'should play nice with normal distinct' do
66
+ @model.vars.must_be.distinct(:offsets => [-1, 0])
67
+ @model.vars.must_be.distinct(:offsets => [0, -1])
68
+ @model.vars.must_be.distinct
69
+ lambda{ @model.solve! }.should raise_error(Gecode::NoSolutionError)
70
+ end
71
+
72
+ it 'should raise error if the offsets are of an incorrect type' do
73
+ lambda do
74
+ @model.vars.must_be.distinct(:offsets => :foo)
75
+ end.should raise_error(TypeError)
76
+ end
77
+
78
+ it_should_behave_like 'non-reifiable constraint'
79
+ it_should_behave_like 'non-negatable constraint'
80
+ end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + '/../property_helper'
2
+
3
+ class ElementSampleProblem < Gecode::Model
4
+ attr :prices
5
+ attr :store
6
+ attr :price
7
+ attr :fixnum_prices
8
+
9
+ def initialize
10
+ prices = [17, 63, 45, 63]
11
+ @fixnum_prices = wrap_enum(prices)
12
+ @prices = int_var_array(4, prices)
13
+ @store = int_var(0...prices.size)
14
+ @price = int_var(prices)
15
+ branch_on @store
16
+ end
17
+ end
18
+
19
+ describe Gecode::IntEnum::Element do
20
+ before do
21
+ @model = ElementSampleProblem.new
22
+ @prices = @model.prices
23
+ @target = @price = @model.price
24
+ @store = @model.store
25
+
26
+ # For int operand producing property spec.
27
+ @property_types = [:int_enum, :int]
28
+ @select_property = lambda do |int_enum, int|
29
+ int_enum[int]
30
+ end
31
+ @selected_property = @prices[@store]
32
+ @constraint_class = Gecode::BlockConstraint
33
+ end
34
+
35
+ it 'should not disturb normal array access' do
36
+ @prices[2].should_not be_nil
37
+ end
38
+
39
+ it 'should constrain the selected element' do
40
+ @prices[@store].must == 63
41
+ @prices.values_at(0,2,3).each{ |x| x.must < 50 }
42
+ @model.solve!.should_not be_nil
43
+ @store.value.should equal(1)
44
+ end
45
+
46
+ it 'should be translated into an element constraint' do
47
+ @prices[@store].must == @price
48
+ @model.allow_space_access do
49
+ Gecode::Raw.should_receive(:element).once.with(
50
+ an_instance_of(Gecode::Raw::Space),
51
+ an_instance_of(Gecode::Raw::IntVarArray),
52
+ @store.bind, @price.bind,
53
+ Gecode::Raw::ICL_DEF,
54
+ Gecode::Raw::PK_DEF)
55
+ end
56
+ @model.solve!
57
+ end
58
+
59
+ it_should_behave_like(
60
+ 'property that produces int operand by short circuiting equality')
61
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../constraint_helper'
2
+
3
+ describe Gecode::IntEnum::Equality do
4
+ before do
5
+ @model = Gecode::Model.new
6
+ @vars = @model.int_var_array(4, -2..2)
7
+
8
+ @types = [:int_enum]
9
+ @invoke = lambda do |receiver, hash|
10
+ receiver.equal(hash)
11
+ @model.solve!
12
+ end
13
+ @expect = lambda do |var, opts, reif_var|
14
+ Gecode::Raw.should_receive(:rel).once.with(
15
+ an_instance_of(Gecode::Raw::Space),
16
+ var, Gecode::Raw::IRT_EQ, *opts)
17
+ end
18
+ end
19
+
20
+ it 'should constrain elements to be equal' do
21
+ @vars[1].must == 1
22
+ @vars.must_be.equal
23
+ @model.solve!
24
+ @vars.values.each{ |x| x.should == 1 }
25
+ end
26
+
27
+ it_should_behave_like 'non-reifiable constraint'
28
+ it_should_behave_like 'non-negatable constraint'
29
+ end