gecoder 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +11 -0
- data/README +12 -1
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/queens.rb +43 -0
- data/example/raw_bindings.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/sudoku.rb +65 -0
- data/ext/missing.cpp +15 -21
- data/ext/missing.h +14 -20
- data/ext/vararray.cpp +14 -20
- data/ext/vararray.h +18 -22
- data/lib/gecoder/bindings/bindings.rb +1979 -1969
- data/lib/gecoder/interface/binding_changes.rb +123 -2
- data/lib/gecoder/interface/constraints/bool/boolean.rb +80 -65
- data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +59 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +42 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +21 -44
- data/lib/gecoder/interface/constraints/int/domain.rb +6 -4
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +18 -44
- data/lib/gecoder/interface/constraints/int_enum/count.rb +3 -18
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +4 -16
- data/lib/gecoder/interface/constraints/int_enum/element.rb +9 -20
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +28 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +56 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +66 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +125 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +37 -0
- data/lib/gecoder/interface/constraints.rb +229 -65
- data/lib/gecoder/interface/enum_wrapper.rb +42 -11
- data/lib/gecoder/interface/model.rb +75 -0
- data/lib/gecoder/interface/search.rb +4 -9
- data/lib/gecoder/interface/variables.rb +36 -2
- data/lib/gecoder/version.rb +1 -1
- data/specs/bool_var.rb +58 -0
- data/specs/constraints/arithmetic.rb +91 -90
- data/specs/constraints/bool_enum.rb +130 -0
- data/specs/constraints/boolean.rb +95 -2
- data/specs/constraints/cardinality.rb +127 -0
- data/specs/constraints/constraint_helper.rb +91 -0
- data/specs/constraints/constraints.rb +31 -0
- data/specs/constraints/element.rb +43 -72
- data/specs/constraints/{domain.rb → int_domain.rb} +4 -0
- data/specs/constraints/{relation.rb → int_relation.rb} +0 -0
- data/specs/constraints/set_domain.rb +165 -0
- data/specs/constraints/set_relation.rb +181 -0
- data/specs/enum_wrapper.rb +13 -2
- data/specs/int_var.rb +33 -1
- data/specs/model.rb +80 -0
- data/specs/set_var.rb +39 -0
- data/specs/spec_helper.rb +35 -0
- data/specs/tmp +11 -124
- data/tasks/distribution.rake +1 -1
- data/vendor/rust/rust/class.rb +10 -10
- data/vendor/rust/rust/constants.rb +1 -1
- data/vendor/rust/rust/function.rb +5 -5
- data/vendor/rust/rust/type.rb +1 -1
- data/vendor/rust/test/constants.rb +1 -0
- data/vendor/rust/test/cppclass.cc +5 -0
- data/vendor/rust/test/cppclass.hh +4 -0
- data/vendor/rust/test/lib/extension-test.rb +1 -1
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-cwrapper.rb +3 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- metadata +31 -4
@@ -8,30 +8,15 @@ module Gecode
|
|
8
8
|
"#{element.class}."
|
9
9
|
end
|
10
10
|
params = {:lhs => self, :element => element}
|
11
|
-
|
12
|
-
|
11
|
+
Gecode::Constraints::SimpleExpressionStub.new(@model, params) do |m, ps|
|
12
|
+
Gecode::Constraints::IntEnum::Count::Expression.new(m, ps)
|
13
|
+
end
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
18
|
# A module that gathers the classes and modules used in count constraints.
|
18
19
|
module Gecode::Constraints::IntEnum::Count
|
19
|
-
|
20
|
-
|
21
|
-
# Describes an expression stub started with an int var enum followed by
|
22
|
-
# #count .
|
23
|
-
class ExpressionStub < Gecode::Constraints::ExpressionStub
|
24
|
-
include Gecode::Constraints::LeftHandSideMethods
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
# Produces an expression with the element for the lhs module.
|
29
|
-
def expression(params)
|
30
|
-
params.update(@params)
|
31
|
-
Gecode::Constraints::IntEnum::Count::Expression.new(@model, params)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
20
|
# Describes an expression
|
36
21
|
class Expression < Gecode::Constraints::IntEnum::Expression
|
37
22
|
def initialize(model, params)
|
@@ -7,8 +7,10 @@ module Gecode
|
|
7
7
|
offsets = *offsets
|
8
8
|
end
|
9
9
|
params = {:lhs => self, :offsets => offsets}
|
10
|
-
|
11
|
-
|
10
|
+
|
11
|
+
Gecode::Constraints::SimpleExpressionStub.new(@model, params) do |m, ps|
|
12
|
+
Gecode::Constraints::IntEnum::Expression.new(m, ps)
|
13
|
+
end
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -31,20 +33,6 @@ module Gecode::Constraints::IntEnum
|
|
31
33
|
|
32
34
|
# A module that gathers the classes and modules used in distinct constraints.
|
33
35
|
module Distinct
|
34
|
-
# Describes an expression started with an int var enum following with
|
35
|
-
# #with_offsets .
|
36
|
-
class OffsetExpressionStub < Gecode::Constraints::ExpressionStub
|
37
|
-
include Gecode::Constraints::LeftHandSideMethods
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
# Produces an expression with offsets for the lhs module.
|
42
|
-
def expression(params)
|
43
|
-
params.update(@params)
|
44
|
-
Gecode::Constraints::IntEnum::Expression.new(@model, params)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
36
|
# Describes a distinct constraint (optionally with offsets).
|
49
37
|
class DistinctConstraint < Gecode::Constraints::Constraint
|
50
38
|
def post
|
@@ -2,29 +2,18 @@
|
|
2
2
|
module Gecode::Constraints::IntEnum::Element
|
3
3
|
# Describes an expression stub started with an int var enum following with an
|
4
4
|
# array access using an integer variables .
|
5
|
-
class ExpressionStub < Gecode::Constraints::
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def expression(params)
|
12
|
-
# We extract the integer and continue as if it had been specified as
|
13
|
-
# left hand side. This might be elegant, but it could get away with
|
14
|
-
# fewer constraints at times (when only equality is used) and
|
15
|
-
# propagation strength can't be specified.
|
16
|
-
# TODO: cut down on the number of constraints when possible. See if
|
17
|
-
# there's some neat way of getting the above remarks.
|
5
|
+
class ExpressionStub < Gecode::Constraints::Int::CompositeStub
|
6
|
+
def constrain_equal(variable, params)
|
7
|
+
enum, position, strength = @params.values_at(:lhs, :position, :strength)
|
8
|
+
if variable.nil?
|
9
|
+
variable = @model.int_var(enum.domain_range)
|
10
|
+
end
|
18
11
|
|
19
|
-
|
20
|
-
enum, position = params.values_at(:lhs, :position)
|
21
|
-
tmp = @model.int_var(enum.domain_range)
|
12
|
+
# The enum can be a constant array.
|
22
13
|
enum = enum.to_int_var_array if enum.respond_to? :to_int_var_array
|
23
|
-
|
24
14
|
Gecode::Raw::element(@model.active_space, enum,
|
25
|
-
position.bind,
|
26
|
-
|
27
|
-
params.update(:lhs => tmp))
|
15
|
+
position.bind, variable.bind, strength)
|
16
|
+
return variable
|
28
17
|
end
|
29
18
|
end
|
30
19
|
|
@@ -16,6 +16,34 @@ module Gecode
|
|
16
16
|
module Constraints::Int
|
17
17
|
class Expression < Gecode::Constraints::Expression
|
18
18
|
end
|
19
|
+
|
20
|
+
# A composite expression which is an int expression with a left hand side
|
21
|
+
# resulting from a previous constraint.
|
22
|
+
class CompositeExpression < Gecode::Constraints::CompositeExpression
|
23
|
+
# The block given should take three parameters. The first is the variable
|
24
|
+
# that should be the left hand side, if it's nil then a new one should be
|
25
|
+
# created. The second is the has of parameters. The block should return
|
26
|
+
# the variable used as left hand side.
|
27
|
+
def initialize(model, params, &block)
|
28
|
+
super(Expression, Gecode::FreeIntVar, model, params, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Describes a stub that produces an int variable, which can then be used with
|
33
|
+
# the normal int variable constraints. An example would be the element
|
34
|
+
# constraint.
|
35
|
+
#
|
36
|
+
# int_enum[int_var].must > rhs
|
37
|
+
#
|
38
|
+
# The int_enum[int_var] part produces an int variable which the constraint
|
39
|
+
# ".must > rhs" is then applied to. In the above case two constraints (and
|
40
|
+
# one temporary variable) are required, but in the case of equality only
|
41
|
+
# one constraint is required.
|
42
|
+
class CompositeStub < Gecode::Constraints::CompositeStub
|
43
|
+
def initialize(model, params)
|
44
|
+
super(CompositeExpression, model, params)
|
45
|
+
end
|
46
|
+
end
|
19
47
|
end
|
20
48
|
end
|
21
49
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeSetVar
|
3
|
+
# Starts a constraint on all the size of the set.
|
4
|
+
def size
|
5
|
+
params = {:lhs => self}
|
6
|
+
Gecode::Constraints::Set::Cardinality::SizeExpressionStub.new(@model, params)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Gecode::Constraints::Set
|
12
|
+
# A module that gathers the classes and modules used in cardinality
|
13
|
+
# constraints.
|
14
|
+
module Cardinality
|
15
|
+
# Describes a cardinality constraint.
|
16
|
+
class CardinalityConstraint < Gecode::Constraints::Constraint
|
17
|
+
def post
|
18
|
+
var, range = @params.values_at(:lhs, :range)
|
19
|
+
Gecode::Raw::cardinality(@model.active_space, var.bind, range.first,
|
20
|
+
range.last)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# A custom composite stub to change the composite expression used.
|
25
|
+
class CompositeStub < Gecode::Constraints::CompositeStub
|
26
|
+
def initialize(model, params)
|
27
|
+
super(Expression, model, params)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Describes a cardinality expression started with set.size.must .
|
32
|
+
class Expression < Gecode::Constraints::Int::CompositeExpression
|
33
|
+
def in(range)
|
34
|
+
if range.kind_of?(Range) and !@params[:negate]
|
35
|
+
@params.update(:range => range)
|
36
|
+
@model.add_constraint CardinalityConstraint.new(@model, @params)
|
37
|
+
else
|
38
|
+
super(range)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Describes an expression stub started with a set variable followed by
|
44
|
+
# #size .
|
45
|
+
class SizeExpressionStub < CompositeStub
|
46
|
+
def constrain_equal(variable, params)
|
47
|
+
lhs = @params[:lhs]
|
48
|
+
if variable.nil?
|
49
|
+
variable = @model.int_var(lhs.glb_size, lhs.lub_size)
|
50
|
+
end
|
51
|
+
Gecode::Raw::cardinality(@model.active_space, lhs.bind, variable.bind)
|
52
|
+
return variable
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Gecode::Constraints::Set
|
2
|
+
class Expression
|
3
|
+
Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |name, type|
|
4
|
+
module_eval <<-"end_code"
|
5
|
+
# Creates a domain constraint using the specified constant set.
|
6
|
+
def #{name}(constant_set, options = {})
|
7
|
+
add_domain_constraint(:#{name}, constant_set, options)
|
8
|
+
end
|
9
|
+
end_code
|
10
|
+
end
|
11
|
+
alias_set_methods
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# Adds a domain constraint for the specified relation name, constant set
|
16
|
+
# and options.
|
17
|
+
def add_domain_constraint(relation_name, constant_set, options)
|
18
|
+
@params[:rhs] = constant_set
|
19
|
+
@params[:relation] = relation_name
|
20
|
+
@params.update Gecode::Constraints::Set::Util.decode_options(options)
|
21
|
+
if relation_name == :==
|
22
|
+
@model.add_constraint Domain::EqualityDomainConstraint.new(@model,
|
23
|
+
@params)
|
24
|
+
else
|
25
|
+
@model.add_constraint Domain::DomainConstraint.new(@model, @params)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# A module that gathers the classes and modules used in domain constraints.
|
31
|
+
module Domain
|
32
|
+
# Describes a domain constraint for equality.
|
33
|
+
class EqualityDomainConstraint < Gecode::Constraints::ReifiableConstraint
|
34
|
+
def post
|
35
|
+
var, domain, reif_var, negate = @params.values_at(:lhs, :rhs, :reif,
|
36
|
+
:negate)
|
37
|
+
if negate
|
38
|
+
rel_type = Gecode::Constraints::Util::NEGATED_SET_RELATION_TYPES[:==]
|
39
|
+
else
|
40
|
+
rel_type = Gecode::Constraints::Util::SET_RELATION_TYPES[:==]
|
41
|
+
end
|
42
|
+
|
43
|
+
(params = []) << var.bind
|
44
|
+
params << rel_type
|
45
|
+
params << Gecode::Constraints::Util.constant_set_to_params(domain)
|
46
|
+
params << reif_var.bind if reif_var.respond_to? :bind
|
47
|
+
Gecode::Raw::dom(@model.active_space, *params.flatten)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Describes a domain constraint for the relations other than equality.
|
52
|
+
class DomainConstraint < Gecode::Constraints::ReifiableConstraint
|
53
|
+
def post
|
54
|
+
var, domain, reif_var, relation = @params.values_at(:lhs, :rhs, :reif,
|
55
|
+
:relation)
|
56
|
+
|
57
|
+
(params = []) << var.bind
|
58
|
+
params << Gecode::Constraints::Util::SET_RELATION_TYPES[relation]
|
59
|
+
params << Gecode::Constraints::Util.constant_set_to_params(domain)
|
60
|
+
params << reif_var.bind if reif_var.respond_to? :bind
|
61
|
+
Gecode::Raw::dom(@model.active_space, *params.flatten)
|
62
|
+
end
|
63
|
+
negate_using_reification
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeSetVar
|
3
|
+
# Starts a constraint on all the elements of the set.
|
4
|
+
def elements
|
5
|
+
params = {:lhs => self}
|
6
|
+
Gecode::Constraints::SimpleExpressionStub.new(@model, params) do |m, ps|
|
7
|
+
Gecode::Constraints::Set::Relation::ElementExpression.new(m, ps)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module Gecode::Constraints::Set
|
14
|
+
class Expression
|
15
|
+
Gecode::Constraints::Util::SET_RELATION_TYPES.each_pair do |name, type|
|
16
|
+
module_eval <<-"end_code"
|
17
|
+
# Wrap previous relation methods providing support for relation
|
18
|
+
# constraints.
|
19
|
+
alias_method 'pre_relation_#{type}_method'.to_sym, :#{name}
|
20
|
+
|
21
|
+
# Creates a relation constraint using the specified expression.
|
22
|
+
def #{name}(expression, options = {})
|
23
|
+
if expression.kind_of? Gecode::FreeSetVar
|
24
|
+
add_relation_constraint(:#{name}, expression, options)
|
25
|
+
else
|
26
|
+
# Send it on.
|
27
|
+
pre_relation_#{type}_method(expression, options)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end_code
|
31
|
+
end
|
32
|
+
alias_set_methods
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Adds a relation constraint for the specified relation name, set variable
|
37
|
+
# and options.
|
38
|
+
def add_relation_constraint(relation_name, set, options)
|
39
|
+
@params[:rhs] = set
|
40
|
+
@params[:relation] = relation_name
|
41
|
+
@params.update Gecode::Constraints::Set::Util.decode_options(options)
|
42
|
+
if relation_name == :==
|
43
|
+
@model.add_constraint Relation::EqualityRelationConstraint.new(@model,
|
44
|
+
@params)
|
45
|
+
else
|
46
|
+
@model.add_constraint Relation::RelationConstraint.new(@model, @params)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# A module that gathers the classes and modules used in relation constraints.
|
52
|
+
module Relation
|
53
|
+
# Describes a relation constraint for equality.
|
54
|
+
class EqualityRelationConstraint < Gecode::Constraints::ReifiableConstraint
|
55
|
+
def post
|
56
|
+
var, rhs, reif_var, negate = @params.values_at(:lhs, :rhs, :reif,
|
57
|
+
:negate)
|
58
|
+
if negate
|
59
|
+
rel_type = Gecode::Constraints::Util::NEGATED_SET_RELATION_TYPES[:==]
|
60
|
+
else
|
61
|
+
rel_type = Gecode::Constraints::Util::SET_RELATION_TYPES[:==]
|
62
|
+
end
|
63
|
+
|
64
|
+
(params = []) << var.bind
|
65
|
+
params << rel_type
|
66
|
+
params << rhs.bind
|
67
|
+
params << reif_var.bind if reif_var.respond_to? :bind
|
68
|
+
Gecode::Raw::rel(@model.active_space, *params)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Describes a relation constraint for the relations other than equality.
|
73
|
+
class RelationConstraint < Gecode::Constraints::ReifiableConstraint
|
74
|
+
def post
|
75
|
+
var, rhs, reif_var, relation = @params.values_at(:lhs, :rhs, :reif,
|
76
|
+
:relation)
|
77
|
+
|
78
|
+
(params = []) << var.bind
|
79
|
+
params << Gecode::Constraints::Util::SET_RELATION_TYPES[relation]
|
80
|
+
params << rhs.bind
|
81
|
+
params << reif_var.bind if reif_var.respond_to? :bind
|
82
|
+
Gecode::Raw::rel(@model.active_space, *params)
|
83
|
+
end
|
84
|
+
negate_using_reification
|
85
|
+
end
|
86
|
+
|
87
|
+
# Describes a relation constraint on the elements of a set.
|
88
|
+
class ElementRelationConstraint < Gecode::Constraints::Constraint
|
89
|
+
def post
|
90
|
+
var, rhs, relation = @params.values_at(:lhs, :rhs, :relation)
|
91
|
+
|
92
|
+
if @params[:negate]
|
93
|
+
type = Gecode::Constraints::Util::NEGATED_RELATION_TYPES[relation]
|
94
|
+
else
|
95
|
+
type = Gecode::Constraints::Util::RELATION_TYPES[relation]
|
96
|
+
end
|
97
|
+
|
98
|
+
if rhs.kind_of? Fixnum
|
99
|
+
# Use a proxy int variable to cover.
|
100
|
+
rhs = @model.int_var(rhs)
|
101
|
+
end
|
102
|
+
Gecode::Raw::rel(@model.active_space, var.bind, type, rhs.bind)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Describes an expression which starts with set.element.must* .
|
107
|
+
class ElementExpression < Gecode::Constraints::Expression
|
108
|
+
Gecode::Constraints::Util::RELATION_TYPES.each_key do |name|
|
109
|
+
module_eval <<-"end_code"
|
110
|
+
# Creates an elements constraint using the specified expression, which
|
111
|
+
# may be either a constant integer of variable.
|
112
|
+
def #{name}(expression)
|
113
|
+
unless expression.kind_of?(Fixnum) or
|
114
|
+
expression.kind_of?(Gecode::FreeIntVar)
|
115
|
+
raise TypeError, "Invalid expression type \#{expression.class}."
|
116
|
+
end
|
117
|
+
@params.update(:rhs => expression, :relation => :#{name})
|
118
|
+
@model.add_constraint ElementRelationConstraint.new(@model, @params)
|
119
|
+
end
|
120
|
+
end_code
|
121
|
+
end
|
122
|
+
alias_comparison_methods
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Gecode
|
2
|
+
class FreeSetVar
|
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::Set::Expression.new(@model, params)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# A module containing constraints that have set variables as left hand side
|
15
|
+
# (but not enumerations).
|
16
|
+
module Constraints::Set
|
17
|
+
# An expression with a set as left hand side.
|
18
|
+
class Expression < Gecode::Constraints::Expression
|
19
|
+
end
|
20
|
+
|
21
|
+
# Utility methods for sets.
|
22
|
+
module Util
|
23
|
+
module_function
|
24
|
+
def decode_options(options)
|
25
|
+
if options.has_key? :strength
|
26
|
+
raise ArgumentError, 'Set constraints do not support the strength ' +
|
27
|
+
'option.'
|
28
|
+
end
|
29
|
+
Gecode::Constraints::Util.decode_options(options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
require 'gecoder/interface/constraints/set/domain'
|
36
|
+
require 'gecoder/interface/constraints/set/relation'
|
37
|
+
require 'gecoder/interface/constraints/set/cardinality'
|