gecoder 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/CHANGES +11 -0
  2. data/README +12 -1
  3. data/example/example_helper.rb +1 -0
  4. data/example/magic_sequence.rb +43 -0
  5. data/example/queens.rb +43 -0
  6. data/example/raw_bindings.rb +42 -0
  7. data/example/send_more_money.rb +43 -0
  8. data/example/sudoku.rb +65 -0
  9. data/ext/missing.cpp +15 -21
  10. data/ext/missing.h +14 -20
  11. data/ext/vararray.cpp +14 -20
  12. data/ext/vararray.h +18 -22
  13. data/lib/gecoder/bindings/bindings.rb +1979 -1969
  14. data/lib/gecoder/interface/binding_changes.rb +123 -2
  15. data/lib/gecoder/interface/constraints/bool/boolean.rb +80 -65
  16. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +59 -0
  17. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
  18. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +42 -0
  19. data/lib/gecoder/interface/constraints/int/arithmetic.rb +21 -44
  20. data/lib/gecoder/interface/constraints/int/domain.rb +6 -4
  21. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +18 -44
  22. data/lib/gecoder/interface/constraints/int_enum/count.rb +3 -18
  23. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +4 -16
  24. data/lib/gecoder/interface/constraints/int_enum/element.rb +9 -20
  25. data/lib/gecoder/interface/constraints/int_var_constraints.rb +28 -0
  26. data/lib/gecoder/interface/constraints/set/cardinality.rb +56 -0
  27. data/lib/gecoder/interface/constraints/set/domain.rb +66 -0
  28. data/lib/gecoder/interface/constraints/set/relation.rb +125 -0
  29. data/lib/gecoder/interface/constraints/set_var_constraints.rb +37 -0
  30. data/lib/gecoder/interface/constraints.rb +229 -65
  31. data/lib/gecoder/interface/enum_wrapper.rb +42 -11
  32. data/lib/gecoder/interface/model.rb +75 -0
  33. data/lib/gecoder/interface/search.rb +4 -9
  34. data/lib/gecoder/interface/variables.rb +36 -2
  35. data/lib/gecoder/version.rb +1 -1
  36. data/specs/bool_var.rb +58 -0
  37. data/specs/constraints/arithmetic.rb +91 -90
  38. data/specs/constraints/bool_enum.rb +130 -0
  39. data/specs/constraints/boolean.rb +95 -2
  40. data/specs/constraints/cardinality.rb +127 -0
  41. data/specs/constraints/constraint_helper.rb +91 -0
  42. data/specs/constraints/constraints.rb +31 -0
  43. data/specs/constraints/element.rb +43 -72
  44. data/specs/constraints/{domain.rb → int_domain.rb} +4 -0
  45. data/specs/constraints/{relation.rb → int_relation.rb} +0 -0
  46. data/specs/constraints/set_domain.rb +165 -0
  47. data/specs/constraints/set_relation.rb +181 -0
  48. data/specs/enum_wrapper.rb +13 -2
  49. data/specs/int_var.rb +33 -1
  50. data/specs/model.rb +80 -0
  51. data/specs/set_var.rb +39 -0
  52. data/specs/spec_helper.rb +35 -0
  53. data/specs/tmp +11 -124
  54. data/tasks/distribution.rake +1 -1
  55. data/vendor/rust/rust/class.rb +10 -10
  56. data/vendor/rust/rust/constants.rb +1 -1
  57. data/vendor/rust/rust/function.rb +5 -5
  58. data/vendor/rust/rust/type.rb +1 -1
  59. data/vendor/rust/test/constants.rb +1 -0
  60. data/vendor/rust/test/cppclass.cc +5 -0
  61. data/vendor/rust/test/cppclass.hh +4 -0
  62. data/vendor/rust/test/lib/extension-test.rb +1 -1
  63. data/vendor/rust/test/operators.cc +41 -0
  64. data/vendor/rust/test/operators.hh +39 -0
  65. data/vendor/rust/test/operators.rb +39 -0
  66. data/vendor/rust/test/test-cwrapper.rb +3 -0
  67. data/vendor/rust/test/test-operators.rb +42 -0
  68. metadata +31 -4
@@ -8,30 +8,15 @@ module Gecode
8
8
  "#{element.class}."
9
9
  end
10
10
  params = {:lhs => self, :element => element}
11
- return Gecode::Constraints::IntEnum::Count::ExpressionStub.new(
12
- @model, params)
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
- return Gecode::Constraints::IntEnum::Distinct::OffsetExpressionStub.new(
11
- @model, params)
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::ExpressionStub
6
- include Gecode::Constraints::LeftHandSideMethods
7
-
8
- private
9
-
10
- # Produces an expression with position for the lhs module.
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
- params.update(@params)
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, tmp.bind, Gecode::Raw::ICL_DEF)
26
- Gecode::Constraints::Int::Expression.new(@model,
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'