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.
- data/CHANGES +137 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +58 -0
- data/Rakefile +14 -0
- data/example/equation_system.rb +15 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/money.rb +36 -0
- data/example/queens.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/send_most_money.rb +58 -0
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +106 -0
- data/example/sudoku.rb +56 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +96 -0
- data/lib/gecoder/bindings/bindings.rb +2029 -0
- data/lib/gecoder/interface.rb +9 -0
- data/lib/gecoder/interface/binding_changes.rb +9 -0
- data/lib/gecoder/interface/branch.rb +163 -0
- data/lib/gecoder/interface/constraints.rb +471 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +251 -0
- data/lib/gecoder/interface/constraints/bool/channel.rb +7 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +200 -0
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +68 -0
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +106 -0
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +55 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +155 -0
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +101 -0
- data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
- data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
- data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +150 -0
- data/lib/gecoder/interface/constraints/int/channel.rb +51 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +80 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +143 -0
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +63 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +86 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +66 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +64 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +64 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +37 -0
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +187 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +135 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +95 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +230 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
- data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +65 -0
- data/lib/gecoder/interface/constraints/set/channel.rb +51 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +130 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +156 -0
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +118 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +155 -0
- data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
- data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +45 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +43 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +69 -0
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +84 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +243 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +205 -0
- data/lib/gecoder/interface/model.rb +453 -0
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +197 -0
- data/lib/gecoder/interface/variables.rb +306 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/bool_var.rb +81 -0
- data/specs/branch.rb +185 -0
- data/specs/constraints/bool/boolean.rb +317 -0
- data/specs/constraints/bool/boolean_properties.rb +51 -0
- data/specs/constraints/bool/linear.rb +213 -0
- data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
- data/specs/constraints/bool_enum/channel.rb +102 -0
- data/specs/constraints/bool_enum/extensional.rb +225 -0
- data/specs/constraints/constraint_helper.rb +234 -0
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +26 -0
- data/specs/constraints/fixnum_enum/element.rb +58 -0
- data/specs/constraints/fixnum_enum/operation.rb +67 -0
- data/specs/constraints/int/arithmetic.rb +149 -0
- data/specs/constraints/int/channel.rb +101 -0
- data/specs/constraints/int/domain.rb +106 -0
- data/specs/constraints/int/linear.rb +183 -0
- data/specs/constraints/int/linear_properties.rb +97 -0
- data/specs/constraints/int/relation.rb +84 -0
- data/specs/constraints/int_enum/arithmetic.rb +72 -0
- data/specs/constraints/int_enum/channel.rb +57 -0
- data/specs/constraints/int_enum/count.rb +72 -0
- data/specs/constraints/int_enum/distinct.rb +80 -0
- data/specs/constraints/int_enum/element.rb +61 -0
- data/specs/constraints/int_enum/equality.rb +29 -0
- data/specs/constraints/int_enum/extensional.rb +224 -0
- data/specs/constraints/int_enum/sort.rb +167 -0
- data/specs/constraints/operands.rb +264 -0
- data/specs/constraints/property_helper.rb +443 -0
- data/specs/constraints/reification_sugar.rb +69 -0
- data/specs/constraints/selected_set/select.rb +56 -0
- data/specs/constraints/selected_set/select_properties.rb +157 -0
- data/specs/constraints/set/cardinality.rb +58 -0
- data/specs/constraints/set/cardinality_properties.rb +46 -0
- data/specs/constraints/set/channel.rb +77 -0
- data/specs/constraints/set/connection.rb +176 -0
- data/specs/constraints/set/domain.rb +197 -0
- data/specs/constraints/set/include.rb +36 -0
- data/specs/constraints/set/operation.rb +132 -0
- data/specs/constraints/set/relation.rb +117 -0
- data/specs/constraints/set_elements/relation.rb +84 -0
- data/specs/constraints/set_enum/channel.rb +80 -0
- data/specs/constraints/set_enum/distinct.rb +59 -0
- data/specs/constraints/set_enum/operation.rb +111 -0
- data/specs/constraints/set_enum/select.rb +73 -0
- data/specs/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +179 -0
- data/specs/examples.rb +17 -0
- data/specs/int_var.rb +163 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +325 -0
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +383 -0
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +82 -0
- data/specs/spec_helper.rb +265 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/dependencies.txt +22 -0
- data/tasks/distribution.rake +194 -0
- data/tasks/rcov.rake +18 -0
- data/tasks/specs.rake +21 -0
- data/tasks/svn.rake +16 -0
- data/tasks/website.rake +51 -0
- data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesupport.dll +0 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +116 -0
- data/vendor/rust/include/rust_conversions.hh +102 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +337 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +96 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +100 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +36 -0
- data/vendor/rust/test/cppclass.cc +45 -0
- data/vendor/rust/test/cppclass.hh +67 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +80 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- 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
|