gecoder-with-gecode 0.9.0-x86-mswin32-60
Sign up to get free protection for your applications and to get access to all the features.
- 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
|