gecoder 0.4.0 → 0.5.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 +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'
|