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,45 @@
|
|
1
|
+
module Gecode::SetEnum
|
2
|
+
class SetEnumConstraintReceiver
|
3
|
+
# Constrains this set enum to channel +int_enum_operand+. The i:th set
|
4
|
+
# in the enumeration of set operands is constrained to includes the value
|
5
|
+
# of the j:th integer operand.
|
6
|
+
#
|
7
|
+
# Neither reification nor negation is supported.
|
8
|
+
#
|
9
|
+
# ==== Examples
|
10
|
+
#
|
11
|
+
# # +set_enum+ is constrained to channel +int_enum+.
|
12
|
+
# int_enum.must.channel set_enum
|
13
|
+
#
|
14
|
+
# # This is another way of writing the above.
|
15
|
+
# set_enum.must.channel int_enum
|
16
|
+
def channel(enum, options = {})
|
17
|
+
unless enum.respond_to? :to_int_enum
|
18
|
+
raise TypeError, "Expected integer enum, for #{enum.class}."
|
19
|
+
end
|
20
|
+
if @params[:negate]
|
21
|
+
raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
|
22
|
+
'is not implemented.'
|
23
|
+
end
|
24
|
+
if options.has_key? :reify
|
25
|
+
raise ArgumentError, 'The channel constraints does not support the ' +
|
26
|
+
'reification option.'
|
27
|
+
end
|
28
|
+
|
29
|
+
@params.update(Gecode::Set::Util.decode_options(options))
|
30
|
+
@params.update(:rhs => enum)
|
31
|
+
@model.add_constraint Channel::IntEnumChannelConstraint.new(@model, @params)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# A module that gathers the classes and modules used in channel constraints.
|
36
|
+
module Channel #:nodoc:
|
37
|
+
class IntEnumChannelConstraint < Gecode::Constraint #:nodoc:
|
38
|
+
def post
|
39
|
+
lhs, rhs = @params.values_at(:lhs, :rhs)
|
40
|
+
Gecode::Raw::channel(@model.active_space, rhs.to_int_enum.bind_array,
|
41
|
+
lhs.to_set_enum.bind_array)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Gecode::SetEnum
|
2
|
+
class SetEnumConstraintReceiver
|
3
|
+
# Constrains all pairs of set operands in the enumeration to at
|
4
|
+
# most have one element in common and be of a specified size.
|
5
|
+
# Providing a size is not optional.
|
6
|
+
#
|
7
|
+
# Neither negation nor reification is supported.
|
8
|
+
#
|
9
|
+
# ==== Examples
|
10
|
+
#
|
11
|
+
# # All set operands in +sets+ must have cardinality 17 and no pair may
|
12
|
+
# # have more than one element in common.
|
13
|
+
# sets.must.at_most_share_one_element(:size => 17)
|
14
|
+
def at_most_share_one_element(options = {})
|
15
|
+
unless options.has_key? :size
|
16
|
+
raise ArgumentError, 'Option :size has to be specified.'
|
17
|
+
end
|
18
|
+
# TODO can we use Set::Util::decode_options here instead?
|
19
|
+
unless options.size == 1
|
20
|
+
raise ArgumentError, 'Only the option :size is accepted, got ' +
|
21
|
+
"#{options.keys.join(', ')}."
|
22
|
+
end
|
23
|
+
if @params[:negate]
|
24
|
+
raise Gecode::MissingConstraintError, 'A negated atmost one ' +
|
25
|
+
'constrain is not implemented.'
|
26
|
+
end
|
27
|
+
|
28
|
+
@model.add_constraint Distinct::AtMostOneConstraint.new(
|
29
|
+
@model, @params.update(options))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# A module that gathers the classes and modules used in distinct constraints.
|
34
|
+
module Distinct #:nodoc:
|
35
|
+
class AtMostOneConstraint < Gecode::Constraint #:nodoc:
|
36
|
+
def post
|
37
|
+
sets, size = @params.values_at(:lhs, :size)
|
38
|
+
Gecode::Raw::atmostOne(@model.active_space,
|
39
|
+
sets.to_set_enum.bind_array, size)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Gecode::SetEnum
|
2
|
+
module SetEnumOperand
|
3
|
+
# Produces a SetOperand representing the union of all sets in this
|
4
|
+
# enumeration.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # The union of all sets in +set_enum+.
|
9
|
+
# set_enum.union
|
10
|
+
def union
|
11
|
+
set_operation(:union)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Produces a SetOperand representing the intersection of all sets in this
|
15
|
+
# enumeration.
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# # The intersection of all sets in +set_enum+.
|
20
|
+
# set_enum.intersection
|
21
|
+
def intersection
|
22
|
+
set_operation(:intersection)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Produces a SetOperand representing the disjoint union of all sets
|
26
|
+
# in this enumeration.
|
27
|
+
#
|
28
|
+
# ==== Examples
|
29
|
+
#
|
30
|
+
# # The disjoint union of all sets in +set_enum+.
|
31
|
+
# set_enum.disjoint_union
|
32
|
+
def disjoint_union
|
33
|
+
set_operation(:disjoint_union)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Produces the SetOperand resulting from +operator+ applied to this
|
39
|
+
# operand.
|
40
|
+
def set_operation(operator)
|
41
|
+
Operation::OperationSetOperand.new(model, self, operator)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# A module that gathers the classes and modules used in operation constraints.
|
46
|
+
module Operation #:nodoc:
|
47
|
+
class OperationSetOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
|
48
|
+
def initialize(model, enum, operator)
|
49
|
+
super model
|
50
|
+
@enum = enum
|
51
|
+
@operator = operator
|
52
|
+
end
|
53
|
+
|
54
|
+
def constrain_equal(set_operand, constrain_domain, propagation_options)
|
55
|
+
operation = Gecode::Util::SET_OPERATION_TYPES[@operator]
|
56
|
+
if constrain_domain
|
57
|
+
if operation == Gecode::Raw::SOT_INTER
|
58
|
+
set_operand.must_be.subset_of @enum.first.upper_bound
|
59
|
+
else
|
60
|
+
set_operand.must_be.subset_of @enum.upper_bound_range
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
Gecode::Raw::rel(@model.active_space, operation,
|
65
|
+
@enum.to_set_enum.bind_array, set_operand.to_set_var.bind)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Gecode::SetEnum
|
2
|
+
module SetEnumOperand
|
3
|
+
# This adds the adder for the methods in the modules including it. The
|
4
|
+
# reason for doing it so indirect is that the first #[] won't be defined
|
5
|
+
# before the module that this is mixed into is mixed into an enum.
|
6
|
+
def self.included(mod) #:nodoc:
|
7
|
+
mod.module_eval do
|
8
|
+
# Now we enter the module SetEnumOperands is mixed into.
|
9
|
+
class << self
|
10
|
+
alias_method :pre_selection_included, :included
|
11
|
+
def included(mod) #:nodoc:
|
12
|
+
mod.module_eval do
|
13
|
+
# Now we enter the module that the module possibly defining #[]
|
14
|
+
# is mixed into.
|
15
|
+
if instance_methods.include?('[]') and
|
16
|
+
not instance_methods.include?('pre_selection_access')
|
17
|
+
alias_method :pre_selection_access, :[]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Produces a SetOperand representing the i:th set
|
21
|
+
# operand in the enumeration, where i is the value of the
|
22
|
+
# int operand used as index.
|
23
|
+
#
|
24
|
+
# A set can also be used as index, in which case a
|
25
|
+
# SelectedSetOperand is produced.
|
26
|
+
#
|
27
|
+
# ==== Examples
|
28
|
+
#
|
29
|
+
# # The set operand at the +x+:th position in +set_enum+,
|
30
|
+
# # where +x+ is a int operand.
|
31
|
+
# set_enum[x]
|
32
|
+
#
|
33
|
+
# # The SelectedSetOperand representing sets at positions
|
34
|
+
# # included in the value of +set+ in +set_enum+,
|
35
|
+
# set_enum[set]
|
36
|
+
#
|
37
|
+
def [](*vars)
|
38
|
+
# Hook in an element constraint if a operand is used for array
|
39
|
+
# access.
|
40
|
+
if vars.first.respond_to? :to_int_var
|
41
|
+
Select::SelectSetOperand.new(
|
42
|
+
model, self, vars.first)
|
43
|
+
elsif vars.first.respond_to? :to_set_var
|
44
|
+
Gecode::SelectedSet::SelectedSetOperand.new(
|
45
|
+
self, vars.first)
|
46
|
+
else
|
47
|
+
if respond_to? :pre_selection_access
|
48
|
+
pre_selection_access(*vars)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
pre_selection_included(mod)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module Select #:nodoc:
|
61
|
+
class SelectSetOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
|
62
|
+
def initialize(model, enum_op, position_int_op)
|
63
|
+
super model
|
64
|
+
@enum = enum_op
|
65
|
+
@position = position_int_op
|
66
|
+
end
|
67
|
+
|
68
|
+
def constrain_equal(set_operand, constrain, propagation_options)
|
69
|
+
enum = @enum.to_set_enum
|
70
|
+
if constrain
|
71
|
+
set_operand.must_be.subset_of enum.upper_bound_range
|
72
|
+
end
|
73
|
+
|
74
|
+
Gecode::Raw::selectSet(@model.active_space, enum.bind_array,
|
75
|
+
@position.to_int_var.bind, set_operand.to_set_var.bind)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# A module containing constraints that have enumerations of set operands as
|
2
|
+
# left hand side.
|
3
|
+
module Gecode::SetEnum #:nodoc:
|
4
|
+
# A SetEnumOperand is a enumeration of SetOperand on which the
|
5
|
+
# constraints defined in SetEnumConstraintReceiver can be placed.
|
6
|
+
#
|
7
|
+
# Enumerations of set operands can be created either by using
|
8
|
+
# Gecode::Model#set_var_array and Gecode::Model#set_var_matrix, or
|
9
|
+
# by wrapping an existing enumeration containing SetOperand using
|
10
|
+
# Gecode::Model#wrap_enum. The enumerations, no matter how they were
|
11
|
+
# created, all respond to the properties defined by SetEnumOperand.
|
12
|
+
#
|
13
|
+
# ==== Examples
|
14
|
+
#
|
15
|
+
# Produces an array of five set operands, with greatest lower bound
|
16
|
+
# {0} and least upper bound {0, 1, 2}, inside a problem formulation
|
17
|
+
# using Gecode::Model#set_var_array:
|
18
|
+
#
|
19
|
+
# set_enum = set_var_array(5, 0, 1..2)
|
20
|
+
#
|
21
|
+
# Uses Gecode::Model#wrap_enum inside a problem formulation to create
|
22
|
+
# a SetEnumOperand from an existing enumeration containing the
|
23
|
+
# set operands +set_operand1+ and +set_operand2+:
|
24
|
+
#
|
25
|
+
# set_enum = wrap_enum([set_operand1, set_operand2])
|
26
|
+
#
|
27
|
+
#--
|
28
|
+
# Classes that mix in SetEnumOperand must define #model and
|
29
|
+
# #to_set_enum .
|
30
|
+
module SetEnumOperand
|
31
|
+
include Gecode::Operand
|
32
|
+
|
33
|
+
def method_missing(method, *args) #:nodoc:
|
34
|
+
if Gecode::SetEnum::Dummy.instance_methods.include? method.to_s
|
35
|
+
# Delegate to the set enum.
|
36
|
+
to_set_enum.method(method).call(*args)
|
37
|
+
else
|
38
|
+
super
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def construct_receiver(params)
|
45
|
+
Gecode::SetEnum::SetEnumConstraintReceiver.new(@model, params)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# SetEnumConstraintReceiver contains all constraints that can be
|
50
|
+
# placed on a SetEnumOperand.
|
51
|
+
#
|
52
|
+
# Constraints are placed by calling SetEnumOperand#must (or any other
|
53
|
+
# of the variations defined in Operand), which produces a
|
54
|
+
# SetEnumConstraintReceiver from which the desired constraint can be used.
|
55
|
+
#
|
56
|
+
# ==== Examples
|
57
|
+
#
|
58
|
+
# Constrains +set_enum+ to channel +int_enum+ by using
|
59
|
+
# SetEnumConstraintReceiver#channel:
|
60
|
+
#
|
61
|
+
# set_enum.must.channel set_enum
|
62
|
+
#
|
63
|
+
# Constrains each pair of set operands in +set_enum+ to at most share
|
64
|
+
# one element. Also constrains each set to have size 17. Uses
|
65
|
+
# SetEnumConstraintReceiver#at_most_share_one_element.
|
66
|
+
#
|
67
|
+
# set_enum.must.at_most_share_one_element(:size => 17)
|
68
|
+
#
|
69
|
+
class SetEnumConstraintReceiver < Gecode::ConstraintReceiver
|
70
|
+
# Raises TypeError unless the left hand side is a set enum operand.
|
71
|
+
def initialize(model, params) #:nodoc:
|
72
|
+
super
|
73
|
+
|
74
|
+
unless params[:lhs].respond_to? :to_set_enum
|
75
|
+
raise TypeError, 'Must have set enum operand as left hand side.'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
require 'gecoder/interface/constraints/set_enum/channel'
|
82
|
+
require 'gecoder/interface/constraints/set_enum/distinct'
|
83
|
+
require 'gecoder/interface/constraints/set_enum/select'
|
84
|
+
require 'gecoder/interface/constraints/set_enum/operation'
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# A module containing constraints that have set operands as left hand side
|
2
|
+
# (but not enumerations).
|
3
|
+
module Gecode::Set #:nodoc:
|
4
|
+
# A SetOperand is a combination of operands on which the
|
5
|
+
# constraints defined in SetConstraintReceiver can be placed.
|
6
|
+
#
|
7
|
+
# Set operands can be created either by using Gecode::Model#set_var et
|
8
|
+
# al, or by using properties that produce set operands. The operands,
|
9
|
+
# no matter how they were created, all respond to the properties
|
10
|
+
# defined by SetOperand.
|
11
|
+
#
|
12
|
+
# ==== Examples
|
13
|
+
#
|
14
|
+
# Produces a single set operand (more specifically a SetVar), with
|
15
|
+
# greatest lower bound {0} and least upper bound {0, 1, 2}, inside a
|
16
|
+
# problem formulation, using Gecode::Model#set_var:
|
17
|
+
#
|
18
|
+
# set_operand = set_var(0, 0..2)
|
19
|
+
#
|
20
|
+
# Uses the SetOperand#union property to produce a new set operand
|
21
|
+
# representing the union between +set_operand1+ and +set_operand2+:
|
22
|
+
#
|
23
|
+
# new_set_operand = set_operand1.union(set_operand2)
|
24
|
+
#
|
25
|
+
# Uses the SetEnumOperand#union property to produce a new set operand
|
26
|
+
# representing the union of the set operands in the enumeration
|
27
|
+
# +set_enum+:
|
28
|
+
#
|
29
|
+
# new_set_operand = set_enum.union
|
30
|
+
#
|
31
|
+
# Uses the SetEnumOperand#[] property to produce a new set operand
|
32
|
+
# representing the set operand at the index decided by
|
33
|
+
# +int_operand+ (which can change during search) in the enumeration
|
34
|
+
# +set_enum+:
|
35
|
+
#
|
36
|
+
# new_set_operand = set_enum[int_operand]
|
37
|
+
#
|
38
|
+
#--
|
39
|
+
# Classes that mix in SetOperand must define #model and #to_set_var .
|
40
|
+
module SetOperand
|
41
|
+
include Gecode::Operand
|
42
|
+
|
43
|
+
def method_missing(method, *args) #:nodoc:
|
44
|
+
if Gecode::SetVar.instance_methods.include? method.to_s
|
45
|
+
# Delegate to the set var.
|
46
|
+
to_set_var.method(method).call(*args)
|
47
|
+
else
|
48
|
+
super
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def construct_receiver(params)
|
55
|
+
SetConstraintReceiver.new(model, params)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# An operand that short circuits set equality.
|
60
|
+
class ShortCircuitEqualityOperand #:nodoc:
|
61
|
+
include Gecode::Set::SetOperand
|
62
|
+
attr :model
|
63
|
+
|
64
|
+
def initialize(model)
|
65
|
+
@model = model
|
66
|
+
end
|
67
|
+
|
68
|
+
def construct_receiver(params)
|
69
|
+
params.update(:lhs => self)
|
70
|
+
receiver = SetConstraintReceiver.new(@model, params)
|
71
|
+
op = self
|
72
|
+
receiver.instance_eval{ @short_circuit = op }
|
73
|
+
class <<receiver
|
74
|
+
alias_method :equality_without_short_circuit, :==
|
75
|
+
def ==(operand, options = {})
|
76
|
+
if !@params[:negate] and !options.has_key?(:reify) and
|
77
|
+
operand.respond_to? :to_set_var
|
78
|
+
# Short circuit the constraint.
|
79
|
+
@params.update Gecode::Util.decode_options(options)
|
80
|
+
@model.add_constraint(Gecode::BlockConstraint.new(
|
81
|
+
@model, @params) do
|
82
|
+
@short_circuit.constrain_equal(operand, false,
|
83
|
+
@params.values_at(:strength, :kind))
|
84
|
+
end)
|
85
|
+
else
|
86
|
+
equality_without_short_circuit(operand, options)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
alias_comparison_methods
|
90
|
+
end
|
91
|
+
|
92
|
+
return receiver
|
93
|
+
end
|
94
|
+
|
95
|
+
def to_set_var
|
96
|
+
variable = model.set_var
|
97
|
+
options =
|
98
|
+
Gecode::Set::Util.decode_options(
|
99
|
+
{}).values_at(:strength, :kind)
|
100
|
+
model.add_interaction do
|
101
|
+
constrain_equal(variable, true, options)
|
102
|
+
end
|
103
|
+
return variable
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# Constrains this operand to equal +set_operand+ using the
|
109
|
+
# specified +propagation_options+. If +constrain_domain+ is true
|
110
|
+
# then the method should also attempt to constrain the bounds of the
|
111
|
+
# domain of +set_operand+.
|
112
|
+
def constrain_equal(set_operand, constrain_domain, propagation_options)
|
113
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# An operand that short circuits set non-negated and non-reified versions
|
118
|
+
# of the relation constraints.
|
119
|
+
class ShortCircuitRelationsOperand #:nodoc:
|
120
|
+
include Gecode::Set::SetOperand
|
121
|
+
attr :model
|
122
|
+
|
123
|
+
def initialize(model)
|
124
|
+
@model = model
|
125
|
+
end
|
126
|
+
|
127
|
+
def construct_receiver(params)
|
128
|
+
params.update(:lhs => self)
|
129
|
+
receiver = SetConstraintReceiver.new(@model, params)
|
130
|
+
op = self
|
131
|
+
receiver.instance_eval{ @short_circuit = op }
|
132
|
+
class <<receiver
|
133
|
+
Gecode::Util::SET_RELATION_TYPES.keys.each do |comp|
|
134
|
+
eval <<-end_code
|
135
|
+
alias_method :alias_#{comp.to_i}_without_short_circuit, :#{comp}
|
136
|
+
def #{comp}(operand, options = {})
|
137
|
+
if !@params[:negate] && !options.has_key?(:reify) &&
|
138
|
+
(operand.respond_to?(:to_set_var) or
|
139
|
+
Gecode::Util::constant_set?(operand))
|
140
|
+
# Short circuit the constraint.
|
141
|
+
@params.update Gecode::Set::Util.decode_options(options)
|
142
|
+
@model.add_constraint(
|
143
|
+
@short_circuit.relation_constraint(
|
144
|
+
:#{comp}, operand, @params))
|
145
|
+
else
|
146
|
+
alias_#{comp.to_i}_without_short_circuit(operand, options)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end_code
|
150
|
+
end
|
151
|
+
alias_comparison_methods
|
152
|
+
end
|
153
|
+
|
154
|
+
return receiver
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_set_var
|
158
|
+
variable = model.set_var
|
159
|
+
params = {:lhs => self}
|
160
|
+
params.update Gecode::Set::Util.decode_options({})
|
161
|
+
model.add_constraint relation_constraint(:==, variable, params)
|
162
|
+
return variable
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns a constraint that constrains this operand to have relation
|
166
|
+
# +relation+ to +set_operand_or_constant_set+, which is either a set
|
167
|
+
# operand or a constant set, given the specified hash +params+ of
|
168
|
+
# parameters. The constraints are never negated nor reified.
|
169
|
+
def relation_constraint(relation, set_operand_or_constant_set, params)
|
170
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# SetConstraintReceiver contains all constraints that can be
|
175
|
+
# placed on a SetOperand.
|
176
|
+
#
|
177
|
+
# Constraints are placed by calling SetOperand#must (or any other
|
178
|
+
# of the variations defined in Operand), which produces a
|
179
|
+
# SetConstraintReceiver from which the desired constraint can be used.
|
180
|
+
#
|
181
|
+
# Most constraint accept :reify option. See ConstraintReceiver for
|
182
|
+
# more information.
|
183
|
+
#
|
184
|
+
# ==== Examples
|
185
|
+
#
|
186
|
+
# Constrains +set_operand+ to be a subset of {0, 1, 2} using
|
187
|
+
# an alias of SetConstraintReceiver#subset:
|
188
|
+
#
|
189
|
+
# set_operand.must_be.subset_of 0..2
|
190
|
+
#
|
191
|
+
# Constrains the union of +set_operand1+ and +set_operand2+ to a
|
192
|
+
# subset of {0, 1, 2} using the SetOperand#union property and
|
193
|
+
# SetConstraintReceiver#subset:
|
194
|
+
#
|
195
|
+
# set_operand1.union(set_operand2).must_be.subset_of 0..2
|
196
|
+
#
|
197
|
+
# Constrains the union of the set operands in +set_enum+ to _not_
|
198
|
+
# equal {0, 1, 2} by using the SetEnumOperand#union property and
|
199
|
+
# an alias of SetConstraintReceiver#==:
|
200
|
+
#
|
201
|
+
# set_enum.union.must_not == 0..2
|
202
|
+
#
|
203
|
+
# The same as above, but alsa specifying that the constraint should be
|
204
|
+
# reified with +bool_operand+:
|
205
|
+
#
|
206
|
+
# set_enum.union.must_not.equal(0..2, :reify => bool_operand)
|
207
|
+
#
|
208
|
+
class SetConstraintReceiver < Gecode::ConstraintReceiver
|
209
|
+
# Raises TypeError unless the left hand side is a set operand.
|
210
|
+
def initialize(model, params) #:nodoc:
|
211
|
+
super
|
212
|
+
|
213
|
+
unless params[:lhs].respond_to? :to_set_var
|
214
|
+
raise TypeError, 'Must have set operand as left hand side.'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Utility methods for sets.
|
220
|
+
module Util #:nodoc:
|
221
|
+
module_function
|
222
|
+
def decode_options(options)
|
223
|
+
if options.has_key? :strength
|
224
|
+
raise ArgumentError, 'Set constraints do not support the strength ' +
|
225
|
+
'option.'
|
226
|
+
end
|
227
|
+
if options.has_key? :kind
|
228
|
+
raise ArgumentError, 'Set constraints do not support the kind ' +
|
229
|
+
'option.'
|
230
|
+
end
|
231
|
+
|
232
|
+
Gecode::Util.decode_options(options)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
require 'gecoder/interface/constraints/set/domain'
|
238
|
+
require 'gecoder/interface/constraints/set/relation'
|
239
|
+
require 'gecoder/interface/constraints/set/cardinality'
|
240
|
+
require 'gecoder/interface/constraints/set/connection'
|
241
|
+
require 'gecoder/interface/constraints/set/include'
|
242
|
+
require 'gecoder/interface/constraints/set/operation'
|
243
|
+
require 'gecoder/interface/constraints/set/channel'
|