gecoder-with-gecode 0.8.0-mswin32 → 0.8.1-mswin32
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 +11 -1
- data/Rakefile +3 -2
- data/example/raw_bindings.rb +7 -5
- data/example/sudoku-set.rb +0 -3
- data/lib/gecode.dll +0 -0
- data/lib/gecoder/bindings/bindings.rb +35 -1
- data/lib/gecoder/interface/binding_changes.rb +4 -8
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +63 -0
- data/lib/gecoder/interface/constraints/bool_enum/{boolean.rb → relation.rb} +8 -6
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +26 -2
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +61 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +1 -0
- data/lib/gecoder/interface/model.rb +28 -6
- data/lib/gecoder/interface/search.rb +47 -18
- data/lib/gecoder/version.rb +1 -1
- data/specs/constraints/{bool_enum.rb → bool_enum_relation.rb} +5 -5
- data/specs/constraints/constraints.rb +9 -0
- data/specs/constraints/extensional.rb +106 -0
- data/specs/examples.rb +17 -0
- data/specs/search.rb +60 -0
- data/specs/set_var.rb +1 -1
- data/tasks/distribution.rake +38 -22
- data/tasks/rcov.rake +3 -2
- data/tasks/specs.rake +9 -3
- data/tasks/svn.rake +6 -3
- metadata +14 -6
data/CHANGES
CHANGED
@@ -1,8 +1,18 @@
|
|
1
|
+
== Version 0.8.1
|
2
|
+
This release adds tuple constraints along with a couple of minor features. It
|
3
|
+
also fixes a bug introduced in the previous version.
|
4
|
+
|
5
|
+
* [#19435] Fixed a bug causing inconsistencies during BAB-search. The bug stopped the send+more=money example from working correctly.
|
6
|
+
* Fixed the "raw_bindings" and "sudoku-set" examples, which were broken by the 0.8.0 release.
|
7
|
+
* Integers can now be used to specify singleton lower and upper bounds when creating set variables.
|
8
|
+
* Added convenience methods Model#maximize! and Model#minimize! for optimizing single variables.
|
9
|
+
* Added tuple constraints for enumerations of integer and boolean variables.
|
10
|
+
|
1
11
|
== Version 0.8.0
|
2
12
|
This release makes the jump from using Gecode 1.3.1 to using Gecode 2.1.1 .
|
3
13
|
The following changes have been made to the interface as a result of the jump.
|
4
14
|
|
5
|
-
*
|
15
|
+
* Removed the distinct constraint for sets.
|
6
16
|
* Added the propagation kind option to the non-set constraints.
|
7
17
|
|
8
18
|
== Version 0.7.1
|
data/Rakefile
CHANGED
@@ -4,10 +4,11 @@ require 'rake/rdoctask'
|
|
4
4
|
require 'rake/gempackagetask'
|
5
5
|
|
6
6
|
require 'tasks/all_tasks'
|
7
|
-
task :default => [:verify_rcov]
|
7
|
+
task :default => [:verify_rcov, :example_specs]
|
8
8
|
|
9
9
|
desc 'Performs the tasks necessary when releasing'
|
10
|
-
task :release => [:
|
10
|
+
task :release => [:clobber, :verify_rcov, :example_specs, :publish_website,
|
11
|
+
:publish_packages, :tag]
|
11
12
|
|
12
13
|
desc 'Runs all the tests'
|
13
14
|
task :test => :specs
|
data/example/raw_bindings.rb
CHANGED
@@ -12,14 +12,16 @@ s, e, n, d, m, o, r, y = (0..7).to_a.map{ |i| letters.at(i) }
|
|
12
12
|
Gecode::Raw::post(space, (s * 1000 + e * 100 + n * 10 + d +
|
13
13
|
m * 1000 + o * 100 + r * 10 + e).
|
14
14
|
equal(m * 10000 + o * 1000 + n * 100 + e * 10 + y ),
|
15
|
-
Gecode::Raw::ICL_DEF)
|
16
|
-
Gecode::Raw::rel(space, s, Gecode::Raw::IRT_NQ, 0, Gecode::Raw::ICL_DEF
|
17
|
-
Gecode::Raw::
|
18
|
-
Gecode::Raw::
|
15
|
+
Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF)
|
16
|
+
Gecode::Raw::rel(space, s, Gecode::Raw::IRT_NQ, 0, Gecode::Raw::ICL_DEF,
|
17
|
+
Gecode::Raw::PK_DEF)
|
18
|
+
Gecode::Raw::rel(space, m, Gecode::Raw::IRT_NQ, 0, Gecode::Raw::ICL_DEF,
|
19
|
+
Gecode::Raw::PK_DEF)
|
20
|
+
Gecode::Raw::distinct(space, letters, Gecode::Raw::ICL_DEF, Gecode::Raw::PK_DEF)
|
19
21
|
|
20
22
|
# Branching.
|
21
23
|
Gecode::Raw::branch(space, letters,
|
22
|
-
Gecode::Raw::
|
24
|
+
Gecode::Raw::INT_VAR_SIZE_MIN, Gecode::Raw::INT_VAL_MIN)
|
23
25
|
|
24
26
|
# Search
|
25
27
|
COPY_DIST = 16
|
data/example/sudoku-set.rb
CHANGED
@@ -61,9 +61,6 @@ class SudokuSet < Gecode::Model
|
|
61
61
|
@sets[i].must_be.disjoint_with @sets[j]
|
62
62
|
end
|
63
63
|
end
|
64
|
-
# The above implies that the sets must be distinct (since cardinality 0 is
|
65
|
-
# not allowed), but we also explicitly add the distinctness constraint.
|
66
|
-
@sets.must_be.distinct(:size => n)
|
67
64
|
|
68
65
|
# The sets must intersect in exactly one element with each row column and
|
69
66
|
# block. I.e. an assignable number must be assigned exactly once in each
|
data/lib/gecode.dll
CHANGED
Binary file
|
@@ -149,7 +149,7 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
|
|
149
149
|
enum.add_value "SRT_CMPL"
|
150
150
|
end
|
151
151
|
|
152
|
-
ns.add_enum "SetOpType
|
152
|
+
ns.add_enum "SetOpType" do |enum|
|
153
153
|
enum.add_value "SOT_UNION"
|
154
154
|
enum.add_value "SOT_DUNION"
|
155
155
|
enum.add_value "SOT_INTER"
|
@@ -337,6 +337,20 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
|
|
337
337
|
klass.add_method "debug"
|
338
338
|
end
|
339
339
|
|
340
|
+
ns.add_cxx_class "TupleSet" do |klass|
|
341
|
+
klass.add_constructor
|
342
|
+
|
343
|
+
klass.add_method "add" do |method|
|
344
|
+
method.add_parameter "Gecode::IntArgs", "tuple"
|
345
|
+
end
|
346
|
+
|
347
|
+
klass.add_method "finalize"
|
348
|
+
|
349
|
+
klass.add_method "finalized", "bool"
|
350
|
+
|
351
|
+
klass.add_method "tuples", "int"
|
352
|
+
end
|
353
|
+
|
340
354
|
ns.add_cxx_class "MBranchingDesc" do |klass|
|
341
355
|
klass.bindname = "BranchingDesc"
|
342
356
|
klass.add_constructor
|
@@ -1207,6 +1221,26 @@ Rust::Bindings::create_bindings Rust::Bindings::LangCxx, "gecode" do |b|
|
|
1207
1221
|
func.add_parameter "Gecode::PropKind", "pk"
|
1208
1222
|
end
|
1209
1223
|
|
1224
|
+
ns.add_function "extensional", "void" do |func|
|
1225
|
+
func.add_parameter "Gecode::MSpace*", "home"
|
1226
|
+
func.add_parameter "Gecode::MIntVarArray *", "x" do |param|
|
1227
|
+
param.custom_conversion = "*ruby2Gecode_MIntVarArrayPtr(argv[1], 2)->ptr()"
|
1228
|
+
end
|
1229
|
+
func.add_parameter "Gecode::TupleSet", "t"
|
1230
|
+
func.add_parameter "Gecode::IntConLevel", "icl"
|
1231
|
+
func.add_parameter "Gecode::PropKind", "pk"
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
ns.add_function "extensional", "void" do |func|
|
1235
|
+
func.add_parameter "Gecode::MSpace*", "home"
|
1236
|
+
func.add_parameter "Gecode::MBoolVarArray *", "x" do |param|
|
1237
|
+
param.custom_conversion = "*ruby2Gecode_MBoolVarArrayPtr(argv[1], 2)->ptr()"
|
1238
|
+
end
|
1239
|
+
func.add_parameter "Gecode::TupleSet", "t"
|
1240
|
+
func.add_parameter "Gecode::IntConLevel", "icl"
|
1241
|
+
func.add_parameter "Gecode::PropKind", "pk"
|
1242
|
+
end
|
1243
|
+
|
1210
1244
|
# ns.add_function "regular", "void" do |func|
|
1211
1245
|
# func.add_parameter "Gecode::MSpace*", "home"
|
1212
1246
|
# func.add_parameter "Gecode::MIntVarArray *", "x" do |param|
|
@@ -291,15 +291,11 @@ module Gecode
|
|
291
291
|
|
292
292
|
private
|
293
293
|
|
294
|
-
# Transforms a lub or glb domain given as a range or enumeration
|
295
|
-
# or more parameters that describe the domain to
|
294
|
+
# Transforms a lub or glb domain given as a fixnum, range or enumeration
|
295
|
+
# into one or more parameters that describe the domain to
|
296
|
+
# Gecode::Raw::SetVar .
|
296
297
|
def domain_to_args(domain)
|
297
|
-
|
298
|
-
return domain.first, domain.last
|
299
|
-
else
|
300
|
-
elements = domain.to_a
|
301
|
-
return Gecode::Raw::IntSet.new(domain, domain.size)
|
302
|
-
end
|
298
|
+
Gecode::Constraints::Util.constant_set_to_int_set(domain)
|
303
299
|
end
|
304
300
|
|
305
301
|
# Creates a new storage array for bool variables.
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Gecode::Constraints::BoolEnum
|
2
|
+
class Expression
|
3
|
+
# Posts an equality constraint on the variables in the enum.
|
4
|
+
def in(tuples, options = {})
|
5
|
+
if @params[:negate]
|
6
|
+
raise Gecode::MissingConstraintError, 'A negated tuple constraint is ' +
|
7
|
+
'not implemented.'
|
8
|
+
end
|
9
|
+
unless options[:reify].nil?
|
10
|
+
raise ArgumentError, 'Reification is not supported by the tuple ' +
|
11
|
+
'constraint.'
|
12
|
+
end
|
13
|
+
unless tuples.respond_to?(:each) and
|
14
|
+
tuples.all?{ |tuple| tuple.respond_to?(:each) }
|
15
|
+
raise TypeError, 'Expected an enumeration with tuples, got ' +
|
16
|
+
"#{tuples.class}."
|
17
|
+
end
|
18
|
+
unless tuples.all?{ |tuple|
|
19
|
+
tuple.all?{ |x| x.kind_of?(TrueClass) or x.kind_of?(FalseClass) }}
|
20
|
+
raise TypeError, 'All tuples must contain booleans.'
|
21
|
+
end
|
22
|
+
|
23
|
+
@params[:tuples] = tuples
|
24
|
+
@model.add_constraint Extensional::TupleConstraint.new(@model,
|
25
|
+
@params.update(Gecode::Constraints::Util.decode_options(options)))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# A module that gathers the classes and modules used in extensional
|
30
|
+
# constraints.
|
31
|
+
module Extensional #:nodoc:
|
32
|
+
# Describes a tuple constraint, which constrains the variables in an
|
33
|
+
# boolean enumeration to be equal to one of the specified tuples. Neither
|
34
|
+
# negation nor reification is supported.
|
35
|
+
#
|
36
|
+
# == Example
|
37
|
+
#
|
38
|
+
# # Constrains the three boolean variables in +bools+ to either
|
39
|
+
# # be true, false, true, or false, false, true.
|
40
|
+
# bools.must_be.in [[true, false, true], [false, false, true]]
|
41
|
+
#
|
42
|
+
# # The same as above, but preferring speed over low memory usage.
|
43
|
+
# bools.must_be.in([[true, false, true], [false, false, true]],
|
44
|
+
# :kind => :speed)
|
45
|
+
class TupleConstraint < Gecode::Constraints::Constraint
|
46
|
+
def post
|
47
|
+
# Bind lhs.
|
48
|
+
lhs = @params[:lhs].to_bool_var_array
|
49
|
+
|
50
|
+
# Create the tuple set.
|
51
|
+
tuple_set = Gecode::Raw::TupleSet.new
|
52
|
+
@params[:tuples].each do |tuple|
|
53
|
+
tuple_set.add tuple.map{ |b| b ? 1 : 0 }
|
54
|
+
end
|
55
|
+
tuple_set.finalize
|
56
|
+
|
57
|
+
# Post the constraint.
|
58
|
+
Gecode::Raw::extensional(@model.active_space, lhs, tuple_set,
|
59
|
+
*propagation_options)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -3,21 +3,23 @@ module Gecode
|
|
3
3
|
# Produces an expression that can be handled as if it was a variable
|
4
4
|
# representing the conjunction of all boolean variables in the enumeration.
|
5
5
|
def conjunction
|
6
|
-
return Gecode::Constraints::BoolEnum::ConjunctionStub.new(
|
6
|
+
return Gecode::Constraints::BoolEnum::Relation::ConjunctionStub.new(
|
7
7
|
@model, :lhs => self)
|
8
8
|
end
|
9
9
|
|
10
10
|
# Produces an expression that can be handled as if it was a variable
|
11
11
|
# representing the disjunction of all boolean variables in the enumeration.
|
12
12
|
def disjunction
|
13
|
-
return Gecode::Constraints::BoolEnum::DisjunctionStub.new(
|
13
|
+
return Gecode::Constraints::BoolEnum::Relation::DisjunctionStub.new(
|
14
14
|
@model, :lhs => self)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
end
|
18
|
+
|
19
|
+
module Gecode::Constraints::BoolEnum
|
18
20
|
# A module that gathers the classes and modules used by boolean enumeration
|
19
|
-
# constraints.
|
20
|
-
module
|
21
|
+
# relation constraints.
|
22
|
+
module Relation #:nodoc:
|
21
23
|
# Describes a CompositeStub for the conjunction constraint, which constrain
|
22
24
|
# the conjunction of all boolean variables in an enumeration.
|
23
25
|
#
|
@@ -83,4 +85,4 @@ module Gecode
|
|
83
85
|
end
|
84
86
|
end
|
85
87
|
end
|
86
|
-
end
|
88
|
+
end
|
@@ -1,8 +1,32 @@
|
|
1
|
-
module Gecode
|
1
|
+
module Gecode
|
2
|
+
module BoolEnumMethods
|
3
|
+
include Gecode::Constraints::LeftHandSideMethods
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
# Produces an expression for the lhs module.
|
8
|
+
def expression(params)
|
9
|
+
params.update(:lhs => self)
|
10
|
+
Constraints::BoolEnum::Expression.new(@model, params)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
2
14
|
# A module containing constraints that have enumerations of boolean variables
|
3
15
|
# as left hand side.
|
4
16
|
module Constraints::BoolEnum
|
17
|
+
# Expressions with bool enums as left hand sides.
|
18
|
+
class Expression < Gecode::Constraints::Expression #:nodoc:
|
19
|
+
# Raises TypeError unless the left hand side is a bool enum.
|
20
|
+
def initialize(model, params)
|
21
|
+
super
|
22
|
+
|
23
|
+
unless params[:lhs].respond_to? :to_bool_var_array
|
24
|
+
raise TypeError, 'Must have bool enum as left hand side.'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
5
28
|
end
|
6
29
|
end
|
7
30
|
|
8
|
-
require 'gecoder/interface/constraints/bool_enum/
|
31
|
+
require 'gecoder/interface/constraints/bool_enum/relation'
|
32
|
+
require 'gecoder/interface/constraints/bool_enum/extensional'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Gecode::Constraints::IntEnum
|
2
|
+
class Expression
|
3
|
+
# Posts an equality constraint on the variables in the enum.
|
4
|
+
def in(tuples, options = {})
|
5
|
+
if @params[:negate]
|
6
|
+
raise Gecode::MissingConstraintError, 'A negated tuple constraint is ' +
|
7
|
+
'not implemented.'
|
8
|
+
end
|
9
|
+
unless options[:reify].nil?
|
10
|
+
raise ArgumentError, 'Reification is not supported by the tuple ' +
|
11
|
+
'constraint.'
|
12
|
+
end
|
13
|
+
unless tuples.respond_to?(:each) and
|
14
|
+
tuples.all?{ |tuple| tuple.respond_to?(:each) }
|
15
|
+
raise TypeError, 'Expected an enumeration with tuples, got ' +
|
16
|
+
"#{tuples.class}."
|
17
|
+
end
|
18
|
+
unless tuples.all?{ |tuple| tuple.all?{ |x| x.kind_of? Fixnum }}
|
19
|
+
raise TypeError, 'All tuples must contain Fixnum.'
|
20
|
+
end
|
21
|
+
|
22
|
+
@params[:tuples] = tuples
|
23
|
+
@model.add_constraint Extensional::TupleConstraint.new(@model,
|
24
|
+
@params.update(Gecode::Constraints::Util.decode_options(options)))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# A module that gathers the classes and modules used in extensional
|
29
|
+
# constraints.
|
30
|
+
module Extensional #:nodoc:
|
31
|
+
# Describes a tuple constraint, which constrains all the variables in an
|
32
|
+
# enumeration of integer variables to be equal to one of the specified
|
33
|
+
# tuples. Neither negation nor reification is supported.
|
34
|
+
#
|
35
|
+
# == Example
|
36
|
+
#
|
37
|
+
# # Constrains the two integer variables in +numbers+ to either have
|
38
|
+
# # values 1 and 7, or values 47 and 11.
|
39
|
+
# numbers.must_be.in [[1,7], [47,11]]
|
40
|
+
#
|
41
|
+
# # The same as above, but preferring speed over low memory usage.
|
42
|
+
# numbers.must_be.in([[1,7], [47,11]], :kind => :speed)
|
43
|
+
class TupleConstraint < Gecode::Constraints::Constraint
|
44
|
+
def post
|
45
|
+
# Bind lhs.
|
46
|
+
lhs = @params[:lhs].to_int_var_array
|
47
|
+
|
48
|
+
# Create the tuple set.
|
49
|
+
tuple_set = Gecode::Raw::TupleSet.new
|
50
|
+
@params[:tuples].each do |tuple|
|
51
|
+
tuple_set.add tuple
|
52
|
+
end
|
53
|
+
tuple_set.finalize
|
54
|
+
|
55
|
+
# Post the constraint.
|
56
|
+
Gecode::Raw::extensional(@model.active_space, lhs, tuple_set,
|
57
|
+
*propagation_options)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -35,3 +35,4 @@ require 'gecoder/interface/constraints/int_enum/element'
|
|
35
35
|
require 'gecoder/interface/constraints/int_enum/count'
|
36
36
|
require 'gecoder/interface/constraints/int_enum/sort'
|
37
37
|
require 'gecoder/interface/constraints/int_enum/arithmetic'
|
38
|
+
require 'gecoder/interface/constraints/int_enum/extensional'
|
@@ -67,11 +67,11 @@ module Gecode
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# Creates a set variable with the specified domain for greatest lower bound
|
70
|
-
# and least upper bound (specified as either a range or enum). If
|
71
|
-
# are specified then the empty set is used as greates lower bound
|
72
|
-
# universe as least upper bound. A range for the allowed cardinality
|
73
|
-
# set can also be specified, if none is specified, or nil is given,
|
74
|
-
# default range (anything) will be used. If only a single Fixnum is
|
70
|
+
# and least upper bound (specified as either a fixnum, range or enum). If
|
71
|
+
# no bounds are specified then the empty set is used as greates lower bound
|
72
|
+
# and the universe as least upper bound. A range for the allowed cardinality
|
73
|
+
# of the set can also be specified, if none is specified, or nil is given,
|
74
|
+
# then the default range (anything) will be used. If only a single Fixnum is
|
75
75
|
# specified as cardinality_range then it's used as lower bound.
|
76
76
|
def set_var(glb_domain = [], lub_domain =
|
77
77
|
Gecode::Raw::SetLimits::MIN..Gecode::Raw::SetLimits::MAX,
|
@@ -220,6 +220,8 @@ module Gecode
|
|
220
220
|
if glb.kind_of?(Range) and lub.kind_of?(Range)
|
221
221
|
glb.first >= lub.first and glb.last <= lub.last
|
222
222
|
else
|
223
|
+
glb = [glb] if glb.kind_of?(Fixnum)
|
224
|
+
lub = [lub] if lub.kind_of?(Fixnum)
|
223
225
|
(glb.to_a - lub.to_a).empty?
|
224
226
|
end
|
225
227
|
end
|
@@ -232,7 +234,8 @@ module Gecode
|
|
232
234
|
# Retrieves the currently selected space, the one which constraints and
|
233
235
|
# variables should be bound to.
|
234
236
|
def selected_space
|
235
|
-
@active_space
|
237
|
+
return @active_space unless @active_space.nil?
|
238
|
+
self.active_space = base_space
|
236
239
|
end
|
237
240
|
|
238
241
|
# Retrieves the space that should be used for variable creation.
|
@@ -243,9 +246,28 @@ module Gecode
|
|
243
246
|
# Refreshes all cached variables. This should be called if the variables
|
244
247
|
# in an existing space were changed.
|
245
248
|
def refresh_variables
|
249
|
+
return if @variables.nil?
|
246
250
|
@variables.each do |variable|
|
247
251
|
variable.refresh if variable.cached?
|
248
252
|
end
|
249
253
|
end
|
254
|
+
|
255
|
+
# Executes any interactions with Gecode still waiting in the queue
|
256
|
+
# (emptying the queue) in the process.
|
257
|
+
def perform_queued_gecode_interactions
|
258
|
+
allow_space_access do
|
259
|
+
gecode_interaction_queue.each{ |con| con.call }
|
260
|
+
gecode_interaction_queue.clear # Empty the queue.
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# Switches the active space used (the space from which variables are read
|
265
|
+
# and to which constraints are posted). @active_space should never be
|
266
|
+
# assigned directly.
|
267
|
+
def active_space=(new_space)
|
268
|
+
@active_space = new_space
|
269
|
+
new_space.refresh
|
270
|
+
refresh_variables
|
271
|
+
end
|
250
272
|
end
|
251
273
|
end
|
@@ -6,14 +6,14 @@ module Gecode
|
|
6
6
|
def solve!
|
7
7
|
space = dfs_engine.next
|
8
8
|
return nil if space.nil?
|
9
|
-
|
9
|
+
self.active_space = space
|
10
10
|
return self
|
11
11
|
end
|
12
12
|
|
13
13
|
# Returns to the original state, before any search was made (but propagation
|
14
14
|
# might have been performed). Returns the reset model.
|
15
15
|
def reset!
|
16
|
-
|
16
|
+
self.active_space = base_space
|
17
17
|
return self
|
18
18
|
end
|
19
19
|
|
@@ -30,7 +30,9 @@ module Gecode
|
|
30
30
|
# Yields each solution that the model has.
|
31
31
|
def each_solution(&block)
|
32
32
|
dfs = dfs_engine
|
33
|
-
|
33
|
+
next_solution = nil
|
34
|
+
while not (next_solution = dfs.next).nil?
|
35
|
+
self.active_space = next_solution
|
34
36
|
yield self
|
35
37
|
end
|
36
38
|
self.reset!
|
@@ -54,10 +56,10 @@ module Gecode
|
|
54
56
|
|
55
57
|
# Set the method used for constrain calls by the BAB-search.
|
56
58
|
Model.constrain_proc = lambda do |home_space, best_space|
|
57
|
-
|
59
|
+
self.active_space = best_space
|
58
60
|
@variable_creation_space = home_space
|
59
61
|
yield(self, self)
|
60
|
-
|
62
|
+
self.active_space = home_space
|
61
63
|
@variable_creation_space = nil
|
62
64
|
|
63
65
|
perform_queued_gecode_interactions
|
@@ -74,13 +76,49 @@ module Gecode
|
|
74
76
|
Model.constrain_proc = nil
|
75
77
|
return nil if result.nil?
|
76
78
|
|
77
|
-
#
|
78
|
-
result
|
79
|
-
refresh_variables
|
80
|
-
@active_space = result
|
79
|
+
# Switch to the result.
|
80
|
+
self.active_space = result
|
81
81
|
return self
|
82
82
|
end
|
83
83
|
|
84
|
+
# Finds the solution that maximizes a given integer variable. The name of
|
85
|
+
# the method that accesses the variable from the model should be given. To
|
86
|
+
# for instance maximize a variable named "profit", that's accessible through
|
87
|
+
# the model, one would use the following.
|
88
|
+
#
|
89
|
+
# model.maximize! :profit
|
90
|
+
#
|
91
|
+
# Returns nil if there is no solution.
|
92
|
+
def maximize!(var)
|
93
|
+
variable = self.method(var).call
|
94
|
+
unless variable.kind_of? Gecode::FreeIntVar
|
95
|
+
raise ArgumentError.new("Expected integer variable, got #{variable.class}.")
|
96
|
+
end
|
97
|
+
|
98
|
+
optimize! do |model, best_so_far|
|
99
|
+
model.method(var).call.must > best_so_far.method(var).call.value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Finds the solution that minimizes a given integer variable. The name of
|
104
|
+
# the method that accesses the variable from the model should be given. To
|
105
|
+
# for instance minimize a variable named "cost", that's accessible through
|
106
|
+
# the model, one would use the following.
|
107
|
+
#
|
108
|
+
# model.minimize! :cost
|
109
|
+
#
|
110
|
+
# Returns nil if there is no solution.
|
111
|
+
def minimize!(var)
|
112
|
+
variable = self.method(var).call
|
113
|
+
unless variable.kind_of? Gecode::FreeIntVar
|
114
|
+
raise ArgumentError.new("Expected integer variable, got #{variable.class}.")
|
115
|
+
end
|
116
|
+
|
117
|
+
optimize! do |model, best_so_far|
|
118
|
+
model.method(var).call.must < best_so_far.method(var).call.value
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
84
122
|
class <<self
|
85
123
|
# Sets the proc that should be used to handle constrain requests.
|
86
124
|
def constrain_proc=(proc) #:nodoc:
|
@@ -111,14 +149,5 @@ module Gecode
|
|
111
149
|
Gecode::Raw::Search::Config::ADAPTIVE_DISTANCE,
|
112
150
|
nil)
|
113
151
|
end
|
114
|
-
|
115
|
-
# Executes any interactions with Gecode still waiting in the queue
|
116
|
-
# (emptying the queue) in the process.
|
117
|
-
def perform_queued_gecode_interactions
|
118
|
-
allow_space_access do
|
119
|
-
gecode_interaction_queue.each{ |con| con.call }
|
120
|
-
gecode_interaction_queue.clear # Empty the queue.
|
121
|
-
end
|
122
|
-
end
|
123
152
|
end
|
124
153
|
end
|
data/lib/gecoder/version.rb
CHANGED
@@ -17,7 +17,7 @@ end
|
|
17
17
|
|
18
18
|
# Expects @stub, which contains the started constraint and @compute_result which
|
19
19
|
# computes whether the left hand side is true or not.
|
20
|
-
describe 'bool enum constraint', :shared => true do
|
20
|
+
describe 'bool enum relation constraint', :shared => true do
|
21
21
|
it 'should handle being constrained to be true' do
|
22
22
|
@stub.must_be.true
|
23
23
|
@model.solve!
|
@@ -67,7 +67,7 @@ describe 'bool enum constraint', :shared => true do
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
describe Gecode::Constraints::BoolEnum, ' (conjunction)' do
|
70
|
+
describe Gecode::Constraints::BoolEnum::Relation, ' (conjunction)' do
|
71
71
|
before do
|
72
72
|
@model = BoolEnumSampleProblem.new
|
73
73
|
@bools = @model.bools
|
@@ -109,11 +109,11 @@ describe Gecode::Constraints::BoolEnum, ' (conjunction)' do
|
|
109
109
|
@compute_result = lambda{ @bools.all?{ |b| b.value } }
|
110
110
|
end
|
111
111
|
|
112
|
-
it_should_behave_like 'bool enum constraint'
|
112
|
+
it_should_behave_like 'bool enum relation constraint'
|
113
113
|
it_should_behave_like 'reifiable constraint'
|
114
114
|
end
|
115
115
|
|
116
|
-
describe Gecode::Constraints::BoolEnum, ' (disjunction)' do
|
116
|
+
describe Gecode::Constraints::BoolEnum::Relation, ' (disjunction)' do
|
117
117
|
before do
|
118
118
|
@model = BoolEnumSampleProblem.new
|
119
119
|
@bools = @model.bools
|
@@ -155,6 +155,6 @@ describe Gecode::Constraints::BoolEnum, ' (disjunction)' do
|
|
155
155
|
@compute_result = lambda{ @bools.any?{ |b| b.value } }
|
156
156
|
end
|
157
157
|
|
158
|
-
it_should_behave_like 'bool enum constraint'
|
158
|
+
it_should_behave_like 'bool enum relation constraint'
|
159
159
|
it_should_behave_like 'reifiable constraint'
|
160
160
|
end
|
@@ -17,6 +17,15 @@ describe Gecode::Constraints::IntEnum::Expression do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
describe Gecode::Constraints::BoolEnum::Expression do
|
21
|
+
it 'should raise error unless lhs is a bool enum' do
|
22
|
+
lambda do
|
23
|
+
Gecode::Constraints::BoolEnum::Expression.new(Gecode::Model.new,
|
24
|
+
:lhs => 'foo', :negate => false)
|
25
|
+
end.should raise_error(TypeError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
20
29
|
describe Gecode::Constraints::SetEnum::Expression do
|
21
30
|
it 'should raise error unless lhs is a set enum' do
|
22
31
|
lambda do
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/constraint_helper'
|
3
|
+
|
4
|
+
describe Gecode::Constraints::IntEnum::Extensional do
|
5
|
+
before do
|
6
|
+
@model = Gecode::Model.new
|
7
|
+
@tuples = [[1,7], [5,1]]
|
8
|
+
@digits = @model.int_var_array(2, 0..9)
|
9
|
+
@model.branch_on @digits
|
10
|
+
|
11
|
+
@invoke_options = lambda do |hash|
|
12
|
+
@digits.must_be.in(@tuples, hash)
|
13
|
+
@model.solve!
|
14
|
+
end
|
15
|
+
@expect_options = option_expectation do |strength, kind, reif_var|
|
16
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
17
|
+
an_instance_of(Gecode::Raw::Space),
|
18
|
+
an_instance_of(Gecode::Raw::IntVarArray),
|
19
|
+
an_instance_of(Gecode::Raw::TupleSet), strength, kind)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should constrain the domain of all variables' do
|
24
|
+
@digits.must_be.in @tuples
|
25
|
+
|
26
|
+
found_solutions = []
|
27
|
+
@model.each_solution do |m|
|
28
|
+
found_solutions << @digits.values
|
29
|
+
end
|
30
|
+
|
31
|
+
found_solutions.size.should == 2
|
32
|
+
(found_solutions - @tuples).should be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should not allow negation' do
|
36
|
+
lambda do
|
37
|
+
@digits.must_not_be.in @tuples
|
38
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
42
|
+
lambda{ @digits.must_be.in 4711 }.should raise_error(TypeError)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should raise error if the right hand side does not contain tuples' do
|
46
|
+
lambda{ @digits.must_be.in [17, 4711] }.should raise_error(TypeError)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should raise error if the right hand side does not contain integer tuples' do
|
50
|
+
lambda{ @digits.must_be.in ['hello'] }.should raise_error(TypeError)
|
51
|
+
end
|
52
|
+
|
53
|
+
it_should_behave_like 'non-reifiable constraint'
|
54
|
+
end
|
55
|
+
|
56
|
+
describe Gecode::Constraints::BoolEnum::Extensional do
|
57
|
+
before do
|
58
|
+
@model = Gecode::Model.new
|
59
|
+
@tuples = [[true, false, true], [false, false, true]]
|
60
|
+
@bools = @model.bool_var_array(3)
|
61
|
+
@model.branch_on @bools
|
62
|
+
|
63
|
+
@invoke_options = lambda do |hash|
|
64
|
+
@bools.must_be.in(@tuples, hash)
|
65
|
+
@model.solve!
|
66
|
+
end
|
67
|
+
@expect_options = option_expectation do |strength, kind, reif_var|
|
68
|
+
Gecode::Raw.should_receive(:extensional).once.with(
|
69
|
+
an_instance_of(Gecode::Raw::Space),
|
70
|
+
an_instance_of(Gecode::Raw::BoolVarArray),
|
71
|
+
an_instance_of(Gecode::Raw::TupleSet), strength, kind)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should constrain the domain of all variables' do
|
76
|
+
@bools.must_be.in @tuples
|
77
|
+
|
78
|
+
found_solutions = []
|
79
|
+
@model.each_solution do |m|
|
80
|
+
found_solutions << @bools.values
|
81
|
+
end
|
82
|
+
|
83
|
+
found_solutions.size.should == 2
|
84
|
+
(found_solutions - @tuples).should be_empty
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should not allow negation' do
|
88
|
+
lambda do
|
89
|
+
@bools.must_not_be.in @tuples
|
90
|
+
end.should raise_error(Gecode::MissingConstraintError)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should raise error if the right hand side is not an enumeration' do
|
94
|
+
lambda{ @bools.must_be.in true }.should raise_error(TypeError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should raise error if the right hand side does not contain tuples' do
|
98
|
+
lambda{ @bools.must_be.in [true, false] }.should raise_error(TypeError)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should raise error if the right hand side does not contain boolean tuples' do
|
102
|
+
lambda{ @bools.must_be.in ['hello'] }.should raise_error(TypeError)
|
103
|
+
end
|
104
|
+
|
105
|
+
it_should_behave_like 'non-reifiable constraint'
|
106
|
+
end
|
data/specs/examples.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
# This spec checks that the examples are still working.
|
5
|
+
files = Dir["#{File.dirname(__FILE__)}/../example/*.rb"]
|
6
|
+
files.delete_if do |file|
|
7
|
+
file =~ /example_helper.rb/
|
8
|
+
end
|
9
|
+
|
10
|
+
files.each do |example|
|
11
|
+
describe "Example (#{File.basename(example)})" do
|
12
|
+
it 'should not output errors' do
|
13
|
+
_, _, stderr = Open3.popen3("ruby #{example} 1> /dev/null")
|
14
|
+
stderr.gets.should be_nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/specs/search.rb
CHANGED
@@ -205,6 +205,66 @@ describe Gecode::Model, '(optimization search)' do
|
|
205
205
|
solution.z.value.should == 25
|
206
206
|
end
|
207
207
|
|
208
|
+
it 'should support maximizing singe variables given as symbols' do
|
209
|
+
solution = SampleOptimizationProblem.new.maximize! :z
|
210
|
+
solution.should_not be_nil
|
211
|
+
solution.x.value.should == 5
|
212
|
+
solution.y.value.should == 5
|
213
|
+
solution.z.value.should == 25
|
214
|
+
end
|
215
|
+
|
216
|
+
it 'should support maximizing singe variables given as strings' do
|
217
|
+
solution = SampleOptimizationProblem.new.maximize! 'z'
|
218
|
+
solution.should_not be_nil
|
219
|
+
solution.x.value.should == 5
|
220
|
+
solution.y.value.should == 5
|
221
|
+
solution.z.value.should == 25
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'should raise error if maximize! is given a non-existing method' do
|
225
|
+
lambda do
|
226
|
+
SampleOptimizationProblem.new.maximize! :does_not_exist
|
227
|
+
end.should raise_error(NameError)
|
228
|
+
end
|
229
|
+
|
230
|
+
it 'should raise error if maximize! is given a method that does not return an integer variable' do
|
231
|
+
lambda do
|
232
|
+
SampleOptimizationProblem.new.maximize! :object_id
|
233
|
+
end.should raise_error(ArgumentError)
|
234
|
+
end
|
235
|
+
|
236
|
+
it 'should support minimizing singe variables given as symbols' do
|
237
|
+
problem = SampleOptimizationProblem.new
|
238
|
+
problem.z.must > 2
|
239
|
+
solution = problem.minimize! :x
|
240
|
+
solution.should_not be_nil
|
241
|
+
solution.x.value.should == 1
|
242
|
+
solution.y.value.should == 3
|
243
|
+
solution.z.value.should == 3
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'should support minimizing singe variables given as strings' do
|
247
|
+
problem = SampleOptimizationProblem.new
|
248
|
+
problem.z.must > 2
|
249
|
+
solution = problem.minimize! 'x'
|
250
|
+
solution.should_not be_nil
|
251
|
+
solution.x.value.should == 1
|
252
|
+
solution.y.value.should == 3
|
253
|
+
solution.z.value.should == 3
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should raise error if minimize! is given a non-existing method' do
|
257
|
+
lambda do
|
258
|
+
SampleOptimizationProblem.new.minimize! :does_not_exist
|
259
|
+
end.should raise_error(NameError)
|
260
|
+
end
|
261
|
+
|
262
|
+
it 'should raise error if minimize! is given a method that does not return an integer variable' do
|
263
|
+
lambda do
|
264
|
+
SampleOptimizationProblem.new.minimize! :object_id
|
265
|
+
end.should raise_error(ArgumentError)
|
266
|
+
end
|
267
|
+
|
208
268
|
it 'should not be bothered by garbage collecting' do
|
209
269
|
# This goes through 400+ spaces.
|
210
270
|
solution = SampleOptimizationProblem2.new.optimize! do |model, best_so_far|
|
data/specs/set_var.rb
CHANGED
data/tasks/distribution.rake
CHANGED
@@ -7,6 +7,7 @@ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
|
7
7
|
PKG_FILE_NAME_WITH_GECODE = "#{PKG_NAME_WITH_GECODE}-#{PKG_VERSION}"
|
8
8
|
# The location where the precompiled DLL should be placed.
|
9
9
|
DLL_LOCATION = 'lib/gecode.dll'
|
10
|
+
EXT_DIR = 'ext'
|
10
11
|
|
11
12
|
desc 'Generate RDoc'
|
12
13
|
rd = Rake::RDocTask.new do |rdoc|
|
@@ -16,14 +17,19 @@ rd = Rake::RDocTask.new do |rdoc|
|
|
16
17
|
rdoc.rdoc_files.include('README', 'CHANGES', 'LGPL-LICENSE', 'lib/**/*.rb')
|
17
18
|
end
|
18
19
|
|
20
|
+
TMP_DIR = 'doc/tmp/rdoc_dev'
|
19
21
|
desc 'Generate RDoc, ignoring nodoc'
|
20
|
-
Rake::RDocTask.new(:rdoc_dev) do |rdoc|
|
22
|
+
Rake::RDocTask.new(:rdoc_dev => :prepare_rdoc_dev) do |rdoc|
|
21
23
|
rdoc.rdoc_dir = 'doc/output/rdoc_dev'
|
22
24
|
rdoc.options << '--title' << 'Gecode/R Developers RDoc' << '--line-numbers' <<
|
23
25
|
'--inline-source' << '--accessor' << 'delegate'
|
24
|
-
|
26
|
+
|
27
|
+
rdoc.rdoc_files.include("#{TMP_DIR}/**/*.rb")
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Copies the files that RDoc should parse, removing #:nodoc:'
|
31
|
+
task :prepare_rdoc_dev do
|
25
32
|
# Copy the rdoc and remove all #:nodoc: .
|
26
|
-
TMP_DIR = 'doc/tmp/rdoc_dev'
|
27
33
|
Dir['lib/**/*.rb'].each do |source_name|
|
28
34
|
destination_name = source_name.sub('lib', TMP_DIR)
|
29
35
|
File.makedirs File.dirname(destination_name)
|
@@ -33,8 +39,6 @@ Rake::RDocTask.new(:rdoc_dev) do |rdoc|
|
|
33
39
|
end
|
34
40
|
destination.close
|
35
41
|
end
|
36
|
-
|
37
|
-
rdoc.rdoc_files.include("#{TMP_DIR}/**/*.rb")
|
38
42
|
end
|
39
43
|
|
40
44
|
spec = Gem::Specification.new do |s|
|
@@ -122,43 +126,55 @@ end
|
|
122
126
|
desc 'Removes generated distribution files'
|
123
127
|
task :clobber do
|
124
128
|
rm DLL_LOCATION if File.exists? DLL_LOCATION
|
129
|
+
FileList[
|
130
|
+
"#{EXT_DIR}/*.o",
|
131
|
+
"#{EXT_DIR}/gecode.{cc,hh}",
|
132
|
+
"#{EXT_DIR}/Makefile",
|
133
|
+
"#{EXT_DIR}/mkmf.log"
|
134
|
+
].to_a.each{ |file| rm file if File.exists? file }
|
125
135
|
end
|
126
136
|
|
127
137
|
desc 'Publish packages on RubyForge'
|
128
138
|
task :publish_packages => [:publish_gecoder_packages,
|
129
|
-
:publish_gecoder_with_gecode_packages
|
130
|
-
|
139
|
+
:publish_gecoder_with_gecode_packages,
|
140
|
+
:publish_gecoder_with_gecode_mswin32_packages]
|
141
|
+
|
142
|
+
# Files included in the vanilla Gecode/R release.
|
143
|
+
vanilla_release_files = [
|
144
|
+
"pkg/#{PKG_FILE_NAME}.gem",
|
145
|
+
"pkg/#{PKG_FILE_NAME}.tgz",
|
146
|
+
"pkg/#{PKG_FILE_NAME}.zip"
|
147
|
+
]
|
131
148
|
desc 'Publish Gecode/R packages on RubyForge'
|
132
|
-
task :publish_gecoder_packages => [:verify_user
|
133
|
-
release_files = FileList[
|
134
|
-
"pkg/#{PKG_FILE_NAME}.gem",
|
135
|
-
"pkg/#{PKG_FILE_NAME}.tgz",
|
136
|
-
"pkg/#{PKG_FILE_NAME}.zip"
|
137
|
-
]
|
149
|
+
task :publish_gecoder_packages => [:verify_user] + vanilla_release_files do
|
138
150
|
require 'meta_project'
|
139
151
|
require 'rake/contrib/xforge'
|
140
152
|
|
141
153
|
Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PROJECT_NAME)) do |xf|
|
142
154
|
xf.user_name = ENV['RUBYFORGE_USER']
|
143
|
-
xf.files =
|
155
|
+
xf.files = vanilla_release_files.to_a
|
144
156
|
xf.release_name = "Gecode/R #{PKG_VERSION}"
|
157
|
+
xf.package_name = PKG_NAME
|
145
158
|
end
|
146
159
|
end
|
147
160
|
|
161
|
+
# Files included in the release with Gecode.
|
162
|
+
gecode_release_files = [
|
163
|
+
"pkg/#{PKG_FILE_NAME_WITH_GECODE}.gem",
|
164
|
+
#"pkg/#{PKG_FILE_NAME_WITH_GECODE}.tgz",
|
165
|
+
#"pkg/#{PKG_FILE_NAME_WITH_GECODE}.zip",
|
166
|
+
"pkg/#{PKG_FILE_NAME_WITH_GECODE}-mswin32.gem"
|
167
|
+
]
|
148
168
|
desc 'Publish Gecode/R with Gecode packages on RubyForge'
|
149
|
-
task :publish_gecoder_with_gecode_packages =>
|
150
|
-
|
151
|
-
"pkg/#{PKG_FILE_NAME_WITH_GECODE}*.gem",
|
152
|
-
"pkg/#{PKG_FILE_NAME_WITH_GECODE}*.tgz",
|
153
|
-
"pkg/#{PKG_FILE_NAME_WITH_GECODE}*.zip"
|
154
|
-
]
|
155
|
-
|
169
|
+
task :publish_gecoder_with_gecode_packages =>
|
170
|
+
[:verify_user] + gecode_release_files do
|
156
171
|
require 'meta_project'
|
157
172
|
require 'rake/contrib/xforge'
|
158
173
|
|
159
174
|
Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PROJECT_NAME)) do |xf|
|
160
175
|
xf.user_name = ENV['RUBYFORGE_USER']
|
161
|
-
xf.files =
|
176
|
+
xf.files = gecode_release_files.to_a
|
162
177
|
xf.release_name = "Gecode/R with Gecode #{PKG_VERSION}"
|
178
|
+
xf.package_name = PKG_NAME_WITH_GECODE
|
163
179
|
end
|
164
180
|
end
|
data/tasks/rcov.rake
CHANGED
@@ -3,9 +3,10 @@ require 'spec/rake/verify_rcov'
|
|
3
3
|
|
4
4
|
RCOV_DIR = "#{File.dirname(__FILE__)}/../doc/output/coverage"
|
5
5
|
|
6
|
-
desc "Run all specs with rcov"
|
6
|
+
desc "Run all specs (except examples) with rcov"
|
7
7
|
Spec::Rake::SpecTask.new(:rcov) do |t|
|
8
8
|
t.spec_files = FileList['specs/**/*.rb']
|
9
|
+
t.spec_files.exclude 'examples.rb'
|
9
10
|
t.rcov = true
|
10
11
|
t.rcov_opts = ['--exclude examples', '--exclude specs']
|
11
12
|
t.rcov_dir = RCOV_DIR
|
@@ -14,4 +15,4 @@ end
|
|
14
15
|
RCov::VerifyTask.new(:verify_rcov => :rcov) do |t|
|
15
16
|
t.threshold = 100.0
|
16
17
|
t.index_html = "#{RCOV_DIR}/index.html"
|
17
|
-
end
|
18
|
+
end
|
data/tasks/specs.rake
CHANGED
@@ -3,13 +3,19 @@ require 'spec/rake/spectask'
|
|
3
3
|
spec_files = FileList['specs/**/*.rb']
|
4
4
|
|
5
5
|
desc 'Run all specs'
|
6
|
-
Spec::Rake::SpecTask.new(
|
6
|
+
Spec::Rake::SpecTask.new(:specs) do |t|
|
7
7
|
t.libs = ['lib']
|
8
8
|
t.spec_files = spec_files
|
9
9
|
end
|
10
10
|
|
11
|
+
desc 'Run specs for the examples'
|
12
|
+
Spec::Rake::SpecTask.new(:example_specs) do |t|
|
13
|
+
t.libs = ['lib']
|
14
|
+
t.spec_files = FileList['specs/examples.rb']
|
15
|
+
end
|
16
|
+
|
11
17
|
desc 'Generate an rspec html report'
|
12
|
-
Spec::Rake::SpecTask.new(
|
18
|
+
Spec::Rake::SpecTask.new(:spec_html) do |t|
|
13
19
|
t.spec_files = spec_files
|
14
20
|
t.spec_opts = ['--format html:doc/output/rspec.html','--backtrace']
|
15
|
-
end
|
21
|
+
end
|
data/tasks/svn.rake
CHANGED
@@ -2,10 +2,13 @@ require 'lib/gecoder/version'
|
|
2
2
|
|
3
3
|
desc "Tag the release in svn"
|
4
4
|
task :tag do
|
5
|
-
|
6
|
-
|
5
|
+
base_url = `svn info`.match(/Repository Root: (.*)/n)[1]
|
6
|
+
base_url.gsub!('rubyforge', "#{ENV['RUBYFORGE_USER']}@rubyforge")
|
7
|
+
from = base_url + '/trunk'
|
8
|
+
to = base_url + "/tags/gecoder-#{GecodeR::VERSION}"
|
9
|
+
options = "-m \"Tag release Gecode/R #{GecodeR::VERSION}\""
|
7
10
|
|
8
11
|
puts "Creating tag in SVN"
|
9
|
-
tag_cmd = "svn cp #{from} #{to}
|
12
|
+
tag_cmd = "svn cp #{from} #{to} #{options}"
|
10
13
|
`#{tag_cmd}` ; raise "ERROR: #{tag_cmd}" unless $? == 0
|
11
14
|
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: gecoder-with-gecode
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.8.
|
7
|
-
date: 2008-04-
|
6
|
+
version: 0.8.1
|
7
|
+
date: 2008-04-20 00:00:00 +02:00
|
8
8
|
summary: Ruby interface to Gecode, an environment for constraint programming.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -34,7 +34,8 @@ files:
|
|
34
34
|
- COPYING
|
35
35
|
- README
|
36
36
|
- LGPL-LICENSE
|
37
|
-
- lib/gecoder/interface/constraints/bool_enum/
|
37
|
+
- lib/gecoder/interface/constraints/bool_enum/extensional.rb
|
38
|
+
- lib/gecoder/interface/constraints/bool_enum/relation.rb
|
38
39
|
- lib/gecoder/interface/constraints/set_enum/operation.rb
|
39
40
|
- lib/gecoder/interface/constraints/set_enum/distinct.rb
|
40
41
|
- lib/gecoder/interface/constraints/set_enum/selection.rb
|
@@ -56,6 +57,7 @@ files:
|
|
56
57
|
- lib/gecoder/interface/constraints/int_enum/count.rb
|
57
58
|
- lib/gecoder/interface/constraints/int_enum/arithmetic.rb
|
58
59
|
- lib/gecoder/interface/constraints/int_enum/element.rb
|
60
|
+
- lib/gecoder/interface/constraints/int_enum/extensional.rb
|
59
61
|
- lib/gecoder/interface/constraints/int_enum_constraints.rb
|
60
62
|
- lib/gecoder/interface/constraints/bool_enum_constraints.rb
|
61
63
|
- lib/gecoder/interface/constraints/set_enum_constraints.rb
|
@@ -156,7 +158,6 @@ files:
|
|
156
158
|
- tasks/dependencies.txt
|
157
159
|
- specs/constraints
|
158
160
|
- specs/constraints/boolean.rb
|
159
|
-
- specs/constraints/bool_enum.rb
|
160
161
|
- specs/constraints/int_domain.rb
|
161
162
|
- specs/constraints/distinct.rb
|
162
163
|
- specs/constraints/set_domain.rb
|
@@ -176,6 +177,8 @@ files:
|
|
176
177
|
- specs/constraints/channel.rb
|
177
178
|
- specs/constraints/linear.rb
|
178
179
|
- specs/constraints/set_operation.rb
|
180
|
+
- specs/constraints/extensional.rb
|
181
|
+
- specs/constraints/bool_enum_relation.rb
|
179
182
|
- specs/branch.rb
|
180
183
|
- specs/model.rb
|
181
184
|
- specs/binding_changes.rb
|
@@ -188,6 +191,7 @@ files:
|
|
188
191
|
- specs/enum_matrix.rb
|
189
192
|
- specs/spec_helper.rb
|
190
193
|
- specs/distribution.rb
|
194
|
+
- specs/examples.rb
|
191
195
|
- vendor/gecode/win32/lib/libgecodeint.dll
|
192
196
|
- vendor/gecode/win32/lib/libgecodekernel.dll
|
193
197
|
- vendor/gecode/win32/lib/libgecodeminimodel.dll
|
@@ -197,7 +201,6 @@ files:
|
|
197
201
|
- lib/gecode.dll
|
198
202
|
test_files:
|
199
203
|
- specs/constraints/boolean.rb
|
200
|
-
- specs/constraints/bool_enum.rb
|
201
204
|
- specs/constraints/int_domain.rb
|
202
205
|
- specs/constraints/distinct.rb
|
203
206
|
- specs/constraints/set_domain.rb
|
@@ -217,6 +220,8 @@ test_files:
|
|
217
220
|
- specs/constraints/channel.rb
|
218
221
|
- specs/constraints/linear.rb
|
219
222
|
- specs/constraints/set_operation.rb
|
223
|
+
- specs/constraints/extensional.rb
|
224
|
+
- specs/constraints/bool_enum_relation.rb
|
220
225
|
- specs/branch.rb
|
221
226
|
- specs/model.rb
|
222
227
|
- specs/binding_changes.rb
|
@@ -229,6 +234,7 @@ test_files:
|
|
229
234
|
- specs/enum_matrix.rb
|
230
235
|
- specs/spec_helper.rb
|
231
236
|
- specs/distribution.rb
|
237
|
+
- specs/examples.rb
|
232
238
|
rdoc_options:
|
233
239
|
- --title
|
234
240
|
- Gecode/R
|
@@ -242,7 +248,8 @@ extra_rdoc_files:
|
|
242
248
|
- README
|
243
249
|
- CHANGES
|
244
250
|
- LGPL-LICENSE
|
245
|
-
- lib/gecoder/interface/constraints/bool_enum/
|
251
|
+
- lib/gecoder/interface/constraints/bool_enum/extensional.rb
|
252
|
+
- lib/gecoder/interface/constraints/bool_enum/relation.rb
|
246
253
|
- lib/gecoder/interface/constraints/set_enum/operation.rb
|
247
254
|
- lib/gecoder/interface/constraints/set_enum/distinct.rb
|
248
255
|
- lib/gecoder/interface/constraints/set_enum/selection.rb
|
@@ -264,6 +271,7 @@ extra_rdoc_files:
|
|
264
271
|
- lib/gecoder/interface/constraints/int_enum/count.rb
|
265
272
|
- lib/gecoder/interface/constraints/int_enum/arithmetic.rb
|
266
273
|
- lib/gecoder/interface/constraints/int_enum/element.rb
|
274
|
+
- lib/gecoder/interface/constraints/int_enum/extensional.rb
|
267
275
|
- lib/gecoder/interface/constraints/int_enum_constraints.rb
|
268
276
|
- lib/gecoder/interface/constraints/bool_enum_constraints.rb
|
269
277
|
- lib/gecoder/interface/constraints/set_enum_constraints.rb
|