gecoder 0.7.0 → 0.7.1
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 +6 -0
- data/README +1 -1
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +107 -0
- data/example/sudoku.rb +2 -6
- data/lib/gecoder/bindings.rb +1 -1
- data/lib/gecoder/bindings/bindings.rb +20 -0
- data/lib/gecoder/interface/binding_changes.rb +2 -2
- data/lib/gecoder/interface/branch.rb +50 -51
- data/lib/gecoder/interface/constraints.rb +10 -10
- data/lib/gecoder/interface/constraints/bool/boolean.rb +79 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +34 -4
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +14 -9
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +26 -8
- data/lib/gecoder/interface/constraints/int/domain.rb +30 -3
- data/lib/gecoder/interface/constraints/int/linear.rb +82 -16
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +31 -3
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +63 -3
- data/lib/gecoder/interface/constraints/int_enum/count.rb +20 -3
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +22 -2
- data/lib/gecoder/interface/constraints/int_enum/element.rb +23 -4
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +9 -2
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +28 -3
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +1 -1
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +13 -8
- data/lib/gecoder/interface/constraints/set/cardinality.rb +27 -8
- data/lib/gecoder/interface/constraints/set/connection.rb +72 -6
- data/lib/gecoder/interface/constraints/set/domain.rb +46 -3
- data/lib/gecoder/interface/constraints/set/operation.rb +35 -4
- data/lib/gecoder/interface/constraints/set/relation.rb +59 -6
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +22 -3
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +26 -2
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +110 -36
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +11 -7
- data/lib/gecoder/interface/model.rb +6 -6
- data/lib/gecoder/interface/search.rb +6 -6
- data/lib/gecoder/interface/variables.rb +56 -12
- data/lib/gecoder/version.rb +1 -1
- data/specs/constraints/linear.rb +167 -1
- data/specs/constraints/set_domain.rb +6 -0
- data/tasks/distribution.rake +25 -3
- data/tasks/website.rake +5 -12
- metadata +10 -4
- data/vendor/rust/configure.rb +0 -6
- data/vendor/rust/out.rb +0 -627
@@ -1,17 +1,21 @@
|
|
1
1
|
module Gecode
|
2
2
|
class FreeBoolVar
|
3
|
+
# Initiates a boolean constraint with this variable or +var+.
|
3
4
|
def |(var)
|
4
5
|
Constraints::Bool::ExpressionNode.new(self, @model) | var
|
5
6
|
end
|
6
7
|
|
8
|
+
# Initiates a boolean constraint with this variable and +var+.
|
7
9
|
def &(var)
|
8
10
|
Constraints::Bool::ExpressionNode.new(self, @model) & var
|
9
11
|
end
|
10
12
|
|
13
|
+
# Initiates a boolean constraint with this variable exclusive or +var+.
|
11
14
|
def ^(var)
|
12
15
|
Constraints::Bool::ExpressionNode.new(self, @model) ^ var
|
13
16
|
end
|
14
17
|
|
18
|
+
# Initiates a boolean constraint with this variable implies +var+.
|
15
19
|
def implies(var)
|
16
20
|
Constraints::Bool::ExpressionNode.new(self, @model).implies var
|
17
21
|
end
|
@@ -20,7 +24,7 @@ module Gecode
|
|
20
24
|
# A module that gathers the classes and modules used in boolean constraints.
|
21
25
|
module Constraints::Bool
|
22
26
|
# Describes a boolean expression (following after must*).
|
23
|
-
class Expression
|
27
|
+
class Expression #:nodoc:
|
24
28
|
def ==(expression, options = {})
|
25
29
|
@params.update Gecode::Constraints::Util.decode_options(options)
|
26
30
|
@model.add_constraint BooleanConstraint.new(@model,
|
@@ -49,7 +53,77 @@ module Gecode
|
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
|
-
# Describes a boolean
|
56
|
+
# Describes a constraint on a boolean expression.
|
57
|
+
#
|
58
|
+
# == Boolean expressions
|
59
|
+
#
|
60
|
+
# A boolean expression consists of several boolean variable with various
|
61
|
+
# boolean operators. The available operators are:
|
62
|
+
#
|
63
|
+
# [<tt>|</tt>] Or
|
64
|
+
# [<tt>&</tt>] And
|
65
|
+
# [<tt>^</tt>] Exclusive or
|
66
|
+
# [+implies+] Implication
|
67
|
+
#
|
68
|
+
# === Examples
|
69
|
+
#
|
70
|
+
# # +b1+ and +b2+
|
71
|
+
# b1 & b2
|
72
|
+
#
|
73
|
+
# # (+b1+ and +b2+) or +b3+
|
74
|
+
# (b1 & b1) | b3
|
75
|
+
#
|
76
|
+
# # (+b1+ and +b2+) or (+b3+ exclusive or +b1+)
|
77
|
+
# (b1 & b2) | (b3 ^ b1)
|
78
|
+
#
|
79
|
+
# # (+b1+ implies +b2+) and (+b3+ implies +b2+)
|
80
|
+
# (b1.implies b2) & (b3.implies b2)
|
81
|
+
#
|
82
|
+
# == Domain
|
83
|
+
#
|
84
|
+
# A domain constraint just specifies that a boolean expression must be true
|
85
|
+
# or false. Negation and reification are supported.
|
86
|
+
#
|
87
|
+
# === Examples
|
88
|
+
#
|
89
|
+
# # +b1+ and +b2+ must be true.
|
90
|
+
# (b1 & b2).must_be.true
|
91
|
+
#
|
92
|
+
# # (+b1+ implies +b2+) and (+b3+ implies +b2+) must be false.
|
93
|
+
# ((b1.implies b2) & (b3.implies b2)).must_be.false
|
94
|
+
#
|
95
|
+
# # +b1+ and +b2+ must be true. We reify it with +bool+ and select the
|
96
|
+
# # strength +domain+.
|
97
|
+
# (b1 & b2).must_be.true(:reify => bool, :strength => :domain)
|
98
|
+
#
|
99
|
+
# == Equality
|
100
|
+
#
|
101
|
+
# A constraint with equality specifies that two boolean expressions must be
|
102
|
+
# equal. Negation and reification are supported. Any of <tt>==</tt>,
|
103
|
+
# +equal+ and +equal_to+ may be used for equality.
|
104
|
+
#
|
105
|
+
# === Examples
|
106
|
+
#
|
107
|
+
# # +b1+ and +b2+ must equal +b1+ or +b2+.
|
108
|
+
# (b1 & b2).must == (b1 | b2)
|
109
|
+
#
|
110
|
+
# # +b1+ and +b2+ must not equal +b3+. We reify it with +bool+ and select
|
111
|
+
# # the strength +domain+.
|
112
|
+
# (b1 & b2).must_not.equal(b3, :reify => bool, :select => :domain)
|
113
|
+
#
|
114
|
+
# == Implication
|
115
|
+
#
|
116
|
+
# A constraint using +imply+ specified that one boolean expression must
|
117
|
+
# imply the other. Negation and reification are supported.
|
118
|
+
#
|
119
|
+
# === Examples
|
120
|
+
#
|
121
|
+
# # +b1+ must imply +b2+
|
122
|
+
# b1.must.imply b2
|
123
|
+
#
|
124
|
+
# # +b1+ and +b2+ must not imply +b3+. We reify it with +bool+ and select
|
125
|
+
# # +domain+ as strength.
|
126
|
+
# (b1 & b2).must_not.imply b3
|
53
127
|
class BooleanConstraint < Gecode::Constraints::ReifiableConstraint
|
54
128
|
def post
|
55
129
|
lhs, rhs, negate, strength, reif_var = @params.values_at(:lhs, :rhs,
|
@@ -87,7 +161,7 @@ module Gecode
|
|
87
161
|
|
88
162
|
# A module containing the methods for the basic boolean operations. Depends
|
89
163
|
# on that the class mixing it in defined #model.
|
90
|
-
module OperationMethods
|
164
|
+
module OperationMethods #:nodoc
|
91
165
|
include Gecode::Constraints::LeftHandSideMethods
|
92
166
|
|
93
167
|
private
|
@@ -130,7 +204,7 @@ module Gecode
|
|
130
204
|
|
131
205
|
# Describes a binary tree of expression nodes which together form a boolean
|
132
206
|
# expression.
|
133
|
-
class ExpressionTree
|
207
|
+
class ExpressionTree #:nodoc:
|
134
208
|
include OperationMethods
|
135
209
|
|
136
210
|
# Constructs a new expression with the specified nodes. The proc should
|
@@ -153,7 +227,7 @@ module Gecode
|
|
153
227
|
end
|
154
228
|
|
155
229
|
# Describes a single node in a boolean expression.
|
156
|
-
class ExpressionNode
|
230
|
+
class ExpressionNode #:nodoc:
|
157
231
|
include OperationMethods
|
158
232
|
|
159
233
|
attr :model
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeBoolVar
|
3
|
+
# Creates a linear expression where the bool variables are summed.
|
4
|
+
def +(var)
|
5
|
+
Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
|
6
|
+
@model) + var
|
7
|
+
end
|
8
|
+
|
9
|
+
alias_method :pre_linear_mult, :* if instance_methods.include? '*'
|
10
|
+
|
11
|
+
# Creates a linear expression where the bool variable is multiplied with
|
12
|
+
# a constant integer.
|
13
|
+
def *(int)
|
14
|
+
if int.kind_of? Fixnum
|
15
|
+
Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
|
16
|
+
@model) * int
|
17
|
+
else
|
18
|
+
pre_linear_mult(int) if respond_to? :pre_linear_mult
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a linear expression where the specified variable is subtracted
|
23
|
+
# from this one.
|
24
|
+
def -(var)
|
25
|
+
Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
|
26
|
+
@model) - var
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -15,9 +15,25 @@ module Gecode
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
# A module that gathers the classes and modules used by boolean enumeration
|
19
|
+
# constraints.
|
18
20
|
module Constraints::BoolEnum
|
19
|
-
# Describes
|
20
|
-
#
|
21
|
+
# Describes a CompositeStub for the conjunction constraint, which constrain
|
22
|
+
# the conjunction of all boolean variables in an enumeration.
|
23
|
+
#
|
24
|
+
# == Example
|
25
|
+
#
|
26
|
+
# # The conjunction of all variables in +bool_enum+ must be true. I.e. all
|
27
|
+
# # boolean variables must take the value true.
|
28
|
+
# bool_enum.conjunction.must_be.true
|
29
|
+
#
|
30
|
+
# # The conjunction of all variables in +bool_enum+ must equal b1.
|
31
|
+
# bool_enum.conjunction.must == b1
|
32
|
+
#
|
33
|
+
# # The conjunction of all variables in +bool_enum+ must not equal b1 and
|
34
|
+
# # b2. It's reified it with +bool+ and selects the strength +domain+.
|
35
|
+
# bool_enum.conjunction.must_not.equal(b1 & b2, :reify => bool,
|
36
|
+
# :strength => :domain)
|
21
37
|
class ConjunctionStub < Gecode::Constraints::Bool::CompositeStub
|
22
38
|
def constrain_equal(variable, params, constrain)
|
23
39
|
enum, strength = @params.values_at(:lhs, :strength)
|
@@ -35,8 +51,22 @@ module Gecode
|
|
35
51
|
end
|
36
52
|
end
|
37
53
|
|
38
|
-
# Describes
|
39
|
-
#
|
54
|
+
# Describes a CompositeStub for the disjunction constraint, which constrain
|
55
|
+
# the disjunction of all boolean variables in an enumeration.
|
56
|
+
#
|
57
|
+
# == Example
|
58
|
+
#
|
59
|
+
# # The disjunction of all variables in +bool_enum+ must be true. I.e. at
|
60
|
+
# # least one of the boolean variables must take the value true.
|
61
|
+
# bool_enum.disjunction.must_be.true
|
62
|
+
#
|
63
|
+
# # The disjunction of all variables in +bool_enum+ must equal b1.
|
64
|
+
# bool_enum.conjunction.must == b1
|
65
|
+
#
|
66
|
+
# # The disjunction of all variables in +bool_enum+ must not equal b1 and
|
67
|
+
# # b2. It's reified it with +bool+ and selects the strength +domain+.
|
68
|
+
# bool_enum.disjunction.must_not.equal(b1 & b2, :reify => bool,
|
69
|
+
# :strength => :domain)
|
40
70
|
class DisjunctionStub < Gecode::Constraints::Bool::CompositeStub
|
41
71
|
def constrain_equal(variable, params, constrain)
|
42
72
|
enum, strength = @params.values_at(:lhs, :strength)
|
@@ -15,12 +15,12 @@ module Gecode
|
|
15
15
|
# (but not enumerations).
|
16
16
|
module Constraints::Bool
|
17
17
|
# Describes a boolean expression.
|
18
|
-
class Expression < Gecode::Constraints::Expression
|
18
|
+
class Expression < Gecode::Constraints::Expression #:nodoc:
|
19
19
|
end
|
20
20
|
|
21
21
|
# A composite expression which is an bool expression with a left hand side
|
22
22
|
# resulting from a previous constraint.
|
23
|
-
class CompositeExpression < Gecode::Constraints::CompositeExpression
|
23
|
+
class CompositeExpression < Gecode::Constraints::CompositeExpression #:nodoc:
|
24
24
|
# The block given should take three parameters. The first is the variable
|
25
25
|
# that should be the left hand side, if it's nil then a new one should be
|
26
26
|
# created. The second is the has of parameters. The block should return
|
@@ -49,16 +49,20 @@ module Gecode
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
# Describes a stub that produces an int variable, which can then be used
|
53
|
-
# the normal
|
54
|
-
#
|
52
|
+
# Describes a stub that produces an int variable, which can then be used
|
53
|
+
# with the normal int variable constraints. An example would be the
|
54
|
+
# conjunction constraint.
|
55
55
|
#
|
56
56
|
# bools.conjunction.must == b1 | b2
|
57
|
+
#
|
58
|
+
# <tt>bools.conjunction</tt> produces a boolean variable which the
|
59
|
+
# constraint <tt>.must == b1 | b2</tt> is then applied to. In the above
|
60
|
+
# case two constraints (and one temporary variable) are required, but in
|
61
|
+
# the case of equality only one constraint is required.
|
57
62
|
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# only one constraint is required.
|
63
|
+
# Whether a constraint involving a reification stub supports negation,
|
64
|
+
# reification, strength options and so on depends on the constraint on the
|
65
|
+
# right hand side.
|
62
66
|
class CompositeStub < Gecode::Constraints::CompositeStub
|
63
67
|
def initialize(model, params)
|
64
68
|
super(CompositeExpression, model, params)
|
@@ -68,3 +72,4 @@ module Gecode
|
|
68
72
|
end
|
69
73
|
|
70
74
|
require 'gecoder/interface/constraints/bool/boolean'
|
75
|
+
require 'gecoder/interface/constraints/bool/linear'
|
@@ -4,10 +4,10 @@ class Gecode::FreeIntVar
|
|
4
4
|
Gecode::Constraints::Int::Arithmetic::AbsExpressionStub.new(@model,
|
5
5
|
:lhs => self)
|
6
6
|
end
|
7
|
-
|
8
|
-
# Creates a linear expression where the int variable is multiplied with
|
9
|
-
# a constant integer.
|
7
|
+
|
10
8
|
alias_method :pre_arith_mult, :* if instance_methods.include? '*'
|
9
|
+
|
10
|
+
# Begins a multiplication constraint involving the two int variable.
|
11
11
|
def *(var)
|
12
12
|
if var.kind_of? Gecode::FreeIntVar
|
13
13
|
Gecode::Constraints::Int::Arithmetic::MultExpressionStub.new(
|
@@ -19,9 +19,18 @@ class Gecode::FreeIntVar
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# A module that gathers the classes and modules used by arithmetic constraints.
|
22
|
-
module Gecode::Constraints::Int::Arithmetic
|
23
|
-
# Describes
|
24
|
-
#
|
22
|
+
module Gecode::Constraints::Int::Arithmetic #:nodoc:
|
23
|
+
# Describes a CompositeStub for absolute value constraints, which constrain
|
24
|
+
# the absolute value of an integer variable.
|
25
|
+
#
|
26
|
+
# == Examples
|
27
|
+
#
|
28
|
+
# # The absolute value of +x+ must be less than 2.
|
29
|
+
# x.abs.must < 2
|
30
|
+
#
|
31
|
+
# # The absolute value of +x+ must be in the range 5..7, with +bool+ as
|
32
|
+
# # reification variable and +value+ as strength.
|
33
|
+
# x.abs.must_be.in(5..7, :reify => bool, :strength => :value)
|
25
34
|
class AbsExpressionStub < Gecode::Constraints::Int::CompositeStub
|
26
35
|
def constrain_equal(variable, params, constrain)
|
27
36
|
lhs, strength = @params.values_at(:lhs, :strength)
|
@@ -34,8 +43,17 @@ module Gecode::Constraints::Int::Arithmetic
|
|
34
43
|
end
|
35
44
|
end
|
36
45
|
|
37
|
-
# Describes
|
38
|
-
#
|
46
|
+
# Describes a CompositeStub for multiplication constraint, which constrain
|
47
|
+
# the value of the multiplication of two variables.
|
48
|
+
#
|
49
|
+
# == Examples
|
50
|
+
#
|
51
|
+
# # The value of +x*y+ must be equal to their sum.
|
52
|
+
# (x*y).must == x + y
|
53
|
+
#
|
54
|
+
# # The valye of +x*y+ must be less than 17, with +bool+ as reification
|
55
|
+
# # variable and +domain+ as strength.
|
56
|
+
# (x*y).must_be.less_than(17, :reify => bool, :strength => :domain)
|
39
57
|
class MultExpressionStub < Gecode::Constraints::Int::CompositeStub
|
40
58
|
def constrain_equal(variable, params, constrain)
|
41
59
|
lhs, lhs2, strength = @params.values_at(:lhs, :var, :strength)
|
@@ -16,8 +16,22 @@ module Gecode::Constraints::Int
|
|
16
16
|
end
|
17
17
|
|
18
18
|
# A module that gathers the classes and modules used in domain constraints.
|
19
|
-
module Domain
|
20
|
-
#
|
19
|
+
module Domain #:nodoc:
|
20
|
+
# Range domain constraints specify that an integer variable must be
|
21
|
+
# contained within a specified range of integers. Supports reification and
|
22
|
+
# negation.
|
23
|
+
#
|
24
|
+
# == Examples
|
25
|
+
#
|
26
|
+
# # +x+ must be in the range 1..10
|
27
|
+
# x.must_be.in 1..10
|
28
|
+
#
|
29
|
+
# # +x+ must not be in the range -5...5
|
30
|
+
# x.must_not_be.in -5...5
|
31
|
+
#
|
32
|
+
# # Specifies the above, but but reifies the constraint with the boolean
|
33
|
+
# # variable +bool+ and specified +value+ as strength.
|
34
|
+
# x.must_not_be.in(-5...5, :reify => bool, :strength => :value)
|
21
35
|
class RangeDomainConstraint < Gecode::Constraints::ReifiableConstraint
|
22
36
|
def post
|
23
37
|
var, domain, reif_var, strength = @params.values_at(:lhs, :domain,
|
@@ -31,7 +45,20 @@ module Gecode::Constraints::Int
|
|
31
45
|
negate_using_reification
|
32
46
|
end
|
33
47
|
|
34
|
-
#
|
48
|
+
# Enum domain constraints specify that an integer variable must be contained
|
49
|
+
# in an enumeration of integers. Supports reification and negation.
|
50
|
+
#
|
51
|
+
# == Examples
|
52
|
+
#
|
53
|
+
# # +x+ must be in the enumeration [3,5,7].
|
54
|
+
# x.must_be.in [3,5,7]
|
55
|
+
#
|
56
|
+
# # +x+ must not be in the enumeration [5,6,7,17].
|
57
|
+
# x.must_not_be.in [5,6,7,17]
|
58
|
+
#
|
59
|
+
# # Specifies the above, but but reifies the constraint with the boolean
|
60
|
+
# # variable +bool+ and specified +value+ as strength.
|
61
|
+
# x.must_not_be.in(-[5,6,7,17], :reify => bool, :strength => :value)
|
35
62
|
class EnumDomainConstraint < Gecode::Constraints::ReifiableConstraint
|
36
63
|
def post
|
37
64
|
space = @model.active_space
|
@@ -6,9 +6,10 @@ module Gecode
|
|
6
6
|
@model) + var
|
7
7
|
end
|
8
8
|
|
9
|
+
alias_method :pre_linear_mult, :* if instance_methods.include? '*'
|
10
|
+
|
9
11
|
# Creates a linear expression where the int variable is multiplied with
|
10
12
|
# a constant integer.
|
11
|
-
alias_method :pre_linear_mult, :* if instance_methods.include? '*'
|
12
13
|
def *(int)
|
13
14
|
if int.kind_of? Fixnum
|
14
15
|
Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
|
@@ -27,7 +28,7 @@ module Gecode
|
|
27
28
|
end
|
28
29
|
|
29
30
|
module Constraints::Int
|
30
|
-
class Expression
|
31
|
+
class Expression #:nodoc:
|
31
32
|
# Add some relation selection based on whether the expression is negated.
|
32
33
|
alias_method :pre_linear_initialize, :initialize
|
33
34
|
def initialize(model, params)
|
@@ -67,7 +68,9 @@ module Gecode
|
|
67
68
|
if expression.nil?
|
68
69
|
simple_expression?(@params[:lhs])
|
69
70
|
else
|
70
|
-
expression.kind_of?(Gecode::FreeIntVar) or
|
71
|
+
expression.kind_of?(Gecode::FreeIntVar) or
|
72
|
+
expression.kind_of?(Gecode::FreeBoolVar) or
|
73
|
+
expression.kind_of?(Fixnum)
|
71
74
|
end
|
72
75
|
end
|
73
76
|
|
@@ -82,12 +85,13 @@ module Gecode
|
|
82
85
|
def add_linear_constraint(relation_type, right_hand_side)
|
83
86
|
# Bind parameters.
|
84
87
|
lhs = @params[:lhs]
|
85
|
-
if lhs.kind_of? Gecode::
|
88
|
+
if lhs.kind_of?(Gecode::FreeIntVar) or lhs.kind_of?(Gecode::FreeBoolVar)
|
86
89
|
lhs = lhs * 1 # Convert to Gecode::Raw::LinExp
|
87
90
|
end
|
88
91
|
if not (right_hand_side.respond_to? :to_minimodel_lin_exp or
|
89
|
-
right_hand_side.kind_of?
|
90
|
-
right_hand_side.kind_of?
|
92
|
+
right_hand_side.kind_of?(Gecode::FreeIntVar) or
|
93
|
+
right_hand_side.kind_of?(Gecode::FreeBoolVar) or
|
94
|
+
right_hand_side.kind_of?(Fixnum))
|
91
95
|
raise TypeError, 'Invalid right hand side of linear equation.'
|
92
96
|
end
|
93
97
|
|
@@ -107,8 +111,34 @@ module Gecode
|
|
107
111
|
end
|
108
112
|
|
109
113
|
# A module that gathers the classes and modules used in linear constraints.
|
110
|
-
module Constraints::Int::Linear
|
111
|
-
#
|
114
|
+
module Constraints::Int::Linear #:nodoc:
|
115
|
+
# Linear constraints specify that an integer variable must have a linear
|
116
|
+
# equation containing variables must hold. The same relations and options
|
117
|
+
# used in +SimpleRelationConstraint+ can also be used for linear
|
118
|
+
# constraints.
|
119
|
+
#
|
120
|
+
# Boolean variables can also be used instead of integer variables. In that
|
121
|
+
# case a boolean variable assigned true is equal to 1 and a boolean variable
|
122
|
+
# assigned false is equal to 0. There is one exception: boolean variables
|
123
|
+
# can not be used alone as left hand side.
|
124
|
+
#
|
125
|
+
# Do not mix boolean and integer variables. Even if possible it's not
|
126
|
+
# supported, and might be removed in the future.
|
127
|
+
#
|
128
|
+
# == Examples
|
129
|
+
#
|
130
|
+
# # The sum of the int variables +x+ and +y+ must equal +z+ + 3.
|
131
|
+
# (x + y).must == z + 3
|
132
|
+
#
|
133
|
+
# # Another way of writing the above.
|
134
|
+
# z.must == x + y - 3
|
135
|
+
#
|
136
|
+
# # The inequality 10(x + y) > 3x must not hold.
|
137
|
+
# (x + y)*10.must_not > x*3
|
138
|
+
#
|
139
|
+
# # Specifies the above, but reifies the constraint with the boolean
|
140
|
+
# # variable +bool+ and gives it propagation strength +domain+.
|
141
|
+
# (x + y)*10.must_not_be.greater_than(x*3, :reify => bool, :strength => :domain)
|
112
142
|
class LinearConstraint < Gecode::Constraints::ReifiableConstraint
|
113
143
|
def post
|
114
144
|
lhs, rhs, relation_type, reif_var, strength = @params.values_at(:lhs,
|
@@ -116,7 +146,7 @@ module Gecode
|
|
116
146
|
reif_var = reif_var.bind if reif_var.respond_to? :bind
|
117
147
|
if rhs.respond_to? :to_minimodel_lin_exp
|
118
148
|
rhs = rhs.to_minimodel_lin_exp
|
119
|
-
elsif rhs.
|
149
|
+
elsif rhs.respond_to? :bind
|
120
150
|
rhs = rhs.bind * 1
|
121
151
|
end
|
122
152
|
|
@@ -128,10 +158,46 @@ module Gecode
|
|
128
158
|
end
|
129
159
|
end
|
130
160
|
end
|
131
|
-
|
132
|
-
#
|
161
|
+
|
162
|
+
# Simple relation constraints specify that an integer variable must have a
|
163
|
+
# specified relation to a constant integer or another integer variable. The
|
164
|
+
# following relations are supported (the aliases of each relation are also
|
165
|
+
# listed).
|
166
|
+
#
|
167
|
+
# * <, lesser, lesser_than
|
168
|
+
# * >, greater, greater_than
|
169
|
+
# * >=, greater_or_equal, greater_than_or_equal_to
|
170
|
+
# * <=, less_or_equal, less_than_or_equal_to
|
171
|
+
# * ==, equal, equal_to
|
172
|
+
#
|
173
|
+
# Each can be negated by using +must_not+ instead of +must+.
|
174
|
+
#
|
175
|
+
# Two options (given as a hash) are available:
|
176
|
+
#
|
177
|
+
# [strength] Specifies the propagation strength of the constraint. Must be
|
178
|
+
# one of +value+, +bounds+, +domain+ and +default+. The
|
179
|
+
# strength generally progresses as +value+ -> +bounds+ ->
|
180
|
+
# +domain+ (+value+ being the weakest, but usually cheapest,
|
181
|
+
# while +domain+ is the strongest but usually costly).
|
182
|
+
# [reify] Specifies a boolean variable that should be used for
|
183
|
+
# reification (see +ReifiableConstraint+).
|
184
|
+
#
|
185
|
+
# == Examples
|
186
|
+
#
|
187
|
+
# # Int variable +x+ must not equal 0.
|
188
|
+
# x.must_not.equal(0)
|
189
|
+
#
|
190
|
+
# # Another way of writing the above.
|
191
|
+
# x.must_not == 0
|
192
|
+
#
|
193
|
+
# # +x+ must be strictly larger than +y+.
|
194
|
+
# x.must > y
|
195
|
+
#
|
196
|
+
# # Specifies the above, but reifies the constraint with the boolean
|
197
|
+
# # variable +bool+.
|
198
|
+
# x.must_be.greater_than(y, :reify => bool)
|
133
199
|
class SimpleRelationConstraint < Gecode::Constraints::ReifiableConstraint
|
134
|
-
def post
|
200
|
+
def post
|
135
201
|
# Fetch the parameters to Gecode.
|
136
202
|
lhs, relation, rhs, reif_var, strength = @params.values_at(:lhs,
|
137
203
|
:relation_type, :element, :reif, :strength)
|
@@ -149,7 +215,7 @@ module Gecode
|
|
149
215
|
|
150
216
|
# Helper methods for linear expressions. Classes mixing in this module must
|
151
217
|
# have a method #model which gives the model the expression is operating in.
|
152
|
-
module Helper
|
218
|
+
module Helper #:nodoc:
|
153
219
|
include Gecode::Constraints::LeftHandSideMethods
|
154
220
|
|
155
221
|
private
|
@@ -181,7 +247,7 @@ module Gecode
|
|
181
247
|
|
182
248
|
# Describes a binary tree of expression nodes which together form a linear
|
183
249
|
# expression.
|
184
|
-
class ExpressionTree
|
250
|
+
class ExpressionTree #:nodoc:
|
185
251
|
include Helper
|
186
252
|
|
187
253
|
# Constructs a new expression with the specified variable
|
@@ -204,7 +270,7 @@ module Gecode
|
|
204
270
|
end
|
205
271
|
|
206
272
|
# Describes a single node in a linear expression.
|
207
|
-
class ExpressionNode
|
273
|
+
class ExpressionNode #:nodoc:
|
208
274
|
include Helper
|
209
275
|
|
210
276
|
attr :model
|
@@ -218,7 +284,7 @@ module Gecode
|
|
218
284
|
# Gecode::Raw::MiniModel::LinExpr
|
219
285
|
def to_minimodel_lin_exp
|
220
286
|
expression = @value
|
221
|
-
if expression.
|
287
|
+
if expression.respond_to? :bind
|
222
288
|
# Minimodel requires that we do this first.
|
223
289
|
expression = expression.bind * 1
|
224
290
|
end
|