gecoder 0.8.3 → 0.9.0
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 +15 -0
- data/README +6 -2
- data/example/equation_system.rb +15 -0
- data/example/magic_sequence.rb +7 -7
- data/example/money.rb +36 -0
- data/example/queens.rb +7 -8
- data/example/send_most_money.rb +1 -1
- data/example/square_tiling.rb +2 -2
- data/example/sudoku-set.rb +11 -12
- data/example/sudoku.rb +40 -45
- data/ext/extconf.rb +0 -0
- data/lib/gecoder/bindings.rb +42 -0
- data/lib/gecoder/bindings/bindings.rb +16 -0
- data/lib/gecoder/interface.rb +2 -1
- data/lib/gecoder/interface/branch.rb +16 -9
- data/lib/gecoder/interface/constraints.rb +410 -451
- data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
- data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
- 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 +131 -130
- data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
- data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
- data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
- data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
- data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
- 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 +43 -53
- data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
- data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
- data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
- data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
- 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 +23 -27
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
- data/lib/gecoder/interface/enum_matrix.rb +4 -4
- data/lib/gecoder/interface/enum_wrapper.rb +71 -22
- data/lib/gecoder/interface/model.rb +167 -12
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +30 -18
- data/lib/gecoder/interface/variables.rb +103 -33
- data/lib/gecoder/version.rb +2 -2
- data/specs/bool_var.rb +19 -12
- data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
- 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/{extensional.rb → bool_enum/extensional.rb} +32 -101
- data/specs/constraints/constraint_helper.rb +149 -179
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +6 -63
- 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 +4 -5
- 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/enum_wrapper.rb +53 -3
- data/specs/int_var.rb +44 -25
- data/specs/model.rb +58 -1
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +24 -5
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +22 -8
- data/specs/spec_helper.rb +206 -6
- data/tasks/distribution.rake +22 -7
- data/tasks/svn.rake +3 -1
- metadata +218 -134
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
- data/specs/constraints/arithmetic.rb +0 -351
- data/specs/constraints/bool_enum_relation.rb +0 -160
- data/specs/constraints/cardinality.rb +0 -157
- data/specs/constraints/channel.rb +0 -454
- data/specs/constraints/connection.rb +0 -369
- data/specs/constraints/count.rb +0 -146
- data/specs/constraints/distinct.rb +0 -164
- data/specs/constraints/element.rb +0 -108
- data/specs/constraints/equality.rb +0 -31
- data/specs/constraints/int_domain.rb +0 -70
- data/specs/constraints/int_relation.rb +0 -82
- data/specs/constraints/linear.rb +0 -340
- data/specs/constraints/selection.rb +0 -292
- data/specs/constraints/set_domain.rb +0 -185
- data/specs/constraints/set_operation.rb +0 -285
- data/specs/constraints/set_relation.rb +0 -197
- data/specs/constraints/sort.rb +0 -179
@@ -1,23 +1,26 @@
|
|
1
|
-
module Gecode
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
#
|
1
|
+
module Gecode::IntEnum
|
2
|
+
class IntEnumConstraintReceiver
|
3
|
+
# Constrains all integer operands in the enumeration to be distinct
|
4
|
+
# (different). The constraint can also be used with constant
|
5
|
+
# offsets, so that the operands, with specified offsets added, must
|
6
|
+
# be distinct.
|
7
|
+
#
|
8
|
+
# The constraint does not support negation nor reification.
|
9
|
+
#
|
10
|
+
# ==== Examples
|
11
|
+
#
|
12
|
+
# # Constrains all operands in +int_enum+ to be assigned different
|
13
|
+
# # values.
|
14
|
+
# int_enum.must_be.distinct
|
15
|
+
#
|
16
|
+
# # The same as above, but also selects that the strength +domain+ should
|
17
|
+
# # be used.
|
18
|
+
# int_enum.must_be.distinct(:strength => :domain)
|
19
|
+
#
|
20
|
+
# # Uses the offset to constrain that no number may be the previous number
|
21
|
+
# # incremented by one.
|
22
|
+
# numbers = int_var_array(8, 0..9)
|
23
|
+
# numbers.must_be.distinct(:offsets => (1..numbers.size).to_a.reverse)
|
21
24
|
def distinct(options = {})
|
22
25
|
if @params[:negate]
|
23
26
|
# The best we could implement it as from here would be a bunch of
|
@@ -29,39 +32,26 @@ module Gecode::Constraints::IntEnum
|
|
29
32
|
raise ArgumentError, 'Reification is not supported by the distinct ' +
|
30
33
|
'constraint.'
|
31
34
|
end
|
32
|
-
|
35
|
+
|
36
|
+
if options.has_key? :offsets
|
37
|
+
offsets = options.delete(:offsets)
|
38
|
+
unless offsets.kind_of? Enumerable
|
39
|
+
raise TypeError, 'Expected Enumerable as offsets, got ' +
|
40
|
+
"#{offsets.class}."
|
41
|
+
end
|
42
|
+
@params[:offsets] = offsets
|
43
|
+
end
|
33
44
|
@model.add_constraint Distinct::DistinctConstraint.new(@model,
|
34
|
-
@params.update(Gecode::
|
45
|
+
@params.update(Gecode::Util.decode_options(options)))
|
35
46
|
end
|
36
47
|
end
|
37
48
|
|
38
49
|
# A module that gathers the classes and modules used in distinct constraints.
|
39
50
|
module Distinct #:nodoc:
|
40
|
-
|
41
|
-
# in an enumeration to be distinct (different). The constraint can also be
|
42
|
-
# used with constant offsets, so that the variables, with specified offsets
|
43
|
-
# added, must be distinct.
|
44
|
-
#
|
45
|
-
# The constraint does not support negation nor reification.
|
46
|
-
#
|
47
|
-
# == Examples
|
48
|
-
#
|
49
|
-
# # Constrains all variables in +int_enum+ to be assigned different
|
50
|
-
# # values.
|
51
|
-
# int_enum.must_be.distinct
|
52
|
-
#
|
53
|
-
# # The same as above, but also selects that the strength +domain+ should
|
54
|
-
# # be used.
|
55
|
-
# int_enum.must_be.distinct(:strength => :domain)
|
56
|
-
#
|
57
|
-
# # Uses the offset to constrain that no number may be the previous number
|
58
|
-
# # incremented by one.
|
59
|
-
# numbers = int_var_array(8, 0..9)
|
60
|
-
# numbers.with_offset((1..numbers.size).to_a.reverse).must_be.distinct
|
61
|
-
class DistinctConstraint < Gecode::Constraints::Constraint
|
51
|
+
class DistinctConstraint < Gecode::Constraint #:nodoc:
|
62
52
|
def post
|
63
53
|
# Bind lhs.
|
64
|
-
@params[:lhs] = @params[:lhs].
|
54
|
+
@params[:lhs] = @params[:lhs].to_int_enum.bind_array
|
65
55
|
|
66
56
|
# Fetch the parameters to Gecode.
|
67
57
|
params = @params.values_at(:offsets, :lhs)
|
@@ -71,4 +61,4 @@ module Gecode::Constraints::IntEnum
|
|
71
61
|
end
|
72
62
|
end
|
73
63
|
end
|
74
|
-
end
|
64
|
+
end
|
@@ -1,65 +1,34 @@
|
|
1
|
-
|
2
|
-
module
|
3
|
-
# Describes a CompositeStub for the element constraint, which places a
|
4
|
-
# constraint on a variable at the specified position in an enumeration of
|
5
|
-
# integer variables. It's basically the array access of constraint
|
6
|
-
# programming.
|
7
|
-
#
|
8
|
-
# == Example
|
9
|
-
#
|
10
|
-
# # The variable at the +x+:th position in +int_enum+ must be larger than
|
11
|
-
# # +y+.
|
12
|
-
# int_enum[x].must > y
|
13
|
-
#
|
14
|
-
# # The price of +selected_item+ as described by +prices+ must not be
|
15
|
-
# # larger than 100.
|
16
|
-
# prices = wrap_enum([500, 24, 4711, 412, 24])
|
17
|
-
# prices[selected_item].must_not > 100
|
18
|
-
#
|
19
|
-
# # Reify the constraint that the +x+:th variable in +int_enum+ must be in
|
20
|
-
# # range 7..17 with the boolean variable +bool+ and select strength
|
21
|
-
# # +domain+.
|
22
|
-
#
|
23
|
-
# int_enum[x].must_be.in(7..17, :reify => bool, :strength => :domain)
|
24
|
-
class ExpressionStub < Gecode::Constraints::Int::CompositeStub
|
25
|
-
def constrain_equal(variable, params, constrain)
|
26
|
-
enum, position = @params.values_at(:lhs, :position)
|
27
|
-
if constrain
|
28
|
-
variable.must_be.in enum.domain_range
|
29
|
-
end
|
30
|
-
|
31
|
-
# The enum can be a constant array.
|
32
|
-
enum = enum.to_int_var_array if enum.respond_to? :to_int_var_array
|
33
|
-
Gecode::Raw::element(@model.active_space, enum,
|
34
|
-
position.bind, variable.bind, *propagation_options)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Methods needed to add support for element constraints to enums.
|
39
|
-
module AdditionalEnumMethods #:nodoc:
|
1
|
+
module Gecode::IntEnum
|
2
|
+
module IntEnumOperand
|
40
3
|
# This adds the adder for the methods in the modules including it. The
|
41
4
|
# reason for doing it so indirect is that the first #[] won't be defined
|
42
5
|
# before the module that this is mixed into is mixed into an enum.
|
43
|
-
def self.included(enum_mod)
|
6
|
+
def self.included(enum_mod) #:nodoc:
|
44
7
|
enum_mod.module_eval do
|
45
|
-
# Now we enter the module
|
8
|
+
# Now we enter the module IntEnumOperands is mixed into.
|
46
9
|
class << self
|
47
10
|
alias_method :pre_element_included, :included
|
48
|
-
def included(mod)
|
11
|
+
def included(mod) #:nodoc:
|
49
12
|
mod.module_eval do
|
50
|
-
# Now we enter the module that the module possibly defining #[]
|
51
|
-
# is mixed into.
|
52
13
|
if instance_methods.include? '[]'
|
53
14
|
alias_method :pre_element_access, :[]
|
54
15
|
end
|
55
|
-
|
16
|
+
|
17
|
+
# Produces an IntOperand representing the
|
18
|
+
# i:th integer operand in the enumeration, where i is the
|
19
|
+
# value of the integer operand used as index. Think of it
|
20
|
+
# as array access in the world of constraint programming.
|
21
|
+
#
|
22
|
+
# ==== Examples
|
23
|
+
#
|
24
|
+
# # The operand at the +x+:th position in +int_enum+,
|
25
|
+
# # where +x+ is an integer operand.
|
26
|
+
# int_enum[x]
|
27
|
+
#
|
56
28
|
def [](*vars)
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
params = {:lhs => self, :position => vars.first}
|
61
|
-
return Gecode::Constraints::IntEnum::Element::ExpressionStub.new(
|
62
|
-
@model, params)
|
29
|
+
if vars.first.respond_to? :to_int_var
|
30
|
+
return Element::ElementIntOperand.new(
|
31
|
+
model, self, vars.first)
|
63
32
|
else
|
64
33
|
pre_element_access(*vars) if respond_to? :pre_element_access
|
65
34
|
end
|
@@ -71,12 +40,25 @@ module Gecode::Constraints::IntEnum::Element #:nodoc:
|
|
71
40
|
end
|
72
41
|
end
|
73
42
|
end
|
74
|
-
end
|
75
43
|
|
76
|
-
module
|
77
|
-
|
78
|
-
|
44
|
+
module Element #:nodoc:
|
45
|
+
class ElementIntOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
46
|
+
def initialize(model, enum_op, position_int_var_op)
|
47
|
+
super model
|
48
|
+
@enum = enum_op
|
49
|
+
@position = position_int_var_op
|
50
|
+
end
|
79
51
|
|
80
|
-
|
81
|
-
|
52
|
+
def constrain_equal(int_operand, constrain, propagation_options)
|
53
|
+
enum = @enum.to_int_enum
|
54
|
+
if constrain
|
55
|
+
int_operand.must_be.in enum.domain_range
|
56
|
+
end
|
57
|
+
|
58
|
+
Gecode::Raw::element(model.active_space, enum.bind_array,
|
59
|
+
@position.to_int_var.bind, int_operand.to_int_var.bind,
|
60
|
+
*propagation_options)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
82
64
|
end
|
@@ -1,6 +1,12 @@
|
|
1
|
-
module Gecode::
|
2
|
-
class
|
3
|
-
#
|
1
|
+
module Gecode::IntEnum
|
2
|
+
class IntEnumConstraintReceiver
|
3
|
+
# Constrains all operands in the enumeration to be equal.
|
4
|
+
# Neither negation nor reification is supported.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # Constrains all operands in +int_enum+ to be equal.
|
9
|
+
# int_enum.must_be.equal
|
4
10
|
def equal(options = {})
|
5
11
|
if @params[:negate]
|
6
12
|
# The best we could implement it as from here would be a bunch of
|
@@ -14,28 +20,18 @@ module Gecode::Constraints::IntEnum
|
|
14
20
|
end
|
15
21
|
|
16
22
|
@model.add_constraint Equality::EqualityConstraint.new(@model,
|
17
|
-
@params.update(Gecode::
|
23
|
+
@params.update(Gecode::Util.decode_options(options)))
|
18
24
|
end
|
19
25
|
end
|
20
26
|
|
21
27
|
# A module that gathers the classes and modules used in equality constraints.
|
22
28
|
module Equality #:nodoc:
|
23
|
-
|
24
|
-
# integer enumeration to be equal. Neither negation nor reification is
|
25
|
-
# supported.
|
26
|
-
#
|
27
|
-
# == Example
|
28
|
-
#
|
29
|
-
# # Constrains all variables in +int_enum+ to be equal.
|
30
|
-
# int_enum.must_be.equal
|
31
|
-
class EqualityConstraint < Gecode::Constraints::Constraint
|
29
|
+
class EqualityConstraint < Gecode::Constraint #:nodoc:
|
32
30
|
def post
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
# Fetch the parameters to Gecode.
|
37
|
-
Gecode::Raw::eq(@model.active_space, lhs, *propagation_options)
|
31
|
+
Gecode::Raw::rel(@model.active_space,
|
32
|
+
@params[:lhs].to_int_enum.bind_array,
|
33
|
+
Gecode::Raw::IRT_EQ, *propagation_options)
|
38
34
|
end
|
39
35
|
end
|
40
36
|
end
|
41
|
-
end
|
37
|
+
end
|
@@ -1,7 +1,17 @@
|
|
1
|
-
module Gecode::
|
2
|
-
class
|
3
|
-
#
|
4
|
-
#
|
1
|
+
module Gecode::IntEnum
|
2
|
+
class IntEnumConstraintReceiver
|
3
|
+
# Constrains all the operands in this enumeration to be equal to
|
4
|
+
# one of the specified tuples. Neither negation nor reification is
|
5
|
+
# supported.
|
6
|
+
#
|
7
|
+
# ==== Examples
|
8
|
+
#
|
9
|
+
# # Constrains the two integer operands in +numbers+ to either have
|
10
|
+
# # values 1 and 7, or values 47 and 11.
|
11
|
+
# numbers.must_be.in [[1,7], [47,11]]
|
12
|
+
#
|
13
|
+
# # The same as above, but preferring speed over low memory usage.
|
14
|
+
# numbers.must_be.in([[1,7], [47,11]], :kind => :speed)
|
5
15
|
def in(tuples, options = {})
|
6
16
|
if @params[:negate]
|
7
17
|
raise Gecode::MissingConstraintError, 'A negated tuple constraint is ' +
|
@@ -12,7 +22,7 @@ module Gecode::Constraints::IntEnum
|
|
12
22
|
'constraint.'
|
13
23
|
end
|
14
24
|
|
15
|
-
util = Gecode::
|
25
|
+
util = Gecode::Util
|
16
26
|
|
17
27
|
# Check that the tuples are correct.
|
18
28
|
expected_size = @params[:lhs].size
|
@@ -27,64 +37,9 @@ module Gecode::Constraints::IntEnum
|
|
27
37
|
@params.update(util.decode_options(options)))
|
28
38
|
end
|
29
39
|
|
30
|
-
#
|
31
|
-
# specified
|
32
|
-
#
|
33
|
-
# IntEnum::Extensional::RegexpConstraint for more information and examples of
|
34
|
-
# such regexps.
|
35
|
-
def match(regexp, options = {})
|
36
|
-
if @params[:negate]
|
37
|
-
raise Gecode::MissingConstraintError, 'A negated regexp constraint ' +
|
38
|
-
'is not implemented.'
|
39
|
-
end
|
40
|
-
unless options[:reify].nil?
|
41
|
-
raise ArgumentError, 'Reification is not supported by the regexp ' +
|
42
|
-
'constraint.'
|
43
|
-
end
|
44
|
-
|
45
|
-
@params[:regexp] =
|
46
|
-
Gecode::Constraints::Util::Extensional.parse_regexp regexp
|
47
|
-
@params.update Gecode::Constraints::Util.decode_options(options)
|
48
|
-
@model.add_constraint Extensional::RegexpConstraint.new(@model, @params)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# A module that gathers the classes and modules used in extensional
|
53
|
-
# constraints.
|
54
|
-
module Extensional #:nodoc:
|
55
|
-
# Describes a tuple constraint, which constrains all the variables in an
|
56
|
-
# enumeration of integer variables to be equal to one of the specified
|
57
|
-
# tuples. Neither negation nor reification is supported.
|
58
|
-
#
|
59
|
-
# == Example
|
60
|
-
#
|
61
|
-
# # Constrains the two integer variables in +numbers+ to either have
|
62
|
-
# # values 1 and 7, or values 47 and 11.
|
63
|
-
# numbers.must_be.in [[1,7], [47,11]]
|
64
|
-
#
|
65
|
-
# # The same as above, but preferring speed over low memory usage.
|
66
|
-
# numbers.must_be.in([[1,7], [47,11]], :kind => :speed)
|
67
|
-
class TupleConstraint < Gecode::Constraints::Constraint
|
68
|
-
def post
|
69
|
-
# Bind lhs.
|
70
|
-
lhs = @params[:lhs].to_int_var_array
|
71
|
-
|
72
|
-
# Create the tuple set.
|
73
|
-
tuple_set = Gecode::Raw::TupleSet.new
|
74
|
-
@params[:tuples].each do |tuple|
|
75
|
-
tuple_set.add tuple
|
76
|
-
end
|
77
|
-
tuple_set.finalize
|
78
|
-
|
79
|
-
# Post the constraint.
|
80
|
-
Gecode::Raw::extensional(@model.active_space, lhs, tuple_set,
|
81
|
-
*propagation_options)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
# Describes a regexp constraint, which constrains the enumeration of
|
86
|
-
# integer variables to match a specified regexp in the integer
|
87
|
-
# domain. Neither negation nor reification is supported.
|
40
|
+
# Constrains the sequence of operands in this enumeration to match
|
41
|
+
# a specified regexp in the integer domain. Neither negation nor
|
42
|
+
# reification is supported.
|
88
43
|
#
|
89
44
|
# == Regexp syntax
|
90
45
|
#
|
@@ -114,7 +69,7 @@ module Gecode::Constraints::IntEnum
|
|
114
69
|
# Additionally Model#at_least_once and Model#at_most_once are
|
115
70
|
# provided as convenience methods.
|
116
71
|
#
|
117
|
-
#
|
72
|
+
# ==== Examples
|
118
73
|
#
|
119
74
|
# # Matches 1 followed by any number of 2s.
|
120
75
|
# [1, repeat(2)]
|
@@ -166,28 +121,66 @@ module Gecode::Constraints::IntEnum
|
|
166
121
|
# # Exactly the same as the above.
|
167
122
|
# [0, repeat(1, 0, 1)]
|
168
123
|
#
|
169
|
-
#
|
124
|
+
# ==== Examples
|
170
125
|
#
|
171
|
-
# # Constrains the two integer
|
126
|
+
# # Constrains the two integer operands in +numbers+ to have
|
172
127
|
# # values 1 and 7.
|
173
128
|
# numbers.must.match [1, 7]
|
174
129
|
#
|
175
|
-
# # Constrains the integer
|
130
|
+
# # Constrains the integer operands in +numbers+ to contain the
|
176
131
|
# # value 47 followed by 11, with all other values set to -1.
|
177
132
|
# numbers.must.match [repeat(-1), 47, 11, repeat(-1)]
|
178
133
|
#
|
179
|
-
# # Constrains exactly three of the integer
|
134
|
+
# # Constrains exactly three of the integer operands in +numbers+ to
|
180
135
|
# # contain 47 or 11, each followed by at least two
|
181
|
-
# #
|
136
|
+
# # operands set to -1. All other operands are constrained to
|
182
137
|
# # equal -1.
|
183
138
|
# numbers.must.match repeat([repeat(-1), any(11, 47),
|
184
139
|
# repeat(-1, 2)], 3, 3)
|
185
140
|
#
|
186
|
-
|
141
|
+
def match(regexp, options = {})
|
142
|
+
if @params[:negate]
|
143
|
+
raise Gecode::MissingConstraintError, 'A negated regexp constraint ' +
|
144
|
+
'is not implemented.'
|
145
|
+
end
|
146
|
+
unless options[:reify].nil?
|
147
|
+
raise ArgumentError, 'Reification is not supported by the regexp ' +
|
148
|
+
'constraint.'
|
149
|
+
end
|
150
|
+
|
151
|
+
@params[:regexp] =
|
152
|
+
Gecode::Util::Extensional.parse_regexp regexp
|
153
|
+
@params.update Gecode::Util.decode_options(options)
|
154
|
+
@model.add_constraint Extensional::RegexpConstraint.new(@model, @params)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# A module that gathers the classes and modules used in extensional
|
159
|
+
# constraints.
|
160
|
+
module Extensional #:nodoc:
|
161
|
+
class TupleConstraint < Gecode::Constraint #:nodoc:
|
162
|
+
def post
|
163
|
+
# Bind lhs.
|
164
|
+
lhs = @params[:lhs].to_int_enum.bind_array
|
165
|
+
|
166
|
+
# Create the tuple set.
|
167
|
+
tuple_set = Gecode::Raw::TupleSet.new
|
168
|
+
@params[:tuples].each do |tuple|
|
169
|
+
tuple_set.add tuple
|
170
|
+
end
|
171
|
+
tuple_set.finalize
|
172
|
+
|
173
|
+
# Post the constraint.
|
174
|
+
Gecode::Raw::extensional(@model.active_space, lhs, tuple_set,
|
175
|
+
*propagation_options)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class RegexpConstraint < Gecode::Constraint #:nodoc:
|
187
180
|
def post
|
188
181
|
lhs, regexp = @params.values_at(:lhs, :regexp)
|
189
|
-
Gecode::Raw::extensional(@model.active_space,
|
190
|
-
regexp, *propagation_options)
|
182
|
+
Gecode::Raw::extensional(@model.active_space,
|
183
|
+
lhs.to_int_enum.bind_array, regexp, *propagation_options)
|
191
184
|
end
|
192
185
|
end
|
193
186
|
end
|