gecoder-with-gecode 0.7.1-mswin32
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 +81 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +45 -0
- data/Rakefile +13 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/queens.rb +43 -0
- data/example/raw_bindings.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 +110 -0
- data/example/sudoku.rb +61 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +54 -0
- data/lib/gecoder/bindings/bindings.rb +2210 -0
- data/lib/gecoder/interface.rb +8 -0
- data/lib/gecoder/interface/binding_changes.rb +313 -0
- data/lib/gecoder/interface/branch.rb +152 -0
- data/lib/gecoder/interface/constraints.rb +397 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +153 -0
- data/lib/gecoder/interface/model.rb +251 -0
- data/lib/gecoder/interface/search.rb +123 -0
- data/lib/gecoder/interface/variables.rb +254 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/binding_changes.rb +76 -0
- data/specs/bool_var.rb +74 -0
- data/specs/branch.rb +170 -0
- data/specs/constraints/arithmetic.rb +266 -0
- data/specs/constraints/bool_enum.rb +140 -0
- data/specs/constraints/boolean.rb +232 -0
- data/specs/constraints/cardinality.rb +154 -0
- data/specs/constraints/channel.rb +126 -0
- data/specs/constraints/connection.rb +373 -0
- data/specs/constraints/constraint_helper.rb +180 -0
- data/specs/constraints/constraints.rb +74 -0
- data/specs/constraints/count.rb +139 -0
- data/specs/constraints/distinct.rb +218 -0
- data/specs/constraints/element.rb +106 -0
- data/specs/constraints/equality.rb +31 -0
- data/specs/constraints/int_domain.rb +69 -0
- data/specs/constraints/int_relation.rb +78 -0
- data/specs/constraints/linear.rb +332 -0
- data/specs/constraints/reification_sugar.rb +96 -0
- data/specs/constraints/selection.rb +292 -0
- data/specs/constraints/set_domain.rb +181 -0
- data/specs/constraints/set_operation.rb +285 -0
- data/specs/constraints/set_relation.rb +201 -0
- data/specs/constraints/sort.rb +175 -0
- data/specs/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +122 -0
- data/specs/int_var.rb +144 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +190 -0
- data/specs/search.rb +246 -0
- data/specs/set_var.rb +68 -0
- data/specs/spec_helper.rb +93 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/building.howto +65 -0
- data/tasks/distribution.rake +156 -0
- data/tasks/rcov.rake +17 -0
- data/tasks/specs.rake +15 -0
- data/tasks/svn.rake +11 -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/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +115 -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 +339 -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 +98 -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 +91 -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 +293 -0
@@ -0,0 +1,126 @@
|
|
1
|
+
module Gecode::Constraints::IntEnum
|
2
|
+
class Expression
|
3
|
+
# Initiates a sort constraint. Beyond the common options the sort constraint
|
4
|
+
# can also take the following options:
|
5
|
+
#
|
6
|
+
# [:as] Defines a target (must be an int variable enumerable) that will
|
7
|
+
# hold the sorted version of the original enumerable. The original
|
8
|
+
# enumerable will not be affected (i.e. will not necessarily be
|
9
|
+
# sorted)
|
10
|
+
# [:order] Sets an int variable enumerable that should be used to store the
|
11
|
+
# order of the original enum's variables when sorted. The original
|
12
|
+
# enumerable will not be affected (i.e. will not necessarily be
|
13
|
+
# sorted)
|
14
|
+
#
|
15
|
+
# If neither of those options are specified then the original enumerable
|
16
|
+
# will be constrained to be sorted (otherwise not). Sort constraints with
|
17
|
+
# options do not allow negation.
|
18
|
+
def sorted(options = {})
|
19
|
+
# Extract and check options.
|
20
|
+
target = options.delete(:as)
|
21
|
+
order = options.delete(:order)
|
22
|
+
unless target.nil? or target.respond_to? :to_int_var_array
|
23
|
+
raise TypeError, 'Expected int var enum as :as, got ' +
|
24
|
+
"#{target.class}."
|
25
|
+
end
|
26
|
+
unless order.nil? or order.respond_to? :to_int_var_array
|
27
|
+
raise TypeError, 'Expected int var enum as :order, got ' +
|
28
|
+
"#{order.class}."
|
29
|
+
end
|
30
|
+
|
31
|
+
# Extract standard options and convert to constraint.
|
32
|
+
@params.update(Gecode::Constraints::Util.decode_options(options))
|
33
|
+
if target.nil? and order.nil?
|
34
|
+
@model.add_constraint Sort::SortConstraint.new(@model, @params)
|
35
|
+
else
|
36
|
+
# Do not allow negation.
|
37
|
+
if @params[:negate]
|
38
|
+
raise Gecode::MissingConstraintError, 'A negated sort with options ' +
|
39
|
+
'is not implemented.'
|
40
|
+
end
|
41
|
+
|
42
|
+
@params.update(:target => target, :order => order)
|
43
|
+
@model.add_constraint Sort::SortConstraintWithOptions.new(@model,
|
44
|
+
@params)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# A module that gathers the classes and modules used in sort constraints.
|
50
|
+
module Sort #:nodoc:
|
51
|
+
# Describes a sort constraint which constrains a target enumeration of
|
52
|
+
# integer variables to be the sorted version of another set of integer
|
53
|
+
# variables. Optionally a third enumeration may be used to define the order
|
54
|
+
# in which the the variables should be sorted.
|
55
|
+
#
|
56
|
+
# Neither negation nor reification is supported.
|
57
|
+
#
|
58
|
+
# == Example
|
59
|
+
#
|
60
|
+
# # Constrains +sorted_numbers+ to be a sorted version of +numbers+.
|
61
|
+
# numbers.must_be.sorted(:as => sorted_numbers)
|
62
|
+
#
|
63
|
+
# # Constrains +sorted_numbers+ to be +numbers+ sorted in the order
|
64
|
+
# # described by the integer variable enumeration +order+.
|
65
|
+
# numbers.must_be.sorted(:as => sorted_numbers, :order => order)
|
66
|
+
class SortConstraintWithOptions < Gecode::Constraints::Constraint
|
67
|
+
def post
|
68
|
+
if @params[:target].nil?
|
69
|
+
# We must have a target.
|
70
|
+
lhs = @params[:lhs]
|
71
|
+
@params[:target] = @model.int_var_array(lhs.size, lhs.domain_range)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Prepare the parameters.
|
75
|
+
params = @params.values_at(:lhs, :target, :order, :strength).map do |param|
|
76
|
+
if param.respond_to? :to_int_var_array
|
77
|
+
param.to_int_var_array
|
78
|
+
else
|
79
|
+
param
|
80
|
+
end
|
81
|
+
end.delete_if{ |param| param.nil? }
|
82
|
+
# Post the constraint.
|
83
|
+
Gecode::Raw::sortedness(@model.active_space, *params)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Describes a sort constraint which constrains an enumeration of integer
|
88
|
+
# variables to be sorted. Supports reification and negation.
|
89
|
+
#
|
90
|
+
# == Example
|
91
|
+
#
|
92
|
+
# # Constrains the variables in +int_enum+ to be sorted ascendingly.
|
93
|
+
# int_enum.must_be.sorted
|
94
|
+
#
|
95
|
+
# # Reifies the constraint that the variables in +int_enum+ to be sorted
|
96
|
+
# # ascendingly with the boolean variable +is_sorted+, while selecting
|
97
|
+
# # +domain+ as strength.
|
98
|
+
# int_enum.must_be.sorted(:reify => :is_sorted, :strength => :domain)
|
99
|
+
class SortConstraint < Gecode::Constraints::ReifiableConstraint
|
100
|
+
def post
|
101
|
+
lhs, strength, reif_var = @params.values_at(:lhs, :strength, :reif)
|
102
|
+
using_reification = !reif_var.nil?
|
103
|
+
|
104
|
+
# We translate the constraint into n-1 relation constraints.
|
105
|
+
options = {:strength =>
|
106
|
+
Gecode::Constraints::Util::PROPAGATION_STRENGTHS.invert[strength]}
|
107
|
+
if using_reification
|
108
|
+
reification_variables = @model.bool_var_array(lhs.size - 1)
|
109
|
+
end
|
110
|
+
(lhs.size - 1).times do |i|
|
111
|
+
first, second = lhs[i, 2]
|
112
|
+
rel_options = options.clone
|
113
|
+
if using_reification
|
114
|
+
# Reify each relation constraint and then bind them all together.
|
115
|
+
rel_options[:reify] = reification_variables[i]
|
116
|
+
end
|
117
|
+
first.must_be.less_than_or_equal_to(second, rel_options)
|
118
|
+
end
|
119
|
+
if using_reification
|
120
|
+
reification_variables.conjunction.must == reif_var
|
121
|
+
end
|
122
|
+
end
|
123
|
+
negate_using_reification
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Gecode
|
2
|
+
module IntEnumMethods
|
3
|
+
include Gecode::Constraints::LeftHandSideMethods
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
# Produces an expression for the lhs module.
|
8
|
+
def expression(params)
|
9
|
+
params.update(:lhs => self)
|
10
|
+
Constraints::IntEnum::Expression.new(@model, params)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# A module containing constraints that have enumerations of integer
|
15
|
+
# variables as left hand side.
|
16
|
+
module Constraints::IntEnum
|
17
|
+
# Expressions with int enums as left hand sides.
|
18
|
+
class Expression < Gecode::Constraints::Expression #:nodoc:
|
19
|
+
# Raises TypeError unless the left hand side is an int enum.
|
20
|
+
def initialize(model, params)
|
21
|
+
super
|
22
|
+
|
23
|
+
unless params[:lhs].respond_to? :to_int_var_array
|
24
|
+
raise TypeError, 'Must have int enum as left hand side.'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'gecoder/interface/constraints/int_enum/distinct'
|
32
|
+
require 'gecoder/interface/constraints/int_enum/equality'
|
33
|
+
require 'gecoder/interface/constraints/int_enum/channel'
|
34
|
+
require 'gecoder/interface/constraints/int_enum/element'
|
35
|
+
require 'gecoder/interface/constraints/int_enum/count'
|
36
|
+
require 'gecoder/interface/constraints/int_enum/sort'
|
37
|
+
require 'gecoder/interface/constraints/int_enum/arithmetic'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeIntVar
|
3
|
+
include Gecode::Constraints::LeftHandSideMethods
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
# Produces an expression for the lhs module.
|
8
|
+
def expression(params)
|
9
|
+
params.update(:lhs => self)
|
10
|
+
Constraints::Int::Expression.new(@model, params)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# A module containing constraints that have int variables as left hand side
|
15
|
+
# (but not enumerations).
|
16
|
+
module Constraints::Int
|
17
|
+
# Describes an integer expression.
|
18
|
+
class Expression < Gecode::Constraints::Expression #:nodoc:
|
19
|
+
end
|
20
|
+
|
21
|
+
# A composite expression which is an int expression with a left hand side
|
22
|
+
# resulting from a previous constraint.
|
23
|
+
class CompositeExpression < Gecode::Constraints::CompositeExpression #:nodoc:
|
24
|
+
# The block given should take three parameters. The first is the variable
|
25
|
+
# that should be the left hand side, if it's nil then a new one should be
|
26
|
+
# created. The second is the has of parameters. The block should return
|
27
|
+
# the variable used as left hand side.
|
28
|
+
def initialize(model, params, &block)
|
29
|
+
super(Expression, Gecode::FreeIntVar, lambda{ model.int_var }, model,
|
30
|
+
params, &block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Describes a stub that produces an int variable, which can then be used
|
35
|
+
# with the normal int variable constraints. An example would be the element
|
36
|
+
# constraint.
|
37
|
+
#
|
38
|
+
# int_enum[int_var].must > rhs
|
39
|
+
#
|
40
|
+
# <tt>int_enum[int_var]</tt> produces an int variable which the constraint
|
41
|
+
# <tt>.must > rhs</tt> is then applied to. In the above case two
|
42
|
+
# constraints (and one temporary variable) are required, but in the case of
|
43
|
+
# equality only one constraint is required.
|
44
|
+
#
|
45
|
+
# Whether a constraint involving a reification stub supports negation,
|
46
|
+
# reification, strength options and so on depends on the constraint on the
|
47
|
+
# right hand side.
|
48
|
+
class CompositeStub < Gecode::Constraints::CompositeStub
|
49
|
+
def initialize(model, params)
|
50
|
+
super(CompositeExpression, model, params)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
require 'gecoder/interface/constraints/int/linear'
|
57
|
+
require 'gecoder/interface/constraints/int/domain'
|
58
|
+
require 'gecoder/interface/constraints/int/arithmetic'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Gecode::Constraints
|
2
|
+
# Base class for all reifiable constraints.
|
3
|
+
class ReifiableConstraint < Constraint
|
4
|
+
# Gets the reification variable of the constraint, nil if none exists.
|
5
|
+
def reification_var
|
6
|
+
@params[:reif]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Sets the reification variable of the constraint, nil if none should be
|
10
|
+
# used.
|
11
|
+
def reification_var=(new_var)
|
12
|
+
@params[:reif] = new_var
|
13
|
+
end
|
14
|
+
|
15
|
+
# Produces a disjunction of two reifiable constraints, producing a new
|
16
|
+
# reifiable constraint.
|
17
|
+
def |(constraint)
|
18
|
+
with_reification_variables(constraint) do |b1, b2|
|
19
|
+
# Create the disjunction constraint.
|
20
|
+
(b1 | b2).must_be.true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Produces a conjunction of two reifiable constraints, producing a new
|
25
|
+
# reifiable constraint.
|
26
|
+
def &(constraint)
|
27
|
+
with_reification_variables(constraint) do |b1, b2|
|
28
|
+
# Create the conjunction constraint.
|
29
|
+
(b1 & b2).must_be.true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Yields two boolean variables to the specified block. The first one is
|
36
|
+
# self's reification variable and the second one is the reification variable
|
37
|
+
# of the specified constraint. Reuses reification variables if possible,
|
38
|
+
# otherwise creates new ones.
|
39
|
+
def with_reification_variables(constraint, &block)
|
40
|
+
raise TypeError unless constraint.kind_of? ReifiableConstraint
|
41
|
+
|
42
|
+
# Set up the reification variables, using existing variables if they
|
43
|
+
# exist.
|
44
|
+
con1_holds = self.reification_var
|
45
|
+
con2_holds = constraint.reification_var
|
46
|
+
if con1_holds.nil?
|
47
|
+
con1_holds = @model.bool_var
|
48
|
+
self.reification_var = con1_holds
|
49
|
+
end
|
50
|
+
if con2_holds.nil?
|
51
|
+
con2_holds = @model.bool_var
|
52
|
+
constraint.reification_var = con2_holds
|
53
|
+
end
|
54
|
+
yield(con1_holds, con2_holds)
|
55
|
+
end
|
56
|
+
|
57
|
+
# If called the negation of the constraint will be handled using the
|
58
|
+
# reification variable. This means that the post method (which has to be
|
59
|
+
# defined prior to calling this method) doesn't have to bother about
|
60
|
+
# negation.
|
61
|
+
def self.negate_using_reification
|
62
|
+
class_eval do
|
63
|
+
alias_method :post_without_negation, :post
|
64
|
+
|
65
|
+
def post
|
66
|
+
if @params[:negate]
|
67
|
+
if @params[:reif].nil?
|
68
|
+
# Create a reification variable if none exists.
|
69
|
+
@params[:reif] = @model.bool_var
|
70
|
+
end
|
71
|
+
@params[:reif].must_be.false
|
72
|
+
end
|
73
|
+
post_without_negation
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeSetVar
|
3
|
+
# Starts a constraint on the size of the set.
|
4
|
+
def size
|
5
|
+
params = {:lhs => self}
|
6
|
+
Gecode::Constraints::Set::Cardinality::SizeExpressionStub.new(
|
7
|
+
@model, params)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Gecode::Constraints::Set
|
13
|
+
# A module that gathers the classes and modules used in cardinality
|
14
|
+
# constraints.
|
15
|
+
module Cardinality #:nodoc:
|
16
|
+
# Describes a cardinality constraint specifically for ranges. This is just
|
17
|
+
# a special case which is used instead of the more general composite
|
18
|
+
# constraint when the target cardinality is a range.
|
19
|
+
class CardinalityConstraint < Gecode::Constraints::Constraint #:nodoc:
|
20
|
+
def post
|
21
|
+
var, range = @params.values_at(:lhs, :range)
|
22
|
+
Gecode::Raw::cardinality(@model.active_space, var.bind, range.first,
|
23
|
+
range.last)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# A custom composite stub to change the composite expression used.
|
28
|
+
class CompositeStub < Gecode::Constraints::CompositeStub #:nodoc:
|
29
|
+
def initialize(model, params)
|
30
|
+
super(Expression, model, params)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Describes a cardinality expression started with set.size.must .
|
35
|
+
class Expression < Gecode::Constraints::Int::CompositeExpression #:nodoc:
|
36
|
+
def in(range)
|
37
|
+
if range.kind_of?(Range) and !@params[:negate]
|
38
|
+
@params.update(:range => range)
|
39
|
+
@model.add_constraint CardinalityConstraint.new(@model, @params)
|
40
|
+
else
|
41
|
+
super(range)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Describes a CompositeStub for the cardianlity constraint which constrains
|
47
|
+
# the cardianlity (size) of a set.
|
48
|
+
#
|
49
|
+
# == Example
|
50
|
+
#
|
51
|
+
# # The size of +set+ must be within 1..17
|
52
|
+
# set.size.must_be.in 1..17
|
53
|
+
#
|
54
|
+
# # The size must equal the integer variable +size+.
|
55
|
+
# set.size.must == size
|
56
|
+
#
|
57
|
+
# # The size must not be larger than 17
|
58
|
+
# set.size.must_not > 17
|
59
|
+
#
|
60
|
+
# # We reify the above with a boolean variable called +is_not_large+ and
|
61
|
+
# # select the strength +domain+.
|
62
|
+
# set.size.must_not_be.larger_than(17, :reify => is_not_large,
|
63
|
+
# :strength => :domain)
|
64
|
+
class SizeExpressionStub < CompositeStub
|
65
|
+
def constrain_equal(variable, params, constrain)
|
66
|
+
lhs = @params[:lhs]
|
67
|
+
if constrain
|
68
|
+
variable.must_be.in lhs.lower_bound.size..lhs.upper_bound.size
|
69
|
+
end
|
70
|
+
|
71
|
+
Gecode::Raw::cardinality(@model.active_space, lhs.bind, variable.bind)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeSetVar
|
3
|
+
# Starts a constraint on the minimum value of the set.
|
4
|
+
def min
|
5
|
+
params = {:lhs => self}
|
6
|
+
Gecode::Constraints::Set::Connection::MinExpressionStub.new(@model, params)
|
7
|
+
end
|
8
|
+
|
9
|
+
# Starts a constraint on the maximum value of the set.
|
10
|
+
def max
|
11
|
+
params = {:lhs => self}
|
12
|
+
Gecode::Constraints::Set::Connection::MaxExpressionStub.new(@model, params)
|
13
|
+
end
|
14
|
+
|
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
|
+
def sum(options = {:weights => weights = Hash.new(1)})
|
24
|
+
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
|
44
|
+
end
|
45
|
+
Gecode::Constraints::Set::Connection::SumExpressionStub.new(@model, params)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
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.'
|
62
|
+
end
|
63
|
+
|
64
|
+
@params.update(:variables => variables)
|
65
|
+
@model.add_constraint Connection::IncludeConstraint.new(@model, @params)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# A module that gathers the classes and modules used in connection
|
70
|
+
# constraints.
|
71
|
+
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]
|
95
|
+
if constrain
|
96
|
+
variable.must_be.in set.upper_bound.min..set.lower_bound.min
|
97
|
+
end
|
98
|
+
|
99
|
+
Gecode::Raw::min(@model.active_space, set.bind, variable.bind)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
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]
|
126
|
+
if constrain
|
127
|
+
variable.must_be.in set.lower_bound.max..set.upper_bound.max
|
128
|
+
end
|
129
|
+
|
130
|
+
Gecode::Raw::max(@model.active_space, set.bind, variable.bind)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
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)
|
157
|
+
lub = set.upper_bound.to_a
|
158
|
+
lub.delete_if{ |e| subs[e].nil? }
|
159
|
+
substituted_lub = lub.map{ |e| subs[e] }
|
160
|
+
if constrain
|
161
|
+
# Compute the theoretical bounds of the weighted sum. This is slightly
|
162
|
+
# sloppy since we could also use the contents of the greatest lower
|
163
|
+
# bound.
|
164
|
+
min = substituted_lub.find_all{ |e| e < 0}.inject(0){ |x, y| x + y }
|
165
|
+
max = substituted_lub.find_all{ |e| e > 0}.inject(0){ |x, y| x + y }
|
166
|
+
variable.must_be.in min..max
|
167
|
+
end
|
168
|
+
|
169
|
+
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)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|