gecoder-with-gecode 0.7.1-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. data/CHANGES +81 -0
  2. data/COPYING +17 -0
  3. data/LGPL-LICENSE +458 -0
  4. data/README +45 -0
  5. data/Rakefile +13 -0
  6. data/example/example_helper.rb +1 -0
  7. data/example/magic_sequence.rb +43 -0
  8. data/example/queens.rb +43 -0
  9. data/example/raw_bindings.rb +42 -0
  10. data/example/send_more_money.rb +43 -0
  11. data/example/send_most_money.rb +58 -0
  12. data/example/square_tiling.rb +84 -0
  13. data/example/sudoku-set.rb +110 -0
  14. data/example/sudoku.rb +61 -0
  15. data/lib/gecode.dll +0 -0
  16. data/lib/gecoder.rb +5 -0
  17. data/lib/gecoder/bindings.rb +54 -0
  18. data/lib/gecoder/bindings/bindings.rb +2210 -0
  19. data/lib/gecoder/interface.rb +8 -0
  20. data/lib/gecoder/interface/binding_changes.rb +313 -0
  21. data/lib/gecoder/interface/branch.rb +152 -0
  22. data/lib/gecoder/interface/constraints.rb +397 -0
  23. data/lib/gecoder/interface/constraints/bool/boolean.rb +246 -0
  24. data/lib/gecoder/interface/constraints/bool/linear.rb +29 -0
  25. data/lib/gecoder/interface/constraints/bool_enum/boolean.rb +84 -0
  26. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +8 -0
  27. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +75 -0
  28. data/lib/gecoder/interface/constraints/int/arithmetic.rb +71 -0
  29. data/lib/gecoder/interface/constraints/int/domain.rb +78 -0
  30. data/lib/gecoder/interface/constraints/int/linear.rb +295 -0
  31. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +72 -0
  32. data/lib/gecoder/interface/constraints/int_enum/channel.rb +100 -0
  33. data/lib/gecoder/interface/constraints/int_enum/count.rb +92 -0
  34. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +69 -0
  35. data/lib/gecoder/interface/constraints/int_enum/element.rb +82 -0
  36. data/lib/gecoder/interface/constraints/int_enum/equality.rb +38 -0
  37. data/lib/gecoder/interface/constraints/int_enum/sort.rb +126 -0
  38. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +37 -0
  39. data/lib/gecoder/interface/constraints/int_var_constraints.rb +58 -0
  40. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
  41. data/lib/gecoder/interface/constraints/set/cardinality.rb +75 -0
  42. data/lib/gecoder/interface/constraints/set/connection.rb +193 -0
  43. data/lib/gecoder/interface/constraints/set/domain.rb +109 -0
  44. data/lib/gecoder/interface/constraints/set/operation.rb +132 -0
  45. data/lib/gecoder/interface/constraints/set/relation.rb +178 -0
  46. data/lib/gecoder/interface/constraints/set_enum/channel.rb +18 -0
  47. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +80 -0
  48. data/lib/gecoder/interface/constraints/set_enum/operation.rb +60 -0
  49. data/lib/gecoder/interface/constraints/set_enum/selection.rb +217 -0
  50. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +34 -0
  51. data/lib/gecoder/interface/constraints/set_var_constraints.rb +72 -0
  52. data/lib/gecoder/interface/enum_matrix.rb +64 -0
  53. data/lib/gecoder/interface/enum_wrapper.rb +153 -0
  54. data/lib/gecoder/interface/model.rb +251 -0
  55. data/lib/gecoder/interface/search.rb +123 -0
  56. data/lib/gecoder/interface/variables.rb +254 -0
  57. data/lib/gecoder/version.rb +4 -0
  58. data/specs/binding_changes.rb +76 -0
  59. data/specs/bool_var.rb +74 -0
  60. data/specs/branch.rb +170 -0
  61. data/specs/constraints/arithmetic.rb +266 -0
  62. data/specs/constraints/bool_enum.rb +140 -0
  63. data/specs/constraints/boolean.rb +232 -0
  64. data/specs/constraints/cardinality.rb +154 -0
  65. data/specs/constraints/channel.rb +126 -0
  66. data/specs/constraints/connection.rb +373 -0
  67. data/specs/constraints/constraint_helper.rb +180 -0
  68. data/specs/constraints/constraints.rb +74 -0
  69. data/specs/constraints/count.rb +139 -0
  70. data/specs/constraints/distinct.rb +218 -0
  71. data/specs/constraints/element.rb +106 -0
  72. data/specs/constraints/equality.rb +31 -0
  73. data/specs/constraints/int_domain.rb +69 -0
  74. data/specs/constraints/int_relation.rb +78 -0
  75. data/specs/constraints/linear.rb +332 -0
  76. data/specs/constraints/reification_sugar.rb +96 -0
  77. data/specs/constraints/selection.rb +292 -0
  78. data/specs/constraints/set_domain.rb +181 -0
  79. data/specs/constraints/set_operation.rb +285 -0
  80. data/specs/constraints/set_relation.rb +201 -0
  81. data/specs/constraints/sort.rb +175 -0
  82. data/specs/distribution.rb +14 -0
  83. data/specs/enum_matrix.rb +43 -0
  84. data/specs/enum_wrapper.rb +122 -0
  85. data/specs/int_var.rb +144 -0
  86. data/specs/logging.rb +24 -0
  87. data/specs/model.rb +190 -0
  88. data/specs/search.rb +246 -0
  89. data/specs/set_var.rb +68 -0
  90. data/specs/spec_helper.rb +93 -0
  91. data/tasks/all_tasks.rb +1 -0
  92. data/tasks/building.howto +65 -0
  93. data/tasks/distribution.rake +156 -0
  94. data/tasks/rcov.rake +17 -0
  95. data/tasks/specs.rake +15 -0
  96. data/tasks/svn.rake +11 -0
  97. data/tasks/website.rake +51 -0
  98. data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
  99. data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
  100. data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
  101. data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
  102. data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
  103. data/vendor/rust/README +28 -0
  104. data/vendor/rust/bin/cxxgenerator.rb +93 -0
  105. data/vendor/rust/include/rust_checks.hh +115 -0
  106. data/vendor/rust/include/rust_conversions.hh +102 -0
  107. data/vendor/rust/rust.rb +67 -0
  108. data/vendor/rust/rust/attribute.rb +51 -0
  109. data/vendor/rust/rust/bindings.rb +172 -0
  110. data/vendor/rust/rust/class.rb +339 -0
  111. data/vendor/rust/rust/constants.rb +48 -0
  112. data/vendor/rust/rust/container.rb +110 -0
  113. data/vendor/rust/rust/cppifaceparser.rb +129 -0
  114. data/vendor/rust/rust/cwrapper.rb +72 -0
  115. data/vendor/rust/rust/cxxclass.rb +98 -0
  116. data/vendor/rust/rust/element.rb +81 -0
  117. data/vendor/rust/rust/enum.rb +63 -0
  118. data/vendor/rust/rust/function.rb +407 -0
  119. data/vendor/rust/rust/namespace.rb +61 -0
  120. data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
  121. data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
  122. data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
  123. data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
  124. data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
  125. data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
  126. data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
  127. data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
  128. data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +91 -0
  129. data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
  130. data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
  131. data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
  132. data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
  133. data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
  134. data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
  135. data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
  136. data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
  137. data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
  138. data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
  139. data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
  140. data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
  141. data/vendor/rust/rust/type.rb +98 -0
  142. data/vendor/rust/test/Makefile +4 -0
  143. data/vendor/rust/test/constants.rb +36 -0
  144. data/vendor/rust/test/cppclass.cc +45 -0
  145. data/vendor/rust/test/cppclass.hh +67 -0
  146. data/vendor/rust/test/cppclass.rb +59 -0
  147. data/vendor/rust/test/cwrapper.c +74 -0
  148. data/vendor/rust/test/cwrapper.h +41 -0
  149. data/vendor/rust/test/cwrapper.rb +56 -0
  150. data/vendor/rust/test/dummyclass.hh +31 -0
  151. data/vendor/rust/test/lib/extension-test.rb +98 -0
  152. data/vendor/rust/test/operators.cc +41 -0
  153. data/vendor/rust/test/operators.hh +39 -0
  154. data/vendor/rust/test/operators.rb +39 -0
  155. data/vendor/rust/test/test-constants.rb +43 -0
  156. data/vendor/rust/test/test-cppclass.rb +82 -0
  157. data/vendor/rust/test/test-cwrapper.rb +80 -0
  158. data/vendor/rust/test/test-operators.rb +42 -0
  159. metadata +293 -0
@@ -0,0 +1,29 @@
1
+ module Gecode
2
+ class FreeBoolVar
3
+ # Creates a linear expression where the bool variables are summed.
4
+ def +(var)
5
+ Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
6
+ @model) + var
7
+ end
8
+
9
+ alias_method :pre_linear_mult, :* if instance_methods.include? '*'
10
+
11
+ # Creates a linear expression where the bool variable is multiplied with
12
+ # a constant integer.
13
+ def *(int)
14
+ if int.kind_of? Fixnum
15
+ Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
16
+ @model) * int
17
+ else
18
+ pre_linear_mult(int) if respond_to? :pre_linear_mult
19
+ end
20
+ end
21
+
22
+ # Creates a linear expression where the specified variable is subtracted
23
+ # from this one.
24
+ def -(var)
25
+ Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
26
+ @model) - var
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,84 @@
1
+ module Gecode
2
+ module BoolEnumMethods
3
+ # Produces an expression that can be handled as if it was a variable
4
+ # representing the conjunction of all boolean variables in the enumeration.
5
+ def conjunction
6
+ return Gecode::Constraints::BoolEnum::ConjunctionStub.new(
7
+ @model, :lhs => self)
8
+ end
9
+
10
+ # Produces an expression that can be handled as if it was a variable
11
+ # representing the disjunction of all boolean variables in the enumeration.
12
+ def disjunction
13
+ return Gecode::Constraints::BoolEnum::DisjunctionStub.new(
14
+ @model, :lhs => self)
15
+ end
16
+ end
17
+
18
+ # A module that gathers the classes and modules used by boolean enumeration
19
+ # constraints.
20
+ module Constraints::BoolEnum
21
+ # Describes a CompositeStub for the conjunction constraint, which constrain
22
+ # the conjunction of all boolean variables in an enumeration.
23
+ #
24
+ # == Example
25
+ #
26
+ # # The conjunction of all variables in +bool_enum+ must be true. I.e. all
27
+ # # boolean variables must take the value true.
28
+ # bool_enum.conjunction.must_be.true
29
+ #
30
+ # # The conjunction of all variables in +bool_enum+ must equal b1.
31
+ # bool_enum.conjunction.must == b1
32
+ #
33
+ # # The conjunction of all variables in +bool_enum+ must not equal b1 and
34
+ # # b2. It's reified it with +bool+ and selects the strength +domain+.
35
+ # bool_enum.conjunction.must_not.equal(b1 & b2, :reify => bool,
36
+ # :strength => :domain)
37
+ class ConjunctionStub < Gecode::Constraints::Bool::CompositeStub
38
+ def constrain_equal(variable, params, constrain)
39
+ enum, strength = @params.values_at(:lhs, :strength)
40
+
41
+ @model.add_interaction do
42
+ if variable.respond_to? :bind
43
+ bound = variable.bind
44
+ else
45
+ bound = variable
46
+ end
47
+ Gecode::Raw::bool_and(@model.active_space, enum.to_bool_var_array,
48
+ bound, strength)
49
+ end
50
+ return variable
51
+ end
52
+ end
53
+
54
+ # Describes a CompositeStub for the disjunction constraint, which constrain
55
+ # the disjunction of all boolean variables in an enumeration.
56
+ #
57
+ # == Example
58
+ #
59
+ # # The disjunction of all variables in +bool_enum+ must be true. I.e. at
60
+ # # least one of the boolean variables must take the value true.
61
+ # bool_enum.disjunction.must_be.true
62
+ #
63
+ # # The disjunction of all variables in +bool_enum+ must equal b1.
64
+ # bool_enum.conjunction.must == b1
65
+ #
66
+ # # The disjunction of all variables in +bool_enum+ must not equal b1 and
67
+ # # b2. It's reified it with +bool+ and selects the strength +domain+.
68
+ # bool_enum.disjunction.must_not.equal(b1 & b2, :reify => bool,
69
+ # :strength => :domain)
70
+ class DisjunctionStub < Gecode::Constraints::Bool::CompositeStub
71
+ def constrain_equal(variable, params, constrain)
72
+ enum, strength = @params.values_at(:lhs, :strength)
73
+
74
+ if variable.respond_to? :bind
75
+ bound = variable.bind
76
+ else
77
+ bound = variable
78
+ end
79
+ Gecode::Raw::bool_or(@model.active_space, enum.to_bool_var_array,
80
+ bound, strength)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,8 @@
1
+ module Gecode
2
+ # A module containing constraints that have enumerations of boolean variables
3
+ # as left hand side.
4
+ module Constraints::BoolEnum
5
+ end
6
+ end
7
+
8
+ require 'gecoder/interface/constraints/bool_enum/boolean'
@@ -0,0 +1,75 @@
1
+ module Gecode
2
+ class FreeBoolVar
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::Bool::Expression.new(@model, params)
11
+ end
12
+ end
13
+
14
+ # A module containing constraints that have int variables as left hand side
15
+ # (but not enumerations).
16
+ module Constraints::Bool
17
+ # Describes a boolean expression.
18
+ class Expression < Gecode::Constraints::Expression #:nodoc:
19
+ end
20
+
21
+ # A composite expression which is an bool expression with a left hand side
22
+ # resulting from a previous constraint.
23
+ class CompositeExpression < Gecode::Constraints::CompositeExpression #:nodoc:
24
+ # The block given should take three parameters. The first is the variable
25
+ # that should be the left hand side, if it's nil then a new one should be
26
+ # created. The second is the has of parameters. The block should return
27
+ # the variable used as left hand side.
28
+ def initialize(model, params, &block)
29
+ super(Expression, Gecode::FreeBoolVar, lambda{ model.bool_var }, model,
30
+ params, &block)
31
+ end
32
+
33
+ # Override to also deal with constant booleans.
34
+ def true(options = {})
35
+ # We don't need any additional constraints.
36
+ @params.update Gecode::Constraints::Util.decode_options(options)
37
+ @model.add_interaction do
38
+ @constrain_equal_proc.call(!@params[:negate], @params)
39
+ end
40
+ end
41
+
42
+ # Override to also deal with constant booleans.
43
+ def false(options = {})
44
+ # We don't need any additional constraints.
45
+ @params.update Gecode::Constraints::Util.decode_options(options)
46
+ @model.add_interaction do
47
+ @constrain_equal_proc.call(@params[:negate], @params)
48
+ end
49
+ end
50
+ end
51
+
52
+ # Describes a stub that produces an int variable, which can then be used
53
+ # with the normal int variable constraints. An example would be the
54
+ # conjunction constraint.
55
+ #
56
+ # bools.conjunction.must == b1 | b2
57
+ #
58
+ # <tt>bools.conjunction</tt> produces a boolean variable which the
59
+ # constraint <tt>.must == b1 | b2</tt> is then applied to. In the above
60
+ # case two constraints (and one temporary variable) are required, but in
61
+ # the case of equality only one constraint is required.
62
+ #
63
+ # Whether a constraint involving a reification stub supports negation,
64
+ # reification, strength options and so on depends on the constraint on the
65
+ # right hand side.
66
+ class CompositeStub < Gecode::Constraints::CompositeStub
67
+ def initialize(model, params)
68
+ super(CompositeExpression, model, params)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ require 'gecoder/interface/constraints/bool/boolean'
75
+ require 'gecoder/interface/constraints/bool/linear'
@@ -0,0 +1,71 @@
1
+ class Gecode::FreeIntVar
2
+ # Initiates an arithmetic absolute value constraint.
3
+ def abs
4
+ Gecode::Constraints::Int::Arithmetic::AbsExpressionStub.new(@model,
5
+ :lhs => self)
6
+ end
7
+
8
+ alias_method :pre_arith_mult, :* if instance_methods.include? '*'
9
+
10
+ # Begins a multiplication constraint involving the two int variable.
11
+ def *(var)
12
+ if var.kind_of? Gecode::FreeIntVar
13
+ Gecode::Constraints::Int::Arithmetic::MultExpressionStub.new(
14
+ @model, :lhs => self, :var => var)
15
+ else
16
+ pre_arith_mult(var) if respond_to? :pre_arith_mult
17
+ end
18
+ end
19
+ end
20
+
21
+ # A module that gathers the classes and modules used by arithmetic constraints.
22
+ module Gecode::Constraints::Int::Arithmetic #:nodoc:
23
+ # Describes a CompositeStub for absolute value constraints, which constrain
24
+ # the absolute value of an integer variable.
25
+ #
26
+ # == Examples
27
+ #
28
+ # # The absolute value of +x+ must be less than 2.
29
+ # x.abs.must < 2
30
+ #
31
+ # # The absolute value of +x+ must be in the range 5..7, with +bool+ as
32
+ # # reification variable and +value+ as strength.
33
+ # x.abs.must_be.in(5..7, :reify => bool, :strength => :value)
34
+ class AbsExpressionStub < Gecode::Constraints::Int::CompositeStub
35
+ def constrain_equal(variable, params, constrain)
36
+ lhs, strength = @params.values_at(:lhs, :strength)
37
+ if constrain
38
+ bounds = [lhs.min.abs, lhs.max.abs]
39
+ variable.must_be.in bounds.min..bounds.max
40
+ end
41
+
42
+ Gecode::Raw::abs(@model.active_space, lhs.bind, variable.bind, strength)
43
+ end
44
+ end
45
+
46
+ # Describes a CompositeStub for multiplication constraint, which constrain
47
+ # the value of the multiplication of two variables.
48
+ #
49
+ # == Examples
50
+ #
51
+ # # The value of +x*y+ must be equal to their sum.
52
+ # (x*y).must == x + y
53
+ #
54
+ # # The valye of +x*y+ must be less than 17, with +bool+ as reification
55
+ # # variable and +domain+ as strength.
56
+ # (x*y).must_be.less_than(17, :reify => bool, :strength => :domain)
57
+ class MultExpressionStub < Gecode::Constraints::Int::CompositeStub
58
+ def constrain_equal(variable, params, constrain)
59
+ lhs, lhs2, strength = @params.values_at(:lhs, :var, :strength)
60
+ if constrain
61
+ a_min = lhs.min; a_max = lhs.max
62
+ b_min = lhs2.min; b_max = lhs2.max
63
+ products = [a_min*b_min, a_min*b_max, a_max*b_min, a_max*b_max]
64
+ variable.must_be.in products.min..products.max
65
+ end
66
+
67
+ Gecode::Raw::mult(@model.active_space, lhs.bind, lhs2.bind,
68
+ variable.bind, strength)
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,78 @@
1
+ module Gecode::Constraints::Int
2
+ class Expression
3
+ # Creates a domain constraint using the specified domain.
4
+ def in(domain, options = {})
5
+ @params.update(Gecode::Constraints::Util.decode_options(options))
6
+ @params[:domain] = domain
7
+ if domain.kind_of? Range
8
+ @model.add_constraint Domain::RangeDomainConstraint.new(@model, @params)
9
+ elsif domain.kind_of?(Enumerable) and domain.all?{ |e| e.kind_of? Fixnum }
10
+ @model.add_constraint Domain::EnumDomainConstraint.new(@model,
11
+ @params)
12
+ else
13
+ raise TypeError, "Expected integer enumerable, got #{domain.class}."
14
+ end
15
+ end
16
+ end
17
+
18
+ # A module that gathers the classes and modules used in domain constraints.
19
+ module Domain #:nodoc:
20
+ # Range domain constraints specify that an integer variable must be
21
+ # contained within a specified range of integers. Supports reification and
22
+ # negation.
23
+ #
24
+ # == Examples
25
+ #
26
+ # # +x+ must be in the range 1..10
27
+ # x.must_be.in 1..10
28
+ #
29
+ # # +x+ must not be in the range -5...5
30
+ # x.must_not_be.in -5...5
31
+ #
32
+ # # Specifies the above, but but reifies the constraint with the boolean
33
+ # # variable +bool+ and specified +value+ as strength.
34
+ # x.must_not_be.in(-5...5, :reify => bool, :strength => :value)
35
+ class RangeDomainConstraint < Gecode::Constraints::ReifiableConstraint
36
+ def post
37
+ var, domain, reif_var, strength = @params.values_at(:lhs, :domain,
38
+ :reif, :strength)
39
+ (params = []) << var.bind
40
+ params << domain.first << domain.last
41
+ params << reif_var.bind if reif_var.respond_to? :bind
42
+ params << strength
43
+ Gecode::Raw::dom(@model.active_space, *params)
44
+ end
45
+ negate_using_reification
46
+ end
47
+
48
+ # Enum domain constraints specify that an integer variable must be contained
49
+ # in an enumeration of integers. Supports reification and negation.
50
+ #
51
+ # == Examples
52
+ #
53
+ # # +x+ must be in the enumeration [3,5,7].
54
+ # x.must_be.in [3,5,7]
55
+ #
56
+ # # +x+ must not be in the enumeration [5,6,7,17].
57
+ # x.must_not_be.in [5,6,7,17]
58
+ #
59
+ # # Specifies the above, but but reifies the constraint with the boolean
60
+ # # variable +bool+ and specified +value+ as strength.
61
+ # x.must_not_be.in(-[5,6,7,17], :reify => bool, :strength => :value)
62
+ class EnumDomainConstraint < Gecode::Constraints::ReifiableConstraint
63
+ def post
64
+ space = @model.active_space
65
+
66
+ var, domain, reif_var, strength = @params.values_at(:lhs, :domain,
67
+ :reif, :strength)
68
+
69
+ (params = []) << var.bind
70
+ params << Gecode::Constraints::Util.constant_set_to_int_set(domain)
71
+ params << reif_var.bind if reif_var.respond_to? :bind
72
+ params << strength
73
+ Gecode::Raw::dom(space, *params)
74
+ end
75
+ negate_using_reification
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,295 @@
1
+ module Gecode
2
+ class FreeIntVar
3
+ # Creates a linear expression where the int variables are summed.
4
+ def +(var)
5
+ Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
6
+ @model) + var
7
+ end
8
+
9
+ alias_method :pre_linear_mult, :* if instance_methods.include? '*'
10
+
11
+ # Creates a linear expression where the int variable is multiplied with
12
+ # a constant integer.
13
+ def *(int)
14
+ if int.kind_of? Fixnum
15
+ Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
16
+ @model) * int
17
+ else
18
+ pre_linear_mult(int) if respond_to? :pre_linear_mult
19
+ end
20
+ end
21
+
22
+ # Creates a linear expression where the specified variable is subtracted
23
+ # from this one.
24
+ def -(var)
25
+ Gecode::Constraints::Int::Linear::ExpressionNode.new(self,
26
+ @model) - var
27
+ end
28
+ end
29
+
30
+ module Constraints::Int
31
+ class Expression #:nodoc:
32
+ # Add some relation selection based on whether the expression is negated.
33
+ alias_method :pre_linear_initialize, :initialize
34
+ def initialize(model, params)
35
+ pre_linear_initialize(model, params)
36
+ unless params[:negate]
37
+ @method_relations = Constraints::Util::RELATION_TYPES
38
+ else
39
+ @method_relations = Constraints::Util::NEGATED_RELATION_TYPES
40
+ end
41
+ end
42
+
43
+ # Define the relation methods.
44
+ Constraints::Util::RELATION_TYPES.each_key do |name|
45
+ module_eval <<-"end_code"
46
+ def #{name}(expression, options = {})
47
+ relation = @method_relations[:#{name}]
48
+ @params.update(
49
+ Gecode::Constraints::Util.decode_options(options))
50
+ if self.simple_expression? and simple_expression?(expression)
51
+ # A relation constraint is enough.
52
+ add_relation_constraint(relation, expression)
53
+ else
54
+ add_linear_constraint(relation, expression)
55
+ end
56
+ end
57
+ end_code
58
+ end
59
+ alias_comparison_methods
60
+
61
+ protected
62
+
63
+ # Checks whether the given expression is simple enough to be used in a
64
+ # simple relation constraint. Returns true if it is, false otherwise. If
65
+ # no expression is given then the this expression's left hand side is
66
+ # checked.
67
+ def simple_expression?(expression = nil)
68
+ if expression.nil?
69
+ simple_expression?(@params[:lhs])
70
+ else
71
+ expression.kind_of?(Gecode::FreeIntVar) or
72
+ expression.kind_of?(Gecode::FreeBoolVar) or
73
+ expression.kind_of?(Fixnum)
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ # Places the linear constraint corresponding to the specified (integer)
80
+ # relation type (as specified by Gecode) in relation to the specifed
81
+ # expression.
82
+ #
83
+ # Raises TypeError if the element is of a type that doesn't allow a
84
+ # relation to be specified.
85
+ def add_linear_constraint(relation_type, right_hand_side)
86
+ # Bind parameters.
87
+ lhs = @params[:lhs]
88
+ if lhs.kind_of?(Gecode::FreeIntVar) or lhs.kind_of?(Gecode::FreeBoolVar)
89
+ lhs = lhs * 1 # Convert to Gecode::Raw::LinExp
90
+ end
91
+ if not (right_hand_side.respond_to? :to_minimodel_lin_exp or
92
+ right_hand_side.kind_of?(Gecode::FreeIntVar) or
93
+ right_hand_side.kind_of?(Gecode::FreeBoolVar) or
94
+ right_hand_side.kind_of?(Fixnum))
95
+ raise TypeError, 'Invalid right hand side of linear equation.'
96
+ end
97
+
98
+ @params.update(:relation_type => relation_type, :lhs => lhs,
99
+ :rhs => right_hand_side)
100
+ @model.add_constraint Linear::LinearConstraint.new(@model, @params)
101
+ end
102
+
103
+ # Places the relation constraint corresponding to the specified (integer)
104
+ # relation type (as specified by Gecode) in relation to the specifed
105
+ # element.
106
+ def add_relation_constraint(relation_type, element)
107
+ @model.add_constraint Linear::SimpleRelationConstraint.new(@model,
108
+ @params.update(:relation_type => relation_type, :element => element))
109
+ end
110
+ end
111
+ end
112
+
113
+ # A module that gathers the classes and modules used in linear constraints.
114
+ module Constraints::Int::Linear #:nodoc:
115
+ # Linear constraints specify that an integer variable must have a linear
116
+ # equation containing variables must hold. The same relations and options
117
+ # used in +SimpleRelationConstraint+ can also be used for linear
118
+ # constraints.
119
+ #
120
+ # Boolean variables can also be used instead of integer variables. In that
121
+ # case a boolean variable assigned true is equal to 1 and a boolean variable
122
+ # assigned false is equal to 0. There is one exception: boolean variables
123
+ # can not be used alone as left hand side.
124
+ #
125
+ # Do not mix boolean and integer variables. Even if possible it's not
126
+ # supported, and might be removed in the future.
127
+ #
128
+ # == Examples
129
+ #
130
+ # # The sum of the int variables +x+ and +y+ must equal +z+ + 3.
131
+ # (x + y).must == z + 3
132
+ #
133
+ # # Another way of writing the above.
134
+ # z.must == x + y - 3
135
+ #
136
+ # # The inequality 10(x + y) > 3x must not hold.
137
+ # (x + y)*10.must_not > x*3
138
+ #
139
+ # # Specifies the above, but reifies the constraint with the boolean
140
+ # # variable +bool+ and gives it propagation strength +domain+.
141
+ # (x + y)*10.must_not_be.greater_than(x*3, :reify => bool, :strength => :domain)
142
+ class LinearConstraint < Gecode::Constraints::ReifiableConstraint
143
+ def post
144
+ lhs, rhs, relation_type, reif_var, strength = @params.values_at(:lhs,
145
+ :rhs, :relation_type, :reif, :strength)
146
+ reif_var = reif_var.bind if reif_var.respond_to? :bind
147
+ if rhs.respond_to? :to_minimodel_lin_exp
148
+ rhs = rhs.to_minimodel_lin_exp
149
+ elsif rhs.respond_to? :bind
150
+ rhs = rhs.bind * 1
151
+ end
152
+
153
+ final_exp = (lhs.to_minimodel_lin_exp - rhs)
154
+ if reif_var.nil?
155
+ final_exp.post(@model.active_space, relation_type, strength)
156
+ else
157
+ final_exp.post(@model.active_space, relation_type, reif_var)
158
+ end
159
+ end
160
+ end
161
+
162
+ # Simple relation constraints specify that an integer variable must have a
163
+ # specified relation to a constant integer or another integer variable. The
164
+ # following relations are supported (the aliases of each relation are also
165
+ # listed).
166
+ #
167
+ # * <, lesser, lesser_than
168
+ # * >, greater, greater_than
169
+ # * >=, greater_or_equal, greater_than_or_equal_to
170
+ # * <=, less_or_equal, less_than_or_equal_to
171
+ # * ==, equal, equal_to
172
+ #
173
+ # Each can be negated by using +must_not+ instead of +must+.
174
+ #
175
+ # Two options (given as a hash) are available:
176
+ #
177
+ # [strength] Specifies the propagation strength of the constraint. Must be
178
+ # one of +value+, +bounds+, +domain+ and +default+. The
179
+ # strength generally progresses as +value+ -> +bounds+ ->
180
+ # +domain+ (+value+ being the weakest, but usually cheapest,
181
+ # while +domain+ is the strongest but usually costly).
182
+ # [reify] Specifies a boolean variable that should be used for
183
+ # reification (see +ReifiableConstraint+).
184
+ #
185
+ # == Examples
186
+ #
187
+ # # Int variable +x+ must not equal 0.
188
+ # x.must_not.equal(0)
189
+ #
190
+ # # Another way of writing the above.
191
+ # x.must_not == 0
192
+ #
193
+ # # +x+ must be strictly larger than +y+.
194
+ # x.must > y
195
+ #
196
+ # # Specifies the above, but reifies the constraint with the boolean
197
+ # # variable +bool+.
198
+ # x.must_be.greater_than(y, :reify => bool)
199
+ class SimpleRelationConstraint < Gecode::Constraints::ReifiableConstraint
200
+ def post
201
+ # Fetch the parameters to Gecode.
202
+ lhs, relation, rhs, reif_var, strength = @params.values_at(:lhs,
203
+ :relation_type, :element, :reif, :strength)
204
+
205
+ rhs = rhs.bind if rhs.respond_to? :bind
206
+ if reif_var.nil?
207
+ Gecode::Raw::rel(@model.active_space, lhs.bind, relation, rhs,
208
+ strength)
209
+ else
210
+ Gecode::Raw::rel(@model.active_space, lhs.bind, relation, rhs,
211
+ reif_var.bind, strength)
212
+ end
213
+ end
214
+ end
215
+
216
+ # Helper methods for linear expressions. Classes mixing in this module must
217
+ # have a method #model which gives the model the expression is operating in.
218
+ module Helper #:nodoc:
219
+ include Gecode::Constraints::LeftHandSideMethods
220
+
221
+ private
222
+
223
+ OPERATION_TYPES = [:+, :-, :*]
224
+
225
+ public
226
+
227
+ # Define methods for the available operations.
228
+ OPERATION_TYPES.each do |name|
229
+ module_eval <<-"end_code"
230
+ def #{name}(expression)
231
+ unless expression.kind_of? ExpressionTree
232
+ expression = ExpressionNode.new(expression)
233
+ end
234
+ ExpressionTree.new(self, expression, :#{name})
235
+ end
236
+ end_code
237
+ end
238
+
239
+ private
240
+
241
+ # Produces an expression for the lhs module.
242
+ def expression(params)
243
+ params.update(:lhs => self)
244
+ Gecode::Constraints::Int::Expression.new(model, params)
245
+ end
246
+ end
247
+
248
+ # Describes a binary tree of expression nodes which together form a linear
249
+ # expression.
250
+ class ExpressionTree #:nodoc:
251
+ include Helper
252
+
253
+ # Constructs a new expression with the specified variable
254
+ def initialize(left_node, right_node, operation)
255
+ @left = left_node
256
+ @right = right_node
257
+ @operation = operation
258
+ end
259
+
260
+ # Converts the linear expression to an instance of
261
+ # Gecode::Raw::MiniModel::LinExpr
262
+ def to_minimodel_lin_exp
263
+ @left.to_minimodel_lin_exp.send(@operation, @right.to_minimodel_lin_exp)
264
+ end
265
+
266
+ # Fetches the space that the expression's variables is in.
267
+ def model
268
+ @left.model || @right.model
269
+ end
270
+ end
271
+
272
+ # Describes a single node in a linear expression.
273
+ class ExpressionNode #:nodoc:
274
+ include Helper
275
+
276
+ attr :model
277
+
278
+ def initialize(value, model = nil)
279
+ @value = value
280
+ @model = model
281
+ end
282
+
283
+ # Converts the linear expression to an instance of
284
+ # Gecode::Raw::MiniModel::LinExpr
285
+ def to_minimodel_lin_exp
286
+ expression = @value
287
+ if expression.respond_to? :bind
288
+ # Minimodel requires that we do this first.
289
+ expression = expression.bind * 1
290
+ end
291
+ expression
292
+ end
293
+ end
294
+ end
295
+ end