gecoder-with-gecode 0.7.1-mswin32

Sign up to get free protection for your applications and to get access to all the features.
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