gecoder-with-gecode 0.9.0-x86-mswin32-60

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 (203) hide show
  1. data/CHANGES +137 -0
  2. data/COPYING +17 -0
  3. data/LGPL-LICENSE +458 -0
  4. data/README +58 -0
  5. data/Rakefile +14 -0
  6. data/example/equation_system.rb +15 -0
  7. data/example/example_helper.rb +1 -0
  8. data/example/magic_sequence.rb +43 -0
  9. data/example/money.rb +36 -0
  10. data/example/queens.rb +42 -0
  11. data/example/send_more_money.rb +43 -0
  12. data/example/send_most_money.rb +58 -0
  13. data/example/square_tiling.rb +84 -0
  14. data/example/sudoku-set.rb +106 -0
  15. data/example/sudoku.rb +56 -0
  16. data/lib/gecode.dll +0 -0
  17. data/lib/gecoder.rb +5 -0
  18. data/lib/gecoder/bindings.rb +96 -0
  19. data/lib/gecoder/bindings/bindings.rb +2029 -0
  20. data/lib/gecoder/interface.rb +9 -0
  21. data/lib/gecoder/interface/binding_changes.rb +9 -0
  22. data/lib/gecoder/interface/branch.rb +163 -0
  23. data/lib/gecoder/interface/constraints.rb +471 -0
  24. data/lib/gecoder/interface/constraints/bool/boolean.rb +251 -0
  25. data/lib/gecoder/interface/constraints/bool/channel.rb +7 -0
  26. data/lib/gecoder/interface/constraints/bool/linear.rb +200 -0
  27. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +68 -0
  28. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +106 -0
  29. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +55 -0
  30. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +84 -0
  31. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +155 -0
  32. data/lib/gecoder/interface/constraints/extensional_regexp.rb +101 -0
  33. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  34. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  35. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  36. data/lib/gecoder/interface/constraints/int/arithmetic.rb +150 -0
  37. data/lib/gecoder/interface/constraints/int/channel.rb +51 -0
  38. data/lib/gecoder/interface/constraints/int/domain.rb +80 -0
  39. data/lib/gecoder/interface/constraints/int/linear.rb +143 -0
  40. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  41. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +63 -0
  42. data/lib/gecoder/interface/constraints/int_enum/channel.rb +86 -0
  43. data/lib/gecoder/interface/constraints/int_enum/count.rb +66 -0
  44. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +64 -0
  45. data/lib/gecoder/interface/constraints/int_enum/element.rb +64 -0
  46. data/lib/gecoder/interface/constraints/int_enum/equality.rb +37 -0
  47. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +187 -0
  48. data/lib/gecoder/interface/constraints/int_enum/sort.rb +135 -0
  49. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +95 -0
  50. data/lib/gecoder/interface/constraints/int_var_constraints.rb +230 -0
  51. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
  52. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  53. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  54. data/lib/gecoder/interface/constraints/set/cardinality.rb +65 -0
  55. data/lib/gecoder/interface/constraints/set/channel.rb +51 -0
  56. data/lib/gecoder/interface/constraints/set/connection.rb +130 -0
  57. data/lib/gecoder/interface/constraints/set/domain.rb +156 -0
  58. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  59. data/lib/gecoder/interface/constraints/set/operation.rb +118 -0
  60. data/lib/gecoder/interface/constraints/set/relation.rb +155 -0
  61. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  62. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  63. data/lib/gecoder/interface/constraints/set_enum/channel.rb +45 -0
  64. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +43 -0
  65. data/lib/gecoder/interface/constraints/set_enum/operation.rb +69 -0
  66. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  67. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +84 -0
  68. data/lib/gecoder/interface/constraints/set_var_constraints.rb +243 -0
  69. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  70. data/lib/gecoder/interface/enum_wrapper.rb +205 -0
  71. data/lib/gecoder/interface/model.rb +453 -0
  72. data/lib/gecoder/interface/model_sugar.rb +84 -0
  73. data/lib/gecoder/interface/search.rb +197 -0
  74. data/lib/gecoder/interface/variables.rb +306 -0
  75. data/lib/gecoder/version.rb +4 -0
  76. data/specs/bool_var.rb +81 -0
  77. data/specs/branch.rb +185 -0
  78. data/specs/constraints/bool/boolean.rb +317 -0
  79. data/specs/constraints/bool/boolean_properties.rb +51 -0
  80. data/specs/constraints/bool/linear.rb +213 -0
  81. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  82. data/specs/constraints/bool_enum/channel.rb +102 -0
  83. data/specs/constraints/bool_enum/extensional.rb +225 -0
  84. data/specs/constraints/constraint_helper.rb +234 -0
  85. data/specs/constraints/constraint_receivers.rb +103 -0
  86. data/specs/constraints/constraints.rb +26 -0
  87. data/specs/constraints/fixnum_enum/element.rb +58 -0
  88. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  89. data/specs/constraints/int/arithmetic.rb +149 -0
  90. data/specs/constraints/int/channel.rb +101 -0
  91. data/specs/constraints/int/domain.rb +106 -0
  92. data/specs/constraints/int/linear.rb +183 -0
  93. data/specs/constraints/int/linear_properties.rb +97 -0
  94. data/specs/constraints/int/relation.rb +84 -0
  95. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  96. data/specs/constraints/int_enum/channel.rb +57 -0
  97. data/specs/constraints/int_enum/count.rb +72 -0
  98. data/specs/constraints/int_enum/distinct.rb +80 -0
  99. data/specs/constraints/int_enum/element.rb +61 -0
  100. data/specs/constraints/int_enum/equality.rb +29 -0
  101. data/specs/constraints/int_enum/extensional.rb +224 -0
  102. data/specs/constraints/int_enum/sort.rb +167 -0
  103. data/specs/constraints/operands.rb +264 -0
  104. data/specs/constraints/property_helper.rb +443 -0
  105. data/specs/constraints/reification_sugar.rb +69 -0
  106. data/specs/constraints/selected_set/select.rb +56 -0
  107. data/specs/constraints/selected_set/select_properties.rb +157 -0
  108. data/specs/constraints/set/cardinality.rb +58 -0
  109. data/specs/constraints/set/cardinality_properties.rb +46 -0
  110. data/specs/constraints/set/channel.rb +77 -0
  111. data/specs/constraints/set/connection.rb +176 -0
  112. data/specs/constraints/set/domain.rb +197 -0
  113. data/specs/constraints/set/include.rb +36 -0
  114. data/specs/constraints/set/operation.rb +132 -0
  115. data/specs/constraints/set/relation.rb +117 -0
  116. data/specs/constraints/set_elements/relation.rb +84 -0
  117. data/specs/constraints/set_enum/channel.rb +80 -0
  118. data/specs/constraints/set_enum/distinct.rb +59 -0
  119. data/specs/constraints/set_enum/operation.rb +111 -0
  120. data/specs/constraints/set_enum/select.rb +73 -0
  121. data/specs/distribution.rb +14 -0
  122. data/specs/enum_matrix.rb +43 -0
  123. data/specs/enum_wrapper.rb +179 -0
  124. data/specs/examples.rb +17 -0
  125. data/specs/int_var.rb +163 -0
  126. data/specs/logging.rb +24 -0
  127. data/specs/model.rb +325 -0
  128. data/specs/model_sugar.rb +30 -0
  129. data/specs/search.rb +383 -0
  130. data/specs/selected_set.rb +39 -0
  131. data/specs/set_elements.rb +34 -0
  132. data/specs/set_var.rb +82 -0
  133. data/specs/spec_helper.rb +265 -0
  134. data/tasks/all_tasks.rb +1 -0
  135. data/tasks/dependencies.txt +22 -0
  136. data/tasks/distribution.rake +194 -0
  137. data/tasks/rcov.rake +18 -0
  138. data/tasks/specs.rake +21 -0
  139. data/tasks/svn.rake +16 -0
  140. data/tasks/website.rake +51 -0
  141. data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
  142. data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
  143. data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
  144. data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
  145. data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
  146. data/vendor/gecode/win32/lib/libgecodesupport.dll +0 -0
  147. data/vendor/rust/README +28 -0
  148. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  149. data/vendor/rust/include/rust_checks.hh +116 -0
  150. data/vendor/rust/include/rust_conversions.hh +102 -0
  151. data/vendor/rust/rust.rb +67 -0
  152. data/vendor/rust/rust/attribute.rb +51 -0
  153. data/vendor/rust/rust/bindings.rb +172 -0
  154. data/vendor/rust/rust/class.rb +337 -0
  155. data/vendor/rust/rust/constants.rb +48 -0
  156. data/vendor/rust/rust/container.rb +110 -0
  157. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  158. data/vendor/rust/rust/cwrapper.rb +72 -0
  159. data/vendor/rust/rust/cxxclass.rb +96 -0
  160. data/vendor/rust/rust/element.rb +81 -0
  161. data/vendor/rust/rust/enum.rb +63 -0
  162. data/vendor/rust/rust/function.rb +407 -0
  163. data/vendor/rust/rust/namespace.rb +61 -0
  164. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  165. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  166. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  167. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  168. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  169. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  170. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  171. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  172. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +100 -0
  173. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  174. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
  175. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  176. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  177. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  178. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  179. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  180. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  181. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  182. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  183. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
  184. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  185. data/vendor/rust/rust/type.rb +98 -0
  186. data/vendor/rust/test/Makefile +4 -0
  187. data/vendor/rust/test/constants.rb +36 -0
  188. data/vendor/rust/test/cppclass.cc +45 -0
  189. data/vendor/rust/test/cppclass.hh +67 -0
  190. data/vendor/rust/test/cppclass.rb +59 -0
  191. data/vendor/rust/test/cwrapper.c +74 -0
  192. data/vendor/rust/test/cwrapper.h +41 -0
  193. data/vendor/rust/test/cwrapper.rb +56 -0
  194. data/vendor/rust/test/dummyclass.hh +31 -0
  195. data/vendor/rust/test/lib/extension-test.rb +98 -0
  196. data/vendor/rust/test/operators.cc +41 -0
  197. data/vendor/rust/test/operators.hh +39 -0
  198. data/vendor/rust/test/operators.rb +39 -0
  199. data/vendor/rust/test/test-constants.rb +43 -0
  200. data/vendor/rust/test/test-cppclass.rb +82 -0
  201. data/vendor/rust/test/test-cwrapper.rb +80 -0
  202. data/vendor/rust/test/test-operators.rb +42 -0
  203. metadata +393 -0
@@ -0,0 +1,75 @@
1
+ # A module containing constraints that have set_enum[set] as left hand
2
+ # side.
3
+ module Gecode::SelectedSet #:nodoc:
4
+ # A SelectedSetOperand is an uncommon operand that results from calling
5
+ # SetEnumOperand#[] with a SetOperand. It facilitates placing the
6
+ # constraints defined in SelectedSetConstraintReceiver
7
+ #
8
+ # ==== Examples
9
+ #
10
+ # Producing a SelectedSetOperand from +set_enum+ and +set_operand+:
11
+ #
12
+ # set_enum[set_operand]
13
+ #
14
+ class SelectedSetOperand
15
+ include Gecode::Operand
16
+
17
+ # Constructs a new selected set operand from +set_enum+ and +set+.
18
+ def initialize(set_enum, set) #:nodoc:
19
+ unless set_enum.respond_to? :to_set_enum
20
+ raise TypeError, "Expected set enum operand, got #{set_enum.class}."
21
+ end
22
+ unless set.respond_to? :to_set_var
23
+ raise TypeError, "Expected set operand, got #{set.class}."
24
+ end
25
+
26
+ @set_enum = set_enum
27
+ @set = set
28
+ end
29
+
30
+ # Returns the set enum and set that make up the selected set
31
+ # operand.
32
+ def to_selected_set #:nodoc:
33
+ return @set_enum, @set
34
+ end
35
+
36
+ def model #:nodoc:
37
+ @set_enum.model
38
+ end
39
+
40
+ private
41
+
42
+ def construct_receiver(params)
43
+ SelectedSetConstraintReceiver.new(model, params)
44
+ end
45
+ end
46
+
47
+ # SelectedSetConstraintReceiver contains all constraints that can be
48
+ # placed on a SelectedSetOperand.
49
+ #
50
+ # Constraints are placed by calling SelectedSetOperand#must (or any other
51
+ # of the variations defined in Operand), which produces a
52
+ # SelectedSetConstraintReceiver from which the desired constraint can
53
+ # be used.
54
+ #
55
+ # ==== Examples
56
+ #
57
+ # Constrains the sets in +set_enum+ that are selected by +set_operand+ to be
58
+ # disjoint. This uses SetEnumOperand#[] and
59
+ # SelectedSetConstraintReceiver#disjoint.
60
+ #
61
+ # set_enum[set_operand].must_be.disjoint
62
+ #
63
+ class SelectedSetConstraintReceiver < Gecode::ConstraintReceiver
64
+ # Raises TypeError unless the left hand side is a selected set operand.
65
+ def initialize(model, params) #:nodoc:
66
+ super
67
+
68
+ unless params[:lhs].respond_to? :to_selected_set
69
+ raise TypeError, 'Must have selected set operand as left hand side.'
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ require 'gecoder/interface/constraints/selected_set/select'
@@ -0,0 +1,65 @@
1
+ module Gecode::Set
2
+ module SetOperand
3
+ # Produces an IntOperand representing the size of the set.
4
+ #
5
+ # ==== Examples
6
+ #
7
+ # # The size of +set+.
8
+ # set.size
9
+ def size
10
+ Cardinality::SetSizeOperand.new(@model, self)
11
+ end
12
+ end
13
+
14
+ # A module that gathers the classes and modules used in cardinality
15
+ # constraints.
16
+ module Cardinality #:nodoc:
17
+ # Describes a cardinality constraint specifically for ranges. This is just
18
+ # a special case which is used instead of the more general composite
19
+ # constraint when the target cardinality is a range.
20
+ class CardinalityConstraint < Gecode::Constraint #:nodoc:
21
+ def post
22
+ var, range = @params.values_at(:lhs, :range)
23
+ Gecode::Raw::cardinality(@model.active_space, var.to_set_var.bind,
24
+ range.first, range.last)
25
+ end
26
+ end
27
+
28
+ class SetSizeOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
29
+ def initialize(model, set_op)
30
+ super model
31
+ @set = set_op
32
+ end
33
+
34
+ def constrain_equal(int_operand, constrain, propagation_options)
35
+ set = @set.to_set_var
36
+ if constrain
37
+ int_operand.must_be.in set.lower_bound.size..set.upper_bound.size
38
+ end
39
+
40
+ Gecode::Raw::cardinality(@model.active_space, set.bind,
41
+ int_operand.to_int_var.bind)
42
+ end
43
+
44
+ alias_method :pre_cardinality_construct_receiver, :construct_receiver
45
+ def construct_receiver(params)
46
+ receiver = pre_cardinality_construct_receiver(params)
47
+ set = @set
48
+ receiver.instance_eval{ @set = set }
49
+ class <<receiver
50
+ alias_method :in_without_short_circuit, :in
51
+ def in(range, options = {})
52
+ if range.kind_of?(Range) and !@params[:negate] and
53
+ !options.has_key?(:reify)
54
+ @params.update(:lhs => @set, :range => range)
55
+ @model.add_constraint CardinalityConstraint.new(@model, @params)
56
+ else
57
+ in_without_short_circuit(range, options)
58
+ end
59
+ end
60
+ end
61
+ return receiver
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ module Gecode::Set
2
+ class SetConstraintReceiver
3
+ # Constrains this set to channel +bool_enum+. The set is constrained
4
+ # to include value i exactly when the operand at index i in the
5
+ # boolean enumeration is true.
6
+ #
7
+ # Neither reification nor negation is supported. The boolean enum and set
8
+ # can be interchanged.
9
+ #
10
+ # ==== Examples
11
+ #
12
+ # # Constrains the enumeration of boolean operands called +bools+ to at
13
+ # # least have the first and third operands set to true
14
+ # set.must_be.superset_of [0, 2]
15
+ # set.must.channel bools
16
+ #
17
+ # # An alternative way of writing the above.
18
+ # set.must_be.superset_of [0, 2]
19
+ # bools.must.channel set
20
+ def channel(bool_enum, options = {})
21
+ if @params[:negate]
22
+ raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
23
+ 'is not implemented.'
24
+ end
25
+ if options.has_key? :reify
26
+ raise ArgumentError, 'The channel constraint does not support the ' +
27
+ 'reification option.'
28
+ end
29
+ unless bool_enum.respond_to? :to_bool_enum
30
+ raise TypeError, 'Expected an enum of bool operands, ' +
31
+ "got #{bool_enum.class}."
32
+ end
33
+
34
+ @params.update(:rhs => bool_enum)
35
+ @params.update Gecode::Set::Util.decode_options(options)
36
+ @model.add_constraint Channel::ChannelConstraint.new(@model, @params)
37
+ end
38
+ end
39
+
40
+ # A module that gathers the classes and modules used in channel constraints
41
+ # involving one set operand and a boolean enum.
42
+ module Channel #:nodoc:
43
+ class ChannelConstraint < Gecode::Constraint #:nodoc:
44
+ def post
45
+ lhs, rhs = @params.values_at(:lhs, :rhs)
46
+ Gecode::Raw::channel(@model.active_space, rhs.to_bool_enum.bind_array,
47
+ lhs.to_set_var.bind)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,130 @@
1
+ module Gecode::Set
2
+ module SetOperand
3
+ # Produces an IntOperand representing the minimum of the set.
4
+ #
5
+ # ==== Examples
6
+ #
7
+ # # The minimum of +set+.
8
+ # set.min
9
+ def min
10
+ Connection::SetMinOperand.new(@model, self)
11
+ end
12
+
13
+ # Produces an IntOperand representing the maximum of the set.
14
+ #
15
+ # ==== Examples
16
+ #
17
+ # # The maximum of +set+.
18
+ # set.max
19
+ def max
20
+ Connection::SetMaxOperand.new(@model, self)
21
+ end
22
+
23
+ # Produces an IntOperand representing the sum of the values in the
24
+ # set. One of the following options may also be given:
25
+ # [:weights] Produces the weighted sum using the specified hash
26
+ # of weights. The hash should map each value to
27
+ # that value's weight.
28
+ # [:substitutions] Produces the sum of the set with all elements
29
+ # replaced according to the hash.
30
+ #
31
+ # Elements not included in the weights or substitutions hash are
32
+ # removed from the upper bound of the set.
33
+ #
34
+ # ==== Examples
35
+ #
36
+ # # The sum of +set+.
37
+ # set.sum
38
+ #
39
+ # # The sum of +set+ with primes < 10 given twice the weight.
40
+ # set.sum(:weights => {2 => 2, 3 => 2, 5 => 2, 7 => 2})
41
+ #
42
+ # # The sum of +set+ with odd values in [1,6] being counted as 1.
43
+ # set.sum(:substitutions => {1 => 1, 3 => 1, 5 => 1})
44
+ def sum(options = {:weights => weights = Hash.new(1)})
45
+ if options.empty? or options.keys.size > 1
46
+ raise ArgumentError, 'At most one of the options :weights and ' +
47
+ ':substitutions may be specified.'
48
+ end
49
+
50
+ case options.keys.first
51
+ when :substitutions: subs = options[:substitutions]
52
+ when :weights:
53
+ weights = options[:weights]
54
+ subs = Hash.new do |hash, key|
55
+ if weights[key].nil?
56
+ hash[key] = nil
57
+ else
58
+ hash[key] = key * weights[key]
59
+ end
60
+ end
61
+ else raise ArgumentError, "Unrecognized option #{options.keys.first}."
62
+ end
63
+ Connection::SetSumOperand.new(@model, self, subs)
64
+ end
65
+ end
66
+
67
+ # A module that gathers the classes and modules used in connection
68
+ # constraints.
69
+ module Connection #:nodoc:
70
+ class SetMinOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
71
+ def initialize(model, set_op)
72
+ super model
73
+ @set = set_op
74
+ end
75
+
76
+ def constrain_equal(int_operand, constrain, propagation_options)
77
+ set = @set.to_set_var
78
+ if constrain
79
+ int_operand.must_be.in set.upper_bound.min..set.lower_bound.min
80
+ end
81
+
82
+ Gecode::Raw::min(@model.active_space, set.bind,
83
+ int_operand.to_int_var.bind)
84
+ end
85
+ end
86
+
87
+ class SetMaxOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
88
+ def initialize(model, set_op)
89
+ super model
90
+ @set = set_op
91
+ end
92
+
93
+ def constrain_equal(int_operand, constrain, propagation_options)
94
+ set = @set.to_set_var
95
+ if constrain
96
+ int_operand.must_be.in set.upper_bound.min..set.lower_bound.min
97
+ end
98
+
99
+ Gecode::Raw::max(@model.active_space, set.bind,
100
+ int_operand.to_int_var.bind)
101
+ end
102
+ end
103
+
104
+ class SetSumOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
105
+ def initialize(model, set_op, subs)
106
+ super model
107
+ @set = set_op
108
+ @subs = subs
109
+ end
110
+
111
+ def constrain_equal(int_operand, constrain, propagation_options)
112
+ set = @set.to_set_var
113
+ lub = set.upper_bound.to_a
114
+ lub.delete_if{ |e| @subs[e].nil? }
115
+ substituted_lub = lub.map{ |e| @subs[e] }
116
+ if constrain
117
+ # Compute the theoretical bounds of the weighted sum. This is slightly
118
+ # sloppy since we could also use the contents of the greatest lower
119
+ # bound.
120
+ min = substituted_lub.find_all{ |e| e < 0}.inject(0){ |x, y| x + y }
121
+ max = substituted_lub.find_all{ |e| e > 0}.inject(0){ |x, y| x + y }
122
+ int_operand.must_be.in min..max
123
+ end
124
+
125
+ Gecode::Raw::weights(@model.active_space, lub, substituted_lub,
126
+ set.bind, int_operand.to_int_var.bind)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,156 @@
1
+ module Gecode::Set
2
+ class SetConstraintReceiver
3
+ # Constrains the set operand to have a domain equal to +constant_set+.
4
+ #
5
+ # ==== Examples
6
+ #
7
+ # # +set+ must equal [1,2,5]
8
+ # set.must == [1,2,5]
9
+ #
10
+ # # +set+ must not equal 1..67
11
+ # set.must_not == 1..67
12
+ #
13
+ # # +set+ must equal the singleton set 0. The constraint is reified with
14
+ # # the boolean operand +is_singleton_zero+.
15
+ # set.must.equal(0, :reify => is_singleton_zero)
16
+ def ==(constant_set, options = {})
17
+ add_domain_constraint(:==, constant_set, options)
18
+ end
19
+
20
+ # Constrains the set operand to be a superset of +constant_set+.
21
+ #
22
+ # ==== Examples
23
+ #
24
+ # # +set+ must be a superset of [1,2,5]
25
+ # set.must_be.superset_of [1,2,5]
26
+ #
27
+ # # +set+ must be a superset of 1..67
28
+ # set.must_be.superset_of 1..67
29
+ #
30
+ # # +set+ must not be a superset of [0].
31
+ # set.must_not_be.superset_of 0
32
+ #
33
+ # # +set+ must be a superset of [1,3,5,7]. The constraint is reified with
34
+ # # the boolean operand +bool+.
35
+ # set.must_be.superset_of([1.3.5.7], :reify => bool)
36
+ def superset(constant_set, options = {})
37
+ add_domain_constraint(:superset, constant_set, options)
38
+ end
39
+
40
+ # Constrains the set operand to be a subset of +constant_set+.
41
+ #
42
+ # ==== Examples
43
+ #
44
+ # # +set+ must be a subset of [1,2,5]
45
+ # set.must_be.subset_of [1,2,5]
46
+ #
47
+ # # +set+ must be a subset of 1..67
48
+ # set.must_be.subset_of 1..67
49
+ #
50
+ # # +set+ must not be a subset of [0].
51
+ # set.must_not_be.subset_of 0
52
+ #
53
+ # # +set+ must be a subset of [1,3,5,7]. The constraint is reified with
54
+ # # the boolean operand +bool+.
55
+ # set.must_be.subset_of([1.3.5.7], :reify => bool)
56
+ def subset(constant_set, options = {})
57
+ add_domain_constraint(:subset, constant_set, options)
58
+ end
59
+
60
+ # Constrains the set operand to be disjoint with +constant_set+.
61
+ #
62
+ # ==== Examples
63
+ #
64
+ # # +set+ must be disjoint with [1,2,5]
65
+ # set.must_be.disjoint_with [1,2,5]
66
+ #
67
+ # # +set+ must be disjoint with 1..67
68
+ # set.must_be.disjoint_with 1..67
69
+ #
70
+ # # +set+ must not be disjoint with [0].
71
+ # set.must_not_be.disjoint_with 0
72
+ #
73
+ # # +set+ must be disjoint with [1,3,5,7]. The constraint is reified with
74
+ # # the boolean operand +bool+.
75
+ # set.must_be.disjoint_with([1.3.5.7], :reify => bool)
76
+ def disjoint(constant_set, options = {})
77
+ add_domain_constraint(:disjoint, constant_set, options)
78
+ end
79
+
80
+ # Constrains the set operand to be the complement of +constant_set+.
81
+ #
82
+ # ==== Examples
83
+ #
84
+ # # +set+ must be the complement of [1,2,5]
85
+ # set.must_be.complement_of [1,2,5]
86
+ #
87
+ # # +set+ must be the complement of 1..67
88
+ # set.must_be.complement_of 1..67
89
+ #
90
+ # # +set+ must not be the complement of [0].
91
+ # set.must_not_be.complement_of 0
92
+ #
93
+ # # +set+ must be the complement of [1,3,5,7]. The constraint is
94
+ # # reified with the boolean operand +bool+.
95
+ # set.must_be.complement_of([1.3.5.7], :reify => bool)
96
+ def complement(constant_set, options = {})
97
+ add_domain_constraint(:complement, constant_set, options)
98
+ end
99
+
100
+ alias_set_methods
101
+
102
+ private
103
+
104
+ # Adds a domain constraint for the specified relation name, constant set
105
+ # and options.
106
+ def add_domain_constraint(relation_name, constant_set, options)
107
+ unless Gecode::Util.constant_set? constant_set
108
+ raise TypeError, "Expected constant set, got #{constant_set.class}."
109
+ end
110
+ @params[:rhs] = constant_set
111
+ @params[:relation] = relation_name
112
+ @params.update Gecode::Set::Util.decode_options(options)
113
+ if relation_name == :==
114
+ @model.add_constraint Domain::EqualityDomainConstraint.new(@model,
115
+ @params)
116
+ else
117
+ @model.add_constraint Domain::DomainConstraint.new(@model, @params)
118
+ end
119
+ end
120
+ end
121
+
122
+ # A module that gathers the classes and modules used in domain constraints.
123
+ module Domain #:nodoc:
124
+ class EqualityDomainConstraint < Gecode::ReifiableConstraint #:nodoc:
125
+ def post
126
+ var, domain, reif_var, negate = @params.values_at(:lhs, :rhs, :reif,
127
+ :negate)
128
+ if negate
129
+ rel_type = Gecode::Util::NEGATED_SET_RELATION_TYPES[:==]
130
+ else
131
+ rel_type = Gecode::Util::SET_RELATION_TYPES[:==]
132
+ end
133
+
134
+ (params = []) << var.to_set_var.bind
135
+ params << rel_type
136
+ params << Gecode::Util.constant_set_to_params(domain)
137
+ params << reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
138
+ Gecode::Raw::dom(@model.active_space, *params.flatten)
139
+ end
140
+ end
141
+
142
+ class DomainConstraint < Gecode::ReifiableConstraint #:nodoc:
143
+ def post
144
+ var, domain, reif_var, relation = @params.values_at(:lhs, :rhs, :reif,
145
+ :relation)
146
+
147
+ (params = []) << var.to_set_var.bind
148
+ params << Gecode::Util::SET_RELATION_TYPES[relation]
149
+ params << Gecode::Util.constant_set_to_params(domain)
150
+ params << reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
151
+ Gecode::Raw::dom(@model.active_space, *params.flatten)
152
+ end
153
+ negate_using_reification
154
+ end
155
+ end
156
+ end