gecoder 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. data/CHANGES +15 -0
  2. data/README +6 -2
  3. data/example/equation_system.rb +15 -0
  4. data/example/magic_sequence.rb +7 -7
  5. data/example/money.rb +36 -0
  6. data/example/queens.rb +7 -8
  7. data/example/send_most_money.rb +1 -1
  8. data/example/square_tiling.rb +2 -2
  9. data/example/sudoku-set.rb +11 -12
  10. data/example/sudoku.rb +40 -45
  11. data/ext/extconf.rb +0 -0
  12. data/lib/gecoder/bindings.rb +42 -0
  13. data/lib/gecoder/bindings/bindings.rb +16 -0
  14. data/lib/gecoder/interface.rb +2 -1
  15. data/lib/gecoder/interface/branch.rb +16 -9
  16. data/lib/gecoder/interface/constraints.rb +410 -451
  17. data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
  18. data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
  19. data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
  20. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
  21. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
  22. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
  23. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
  24. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
  25. data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
  26. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  27. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  28. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  29. data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
  30. data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
  31. data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
  32. data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
  33. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  34. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
  35. data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
  36. data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
  37. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
  38. data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
  39. data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
  40. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
  41. data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
  42. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
  43. data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
  44. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
  45. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  46. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  47. data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
  48. data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
  49. data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
  50. data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
  51. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  52. data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
  53. data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
  54. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  55. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  56. data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
  57. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
  58. data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
  59. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  60. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
  61. data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
  62. data/lib/gecoder/interface/enum_matrix.rb +4 -4
  63. data/lib/gecoder/interface/enum_wrapper.rb +71 -22
  64. data/lib/gecoder/interface/model.rb +167 -12
  65. data/lib/gecoder/interface/model_sugar.rb +84 -0
  66. data/lib/gecoder/interface/search.rb +30 -18
  67. data/lib/gecoder/interface/variables.rb +103 -33
  68. data/lib/gecoder/version.rb +2 -2
  69. data/specs/bool_var.rb +19 -12
  70. data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
  71. data/specs/constraints/bool/boolean_properties.rb +51 -0
  72. data/specs/constraints/bool/linear.rb +213 -0
  73. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  74. data/specs/constraints/bool_enum/channel.rb +102 -0
  75. data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
  76. data/specs/constraints/constraint_helper.rb +149 -179
  77. data/specs/constraints/constraint_receivers.rb +103 -0
  78. data/specs/constraints/constraints.rb +6 -63
  79. data/specs/constraints/fixnum_enum/element.rb +58 -0
  80. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  81. data/specs/constraints/int/arithmetic.rb +149 -0
  82. data/specs/constraints/int/channel.rb +101 -0
  83. data/specs/constraints/int/domain.rb +106 -0
  84. data/specs/constraints/int/linear.rb +183 -0
  85. data/specs/constraints/int/linear_properties.rb +97 -0
  86. data/specs/constraints/int/relation.rb +84 -0
  87. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  88. data/specs/constraints/int_enum/channel.rb +57 -0
  89. data/specs/constraints/int_enum/count.rb +72 -0
  90. data/specs/constraints/int_enum/distinct.rb +80 -0
  91. data/specs/constraints/int_enum/element.rb +61 -0
  92. data/specs/constraints/int_enum/equality.rb +29 -0
  93. data/specs/constraints/int_enum/extensional.rb +224 -0
  94. data/specs/constraints/int_enum/sort.rb +167 -0
  95. data/specs/constraints/operands.rb +264 -0
  96. data/specs/constraints/property_helper.rb +443 -0
  97. data/specs/constraints/reification_sugar.rb +4 -5
  98. data/specs/constraints/selected_set/select.rb +56 -0
  99. data/specs/constraints/selected_set/select_properties.rb +157 -0
  100. data/specs/constraints/set/cardinality.rb +58 -0
  101. data/specs/constraints/set/cardinality_properties.rb +46 -0
  102. data/specs/constraints/set/channel.rb +77 -0
  103. data/specs/constraints/set/connection.rb +176 -0
  104. data/specs/constraints/set/domain.rb +197 -0
  105. data/specs/constraints/set/include.rb +36 -0
  106. data/specs/constraints/set/operation.rb +132 -0
  107. data/specs/constraints/set/relation.rb +117 -0
  108. data/specs/constraints/set_elements/relation.rb +84 -0
  109. data/specs/constraints/set_enum/channel.rb +80 -0
  110. data/specs/constraints/set_enum/distinct.rb +59 -0
  111. data/specs/constraints/set_enum/operation.rb +111 -0
  112. data/specs/constraints/set_enum/select.rb +73 -0
  113. data/specs/enum_wrapper.rb +53 -3
  114. data/specs/int_var.rb +44 -25
  115. data/specs/model.rb +58 -1
  116. data/specs/model_sugar.rb +30 -0
  117. data/specs/search.rb +24 -5
  118. data/specs/selected_set.rb +39 -0
  119. data/specs/set_elements.rb +34 -0
  120. data/specs/set_var.rb +22 -8
  121. data/specs/spec_helper.rb +206 -6
  122. data/tasks/distribution.rake +22 -7
  123. data/tasks/svn.rake +3 -1
  124. metadata +218 -134
  125. data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
  126. data/specs/constraints/arithmetic.rb +0 -351
  127. data/specs/constraints/bool_enum_relation.rb +0 -160
  128. data/specs/constraints/cardinality.rb +0 -157
  129. data/specs/constraints/channel.rb +0 -454
  130. data/specs/constraints/connection.rb +0 -369
  131. data/specs/constraints/count.rb +0 -146
  132. data/specs/constraints/distinct.rb +0 -164
  133. data/specs/constraints/element.rb +0 -108
  134. data/specs/constraints/equality.rb +0 -31
  135. data/specs/constraints/int_domain.rb +0 -70
  136. data/specs/constraints/int_relation.rb +0 -82
  137. data/specs/constraints/linear.rb +0 -340
  138. data/specs/constraints/selection.rb +0 -292
  139. data/specs/constraints/set_domain.rb +0 -185
  140. data/specs/constraints/set_operation.rb +0 -285
  141. data/specs/constraints/set_relation.rb +0 -197
  142. data/specs/constraints/sort.rb +0 -179
@@ -1,193 +1,130 @@
1
- module Gecode
2
- class FreeSetVar
3
- # Starts a constraint on the minimum value of the set.
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
4
9
  def min
5
- params = {:lhs => self}
6
- Gecode::Constraints::Set::Connection::MinExpressionStub.new(@model, params)
10
+ Connection::SetMinOperand.new(@model, self)
7
11
  end
8
12
 
9
- # Starts a constraint on the maximum value of the set.
13
+ # Produces an IntOperand representing the maximum of the set.
14
+ #
15
+ # ==== Examples
16
+ #
17
+ # # The maximum of +set+.
18
+ # set.max
10
19
  def max
11
- params = {:lhs => self}
12
- Gecode::Constraints::Set::Connection::MaxExpressionStub.new(@model, params)
20
+ Connection::SetMaxOperand.new(@model, self)
13
21
  end
14
22
 
15
- # Starts a constraint on the sum of the set. The option :weights may
16
- # optionally be given with a hash of weights as value. If it is then the
17
- # weighted sum, using the hash as weight function, will be constrained. The
18
- # option :substitutions may also be given (with a hash as value), if it is
19
- # then the sum of the set with all elements replaced according to the hash
20
- # is constrained. Elements mapped to nil by the weights or substitutions
21
- # hash are removed from the upper bound of the set. Only one of the two
22
- # options may be given at the same time.
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})
23
44
  def sum(options = {:weights => weights = Hash.new(1)})
24
45
  if options.empty? or options.keys.size > 1
25
- raise ArgumentError, 'One of the options :weights and :substitutions, ' +
26
- 'or neither, must be specified.'
27
- end
28
- params = {:lhs => self}
29
- unless options.empty?
30
- case options.keys.first
31
- when :substitutions: params.update(options)
32
- when :weights:
33
- weights = options[:weights]
34
- substitutions = Hash.new do |hash, key|
35
- if weights[key].nil?
36
- hash[key] = nil
37
- else
38
- hash[key] = key * weights[key]
39
- end
40
- end
41
- params.update(:substitutions => substitutions)
42
- else raise ArgumentError, "Unrecognized option #{options.keys.first}."
43
- end
46
+ raise ArgumentError, 'At most one of the options :weights and ' +
47
+ ':substitutions may be specified.'
44
48
  end
45
- Gecode::Constraints::Set::Connection::SumExpressionStub.new(@model, params)
46
- end
47
- end
48
- end
49
49
 
50
- module Gecode::Constraints::Set
51
- class Expression
52
- # Adds a constraint that forces specified values to be included in the
53
- # set. This constraint has the side effect of sorting the variables in
54
- # non-descending order.
55
- def include(variables)
56
- unless variables.respond_to? :to_int_var_array
57
- raise TypeError, "Expected int var enum, got #{variables.class}."
58
- end
59
- if @params[:negate]
60
- raise Gecode::MissingConstraintError, 'A negated include is not ' +
61
- 'implemented.'
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
62
  end
63
-
64
- @params.update(:variables => variables)
65
- @model.add_constraint Connection::IncludeConstraint.new(@model, @params)
63
+ Connection::SetSumOperand.new(@model, self, subs)
66
64
  end
67
65
  end
68
-
66
+
69
67
  # A module that gathers the classes and modules used in connection
70
68
  # constraints.
71
69
  module Connection #:nodoc:
72
- # Describes a CompositeStub for the min constraint which constrains the
73
- # minimum value of a set variable.
74
- #
75
- # == Examples
76
- #
77
- # # Constrains the minimum value of +set+ to be larger than 17.
78
- # set.min.must > 17
79
- #
80
- # # Constrains the minimum value of +set+ to equal the integer variable
81
- # # +min+.
82
- # set.min.must == min
83
- #
84
- # # Constrains the minimum value of +set+ to not be larger than the
85
- # # integer variable +ceil+.
86
- # set.min.must_not > ceil
87
- #
88
- # # The same as above but reified with the boolean variable
89
- # # +is_not_above_ceiling+ and with the strength +domain+ applied.
90
- # set.min.must_not_be.larger_than(ceil, :reify => :is_not_above_ceiling,
91
- # :strength => :domain)
92
- class MinExpressionStub < Gecode::Constraints::Int::CompositeStub
93
- def constrain_equal(variable, params, constrain)
94
- set = params[:lhs]
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
95
78
  if constrain
96
- variable.must_be.in set.upper_bound.min..set.lower_bound.min
79
+ int_operand.must_be.in set.upper_bound.min..set.lower_bound.min
97
80
  end
98
81
 
99
- Gecode::Raw::min(@model.active_space, set.bind, variable.bind)
82
+ Gecode::Raw::min(@model.active_space, set.bind,
83
+ int_operand.to_int_var.bind)
100
84
  end
101
85
  end
102
86
 
103
- # Describes a CompositeStub for the max constraint which constrains the
104
- # maximum value of a set variable.
105
- #
106
- # == Examples
107
- #
108
- # # Constrains the maximum value of +set+ to be larger than 17.
109
- # set.max.must > 17
110
- #
111
- # # Constrains the maximum value of +set+ to equal the integer variable
112
- # # +max+.
113
- # set.max.must == max
114
- #
115
- # # Constrains the maximum value of +set+ to not be less than the
116
- # # integer variable +floor+.
117
- # set.max.must_not < floor
118
- #
119
- # # The same as above but reified with the boolean variable
120
- # # +is_not_below_floor+ and with the strength +domain+ applied.
121
- # set.max.must_not_be.less_than(ceil, :reify => :is_not_below_floor,
122
- # :strength => :domain)
123
- class MaxExpressionStub < Gecode::Constraints::Int::CompositeStub
124
- def constrain_equal(variable, params, constrain)
125
- set = params[:lhs]
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
126
95
  if constrain
127
- variable.must_be.in set.lower_bound.max..set.upper_bound.max
96
+ int_operand.must_be.in set.upper_bound.min..set.lower_bound.min
128
97
  end
129
98
 
130
- Gecode::Raw::max(@model.active_space, set.bind, variable.bind)
99
+ Gecode::Raw::max(@model.active_space, set.bind,
100
+ int_operand.to_int_var.bind)
131
101
  end
132
102
  end
133
103
 
134
- # Describes a CompositeStub for the sum constraint which constrains the
135
- # sum of all values in a set variable.
136
- #
137
- # == Examples
138
- #
139
- # # Constrains the sum of all values in +set+ to be larger than 17.
140
- # set.sum.must > 17
141
- #
142
- # # Constrains the sum of all values in +set+ to equal the integer
143
- # # variable +sum+.
144
- # set.sum.must == sum
145
- #
146
- # # Constrains the sum of all values in +set+ to not be larger than the
147
- # # integer variable +resources+.
148
- # set.sum.must_not > resources
149
- #
150
- # # The same as above but reified with the boolean variable
151
- # # +not_over_budget+ and with the strength +domain+ applied.
152
- # set.sum.must_not_be.larger_than(resources, :reify => :not_over_budget,
153
- # :strength => :domain)
154
- class SumExpressionStub < Gecode::Constraints::Int::CompositeStub
155
- def constrain_equal(variable, params, constrain)
156
- set, subs = params.values_at(:lhs, :substitutions)
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
157
113
  lub = set.upper_bound.to_a
158
- lub.delete_if{ |e| subs[e].nil? }
159
- substituted_lub = lub.map{ |e| subs[e] }
114
+ lub.delete_if{ |e| @subs[e].nil? }
115
+ substituted_lub = lub.map{ |e| @subs[e] }
160
116
  if constrain
161
117
  # Compute the theoretical bounds of the weighted sum. This is slightly
162
118
  # sloppy since we could also use the contents of the greatest lower
163
119
  # bound.
164
120
  min = substituted_lub.find_all{ |e| e < 0}.inject(0){ |x, y| x + y }
165
121
  max = substituted_lub.find_all{ |e| e > 0}.inject(0){ |x, y| x + y }
166
- variable.must_be.in min..max
122
+ int_operand.must_be.in min..max
167
123
  end
168
124
 
169
125
  Gecode::Raw::weights(@model.active_space, lub, substituted_lub,
170
- set.bind, variable.bind)
171
- end
172
- end
173
-
174
- # Describes an include constraint, which constrains the set to include the
175
- # values of the specified enumeration of integer variables.
176
- #
177
- # The constraint has the side effect of sorting the integer variables in a
178
- # non-descending order. It does not support reification nor negation.
179
- #
180
- # == Examples
181
- #
182
- # # Constrain +set+ to include the values of all variables in
183
- # # +int_enum+.
184
- # set.must.include int_enum
185
- class IncludeConstraint < Gecode::Constraints::Constraint
186
- def post
187
- set, variables = @params.values_at(:lhs, :variables)
188
- Gecode::Raw::match(@model.active_space, set.bind,
189
- variables.to_int_var_array)
126
+ set.bind, int_operand.to_int_var.bind)
190
127
  end
191
128
  end
192
129
  end
193
- end
130
+ end
@@ -1,13 +1,102 @@
1
- module Gecode::Constraints::Set
2
- class Expression
3
- Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |name, type|
4
- module_eval <<-"end_code"
5
- # Creates a domain constraint using the specified constant set.
6
- def #{name}(constant_set, options = {})
7
- add_domain_constraint(:#{name}, constant_set, options)
8
- end
9
- end_code
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)
10
98
  end
99
+
11
100
  alias_set_methods
12
101
 
13
102
  private
@@ -15,12 +104,12 @@ module Gecode::Constraints::Set
15
104
  # Adds a domain constraint for the specified relation name, constant set
16
105
  # and options.
17
106
  def add_domain_constraint(relation_name, constant_set, options)
18
- unless Gecode::Constraints::Util.constant_set? constant_set
107
+ unless Gecode::Util.constant_set? constant_set
19
108
  raise TypeError, "Expected constant set, got #{constant_set.class}."
20
109
  end
21
110
  @params[:rhs] = constant_set
22
111
  @params[:relation] = relation_name
23
- @params.update Gecode::Constraints::Set::Util.decode_options(options)
112
+ @params.update Gecode::Set::Util.decode_options(options)
24
113
  if relation_name == :==
25
114
  @model.add_constraint Domain::EqualityDomainConstraint.new(@model,
26
115
  @params)
@@ -32,78 +121,36 @@ module Gecode::Constraints::Set
32
121
 
33
122
  # A module that gathers the classes and modules used in domain constraints.
34
123
  module Domain #:nodoc:
35
- # Describes a domain constraint which constrains a set to be equal to a
36
- # constant set.
37
- #
38
- # == Examples
39
- #
40
- # # +set+ must equal [1,2,5]
41
- # set.must == [1,2,5]
42
- #
43
- # # +set+ must not equal 1..67
44
- # set.must_not == 1..67
45
- #
46
- # # +set+ must equal the singleton set 0. The constraint is reified with
47
- # # the boolean varaible +is_singleton_zero+.
48
- # set.must.equal(0, :reify => is_singleton_zero)
49
- class EqualityDomainConstraint < Gecode::Constraints::ReifiableConstraint
124
+ class EqualityDomainConstraint < Gecode::ReifiableConstraint #:nodoc:
50
125
  def post
51
126
  var, domain, reif_var, negate = @params.values_at(:lhs, :rhs, :reif,
52
127
  :negate)
53
128
  if negate
54
- rel_type = Gecode::Constraints::Util::NEGATED_SET_RELATION_TYPES[:==]
129
+ rel_type = Gecode::Util::NEGATED_SET_RELATION_TYPES[:==]
55
130
  else
56
- rel_type = Gecode::Constraints::Util::SET_RELATION_TYPES[:==]
131
+ rel_type = Gecode::Util::SET_RELATION_TYPES[:==]
57
132
  end
58
133
 
59
- (params = []) << var.bind
134
+ (params = []) << var.to_set_var.bind
60
135
  params << rel_type
61
- params << Gecode::Constraints::Util.constant_set_to_params(domain)
62
- params << reif_var.bind if reif_var.respond_to? :bind
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
63
138
  Gecode::Raw::dom(@model.active_space, *params.flatten)
64
139
  end
65
140
  end
66
141
 
67
- # Describes a domain constraint which constrains a set to have a specific
68
- # relation to a constant set. A constant set may be specified in three ways
69
- #
70
- # [Fixnum] Represents a singleton set.
71
- # [Range] Represents a set containing all elements in the
72
- # range. This represents the set more efficiently
73
- # than when another enumeration with the same
74
- # elements are used.
75
- # [Enumeration of Fixnum] Represents a set containing the enumeration’s
76
- # elements.
77
- #
78
- # The relations allowed are the same as in
79
- # <tt>Set::Relation::RelationConstraint</tt>.
80
- #
81
- # == Examples
82
- #
83
- # # +set+ must be subset of [1,2,5]
84
- # set.must_be.subset_of [1,2,5]
85
- #
86
- # # +set+ must be disjoint with 1..67
87
- # set.must_be.disjoint_with 1..67
88
- #
89
- # # +set+ must not be a superset of [0].
90
- # set.must_not_be.superset_of 0
91
- #
92
- # # +set+ must be subset of [1,3,5,7]. The constraint is reified with
93
- # # the boolean varaible +only_constains_odd_values+.
94
- # set.must_be.subset_of([1.3.5.7], :reify => only_contains_odd_values)
95
- class DomainConstraint < Gecode::Constraints::ReifiableConstraint
142
+ class DomainConstraint < Gecode::ReifiableConstraint #:nodoc:
96
143
  def post
97
144
  var, domain, reif_var, relation = @params.values_at(:lhs, :rhs, :reif,
98
145
  :relation)
99
146
 
100
- (params = []) << var.bind
101
- params << Gecode::Constraints::Util::SET_RELATION_TYPES[relation]
102
- params << Gecode::Constraints::Util.constant_set_to_params(domain)
103
- params << reif_var.bind if reif_var.respond_to? :bind
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
104
151
  Gecode::Raw::dom(@model.active_space, *params.flatten)
105
152
  end
106
153
  negate_using_reification
107
154
  end
108
155
  end
109
- end
156
+ end