An integer enumeration operand is an enumeration of integer operands.
Enumerations of integer operands are commonly created using Gecode::Mixin#int_var_array
and Gecode::Mixin#int_var_matrix
.
# Creates an array of five integer operands with domain 0..9 . int_enum = int_var_array(5, 0..9)
A less common way to create the operands is by using Gecode::Mixin#wrap_enum
to wrap an existing enumeration that contains
integer operands.
int_enum = wrap_enum([int_operand1, int_operand2])
Generated from IntEnumConstraintReceiver
.
distinct
distinct(options = {})
Constrains all integer operands in the enumeration to be distinct (different). The constraint can also be used with constant offsets, so that the operands, with specified offsets added, must be distinct.
The constraint does not support negation nor reification.
# Constrains all operands in +int_enum+ to be assigned different # values. int_enum.must_be.distinct # The same as above, but also selects that the strength +domain+ should # be used. int_enum.must_be.distinct(:strength => :domain) # Uses the offset to constrain that no number may be the previous number # incremented by one. numbers = int_var_array(8, 0..9) numbers.must_be.distinct(:offsets => (1..numbers.size).to_a.reverse)
channel
channel(int_enum, options = {})
Constrains this enumeration to “channel” int_enum
. Channel
constraints are used to give access to multiple viewpoints when modelling.
The channel constraint can be thought of as constraining the arrays to be each other’s inverses. I.e. if the i:th value in the first enumeration is j, then the j:th value in the second enumeration is constrained to be i.
Neither reification nor negation is supported.
Lets say that we’re modelling a sequence of numbers that must be distinct and that we want access to the following two view simultaneously.
The sequence is modelled as an array of integer variables where the first variable holds the value of the first position in the sequence, the second the value of the second position and so on.
# n variables with values from 0 to n-1. elements = int_var_array(n, 0...n) elements.must_be.distinct
That way elements
will contain the actual sequence when the problem has
been solved.
The sequence is modelled as the positions of each value in 0..(n-1) in the sequence. That way the first variable would hold the positions of 0 in the sequence, the second variable would hold the positions of 1 in the sequence and so on.
positions = int_var_array(n, 0...n)
positions.must_be.distinct
In essence the relationship between the two arrays elements
and
positions
is that
elements.map{ |e| e.val }[i] == positions.map{ |p| p.val }.index(i)
for all i in 0..(n-1). This relationship is enforced by the channel constraint as follows.
elements.must.channel positions
in
in(tuples, options = {})
Constrains all the operands in this enumeration to be equal to one of the specified tuples. Neither negation nor reification is supported.
# Constrains the two integer operands in +numbers+ to either have # values 1 and 7, or values 47 and 11. numbers.must_be.in [[1,7], [47,11]] # The same as above, but preferring speed over low memory usage. numbers.must_be.in([[1,7], [47,11]], :kind => :speed)
match
match(regexp, options = {})
Constrains the sequence of operands in this enumeration to match a specified regexp in the integer domain. Neither negation nor reification is supported.
The regular expressions are specified using arrays, integers and a few methods provided by Mixin. Arrays are used to group the integers in sequences that must be matched. The following array describes a regular expression matching a 1 followed by a 7.
[1, 7]
Arrays can be nested or left out when not needed. I.e. the above is semantically equal to
[[[1], 7]]
A couple of methods provided by Mixin are used to express patterns beyond mere sequences:
Additionally Mixin#at_least_once and Mixin#at_most_once are provided as convenience methods.
# Matches 1 followed by any number of 2s. [1, repeat(2)] # Semantically the same as above. It just has a bunch of # needless brackets thrown in. [[1], [repeat([2])]] # Matches 1 followed by [a 2 followed by a 3] at least two times. # Matches e.g. 1, 2, 3, 2, 3 [1, repeat([2, 3], 2)] # Matches between one and two [2 followed by [at least three 1]] # followed by between three and four 3. Matches e.g. # 2, 1, 1, 1, 2, 1, 1, 1, 3, 3, 3 [repeat([2, repeat(1, 3], 1, 2), repeat(3, 3, 4)] # Matches [1, 2 or 3] followed by 4. Matches e.g. 2, 4 [any(1, 2, 3), 4] # Matches 0 followed by [[1 followed by 2] or [3 followed by 5]]. # Matches e.g. 0, 1, 2 as well as 0, 3, 5 [0, any([1, 2], [3, 5])] # Matches 0 followed by [[[1 followed by 7] at least two times] # or [[8, 9], at most two times]. Matches e.g. # 0, 1, 7, 1, 7, 1, 7 as well as 0, 8, 9 [0, any(repeat([1, 7], 2), repeat([8, 9], 0, 2)] # Matches 0 followed by at least one 1. [0, at_least_once(1)] # Exactly the same as the above. [0, repeat(1, 1)] # Matches 0 followed by at least one [[1 followed by 7] or [3 # followed by 2]]. Matches e.g. 0, 1, 7, 3, 2, 1, 7 [0, at_least_once(any([1, 7], [3, 2]] # Matches 0 followed by at either [[1 followed by 7] at least once] # or [[3 followed by 2] at least once]. Matches e.g. # 0, 1, 7, 1, 7 but does _not_ match 0, 1, 7, 3, 2, 1, 7 [0, any(at_least_once([1, 7]), at_least_once([3, 2])] # Matches 0, followed by at most one 1. Matches 0 as well as # 0, 1 [0, at_most_once(1)] # Exactly the same as the above. [0, repeat(1, 0, 1)]
# Constrains the two integer operands in +numbers+ to have # values 1 and 7. numbers.must.match [1, 7] # Constrains the integer operands in +numbers+ to contain the # value 47 followed by 11, with all other values set to -1. numbers.must.match [repeat(-1), 47, 11, repeat(-1)] # Constrains exactly three of the integer operands in +numbers+ to # contain 47 or 11, each followed by at least two # operands set to -1. All other operands are constrained to # equal -1. numbers.must.match repeat([repeat(-1), any(11, 47), repeat(-1, 2)], 3, 3)
sorted
sorted(options = {})
Constrains the elements in this enumeration to be sorted in ascending order. The following options can be given in addition to the common constraint options:
If neither of those options are specified then the original enumerable will be constrained to be sorted (otherwise not). Sort constraints with options do not allow negation.
# Constrain +numbers+ to be sorted. numbers.must_be.sorted # Constrain +numbers+ to not be sorted. numbers.must_not_be.sorted # Constrain +sorted_numbers+ to be a sorted version of +numbers+. numbers.must_be.sorted(:as => sorted_numbers) # Constrain +order+ to be the order in which +numbers+ has to be # ordered to be sorted. numbers.must_be.sorted(:order => order) # Constrain +sorted_numbers+ to be +numbers+ sorted in the order # described by the IntEnum +order+. numbers.must_be.sorted(:as => sorted_numbers, :order => order) # Constrains +numbers+ to be sorted, reifying with the boolean # operand +is_sorted+, while selecting +domain+ as strength. numbers.must_be.sorted(:reify => :is_sorted, :strength => :domain)
equal
equal(options = {})
Constrains all operands in the enumeration to be equal. Neither negation nor reification is supported.
# Constrains all operands in +int_enum+ to be equal.
int_enum.must_be.equal
Generated from IntEnumOperand
.
[]
[](*vars)
Produces an IntOperand representing the i:th integer operand in the enumeration, where i is the value of the integer operand used as index. Think of it as array access in the world of constraint programming.
# The operand at the +x+:th position in +int_enum+, # where +x+ is an integer operand. int_enum[x]
count
count(int_operand_or_fixnum)
Produces a new IntOperand representing the number of times
int_operand_or_fixnum
is present in this enumeration.
# The number of times 17 occurs in +int_enum+. int_enum.count(17) # The number of times +int_operand+ occurs in +int_enum+. int_enum.count(int_operand)
max
max()
Produces an IntOperand representing the maximum value of the integer operands in this enumeration.
# The maximum of +int_enum+.
int_enum.max
min
min()
Produces an IntOperand representing the minimum value of the integer operands in this enumeration.
# The minimum of +int_enum+.
int_enum.min