gecoder 0.2.0 → 0.3.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 +21 -0
- data/README +9 -1
- data/ext/missing.cpp +1 -1
- data/ext/vararray.cpp +4 -0
- data/ext/vararray.h +2 -1
- data/lib/gecoder/bindings/bindings.rb +55 -5
- data/lib/gecoder/interface.rb +1 -0
- data/lib/gecoder/interface/binding_changes.rb +183 -81
- data/lib/gecoder/interface/branch.rb +1 -1
- data/lib/gecoder/interface/constraints.rb +121 -5
- data/lib/gecoder/interface/constraints/bool/boolean.rb +160 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +23 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +258 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +66 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +31 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +22 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +57 -0
- data/lib/gecoder/interface/enum_wrapper.rb +39 -33
- data/lib/gecoder/interface/model.rb +44 -64
- data/lib/gecoder/interface/search.rb +40 -3
- data/lib/gecoder/interface/variables.rb +62 -0
- metadata +19 -8
- data/lib/gecoder/interface/constraints/distinct.rb +0 -15
- data/lib/gecoder/interface/constraints/linear.rb +0 -158
- data/lib/gecoder/interface/constraints/relation.rb +0 -76
@@ -0,0 +1,62 @@
|
|
1
|
+
module Gecode
|
2
|
+
# An variable that is bound to a model, but not to a particular space.
|
3
|
+
class FreeVarBase
|
4
|
+
attr_accessor :model
|
5
|
+
|
6
|
+
# Creates an int variable with the specified index.
|
7
|
+
def initialize(model, index)
|
8
|
+
@model = model
|
9
|
+
@index = index
|
10
|
+
@bound_space = @bound_var = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Returns the space that the int variable should bind to when needed.
|
16
|
+
def active_space
|
17
|
+
@model.active_space
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates a class for a free variable that can be bound into the specified
|
22
|
+
# class using the specified method in a space.
|
23
|
+
def Gecode::FreeVar(bound_class, space_bind_method)
|
24
|
+
clazz = Class.new(FreeVarBase)
|
25
|
+
clazz.class_eval <<-"end_method_definitions"
|
26
|
+
# Delegate methods we can't handle to the bound int variable if possible.
|
27
|
+
def method_missing(name, *args)
|
28
|
+
if #{bound_class}.instance_methods.include? name.to_s
|
29
|
+
bind.send(name, *args)
|
30
|
+
else
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Binds the int variable to the currently active space of the model,
|
36
|
+
# returning the bound int variable.
|
37
|
+
def bind
|
38
|
+
space = active_space
|
39
|
+
unless @bound_space == space
|
40
|
+
# We have not bound the variable to this space, so we do it now.
|
41
|
+
@bound = space.method(:#{space_bind_method}).call(@index)
|
42
|
+
@bound_space = space
|
43
|
+
end
|
44
|
+
return @bound
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
if assigned?
|
49
|
+
"#<#{bound_class} range: \#{val.to_s}>"
|
50
|
+
else
|
51
|
+
"#<#{bound_class} range: \#{min}..\#{max}>"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end_method_definitions
|
55
|
+
return clazz
|
56
|
+
end
|
57
|
+
|
58
|
+
# Int variables.
|
59
|
+
FreeIntVar = FreeVar(Gecode::Raw::IntVar, :int_var)
|
60
|
+
# Bool variables.
|
61
|
+
FreeBoolVar = FreeVar(Gecode::Raw::BoolVar, :bool_var)
|
62
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: gecoder
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-06-
|
6
|
+
version: 0.3.0
|
7
|
+
date: 2007-06-26 00:00:00 +02:00
|
8
8
|
summary: Ruby interface to Gecode, an environment for constraint programming.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- README
|
34
34
|
- COPYING
|
35
35
|
- LGPL-LICENSE
|
36
|
+
- CHANGES
|
36
37
|
- lib/gecoder.rb
|
37
38
|
- lib/gecoder/interface.rb
|
38
39
|
- lib/gecoder/bindings.rb
|
@@ -42,9 +43,14 @@ files:
|
|
42
43
|
- lib/gecoder/interface/binding_changes.rb
|
43
44
|
- lib/gecoder/interface/branch.rb
|
44
45
|
- lib/gecoder/interface/enum_wrapper.rb
|
45
|
-
- lib/gecoder/interface/
|
46
|
-
- lib/gecoder/interface/constraints/
|
47
|
-
- lib/gecoder/interface/constraints/
|
46
|
+
- lib/gecoder/interface/variables.rb
|
47
|
+
- lib/gecoder/interface/constraints/reifiable_constraints.rb
|
48
|
+
- lib/gecoder/interface/constraints/bool_var_constraints.rb
|
49
|
+
- lib/gecoder/interface/constraints/int_var_constraints.rb
|
50
|
+
- lib/gecoder/interface/constraints/int_enum_constraints.rb
|
51
|
+
- lib/gecoder/interface/constraints/bool/boolean.rb
|
52
|
+
- lib/gecoder/interface/constraints/int/linear.rb
|
53
|
+
- lib/gecoder/interface/constraints/int_enum/distinct.rb
|
48
54
|
- lib/gecoder/bindings/bindings.rb
|
49
55
|
- vendor/rust
|
50
56
|
- vendor/rust/test
|
@@ -130,9 +136,14 @@ extra_rdoc_files:
|
|
130
136
|
- lib/gecoder/interface/binding_changes.rb
|
131
137
|
- lib/gecoder/interface/branch.rb
|
132
138
|
- lib/gecoder/interface/enum_wrapper.rb
|
133
|
-
- lib/gecoder/interface/
|
134
|
-
- lib/gecoder/interface/constraints/
|
135
|
-
- lib/gecoder/interface/constraints/
|
139
|
+
- lib/gecoder/interface/variables.rb
|
140
|
+
- lib/gecoder/interface/constraints/reifiable_constraints.rb
|
141
|
+
- lib/gecoder/interface/constraints/bool_var_constraints.rb
|
142
|
+
- lib/gecoder/interface/constraints/int_var_constraints.rb
|
143
|
+
- lib/gecoder/interface/constraints/int_enum_constraints.rb
|
144
|
+
- lib/gecoder/interface/constraints/bool/boolean.rb
|
145
|
+
- lib/gecoder/interface/constraints/int/linear.rb
|
146
|
+
- lib/gecoder/interface/constraints/int_enum/distinct.rb
|
136
147
|
- lib/gecoder/bindings/bindings.rb
|
137
148
|
executables: []
|
138
149
|
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Gecode
|
2
|
-
class IntVarEnumConstraintExpression
|
3
|
-
# Posts a distinct constraint on the variables in the enum.
|
4
|
-
def distinct
|
5
|
-
if @negate
|
6
|
-
# The best we could implement it as from here would be a bunch of
|
7
|
-
# reified pairwise equality constraints.
|
8
|
-
raise Gecode::MissingConstraintError, 'A negated distinct has not ' +
|
9
|
-
'been implemented.'
|
10
|
-
end
|
11
|
-
|
12
|
-
Gecode::Raw::distinct(@space, @var_array, Gecode::Raw::ICL_DEF)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,158 +0,0 @@
|
|
1
|
-
module Gecode
|
2
|
-
class FreeIntVar
|
3
|
-
# Creates a linear expression where the int variables are summed.
|
4
|
-
def +(var)
|
5
|
-
Gecode::LinearConstraintExpressionNode.new(self, active_space) + var
|
6
|
-
end
|
7
|
-
|
8
|
-
# Creates a linear expression where the int variable is multiplied with
|
9
|
-
# a constant integer.
|
10
|
-
def *(int)
|
11
|
-
Gecode::LinearConstraintExpressionNode.new(self, active_space) * int
|
12
|
-
end
|
13
|
-
|
14
|
-
# Creates a linear expression where the specified variable is subtracted
|
15
|
-
# from this one.
|
16
|
-
def -(var)
|
17
|
-
Gecode::LinearConstraintExpressionNode.new(self, active_space) - var
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
module LinearConstraintHelper
|
22
|
-
OPERATION_TYPES = [:+, :-, :*]
|
23
|
-
|
24
|
-
# Define methods for the available operations.
|
25
|
-
OPERATION_TYPES.each do |name|
|
26
|
-
module_eval <<-"end_code"
|
27
|
-
def #{name}(expression)
|
28
|
-
unless expression.kind_of? Gecode::LinearConstraintExpressionTree
|
29
|
-
expression = Gecode::LinearConstraintExpressionNode.new(expression)
|
30
|
-
end
|
31
|
-
Gecode::LinearConstraintExpressionTree.new(self, expression, :#{name})
|
32
|
-
end
|
33
|
-
end_code
|
34
|
-
end
|
35
|
-
|
36
|
-
# Specifies that a constraint must hold for the linear expression.
|
37
|
-
def must
|
38
|
-
Gecode::LinearConstraintExpression.new(self)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Specifies that the negation of a constraint must hold for the linear
|
42
|
-
# expression.
|
43
|
-
def must_not
|
44
|
-
Gecode::LinearConstraintExpression.new(self, true)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# Describes a linear constraint that starts with a linear expression followed
|
49
|
-
# by must or must_not.
|
50
|
-
class LinearConstraintExpressionTree
|
51
|
-
include Gecode::LinearConstraintHelper
|
52
|
-
|
53
|
-
# Constructs a new expression with the specified variable
|
54
|
-
def initialize(left_node, right_node, operation)
|
55
|
-
@left = left_node
|
56
|
-
@right = right_node
|
57
|
-
@operation = operation
|
58
|
-
end
|
59
|
-
|
60
|
-
# Converts the linear expression to an instance of
|
61
|
-
# Gecode::Raw::MiniModel::LinExpr
|
62
|
-
def to_minimodel_lin_exp
|
63
|
-
@left.to_minimodel_lin_exp.send(@operation, @right.to_minimodel_lin_exp)
|
64
|
-
end
|
65
|
-
|
66
|
-
# Fetches the space that the expression's variables is in.
|
67
|
-
def space
|
68
|
-
@left.space || @right.space
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Describes a single node in a linear constrain expression.
|
73
|
-
class LinearConstraintExpressionNode
|
74
|
-
include Gecode::LinearConstraintHelper
|
75
|
-
|
76
|
-
attr :space
|
77
|
-
|
78
|
-
def initialize(value, space = nil)
|
79
|
-
@value = value
|
80
|
-
@space = space
|
81
|
-
end
|
82
|
-
|
83
|
-
# Converts the linear expression to an instance of
|
84
|
-
# Gecode::Raw::MiniModel::LinExpr
|
85
|
-
def to_minimodel_lin_exp
|
86
|
-
expression = @value
|
87
|
-
if expression.kind_of? FreeIntVar
|
88
|
-
# Minimodel requires that we do this first.
|
89
|
-
expression = expression.bind * 1
|
90
|
-
end
|
91
|
-
expression
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# Describes a linear constraint expression that starts with a linear
|
96
|
-
# expression followed by must or must_not.
|
97
|
-
class LinearConstraintExpression
|
98
|
-
# TODO: this is awfully similar to IntVarConstrainExpression. There should
|
99
|
-
# be some way to combine them.
|
100
|
-
|
101
|
-
# Maps the names of the methods to the corresponding integer relation
|
102
|
-
# type in Gecode.
|
103
|
-
RELATION_TYPES = {
|
104
|
-
:== => Gecode::Raw::IRT_EQ,
|
105
|
-
:<= => Gecode::Raw::IRT_LQ,
|
106
|
-
:< => Gecode::Raw::IRT_LE,
|
107
|
-
:>= => Gecode::Raw::IRT_GQ,
|
108
|
-
:> => Gecode::Raw::IRT_GR }
|
109
|
-
# The same as above, but negated.
|
110
|
-
NEGATED_RELATION_TYPES = {
|
111
|
-
:== => Gecode::Raw::IRT_NQ,
|
112
|
-
:<= => Gecode::Raw::IRT_GR,
|
113
|
-
:< => Gecode::Raw::IRT_GQ,
|
114
|
-
:>= => Gecode::Raw::IRT_LE,
|
115
|
-
:> => Gecode::Raw::IRT_LQ
|
116
|
-
}
|
117
|
-
|
118
|
-
# Constructs the expression with the specified left hand side. The
|
119
|
-
# expression can optionally be negated.
|
120
|
-
def initialize(left_hand_side, negate = false)
|
121
|
-
@lhs = left_hand_side
|
122
|
-
unless negate
|
123
|
-
@method_relations = RELATION_TYPES
|
124
|
-
else
|
125
|
-
@method_relations = NEGATED_RELATION_TYPES
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
RELATION_TYPES.each_key do |name|
|
130
|
-
module_eval <<-"end_code"
|
131
|
-
def #{name}(expression)
|
132
|
-
post_relation_constraint(@method_relations[:#{name}], expression)
|
133
|
-
end
|
134
|
-
end_code
|
135
|
-
end
|
136
|
-
|
137
|
-
private
|
138
|
-
|
139
|
-
# Places the relation constraint corresponding to the specified (integer)
|
140
|
-
# relation type (as specified by Gecode) in relation to the specifed
|
141
|
-
# element.
|
142
|
-
#
|
143
|
-
# Raises TypeError if the element is of a type that doesn't allow a relation
|
144
|
-
# to be specified.
|
145
|
-
def post_relation_constraint(relation_type, right_hand_side)
|
146
|
-
if right_hand_side.respond_to? :to_minimodel_lin_exp
|
147
|
-
right_hand_side = right_hand_side.to_minimodel_lin_exp
|
148
|
-
elsif right_hand_side.kind_of? Gecode::FreeIntVar
|
149
|
-
right_hand_side = right_hand_side.bind * 1
|
150
|
-
elsif not right_hand_side.kind_of? Fixnum
|
151
|
-
raise TypeError, 'Invalid right hand side of linear equation.'
|
152
|
-
end
|
153
|
-
|
154
|
-
(@lhs.to_minimodel_lin_exp - right_hand_side).post(@lhs.space,
|
155
|
-
relation_type, Gecode::Raw::ICL_DEF)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
@@ -1,76 +0,0 @@
|
|
1
|
-
module Gecode
|
2
|
-
class FreeIntVar
|
3
|
-
# Specifies that a constraint must hold for the integer variable.
|
4
|
-
def must
|
5
|
-
Gecode::IntVarConstraintExpression.new(active_space, self.bind)
|
6
|
-
end
|
7
|
-
|
8
|
-
# Specifies that the negation of a constraint must hold for the integer
|
9
|
-
# variable.
|
10
|
-
def must_not
|
11
|
-
Gecode::IntVarConstraintExpression.new(active_space, self.bind, true)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Describes a constraint expression that starts with a single integer variable
|
16
|
-
# followed by must or must_not.
|
17
|
-
class IntVarConstraintExpression
|
18
|
-
private
|
19
|
-
|
20
|
-
# Maps the names of the methods to the corresponding integer relation
|
21
|
-
# type in Gecode.
|
22
|
-
RELATION_TYPES = {
|
23
|
-
:== => Gecode::Raw::IRT_EQ,
|
24
|
-
:<= => Gecode::Raw::IRT_LQ,
|
25
|
-
:< => Gecode::Raw::IRT_LE,
|
26
|
-
:>= => Gecode::Raw::IRT_GQ,
|
27
|
-
:> => Gecode::Raw::IRT_GR }
|
28
|
-
# The same as above, but negated.
|
29
|
-
NEGATED_RELATION_TYPES = {
|
30
|
-
:== => Gecode::Raw::IRT_NQ,
|
31
|
-
:<= => Gecode::Raw::IRT_GR,
|
32
|
-
:< => Gecode::Raw::IRT_GQ,
|
33
|
-
:>= => Gecode::Raw::IRT_LE,
|
34
|
-
:> => Gecode::Raw::IRT_LQ
|
35
|
-
}
|
36
|
-
|
37
|
-
public
|
38
|
-
|
39
|
-
# Constructs a new expression with the specified space and (bound) variable
|
40
|
-
# as source. The expression can optionally be negated.
|
41
|
-
def initialize(space, var, negate = false)
|
42
|
-
@space = space
|
43
|
-
@var = var
|
44
|
-
unless negate
|
45
|
-
@method_relations = RELATION_TYPES
|
46
|
-
else
|
47
|
-
@method_relations = NEGATED_RELATION_TYPES
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
RELATION_TYPES.each_key do |name|
|
52
|
-
module_eval <<-"end_code"
|
53
|
-
def #{name}(element)
|
54
|
-
post_relation_constraint(@method_relations[:#{name}], element)
|
55
|
-
end
|
56
|
-
end_code
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
# Places the relation constraint corresponding to the specified (integer)
|
62
|
-
# relation type (as specified by Gecode) in relation to the specifed
|
63
|
-
# element.
|
64
|
-
#
|
65
|
-
# Raises TypeError if the element is of a type that doesn't allow a relation
|
66
|
-
# to be specified.
|
67
|
-
def post_relation_constraint(relation_type, element)
|
68
|
-
if element.kind_of? Fixnum
|
69
|
-
Gecode::Raw::rel(@space, @var, relation_type, element,
|
70
|
-
Gecode::Raw::ICL_DEF)
|
71
|
-
else
|
72
|
-
raise TypeError, 'Relations only allow Fixnum.'
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|