gecoder 0.8.3 → 0.9.0

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