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,80 @@
|
|
1
|
+
module Gecode::Int
|
2
|
+
class IntConstraintReceiver
|
3
|
+
# Creates a domain constraint using the specified domain, specified
|
4
|
+
# as an enumeration of integers. The integer operand is constrained
|
5
|
+
# to take a value in the domain. Domains should be specified as
|
6
|
+
# ranges if possible.
|
7
|
+
#
|
8
|
+
# ==== Examples
|
9
|
+
#
|
10
|
+
# # +x+ must be in the range 1..10
|
11
|
+
# x.must_be.in 1..10
|
12
|
+
#
|
13
|
+
# # +x+ must not be in the range -5...5
|
14
|
+
# x.must_not_be.in -5...5
|
15
|
+
#
|
16
|
+
# # Specifies the above, but reifies the constraint with the boolean
|
17
|
+
# # operand +bool+ and specified +value+ as strength.
|
18
|
+
# x.must_not_be.in(-5...5, :reify => bool, :strength => :value)
|
19
|
+
#
|
20
|
+
# # +x+ must be in the enumeration [3,5,7].
|
21
|
+
# x.must_be.in [3,5,7]
|
22
|
+
#
|
23
|
+
# # +x+ must not be in the enumeration [5,6,7,17].
|
24
|
+
# x.must_not_be.in [5,6,7,17]
|
25
|
+
#
|
26
|
+
# # Specifies the above, but reifies the constraint with the boolean
|
27
|
+
# # operand +bool+ and specified +value+ as strength.
|
28
|
+
# x.must_not_be.in([5,6,7,17], :reify => bool, :strength => :value)
|
29
|
+
#
|
30
|
+
def in(domain, options = {})
|
31
|
+
@params.update(Gecode::Util.decode_options(options))
|
32
|
+
@params[:domain] = domain
|
33
|
+
if domain.kind_of? Range
|
34
|
+
@model.add_constraint Domain::RangeDomainConstraint.new(@model, @params)
|
35
|
+
elsif domain.kind_of?(Enumerable) and domain.all?{ |e| e.kind_of? Fixnum }
|
36
|
+
@model.add_constraint Domain::EnumDomainConstraint.new(@model,
|
37
|
+
@params)
|
38
|
+
else
|
39
|
+
raise TypeError, "Expected integer enumerable, got #{domain.class}."
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# A module that gathers the classes and modules used in domain constraints.
|
45
|
+
module Domain #:nodoc:
|
46
|
+
# Range domain constraints specify that an integer operand must be
|
47
|
+
# contained within a specified range of integers.
|
48
|
+
class RangeDomainConstraint < Gecode::ReifiableConstraint #:nodoc:
|
49
|
+
def post
|
50
|
+
var, domain, reif_var = @params.values_at(:lhs, :domain, :reif)
|
51
|
+
|
52
|
+
(params = []) << var.to_int_var.bind
|
53
|
+
last = domain.last
|
54
|
+
last -= 1 if domain.exclude_end?
|
55
|
+
params << domain.first << last
|
56
|
+
params << reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
|
57
|
+
params.concat propagation_options
|
58
|
+
|
59
|
+
Gecode::Raw::dom(@model.active_space, *params)
|
60
|
+
end
|
61
|
+
negate_using_reification
|
62
|
+
end
|
63
|
+
|
64
|
+
# Enum domain constraints specify that an integer operand must be contained
|
65
|
+
# in an enumeration of integers.
|
66
|
+
class EnumDomainConstraint < Gecode::ReifiableConstraint #:nodoc:
|
67
|
+
def post
|
68
|
+
var, domain, reif_var = @params.values_at(:lhs, :domain, :reif)
|
69
|
+
|
70
|
+
(params = []) << var.to_int_var.bind
|
71
|
+
params << Gecode::Util.constant_set_to_int_set(domain)
|
72
|
+
params << reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
|
73
|
+
params.concat propagation_options
|
74
|
+
|
75
|
+
Gecode::Raw::dom(@model.active_space, *params)
|
76
|
+
end
|
77
|
+
negate_using_reification
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Gecode::Int
|
2
|
+
module IntOperand
|
3
|
+
# Produces a new IntOperand representing this operand plus
|
4
|
+
# +int_operand_or_fixnum+.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # +int1+ plus +int2+
|
9
|
+
# int1 + int2
|
10
|
+
#
|
11
|
+
# # +int+ plus 17
|
12
|
+
# int + 17
|
13
|
+
def +(int_operand_or_fixnum)
|
14
|
+
int_linear_expression_operation(:+, int_operand_or_fixnum)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Produces a new IntOperand representing this operand minus
|
18
|
+
# +int_operand_or_fixnum+.
|
19
|
+
#
|
20
|
+
# ==== Examples
|
21
|
+
#
|
22
|
+
# # +int1+ minus +int2+
|
23
|
+
# int1 - int2
|
24
|
+
#
|
25
|
+
# # +int+ minus 17
|
26
|
+
# int - 17
|
27
|
+
def -(int_operand_or_fixnum)
|
28
|
+
int_linear_expression_operation(:-, int_operand_or_fixnum)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Produces a new IntOperand representing this operand times a
|
32
|
+
# constant.
|
33
|
+
#
|
34
|
+
# ==== Examples
|
35
|
+
#
|
36
|
+
# # +int+ times 17
|
37
|
+
# int * 17
|
38
|
+
def *(fixnum)
|
39
|
+
if fixnum.kind_of? Fixnum
|
40
|
+
int_linear_expression_operation(:*, fixnum)
|
41
|
+
else
|
42
|
+
raise TypeError, "Expected fixnum, got #{fixnum.class}."
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Performs the int linear expression operation +operator+ on self
|
49
|
+
# and +operand2+.
|
50
|
+
def int_linear_expression_operation(operator, operand2)
|
51
|
+
unless operand2.respond_to? :to_minimodel_lin_exp
|
52
|
+
operand2 = Linear::ExpressionNode.new operand2
|
53
|
+
end
|
54
|
+
operand1 = self
|
55
|
+
unless operand1.respond_to? :to_minimodel_lin_exp
|
56
|
+
operand1 = Linear::ExpressionNode.new(self, @model)
|
57
|
+
end
|
58
|
+
Linear::ExpressionTree.new(operand1, operand2, operator)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# A module that gathers the classes and modules used in linear constraints.
|
63
|
+
module Linear #:nodoc:
|
64
|
+
class LinearRelationConstraint < Gecode::ReifiableConstraint #:nodoc:
|
65
|
+
def post
|
66
|
+
lhs, rhs, relation_type, reif_var =
|
67
|
+
@params.values_at(:lhs, :rhs, :relation_type, :reif)
|
68
|
+
reif_var = reif_var.to_bool_var.bind if reif_var.respond_to? :to_bool_var
|
69
|
+
final_exp = (lhs.to_minimodel_lin_exp - rhs.to_minimodel_lin_exp)
|
70
|
+
if reif_var.nil?
|
71
|
+
final_exp.post(@model.active_space, relation_type,
|
72
|
+
*propagation_options)
|
73
|
+
else
|
74
|
+
final_exp.post(@model.active_space, relation_type, reif_var,
|
75
|
+
*propagation_options)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Describes a binary tree of expression nodes which together form a linear
|
81
|
+
# expression.
|
82
|
+
class ExpressionTree < Gecode::Int::ShortCircuitRelationsOperand #:nodoc:
|
83
|
+
attr :model
|
84
|
+
|
85
|
+
# Constructs a new expression with the specified operands.
|
86
|
+
def initialize(left_node, right_node, operation)
|
87
|
+
super(left_node.model || right_node.model)
|
88
|
+
@left = left_node
|
89
|
+
@right = right_node
|
90
|
+
@operation = operation
|
91
|
+
@model = @left.model || @right.model
|
92
|
+
end
|
93
|
+
|
94
|
+
# Converts the linear expression to an instance of
|
95
|
+
# Gecode::Raw::MiniModel::LinExpr
|
96
|
+
def to_minimodel_lin_exp
|
97
|
+
@left.to_minimodel_lin_exp.send(@operation, @right.to_minimodel_lin_exp)
|
98
|
+
end
|
99
|
+
|
100
|
+
def relation_constraint(relation, int_operand_or_fix, params)
|
101
|
+
unless params[:negate]
|
102
|
+
relation_type =
|
103
|
+
Gecode::Util::RELATION_TYPES[relation]
|
104
|
+
else
|
105
|
+
relation_type =
|
106
|
+
Gecode::Util::NEGATED_RELATION_TYPES[relation]
|
107
|
+
end
|
108
|
+
|
109
|
+
unless int_operand_or_fix.respond_to? :to_minimodel_lin_exp
|
110
|
+
int_operand_or_fix = Linear::ExpressionNode.new(int_operand_or_fix);
|
111
|
+
end
|
112
|
+
|
113
|
+
params.update(:lhs => self, :rhs => int_operand_or_fix,
|
114
|
+
:relation_type => relation_type)
|
115
|
+
LinearRelationConstraint.new(model, params)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Describes a single node in a linear expression.
|
120
|
+
class ExpressionNode #:nodoc:
|
121
|
+
attr :model
|
122
|
+
|
123
|
+
def initialize(value, model = nil)
|
124
|
+
unless value.respond_to?(:to_int_var) or value.kind_of?(Fixnum)
|
125
|
+
raise TypeError, 'Expected int operand or fixnum, ' +
|
126
|
+
"got #{value.class}."
|
127
|
+
end
|
128
|
+
@value = value
|
129
|
+
@model = model
|
130
|
+
end
|
131
|
+
|
132
|
+
# Converts the linear expression to an instance of
|
133
|
+
# Gecode::Raw::MiniModel::LinExpr
|
134
|
+
def to_minimodel_lin_exp
|
135
|
+
expression = @value
|
136
|
+
if expression.respond_to? :to_int_var
|
137
|
+
expression = expression.to_int_var.bind * 1
|
138
|
+
end
|
139
|
+
expression
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
module Gecode::Int
|
2
|
+
class IntConstraintReceiver
|
3
|
+
# Constrains the integer operand to equal +int_operand_or_fixnum+.
|
4
|
+
# #equal and #equal_to are aliases of this method.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # +int1+ must equal +int2+
|
9
|
+
# int1.must == int2
|
10
|
+
#
|
11
|
+
# # +int+ must equal 17
|
12
|
+
# int.must == 17
|
13
|
+
#
|
14
|
+
# # +int1+ must equal +int2+. We reify the constraint with
|
15
|
+
# # +bool+ and select +domain+ as strength.
|
16
|
+
# int1.must.equal(int2, :reify => bool, :strength => :domain)
|
17
|
+
def ==(int_operand_or_fixnum, options = {})
|
18
|
+
comparison(:==, int_operand_or_fixnum, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Constrains the integer operand to be strictly greater than
|
22
|
+
# +int_operand_or_fixnum+. #greater and #greater_than are
|
23
|
+
# aliases of this method.
|
24
|
+
#
|
25
|
+
# ==== Examples
|
26
|
+
#
|
27
|
+
# # +int1+ must be strictly greater than +int2+
|
28
|
+
# int1.must > int2
|
29
|
+
#
|
30
|
+
# # +int+ must be strictly greater than 17
|
31
|
+
# int.must > 17
|
32
|
+
#
|
33
|
+
# # +int1+ must be strictly greater than +int2+. We reify the
|
34
|
+
# # constraint with +bool+ and select +domain+ as strength.
|
35
|
+
# int1.must_be.greater_than(int2, :reify => bool, :strength => :domain)
|
36
|
+
def >(int_operand_or_fixnum, options = {})
|
37
|
+
comparison(:>, int_operand_or_fixnum, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Constrains the integer operand to be greater than or equal to
|
41
|
+
# +int_operand_or_fixnum+. #greater_or_equal and
|
42
|
+
# #greater_than_or_equal_to are aliases of this method.
|
43
|
+
#
|
44
|
+
# ==== Examples
|
45
|
+
#
|
46
|
+
# # +int1+ must be greater than or equal to +int2+
|
47
|
+
# int1.must >= int2
|
48
|
+
#
|
49
|
+
# # +int+ must be greater than or equal to 17
|
50
|
+
# int.must >= 17
|
51
|
+
#
|
52
|
+
# # +int1+ must be greater than or equal to +int2+. We reify the
|
53
|
+
# # constraint with +bool+ and select +domain+ as strength.
|
54
|
+
# int1.must.greater_or_equal(int2, :reify => bool, :strength => :domain)
|
55
|
+
def >=(int_operand_or_fixnum, options = {})
|
56
|
+
comparison(:>=, int_operand_or_fixnum, options)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Constrains the integer operand to be strictly less than
|
60
|
+
# +int_operand_or_fixnum+. #lesser and #lesser_than are
|
61
|
+
# aliases of this method.
|
62
|
+
#
|
63
|
+
# ==== Examples
|
64
|
+
#
|
65
|
+
# # +int1+ must be strictly less than +int2+
|
66
|
+
# int1.must < int2
|
67
|
+
#
|
68
|
+
# # +int+ must be strictly less than 17
|
69
|
+
# int.must < 17
|
70
|
+
#
|
71
|
+
# # +int1+ must be strictly less than +int2+. We reify the
|
72
|
+
# # constraint with +bool+ and select +domain+ as strength.
|
73
|
+
# int1.must_be.less_than(int2, :reify => bool, :strength => :domain)
|
74
|
+
def <(int_operand_or_fixnum, options = {})
|
75
|
+
comparison(:<, int_operand_or_fixnum, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Constrains the integer operand to be less than or equal to
|
79
|
+
# +int_operand_or_fixnum+. #less_or_equal and
|
80
|
+
# #less_than_or_equal_to are aliases of this method.
|
81
|
+
#
|
82
|
+
# ==== Examples
|
83
|
+
#
|
84
|
+
# # +int1+ must be less than or equal to +int2+
|
85
|
+
# int1.must <= int2
|
86
|
+
#
|
87
|
+
# # +int+ must be less than or equal to 17
|
88
|
+
# int.must <= 17
|
89
|
+
#
|
90
|
+
# # +int1+ must be less than or equal to +int2+. We reify the
|
91
|
+
# # constraint with +bool+ and select +domain+ as strength.
|
92
|
+
# int1.must.less_or_equal(int2, :reify => bool, :strength => :domain)
|
93
|
+
def <=(int_operand_or_fixnum, options = {})
|
94
|
+
comparison(:<=, int_operand_or_fixnum, options)
|
95
|
+
end
|
96
|
+
|
97
|
+
alias_comparison_methods
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
# Helper for the comparison methods. The reason that they are not
|
102
|
+
# generated in a loop is that it would mess up the RDoc.
|
103
|
+
def comparison(name, int_operand_or_fixnum, options)
|
104
|
+
unless int_operand_or_fixnum.respond_to?(:to_int_var) or
|
105
|
+
int_operand_or_fixnum.kind_of?(Fixnum)
|
106
|
+
raise TypeError, "Expected int operand or integer, got " +
|
107
|
+
"#{int_operand_or_fixnum.class}."
|
108
|
+
end
|
109
|
+
|
110
|
+
unless @params[:negate]
|
111
|
+
relation_type = Gecode::Util::RELATION_TYPES[name]
|
112
|
+
else
|
113
|
+
relation_type = Gecode::Util::NEGATED_RELATION_TYPES[name]
|
114
|
+
end
|
115
|
+
@params.update Gecode::Util.decode_options(options)
|
116
|
+
@model.add_constraint Relation::RelationConstraint.new(@model,
|
117
|
+
@params.update(:relation_type => relation_type,
|
118
|
+
:rhs => int_operand_or_fixnum))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# A module that gathers the classes and modules used in relation constraints.
|
123
|
+
module Relation #:nodoc:
|
124
|
+
class RelationConstraint < Gecode::ReifiableConstraint #:nodoc:
|
125
|
+
def post
|
126
|
+
# Fetch the parameters to Gecode.
|
127
|
+
lhs, relation, rhs, reif_var =
|
128
|
+
@params.values_at(:lhs, :relation_type, :rhs, :reif)
|
129
|
+
|
130
|
+
rhs = rhs.to_int_var.bind if rhs.respond_to? :to_int_var
|
131
|
+
if reif_var.nil?
|
132
|
+
Gecode::Raw::rel(@model.active_space, lhs.to_int_var.bind,
|
133
|
+
relation, rhs, *propagation_options)
|
134
|
+
else
|
135
|
+
Gecode::Raw::rel(@model.active_space, lhs.to_int_var.bind,
|
136
|
+
relation, rhs, reif_var.to_bool_var.bind, *propagation_options)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Gecode::IntEnum
|
2
|
+
module IntEnumOperand
|
3
|
+
# Produces an IntOperand representing the maximum value of the
|
4
|
+
# integer operands in this enumeration.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # The maximum of +int_enum+.
|
9
|
+
# int_enum.max
|
10
|
+
def max
|
11
|
+
Arithmetic::IntEnumMaxOperand.new(@model, self)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Produces an IntOperand representing the minimum value of the
|
15
|
+
# integer operands in this enumeration.
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# # The minimum of +int_enum+.
|
20
|
+
# int_enum.min
|
21
|
+
def min
|
22
|
+
Arithmetic::IntEnumMinOperand.new(@model, self)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# A module that gathers the classes and modules used by arithmetic
|
27
|
+
# constraints.
|
28
|
+
module Arithmetic #:nodoc:
|
29
|
+
class IntEnumMaxOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
30
|
+
def initialize(model, int_enum)
|
31
|
+
super model
|
32
|
+
@int_enum = int_enum
|
33
|
+
end
|
34
|
+
|
35
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
36
|
+
enum = @int_enum.to_int_enum
|
37
|
+
if constrain
|
38
|
+
int_operand.must_be.in enum.domain_range
|
39
|
+
end
|
40
|
+
|
41
|
+
Gecode::Raw::max(@model.active_space, enum.bind_array,
|
42
|
+
int_operand.to_int_var.bind, *propagation_options)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class IntEnumMinOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
47
|
+
def initialize(model, int_enum)
|
48
|
+
super model
|
49
|
+
@int_enum = int_enum
|
50
|
+
end
|
51
|
+
|
52
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
53
|
+
enum = @int_enum.to_int_enum
|
54
|
+
if constrain
|
55
|
+
int_operand.must_be.in enum.domain_range
|
56
|
+
end
|
57
|
+
|
58
|
+
Gecode::Raw::min(@model.active_space, enum.bind_array,
|
59
|
+
int_operand.to_int_var.bind, *propagation_options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Gecode::IntEnum
|
2
|
+
class IntEnumConstraintReceiver
|
3
|
+
# Constrains this enumeration to "channel" +int_enum+. Channel
|
4
|
+
# constraints are used to give access to multiple viewpoints when
|
5
|
+
# modelling.
|
6
|
+
#
|
7
|
+
# The channel constraint can be thought of as constraining the arrays to
|
8
|
+
# be each other's inverses. I.e. if the i:th value in the first enumeration
|
9
|
+
# is j, then the j:th value in the second enumeration is constrained to be
|
10
|
+
# i.
|
11
|
+
#
|
12
|
+
# Neither reification nor negation is supported.
|
13
|
+
#
|
14
|
+
# ==== Examples
|
15
|
+
#
|
16
|
+
# Lets say that we're modelling a sequence of numbers that must be distinct
|
17
|
+
# and that we want access to the following two view simultaneously.
|
18
|
+
#
|
19
|
+
# === First view
|
20
|
+
#
|
21
|
+
# The sequence is modelled as an array of integer variables where the first
|
22
|
+
# variable holds the value of the first position in the sequence, the
|
23
|
+
# second the value of the second position and so on.
|
24
|
+
#
|
25
|
+
# # n variables with values from 0 to n-1.
|
26
|
+
# elements = int_var_array(n, 0...n)
|
27
|
+
# elements.must_be.distinct
|
28
|
+
#
|
29
|
+
# That way +elements+ will contain the actual sequence when the problem has
|
30
|
+
# been solved.
|
31
|
+
#
|
32
|
+
# === Second view
|
33
|
+
#
|
34
|
+
# The sequence is modelled as the positions of each value in 0..(n-1) in
|
35
|
+
# the sequence. That way the first variable would hold the positions of 0
|
36
|
+
# in the sequence, the second variable would hold the positions of 1 in the
|
37
|
+
# sequence and so on.
|
38
|
+
#
|
39
|
+
# positions = int_var_array(n, 0...n)
|
40
|
+
# positions.must_be.distinct
|
41
|
+
#
|
42
|
+
# === Connecting the views
|
43
|
+
#
|
44
|
+
# In essence the relationship between the two arrays +elements+ and
|
45
|
+
# +positions+ is that
|
46
|
+
#
|
47
|
+
# elements.map{ |e| e.val }[i] == positions.map{ |p| p.val }.index(i)
|
48
|
+
#
|
49
|
+
# for all i in 0..(n-1). This relationship is enforced by the channel
|
50
|
+
# constraint as follows.
|
51
|
+
#
|
52
|
+
# elements.must.channel positions
|
53
|
+
#
|
54
|
+
def channel(int_enum, options = {})
|
55
|
+
if @params[:negate]
|
56
|
+
raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
|
57
|
+
'is not implemented.'
|
58
|
+
end
|
59
|
+
unless int_enum.respond_to? :to_int_enum
|
60
|
+
raise TypeError, "Expected int enum, got #{int_enum.class}."
|
61
|
+
end
|
62
|
+
if options.has_key? :reify
|
63
|
+
raise ArgumentError, 'The channel constraints does not support the ' +
|
64
|
+
'reification option.'
|
65
|
+
end
|
66
|
+
|
67
|
+
@params.update(Gecode::Util.decode_options(options))
|
68
|
+
@params.update(:rhs => int_enum)
|
69
|
+
@model.add_constraint Channel::ChannelConstraint.new(@model, @params)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Provides commutativity with SetEnumConstraintReceiver#channel .
|
73
|
+
provide_commutativity(:channel){ |rhs, _| rhs.respond_to? :to_set_enum }
|
74
|
+
end
|
75
|
+
|
76
|
+
# A module that gathers the classes and modules used in channel constraints.
|
77
|
+
module Channel #:nodoc:
|
78
|
+
class ChannelConstraint < Gecode::Constraint #:nodoc:
|
79
|
+
def post
|
80
|
+
lhs, rhs = @params.values_at(:lhs, :rhs)
|
81
|
+
Gecode::Raw::channel(@model.active_space, lhs.to_int_enum.bind_array,
|
82
|
+
rhs.to_int_enum.bind_array, *propagation_options)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|