gecoder-with-gecode 0.7.1-mswin32

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 (159) hide show
  1. data/CHANGES +81 -0
  2. data/COPYING +17 -0
  3. data/LGPL-LICENSE +458 -0
  4. data/README +45 -0
  5. data/Rakefile +13 -0
  6. data/example/example_helper.rb +1 -0
  7. data/example/magic_sequence.rb +43 -0
  8. data/example/queens.rb +43 -0
  9. data/example/raw_bindings.rb +42 -0
  10. data/example/send_more_money.rb +43 -0
  11. data/example/send_most_money.rb +58 -0
  12. data/example/square_tiling.rb +84 -0
  13. data/example/sudoku-set.rb +110 -0
  14. data/example/sudoku.rb +61 -0
  15. data/lib/gecode.dll +0 -0
  16. data/lib/gecoder.rb +5 -0
  17. data/lib/gecoder/bindings.rb +54 -0
  18. data/lib/gecoder/bindings/bindings.rb +2210 -0
  19. data/lib/gecoder/interface.rb +8 -0
  20. data/lib/gecoder/interface/binding_changes.rb +313 -0
  21. data/lib/gecoder/interface/branch.rb +152 -0
  22. data/lib/gecoder/interface/constraints.rb +397 -0
  23. data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
  24. data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
  25. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
  26. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
  27. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
  28. data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
  29. data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
  30. data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
  31. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
  32. data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
  33. data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
  34. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
  35. data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
  36. data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
  37. data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
  38. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
  39. data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
  40. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
  41. data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
  42. data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
  43. data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
  44. data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
  45. data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
  46. data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
  47. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
  48. data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
  49. data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
  50. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
  51. data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
  52. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  53. data/lib/gecoder/interface/enum_wrapper.rb +153 -0
  54. data/lib/gecoder/interface/model.rb +251 -0
  55. data/lib/gecoder/interface/search.rb +123 -0
  56. data/lib/gecoder/interface/variables.rb +254 -0
  57. data/lib/gecoder/version.rb +4 -0
  58. data/specs/binding_changes.rb +76 -0
  59. data/specs/bool_var.rb +74 -0
  60. data/specs/branch.rb +170 -0
  61. data/specs/constraints/arithmetic.rb +266 -0
  62. data/specs/constraints/bool_enum.rb +140 -0
  63. data/specs/constraints/boolean.rb +232 -0
  64. data/specs/constraints/cardinality.rb +154 -0
  65. data/specs/constraints/channel.rb +126 -0
  66. data/specs/constraints/connection.rb +373 -0
  67. data/specs/constraints/constraint_helper.rb +180 -0
  68. data/specs/constraints/constraints.rb +74 -0
  69. data/specs/constraints/count.rb +139 -0
  70. data/specs/constraints/distinct.rb +218 -0
  71. data/specs/constraints/element.rb +106 -0
  72. data/specs/constraints/equality.rb +31 -0
  73. data/specs/constraints/int_domain.rb +69 -0
  74. data/specs/constraints/int_relation.rb +78 -0
  75. data/specs/constraints/linear.rb +332 -0
  76. data/specs/constraints/reification_sugar.rb +96 -0
  77. data/specs/constraints/selection.rb +292 -0
  78. data/specs/constraints/set_domain.rb +181 -0
  79. data/specs/constraints/set_operation.rb +285 -0
  80. data/specs/constraints/set_relation.rb +201 -0
  81. data/specs/constraints/sort.rb +175 -0
  82. data/specs/distribution.rb +14 -0
  83. data/specs/enum_matrix.rb +43 -0
  84. data/specs/enum_wrapper.rb +122 -0
  85. data/specs/int_var.rb +144 -0
  86. data/specs/logging.rb +24 -0
  87. data/specs/model.rb +190 -0
  88. data/specs/search.rb +246 -0
  89. data/specs/set_var.rb +68 -0
  90. data/specs/spec_helper.rb +93 -0
  91. data/tasks/all_tasks.rb +1 -0
  92. data/tasks/building.howto +65 -0
  93. data/tasks/distribution.rake +156 -0
  94. data/tasks/rcov.rake +17 -0
  95. data/tasks/specs.rake +15 -0
  96. data/tasks/svn.rake +11 -0
  97. data/tasks/website.rake +51 -0
  98. data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
  99. data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
  100. data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
  101. data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
  102. data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
  103. data/vendor/rust/README +28 -0
  104. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  105. data/vendor/rust/include/rust_checks.hh +115 -0
  106. data/vendor/rust/include/rust_conversions.hh +102 -0
  107. data/vendor/rust/rust.rb +67 -0
  108. data/vendor/rust/rust/attribute.rb +51 -0
  109. data/vendor/rust/rust/bindings.rb +172 -0
  110. data/vendor/rust/rust/class.rb +339 -0
  111. data/vendor/rust/rust/constants.rb +48 -0
  112. data/vendor/rust/rust/container.rb +110 -0
  113. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  114. data/vendor/rust/rust/cwrapper.rb +72 -0
  115. data/vendor/rust/rust/cxxclass.rb +98 -0
  116. data/vendor/rust/rust/element.rb +81 -0
  117. data/vendor/rust/rust/enum.rb +63 -0
  118. data/vendor/rust/rust/function.rb +407 -0
  119. data/vendor/rust/rust/namespace.rb +61 -0
  120. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  121. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  122. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  123. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  124. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  125. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  126. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  127. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  128. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
  129. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  130. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
  131. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  132. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  133. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  134. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  135. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  136. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  137. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  138. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  139. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
  140. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  141. data/vendor/rust/rust/type.rb +98 -0
  142. data/vendor/rust/test/Makefile +4 -0
  143. data/vendor/rust/test/constants.rb +36 -0
  144. data/vendor/rust/test/cppclass.cc +45 -0
  145. data/vendor/rust/test/cppclass.hh +67 -0
  146. data/vendor/rust/test/cppclass.rb +59 -0
  147. data/vendor/rust/test/cwrapper.c +74 -0
  148. data/vendor/rust/test/cwrapper.h +41 -0
  149. data/vendor/rust/test/cwrapper.rb +56 -0
  150. data/vendor/rust/test/dummyclass.hh +31 -0
  151. data/vendor/rust/test/lib/extension-test.rb +98 -0
  152. data/vendor/rust/test/operators.cc +41 -0
  153. data/vendor/rust/test/operators.hh +39 -0
  154. data/vendor/rust/test/operators.rb +39 -0
  155. data/vendor/rust/test/test-constants.rb +43 -0
  156. data/vendor/rust/test/test-cppclass.rb +82 -0
  157. data/vendor/rust/test/test-cwrapper.rb +80 -0
  158. data/vendor/rust/test/test-operators.rb +42 -0
  159. metadata +293 -0
@@ -0,0 +1,106 @@
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
+ @target = @price = @model.price
25
+ @store = @model.store
26
+ @fixnum_prices = @model.fixnum_prices
27
+
28
+ # Creates an expectation corresponding to the specified input.
29
+ @expect = lambda do |element, relation, target, strength, reif_var, negated|
30
+ @model.allow_space_access do
31
+ target = an_instance_of(Gecode::Raw::IntVar) if target.respond_to? :bind
32
+ element = an_instance_of(Gecode::Raw::IntVar) if element.respond_to? :bind
33
+ if reif_var.nil?
34
+ if !negated and relation == Gecode::Raw::IRT_EQ and
35
+ !target.kind_of? Fixnum
36
+ Gecode::Raw.should_receive(:element).once.with(
37
+ an_instance_of(Gecode::Raw::Space),
38
+ an_instance_of(Gecode::Raw::IntVarArray),
39
+ element, target, strength)
40
+ else
41
+ Gecode::Raw.should_receive(:element).once.with(
42
+ an_instance_of(Gecode::Raw::Space),
43
+ an_instance_of(Gecode::Raw::IntVarArray),
44
+ element, an_instance_of(Gecode::Raw::IntVar), strength)
45
+ Gecode::Raw.should_receive(:rel).once.with(
46
+ an_instance_of(Gecode::Raw::Space),
47
+ an_instance_of(Gecode::Raw::IntVar), relation, target, strength)
48
+ end
49
+ else
50
+ Gecode::Raw.should_receive(:element).once.with(
51
+ an_instance_of(Gecode::Raw::Space),
52
+ an_instance_of(Gecode::Raw::IntVarArray),
53
+ element, an_instance_of(Gecode::Raw::IntVar), strength)
54
+ Gecode::Raw.should_receive(:rel).once.with(
55
+ an_instance_of(Gecode::Raw::Space),
56
+ an_instance_of(Gecode::Raw::IntVar), relation, target,
57
+ an_instance_of(Gecode::Raw::BoolVar), strength)
58
+ end
59
+ end
60
+ end
61
+
62
+ # For constraint option spec.
63
+ @invoke_options = lambda do |hash|
64
+ @prices[@store].must_be.greater_than(@price, hash)
65
+ @model.solve!
66
+ end
67
+ @expect_options = lambda do |strength, reif_var|
68
+ @expect.call(@store, Gecode::Raw::IRT_GR, @price, strength, reif_var,
69
+ false)
70
+ end
71
+
72
+ # For composite spec.
73
+ @invoke_relation = lambda do |relation, target, negated|
74
+ if negated
75
+ @prices[@store].must_not.send(relation, target)
76
+ else
77
+ @prices[@store].must.send(relation, target)
78
+ end
79
+ @model.solve!
80
+ end
81
+ @expect_relation = lambda do |relation, target, negated|
82
+ @expect.call(@store, relation, target, Gecode::Raw::ICL_DEF, nil, negated)
83
+ end
84
+ end
85
+
86
+ it 'should not disturb normal array access' do
87
+ @fixnum_prices[2].should_not be_nil
88
+ @prices[2].should_not be_nil
89
+ end
90
+
91
+ it 'should handle fixnum enums as enumeration' do
92
+ @fixnum_prices[@store].must == @fixnum_prices[2]
93
+ @model.solve!.store.value.should equal(2)
94
+ end
95
+
96
+ it 'should translate reification when using equality' do
97
+ bool_var = @model.bool_var
98
+ @expect.call(@store, Gecode::Raw::IRT_EQ, @target, Gecode::Raw::ICL_DEF,
99
+ bool_var, false)
100
+ @prices[@store].must_be.equal_to(@target, :reify => bool_var)
101
+ @model.solve!
102
+ end
103
+
104
+ it_should_behave_like 'composite constraint'
105
+ it_should_behave_like 'constraint with options'
106
+ end
@@ -0,0 +1,31 @@
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(
14
+ an_instance_of(Gecode::Raw::Space),
15
+ anything, strength)
16
+ end
17
+ end
18
+
19
+ it 'should translate equality constraints' do
20
+ @expect_options.call(Gecode::Raw::ICL_DEF, nil)
21
+ @invoke_options.call({})
22
+ @vars.must_be.equal
23
+ end
24
+
25
+ it 'should not allow negation' do
26
+ lambda{ @vars.must_not_be.equal }.should raise_error(
27
+ Gecode::MissingConstraintError)
28
+ end
29
+
30
+ it_should_behave_like 'constraint with strength option'
31
+ end
@@ -0,0 +1,69 @@
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
+ @model.allow_space_access do
19
+ if reif_var.nil?
20
+ Gecode::Raw.should_receive(:dom).once.with(
21
+ an_instance_of(Gecode::Raw::Space),
22
+ an_instance_of(Gecode::Raw::IntVar),
23
+ an_instance_of(Gecode::Raw::IntSet), strength)
24
+ else
25
+ Gecode::Raw.should_receive(:dom).once.with(
26
+ an_instance_of(Gecode::Raw::Space),
27
+ an_instance_of(Gecode::Raw::IntVar),
28
+ an_instance_of(Gecode::Raw::IntSet),
29
+ an_instance_of(Gecode::Raw::BoolVar), strength)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ it 'should translate domain constraints with range domains' do
36
+ Gecode::Raw.should_receive(:dom).once.with(
37
+ an_instance_of(Gecode::Raw::Space),
38
+ an_instance_of(Gecode::Raw::IntVar), @range_domain.first,
39
+ @range_domain.last, Gecode::Raw::ICL_DEF)
40
+ @x.must_be.in @range_domain
41
+ @model.solve!
42
+ end
43
+
44
+ it 'should translate domain constraints with three dot range domains' do
45
+ Gecode::Raw.should_receive(:dom).once.with(
46
+ an_instance_of(Gecode::Raw::Space),
47
+ an_instance_of(Gecode::Raw::IntVar), @three_dot_range_domain.first,
48
+ @three_dot_range_domain.last, Gecode::Raw::ICL_DEF)
49
+ @x.must_be.in @three_dot_range_domain
50
+ @model.solve!
51
+ end
52
+
53
+ it 'should translate domain constraints with non-range domains' do
54
+ @expect_options.call(Gecode::Raw::ICL_DEF, nil)
55
+ @invoke_options.call({})
56
+ end
57
+
58
+ it 'should handle negation' do
59
+ @x.must_not_be.in @range_domain
60
+ @model.solve!
61
+ @x.should have_domain(@domain.to_a - @range_domain.to_a)
62
+ end
63
+
64
+ it 'should raise error if the right hand side is not an enumeration' do
65
+ lambda{ @x.must_be.in 'hello' }.should raise_error(TypeError)
66
+ end
67
+
68
+ it_should_behave_like 'constraint with options'
69
+ end
@@ -0,0 +1,78 @@
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(
19
+ an_instance_of(Gecode::Raw::Space),
20
+ anything, Gecode::Raw::IRT_GR, anything,
21
+ strength)
22
+ else
23
+ Gecode::Raw.should_receive(:rel).once.with(
24
+ an_instance_of(Gecode::Raw::Space),
25
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::IRT_GR, anything,
26
+ an_instance_of(Gecode::Raw::BoolVar), strength)
27
+ end
28
+ end
29
+ end
30
+
31
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
32
+ it "should translate #{relation} with constant to simple relation" do
33
+ Gecode::Raw.should_receive(:rel).once.with(
34
+ an_instance_of(Gecode::Raw::Space),
35
+ an_instance_of(Gecode::Raw::IntVar), type, @int, Gecode::Raw::ICL_DEF)
36
+ @x.must.send(relation, @int)
37
+ @model.solve!
38
+ end
39
+ end
40
+
41
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
42
+ it "should translate negated #{relation} with constant to simple relation" do
43
+ Gecode::Raw.should_receive(:rel).once.with(
44
+ an_instance_of(Gecode::Raw::Space),
45
+ an_instance_of(Gecode::Raw::IntVar), type, @int, Gecode::Raw::ICL_DEF)
46
+ @x.must_not.send(relation, @int)
47
+ @model.solve!
48
+ end
49
+ end
50
+
51
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |relation, type|
52
+ it "should translate #{relation} with variables to simple relation" do
53
+ Gecode::Raw.should_receive(:rel).once.with(
54
+ an_instance_of(Gecode::Raw::Space),
55
+ an_instance_of(Gecode::Raw::IntVar), type,
56
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
57
+ @x.must.send(relation, @y)
58
+ @model.solve!
59
+ end
60
+ end
61
+
62
+ Gecode::Constraints::Util::NEGATED_RELATION_TYPES.each_pair do |relation, type|
63
+ it "should translate negated #{relation} with variable to simple relation" do
64
+ Gecode::Raw.should_receive(:rel).once.with(
65
+ an_instance_of(Gecode::Raw::Space),
66
+ an_instance_of(Gecode::Raw::IntVar), type,
67
+ an_instance_of(Gecode::Raw::IntVar), Gecode::Raw::ICL_DEF)
68
+ @x.must_not.send(relation, @y)
69
+ @model.solve!
70
+ end
71
+ end
72
+
73
+ it 'should raise error on arguments of the wrong type' do
74
+ lambda{ @x.must == 'hello' }.should raise_error(TypeError)
75
+ end
76
+
77
+ it_should_behave_like 'constraint with options'
78
+ end
@@ -0,0 +1,332 @@
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
+ class BoolLinearSampleProblem < Gecode::Model
18
+ attr :x
19
+ attr :y
20
+ attr :z
21
+
22
+ def initialize
23
+ @x = self.bool_var
24
+ @y = self.bool_var
25
+ @z = self.bool_var
26
+ branch_on wrap_enum([@x, @y, @z])
27
+ end
28
+ end
29
+
30
+ class TrueClass
31
+ def to_i
32
+ 1
33
+ end
34
+ end
35
+
36
+ class FalseClass
37
+ def to_i
38
+ 0
39
+ end
40
+ end
41
+
42
+ describe Gecode::Constraints::Int::Linear do
43
+ before do
44
+ @x_dom = 0..2
45
+ @y_dom = -3..3
46
+ @z_dom = 0..10
47
+ @model = LinearSampleProblem.new(@x_dom, @y_dom, @z_dom)
48
+ @x = @model.x
49
+ @y = @model.y
50
+ @z = @model.z
51
+
52
+ # For constraint option spec.
53
+ @invoke_options = lambda do |hash|
54
+ (@x + @y).must_be.greater_than(@z, hash)
55
+ @model.solve!
56
+ end
57
+ @expect_options = lambda do |strength, reif_var|
58
+ # TODO: this is hard to spec from this level.
59
+ end
60
+ end
61
+
62
+ it 'should handle addition with a variable' do
63
+ (@x + @y).must == 0
64
+ sol = @model.solve!
65
+ x = sol.x.value
66
+ y = sol.y.value
67
+ (x + y).should be_zero
68
+ end
69
+
70
+ it 'should handle addition with multiple variables' do
71
+ (@x + @y + @z).must == 0
72
+ sol = @model.solve!
73
+ x = sol.x.value
74
+ y = sol.y.value
75
+ z = sol.z.value
76
+ (x + y + z).should be_zero
77
+ end
78
+
79
+ it 'should handle subtraction with a variable' do
80
+ (@x - @y).must == 0
81
+ sol = @model.solve!
82
+ x = sol.x.value
83
+ y = sol.y.value
84
+ (x - y).should be_zero
85
+ end
86
+
87
+ it 'should handle non-zero constants as right hand side' do
88
+ (@x + @y).must == 1
89
+ sol = @model.solve!
90
+ x = sol.x.value
91
+ y = sol.y.value
92
+ (x + y).should equal(1)
93
+ end
94
+
95
+ it 'should handle variables as right hand side' do
96
+ (@x + @y).must == @z
97
+ sol = @model.solve!
98
+ x = sol.x.value
99
+ y = sol.y.value
100
+ z = sol.z.value
101
+ (x + y).should equal(z)
102
+ end
103
+
104
+ it 'should handle linear expressions as right hand side' do
105
+ (@x + @y).must == @z + @y
106
+ sol = @model.solve!
107
+ x = sol.x.value
108
+ y = sol.y.value
109
+ z = sol.z.value
110
+ (x + y).should equal(z + y)
111
+ end
112
+
113
+ it 'should raise error on invalid right hand sides' do
114
+ lambda{ ((@x + @y).must == 'z') }.should raise_error(TypeError)
115
+ end
116
+
117
+ it 'should handle coefficients other than 1' do
118
+ (@x * 2 + @y).must == 0
119
+ sol = @model.solve!
120
+ x = sol.x.value
121
+ y = sol.y.value
122
+ (2*x + y).should equal(0)
123
+ end
124
+
125
+ it 'should handle addition with constants' do
126
+ (@y + 2).must == 1
127
+ sol = @model.solve!
128
+ y = sol.y.value
129
+ (y + 2).should equal(1)
130
+ end
131
+
132
+ it 'should handle subtraction with a constant' do
133
+ (@x - 2).must == 0
134
+ sol = @model.solve!
135
+ x = sol.x.value
136
+ (x - 2).should be_zero
137
+ end
138
+
139
+ it 'should a single variable as left hande side' do
140
+ @x.must == @y + @z
141
+ sol = @model.solve!
142
+ x = sol.x.value
143
+ y = sol.y.value
144
+ z = sol.z.value
145
+ x.should equal(y + z)
146
+ end
147
+
148
+ it 'should handle parenthesis' do
149
+ (@x - (@y + @z)).must == 1
150
+ sol = @model.solve!
151
+ x = sol.x.value
152
+ y = sol.y.value
153
+ z = sol.z.value
154
+ (x - (y + z)).should equal(1)
155
+ end
156
+
157
+ it 'should handle multiplication of parenthesis' do
158
+ (((@x + @y*10)*10 + @z)*10).must == 0
159
+ sol = @model.solve!
160
+ x = sol.x.value
161
+ y = sol.y.value
162
+ z = sol.z.value
163
+ (((x + y*10)*10 + z)*10).should equal(0)
164
+ end
165
+
166
+ relations = ['>', '>=', '<', '<=', '==']
167
+
168
+ relations.each do |relation|
169
+ it "should handle #{relation} with constant integers" do
170
+ (@x + @y).must.send(relation, 1)
171
+ sol = @model.solve!
172
+ sol.should_not be_nil
173
+ (sol.x.value + sol.y.value).should.send(relation, 1)
174
+ end
175
+ end
176
+
177
+ relations.each do |relation|
178
+ it "should handle negated #{relation} with constant integers" do
179
+ (@x + @y).must_not.send(relation, 1)
180
+ sol = @model.solve!
181
+ sol.should_not be_nil
182
+ (sol.x.value + sol.y.value).should_not.send(relation, 1)
183
+ end
184
+ end
185
+
186
+ it 'should not interfere with other defined multiplication methods' do
187
+ (@x * :foo).should be_nil
188
+ end
189
+
190
+ it_should_behave_like 'constraint with options'
191
+ end
192
+
193
+ describe Gecode::Constraints::Int::Linear, '(with booleans)' do
194
+ before do
195
+ @model = BoolLinearSampleProblem.new
196
+ @x = @model.x
197
+ @y = @model.y
198
+ @z = @model.z
199
+
200
+ # For constraint option spec.
201
+ @invoke_options = lambda do |hash|
202
+ (@x + @y).must_be.greater_than(@z, hash)
203
+ @model.solve!
204
+ end
205
+ @expect_options = lambda do |strength, reif_var|
206
+ # TODO: this is hard to spec from this level.
207
+ end
208
+ end
209
+
210
+ it 'should handle addition with a variable' do
211
+ (@x + @y).must == 0
212
+ sol = @model.solve!
213
+ x = sol.x.value.to_i
214
+ y = sol.y.value.to_i
215
+ (x + y).should be_zero
216
+ end
217
+
218
+ it 'should handle addition with multiple variables' do
219
+ (@x + @y + @z).must == 0
220
+ sol = @model.solve!
221
+ x = sol.x.value.to_i
222
+ y = sol.y.value.to_i
223
+ z = sol.z.value.to_i
224
+ (x + y + z).should be_zero
225
+ end
226
+
227
+ it 'should handle subtraction with a variable' do
228
+ (@x - @y).must == 0
229
+ sol = @model.solve!
230
+ x = sol.x.value.to_i
231
+ y = sol.y.value.to_i
232
+ (x - y).should be_zero
233
+ end
234
+
235
+ it 'should handle non-zero constants as right hand side' do
236
+ (@x + @y).must == 1
237
+ sol = @model.solve!
238
+ x = sol.x.value.to_i
239
+ y = sol.y.value.to_i
240
+ (x + y).should equal(1)
241
+ end
242
+
243
+ it 'should handle variables as right hand side' do
244
+ (@x + @y).must == @z
245
+ sol = @model.solve!
246
+ x = sol.x.value.to_i
247
+ y = sol.y.value.to_i
248
+ z = sol.z.value.to_i
249
+ (x + y).should equal(z)
250
+ end
251
+
252
+ it 'should handle linear expressions as right hand side' do
253
+ (@x + @y).must == @z + @y
254
+ sol = @model.solve!
255
+ x = sol.x.value.to_i
256
+ y = sol.y.value.to_i
257
+ z = sol.z.value.to_i
258
+ (x + y).should equal(z + y)
259
+ end
260
+
261
+ it 'should raise error on invalid right hand sides' do
262
+ lambda{ ((@x + @y).must == 'z') }.should raise_error(TypeError)
263
+ end
264
+
265
+ it 'should handle coefficients other than 1' do
266
+ (@x * 2 + @y).must == 0
267
+ sol = @model.solve!
268
+ x = sol.x.value.to_i
269
+ y = sol.y.value.to_i
270
+ (2*x + y).should equal(0)
271
+ end
272
+
273
+ it 'should handle addition with constants' do
274
+ (@y + 1).must == 1
275
+ sol = @model.solve!
276
+ y = sol.y.value.to_i
277
+ (y + 1).should equal(1)
278
+ end
279
+
280
+ it 'should handle subtraction with a constant' do
281
+ (@x - 1).must == 0
282
+ sol = @model.solve!
283
+ x = sol.x.value.to_i
284
+ (x - 1).should be_zero
285
+ end
286
+
287
+ it 'should handle parenthesis' do
288
+ (@x - (@y + @z)).must == 1
289
+ sol = @model.solve!
290
+ x = sol.x.value.to_i
291
+ y = sol.y.value.to_i
292
+ z = sol.z.value.to_i
293
+ (x - (y + z)).should equal(1)
294
+ end
295
+
296
+ it 'should handle multiplication of parenthesis' do
297
+ (((@x + @y*10)*10 + @z)*10).must == 0
298
+ sol = @model.solve!
299
+ x = sol.x.value.to_i
300
+ y = sol.y.value.to_i
301
+ z = sol.z.value.to_i
302
+ (((x + y*10)*10 + z)*10).should equal(0)
303
+ end
304
+
305
+ relations = ['>', '>=', '<', '<=', '==']
306
+
307
+ relations.each do |relation|
308
+ it "should handle #{relation} with constant integers" do
309
+ (@x + @y).must.send(relation, 1)
310
+ sol = @model.solve!
311
+ sol.should_not be_nil
312
+ (sol.x.value.to_i + sol.y.value.to_i).should.send(relation, 1)
313
+ end
314
+ end
315
+
316
+ relations.each do |relation|
317
+ it "should handle negated #{relation} with constant integers" do
318
+ (@x + @y).must_not.send(relation, 1)
319
+ sol = @model.solve!
320
+ sol.should_not be_nil
321
+ (sol.x.value.to_i + sol.y.value.to_i).should_not.send(relation, 1)
322
+ end
323
+ end
324
+
325
+ it 'should not interfere with other defined multiplication methods' do
326
+ (@x * :foo).should be_nil
327
+ end
328
+
329
+ it_should_behave_like 'constraint with options'
330
+ end
331
+
332
+