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,72 @@
1
+ module Gecode::IntEnumMethods
2
+ # Starts an arithmetic max constraint. This overrides the normal enum max, but
3
+ # that's not a problem since variables are not implemented to be comparable.
4
+ def max
5
+ return Gecode::Constraints::IntEnum::Arithmetic::MaxExpressionStub.new(
6
+ @model, :lhs => self)
7
+ end
8
+
9
+ # Starts an arithmetic min constraint. This overrides the normal enum min, but
10
+ # that's not a problem since variables are not implemented to be comparable.
11
+ def min
12
+ return Gecode::Constraints::IntEnum::Arithmetic::MinExpressionStub.new(
13
+ @model, :lhs => self)
14
+ end
15
+ end
16
+
17
+ # A module that gathers the classes and modules used by arithmetic constraints.
18
+ module Gecode::Constraints::IntEnum::Arithmetic #:nodoc:
19
+ # Describes a CompositeStub for the max constraint, which constrains the
20
+ # maximum value of the integer variables in an enumeration.
21
+ #
22
+ # == Example
23
+ #
24
+ # # The maximum must be positive.
25
+ # int_enum.max.must > 0
26
+ #
27
+ # # The maximum must equal a integer variable +max+.
28
+ # int_enum.max.must == max
29
+ #
30
+ # # The maximum must not be negative. The constraint is reified with the
31
+ # # boolean variable +is_negative+ and strength +domain+ is selected.
32
+ # int_enum.max.must_not_be.less_than(0, :reify => is_negative,
33
+ # :strength => :domain)
34
+ class MaxExpressionStub < Gecode::Constraints::Int::CompositeStub
35
+ def constrain_equal(variable, params, constrain)
36
+ enum, strength = @params.values_at(:lhs, :strength)
37
+ if constrain
38
+ variable.must_be.in enum.domain_range
39
+ end
40
+
41
+ Gecode::Raw::max(@model.active_space, enum.to_int_var_array,
42
+ variable.bind, strength)
43
+ end
44
+ end
45
+
46
+ # Describes a CompositeStub for the min constraint, which constrains the
47
+ # minimum value of the integer variables in an enumeration.
48
+ #
49
+ # == Example
50
+ #
51
+ # # The minimum must be positive.
52
+ # int_enum.min.must > 0
53
+ #
54
+ # # The minimum must equal a integer variable +min+.
55
+ # int_enum.min.must == min
56
+ #
57
+ # # The minimum must not be non-positive. The constraint is reified with the
58
+ # # boolean variable +is_positive+ and strength +domain+ is selected.
59
+ # int_enum.min.must_not_be.less_or_equal(0, :reify => is_positive,
60
+ # :strength => :domain)
61
+ class MinExpressionStub < Gecode::Constraints::Int::CompositeStub
62
+ def constrain_equal(variable, params, constrain)
63
+ enum, strength = @params.values_at(:lhs, :strength)
64
+ if constrain
65
+ variable.must_be.in enum.domain_range
66
+ end
67
+
68
+ Gecode::Raw::min(@model.active_space, enum.to_int_var_array,
69
+ variable.bind, strength)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,100 @@
1
+ module Gecode::Constraints::IntEnum
2
+ class Expression
3
+ # Adds a channel constraint on the variables in the enum with the specified
4
+ # other set or int enum.
5
+ def channel(enum, options = {})
6
+ if @params[:negate]
7
+ raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
8
+ 'is not implemented.'
9
+ end
10
+ unless enum.respond_to?(:to_int_var_array) or
11
+ enum.respond_to?(:to_set_var_array)
12
+ raise TypeError, "Expected int or set enum, got #{enum.class}."
13
+ end
14
+
15
+ @params.update(Gecode::Constraints::Util.decode_options(options))
16
+ @params.update(:rhs => enum)
17
+ @model.add_constraint Channel::ChannelConstraint.new(@model, @params)
18
+ end
19
+ end
20
+
21
+ # A module that gathers the classes and modules used in channel constraints.
22
+ module Channel #:nodoc:
23
+ # Describes a channel constraint which "channels" two enumerations of
24
+ # integer variables or one enumeration of integer variables and one
25
+ # enumeration of set variables. Channel constraints are used to give
26
+ # access to multiple viewpoints when modelling.
27
+ #
28
+ # When used on two integer enumeration, the channel constraint can be
29
+ # thought of as constraining the arrays to be each other's inverses. When
30
+ # used with an enumeration of sets the i:th set includes the value of the
31
+ # j:th integer.
32
+ #
33
+ # Neither reification nor negation is supported. Selecting strength is only
34
+ # supported when using the constraint between two integer enumerations,
35
+ # it's not supported when a set enumeration is used.
36
+ #
37
+ # == Example
38
+ #
39
+ # Lets say that we’re modelling a sequence of numbers that must be distinct
40
+ # and that we want access to the following two view simultaneously.
41
+ #
42
+ # === First view
43
+ #
44
+ # The sequence is modelled as an array of integer variables where the first
45
+ # variable holds the value of the first position in the sequence, the
46
+ # second the value of the second position and so on.
47
+ #
48
+ # # n variables with values from 0 to n-1.
49
+ # elements = int_var_array(n, 0...n)
50
+ # elements.must_be.distinct
51
+ #
52
+ # That way +elements+ will contain the actual sequence when the problem has
53
+ # been solved.
54
+ #
55
+ # === Second view
56
+ #
57
+ # The sequence is modelled as the positions of each value in 0..(n-1) in
58
+ # the sequence. That way the first variable would hold the positions of 0
59
+ # in the sequence, the second variable would hold the positions of 1 in the
60
+ # sequence and so on.
61
+ #
62
+ # positions = int_var_array(n, 0...n)
63
+ # positions.must_be.distinct
64
+ #
65
+ # === Connecting the views
66
+ #
67
+ # In essence the relationship between the two arrays +elements+ and
68
+ # +positions+ is that
69
+ #
70
+ # elements.map{ |e| e.val }[i] == positions.map{ |p| p.val }.index(i)
71
+ #
72
+ # for all i in 0..(n-1). This relationship is enforced by the channel
73
+ # constraint as follows.
74
+ #
75
+ # elements.must.channel positions
76
+ #
77
+ # == Example (sets)
78
+ #
79
+ # # +set_enum+ is constrained to channel +int_enum+.
80
+ # int_enum.must.channel set_enum
81
+ #
82
+ # # This is another way of saying the above.
83
+ # set_enum.must.channel int_enum
84
+ class ChannelConstraint < Gecode::Constraints::Constraint
85
+ def post
86
+ lhs, rhs, strength = @params.values_at(:lhs, :rhs, :strength)
87
+
88
+ lhs = lhs.to_int_var_array
89
+ if rhs.respond_to? :to_int_var_array
90
+ # Int var array.
91
+ Gecode::Raw::channel(@model.active_space, lhs, rhs.to_int_var_array,
92
+ strength)
93
+ else
94
+ # Set var array, no strength.
95
+ Gecode::Raw::channel(@model.active_space, lhs, rhs.to_set_var_array)
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,92 @@
1
+ module Gecode
2
+ module IntEnumMethods
3
+ # Specifies that a specific element should be counted, starting a count
4
+ # constraint. The element can be either an int var or a fixnum.
5
+ def count(element)
6
+ unless element.kind_of?(FreeIntVar) or element.kind_of?(Fixnum)
7
+ raise TypeError, 'Elements used with count can not be of type ' +
8
+ "#{element.class}."
9
+ end
10
+ params = {:lhs => self, :element => element}
11
+ Gecode::Constraints::SimpleExpressionStub.new(@model, params) do |m, ps|
12
+ Gecode::Constraints::IntEnum::Count::Expression.new(m, ps)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ # A module that gathers the classes and modules used in count constraints.
19
+ module Gecode::Constraints::IntEnum::Count #:nodoc:
20
+ # Describes an expression
21
+ class Expression < Gecode::Constraints::IntEnum::Expression #:nodoc:
22
+ def initialize(model, params)
23
+ super
24
+ unless params[:negate]
25
+ @method_relations = Gecode::Constraints::Util::RELATION_TYPES
26
+ else
27
+ @method_relations = Gecode::Constraints::Util::NEGATED_RELATION_TYPES
28
+ end
29
+ end
30
+
31
+ Gecode::Constraints::Util::RELATION_TYPES.each_pair do |name, type|
32
+ class_eval <<-"end_code"
33
+ def #{name}(expression, options = {})
34
+ unless expression.kind_of?(Fixnum) or
35
+ expression.kind_of?(Gecode::FreeIntVar)
36
+ raise TypeError, 'Invalid right hand side of count constraint: ' +
37
+ "\#{expression.class}."
38
+ end
39
+
40
+ relation = @method_relations[:#{name}]
41
+ @params.update(Gecode::Constraints::Util.decode_options(options))
42
+ @params.update(:rhs => expression, :relation_type => relation)
43
+ @model.add_constraint CountConstraint.new(@model, @params)
44
+ end
45
+ end_code
46
+ end
47
+ alias_comparison_methods
48
+ end
49
+
50
+ # Describes a count constraint, which constrains the number of times a value
51
+ # (constant or a variable) may occurr in an enumeration of integer variable.
52
+ #
53
+ # All relations available for +SimpleRelationConstraint+ can be used with
54
+ # count constraints. Negation and reification is supported.
55
+ #
56
+ # == Examples
57
+ #
58
+ # # Constrain +int_enum+ to not contain 0 exactly once.
59
+ # int_enum.count(0).must_not == 1
60
+ #
61
+ # # Constrain +int_enum+ to contain +x+ exactly +x_count+ times.
62
+ # int_enum.count(x).must == x_count
63
+ #
64
+ # # Reifies the constraint that +int_enum+ has +x+ zeros with the boolean
65
+ # # variable +has_x_zeros+ and selects the strength +domain+.
66
+ # int_enum.count(0).must.equal(x, :reify => has_x_zeros,
67
+ # :strength => :domain)
68
+ class CountConstraint < Gecode::Constraints::ReifiableConstraint
69
+ def post
70
+ lhs, element, relation_type, rhs, strength, reif_var =
71
+ @params.values_at(:lhs, :element, :relation_type, :rhs, :strength,
72
+ :reif)
73
+
74
+ # Bind variables if needed.
75
+ element = element.bind if element.respond_to? :bind
76
+ rhs = rhs.bind if rhs.respond_to? :bind
77
+
78
+ # Post the constraint to gecode.
79
+ if reif_var.nil?
80
+ Gecode::Raw::count(@model.active_space, lhs.to_int_var_array,
81
+ element, relation_type, rhs, strength)
82
+ else
83
+ # We use a proxy int variable to get the reification.
84
+ proxy = @model.int_var(rhs.min..rhs.max)
85
+ rel = Gecode::Constraints::Util::RELATION_TYPES.invert[relation_type]
86
+ proxy.must.send(rel, @params[:rhs], :reify => reif_var)
87
+ Gecode::Raw::count(@model.active_space, lhs.to_int_var_array,
88
+ element, Gecode::Raw::IRT_EQ, proxy.bind, strength)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,69 @@
1
+ module Gecode
2
+ module IntEnumMethods
3
+ # Specifies offsets to be used with a distinct constraint. The offsets can
4
+ # be specified one by one or as an array of offsets.
5
+ def with_offsets(*offsets)
6
+ if offsets.kind_of? Enumerable
7
+ offsets = *offsets
8
+ end
9
+ params = {:lhs => self, :offsets => offsets}
10
+
11
+ Gecode::Constraints::SimpleExpressionStub.new(@model, params) do |m, ps|
12
+ Gecode::Constraints::IntEnum::Expression.new(m, ps)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ module Gecode::Constraints::IntEnum
19
+ class Expression
20
+ # Posts a distinct constraint on the variables in the enum.
21
+ def distinct(options = {})
22
+ if @params[:negate]
23
+ # The best we could implement it as from here would be a bunch of
24
+ # reified pairwise equality constraints.
25
+ raise Gecode::MissingConstraintError, 'A negated distinct is not ' +
26
+ 'implemented.'
27
+ end
28
+
29
+ @model.add_constraint Distinct::DistinctConstraint.new(@model,
30
+ @params.update(Gecode::Constraints::Util.decode_options(options)))
31
+ end
32
+ end
33
+
34
+ # A module that gathers the classes and modules used in distinct constraints.
35
+ module Distinct #:nodoc:
36
+ # Describes a distinct constraint, which constrains all integer variables
37
+ # in an enumeration to be distinct (different). The constraint can also be
38
+ # used with constant offsets, so that the variables, with specified offsets
39
+ # added, must be distinct.
40
+ #
41
+ # The constraint does not support negation nor reification.
42
+ #
43
+ # == Examples
44
+ #
45
+ # # Constrains all variables in +int_enum+ to be assigned different
46
+ # # values.
47
+ # int_enum.must_be.distinct
48
+ #
49
+ # # The same as above, but also selects that the strength +domain+ should
50
+ # # be used.
51
+ # int_enum.must_be.distinct(:strength => :domain)
52
+ #
53
+ # # Uses the offset to constrain that no number may be the previous number
54
+ # # incremented by one.
55
+ # numbers = int_var_array(8, 0..9)
56
+ # numbers.with_offset((1..numbers.size).to_a.reverse).must_be.distinct
57
+ class DistinctConstraint < Gecode::Constraints::Constraint
58
+ def post
59
+ # Bind lhs.
60
+ @params[:lhs] = @params[:lhs].to_int_var_array
61
+
62
+ # Fetch the parameters to Gecode.
63
+ params = @params.values_at(:offsets, :lhs, :strength)
64
+ params.delete_if{ |x| x.nil? }
65
+ Gecode::Raw::distinct(@model.active_space, *params)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,82 @@
1
+ # A module that gathers the classes and modules used by element constraints.
2
+ module Gecode::Constraints::IntEnum::Element #:nodoc:
3
+ # Describes a CompositeStub for the element constraint, which places a
4
+ # constraint on a variable at the specified position in an enumeration of
5
+ # integer variables. It's basically the array access of constraint
6
+ # programming.
7
+ #
8
+ # == Example
9
+ #
10
+ # # The variable at the +x+:th position in +int_enum+ must be larger than
11
+ # # +y+.
12
+ # int_enum[x].must > y
13
+ #
14
+ # # The price of +selected_item+ as described by +prices+ must not be
15
+ # # larger than 100.
16
+ # prices = wrap_enum([500, 24, 4711, 412, 24])
17
+ # prices[selected_item].must_not > 100
18
+ #
19
+ # # Reify the constraint that the +x+:th variable in +int_enum+ must be in
20
+ # # range 7..17 with the boolean variable +bool+ and select strength
21
+ # # +domain+.
22
+ #
23
+ # int_enum[x].must_be.in(7..17, :reify => bool, :strength => :domain)
24
+ class ExpressionStub < Gecode::Constraints::Int::CompositeStub
25
+ def constrain_equal(variable, params, constrain)
26
+ enum, position, strength = @params.values_at(:lhs, :position, :strength)
27
+ if constrain
28
+ variable.must_be.in enum.domain_range
29
+ end
30
+
31
+ # The enum can be a constant array.
32
+ enum = enum.to_int_var_array if enum.respond_to? :to_int_var_array
33
+ Gecode::Raw::element(@model.active_space, enum,
34
+ position.bind, variable.bind, strength)
35
+ end
36
+ end
37
+
38
+ # Methods needed to add support for element constraints to enums.
39
+ module AdditionalEnumMethods #:nodoc:
40
+ # This adds the adder for the methods in the modules including it. The
41
+ # reason for doing it so indirect is that the first #[] won't be defined
42
+ # before the module that this is mixed into is mixed into an enum.
43
+ def self.included(enum_mod)
44
+ enum_mod.module_eval do
45
+ # Now we enter the module AdditionalEnumMethods is mixed into.
46
+ class << self
47
+ alias_method :pre_element_included, :included
48
+ def included(mod)
49
+ mod.module_eval do
50
+ # Now we enter the module that the module possibly defining #[]
51
+ # is mixed into.
52
+ if instance_methods.include? '[]'
53
+ alias_method :pre_element_access, :[]
54
+ end
55
+
56
+ def [](*vars)
57
+ # Hook in an element constraint if a variable is used for array
58
+ # access.
59
+ if vars.first.kind_of? Gecode::FreeIntVar
60
+ params = {:lhs => self, :position => vars.first}
61
+ return Gecode::Constraints::IntEnum::Element::ExpressionStub.new(
62
+ @model, params)
63
+ else
64
+ pre_element_access(*vars) if respond_to? :pre_element_access
65
+ end
66
+ end
67
+ end
68
+ pre_element_included(mod)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ module Gecode::IntEnumMethods
77
+ include Gecode::Constraints::IntEnum::Element::AdditionalEnumMethods
78
+ end
79
+
80
+ module Gecode::FixnumEnumMethods
81
+ include Gecode::Constraints::IntEnum::Element::AdditionalEnumMethods
82
+ end
@@ -0,0 +1,38 @@
1
+ module Gecode::Constraints::IntEnum
2
+ class Expression
3
+ # Posts an equality constraint on the variables in the enum.
4
+ def equal(options = {})
5
+ if @params[:negate]
6
+ # The best we could implement it as from here would be a bunch of
7
+ # reified pairwise inequality constraints.
8
+ raise Gecode::MissingConstraintError, 'A negated equality is not ' +
9
+ 'implemented.'
10
+ end
11
+
12
+ @model.add_constraint Equality::EqualityConstraint.new(@model,
13
+ @params.update(Gecode::Constraints::Util.decode_options(options)))
14
+ end
15
+ end
16
+
17
+ # A module that gathers the classes and modules used in equality constraints.
18
+ module Equality #:nodoc:
19
+ # Describes an equality constraint, which constrains all variables in an
20
+ # integer enumeration to be equal. Neither negation nor reification is
21
+ # supported.
22
+ #
23
+ # == Example
24
+ #
25
+ # # Constrains all variables in +int_enum+ to be equal.
26
+ # int_enum.must_be.equal
27
+ class EqualityConstraint < Gecode::Constraints::Constraint
28
+ def post
29
+ # Bind lhs.
30
+ @params[:lhs] = @params[:lhs].to_int_var_array
31
+
32
+ # Fetch the parameters to Gecode.
33
+ params = @params.values_at(:lhs, :strength)
34
+ Gecode::Raw::eq(@model.active_space, *params)
35
+ end
36
+ end
37
+ end
38
+ end