gecoder 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|