gecoder 0.8.3 → 0.9.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.
Files changed (142) hide show
  1. data/CHANGES +15 -0
  2. data/README +6 -2
  3. data/example/equation_system.rb +15 -0
  4. data/example/magic_sequence.rb +7 -7
  5. data/example/money.rb +36 -0
  6. data/example/queens.rb +7 -8
  7. data/example/send_most_money.rb +1 -1
  8. data/example/square_tiling.rb +2 -2
  9. data/example/sudoku-set.rb +11 -12
  10. data/example/sudoku.rb +40 -45
  11. data/ext/extconf.rb +0 -0
  12. data/lib/gecoder/bindings.rb +42 -0
  13. data/lib/gecoder/bindings/bindings.rb +16 -0
  14. data/lib/gecoder/interface.rb +2 -1
  15. data/lib/gecoder/interface/branch.rb +16 -9
  16. data/lib/gecoder/interface/constraints.rb +410 -451
  17. data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
  18. data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
  19. data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
  20. data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
  21. data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
  22. data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
  23. data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
  24. data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
  25. data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
  26. data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
  27. data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
  28. data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
  29. data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
  30. data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
  31. data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
  32. data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
  33. data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
  34. data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
  35. data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
  36. data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
  37. data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
  38. data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
  39. data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
  40. data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
  41. data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
  42. data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
  43. data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
  44. data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
  45. data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
  46. data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
  47. data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
  48. data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
  49. data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
  50. data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
  51. data/lib/gecoder/interface/constraints/set/include.rb +36 -0
  52. data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
  53. data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
  54. data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
  55. data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
  56. data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
  57. data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
  58. data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
  59. data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
  60. data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
  61. data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
  62. data/lib/gecoder/interface/enum_matrix.rb +4 -4
  63. data/lib/gecoder/interface/enum_wrapper.rb +71 -22
  64. data/lib/gecoder/interface/model.rb +167 -12
  65. data/lib/gecoder/interface/model_sugar.rb +84 -0
  66. data/lib/gecoder/interface/search.rb +30 -18
  67. data/lib/gecoder/interface/variables.rb +103 -33
  68. data/lib/gecoder/version.rb +2 -2
  69. data/specs/bool_var.rb +19 -12
  70. data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
  71. data/specs/constraints/bool/boolean_properties.rb +51 -0
  72. data/specs/constraints/bool/linear.rb +213 -0
  73. data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
  74. data/specs/constraints/bool_enum/channel.rb +102 -0
  75. data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
  76. data/specs/constraints/constraint_helper.rb +149 -179
  77. data/specs/constraints/constraint_receivers.rb +103 -0
  78. data/specs/constraints/constraints.rb +6 -63
  79. data/specs/constraints/fixnum_enum/element.rb +58 -0
  80. data/specs/constraints/fixnum_enum/operation.rb +67 -0
  81. data/specs/constraints/int/arithmetic.rb +149 -0
  82. data/specs/constraints/int/channel.rb +101 -0
  83. data/specs/constraints/int/domain.rb +106 -0
  84. data/specs/constraints/int/linear.rb +183 -0
  85. data/specs/constraints/int/linear_properties.rb +97 -0
  86. data/specs/constraints/int/relation.rb +84 -0
  87. data/specs/constraints/int_enum/arithmetic.rb +72 -0
  88. data/specs/constraints/int_enum/channel.rb +57 -0
  89. data/specs/constraints/int_enum/count.rb +72 -0
  90. data/specs/constraints/int_enum/distinct.rb +80 -0
  91. data/specs/constraints/int_enum/element.rb +61 -0
  92. data/specs/constraints/int_enum/equality.rb +29 -0
  93. data/specs/constraints/int_enum/extensional.rb +224 -0
  94. data/specs/constraints/int_enum/sort.rb +167 -0
  95. data/specs/constraints/operands.rb +264 -0
  96. data/specs/constraints/property_helper.rb +443 -0
  97. data/specs/constraints/reification_sugar.rb +4 -5
  98. data/specs/constraints/selected_set/select.rb +56 -0
  99. data/specs/constraints/selected_set/select_properties.rb +157 -0
  100. data/specs/constraints/set/cardinality.rb +58 -0
  101. data/specs/constraints/set/cardinality_properties.rb +46 -0
  102. data/specs/constraints/set/channel.rb +77 -0
  103. data/specs/constraints/set/connection.rb +176 -0
  104. data/specs/constraints/set/domain.rb +197 -0
  105. data/specs/constraints/set/include.rb +36 -0
  106. data/specs/constraints/set/operation.rb +132 -0
  107. data/specs/constraints/set/relation.rb +117 -0
  108. data/specs/constraints/set_elements/relation.rb +84 -0
  109. data/specs/constraints/set_enum/channel.rb +80 -0
  110. data/specs/constraints/set_enum/distinct.rb +59 -0
  111. data/specs/constraints/set_enum/operation.rb +111 -0
  112. data/specs/constraints/set_enum/select.rb +73 -0
  113. data/specs/enum_wrapper.rb +53 -3
  114. data/specs/int_var.rb +44 -25
  115. data/specs/model.rb +58 -1
  116. data/specs/model_sugar.rb +30 -0
  117. data/specs/search.rb +24 -5
  118. data/specs/selected_set.rb +39 -0
  119. data/specs/set_elements.rb +34 -0
  120. data/specs/set_var.rb +22 -8
  121. data/specs/spec_helper.rb +206 -6
  122. data/tasks/distribution.rake +22 -7
  123. data/tasks/svn.rake +3 -1
  124. metadata +218 -134
  125. data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
  126. data/specs/constraints/arithmetic.rb +0 -351
  127. data/specs/constraints/bool_enum_relation.rb +0 -160
  128. data/specs/constraints/cardinality.rb +0 -157
  129. data/specs/constraints/channel.rb +0 -454
  130. data/specs/constraints/connection.rb +0 -369
  131. data/specs/constraints/count.rb +0 -146
  132. data/specs/constraints/distinct.rb +0 -164
  133. data/specs/constraints/element.rb +0 -108
  134. data/specs/constraints/equality.rb +0 -31
  135. data/specs/constraints/int_domain.rb +0 -70
  136. data/specs/constraints/int_relation.rb +0 -82
  137. data/specs/constraints/linear.rb +0 -340
  138. data/specs/constraints/selection.rb +0 -292
  139. data/specs/constraints/set_domain.rb +0 -185
  140. data/specs/constraints/set_operation.rb +0 -285
  141. data/specs/constraints/set_relation.rb +0 -197
  142. data/specs/constraints/sort.rb +0 -179
@@ -0,0 +1,63 @@
1
+ module Gecode::FixnumEnum
2
+ module FixnumEnumOperand
3
+ # This adds the adder for the methods in the modules including it. The
4
+ # reason for doing it so indirect is that the first #[] won't be defined
5
+ # before the module that this is mixed into is mixed into an enum.
6
+ def self.included(enum_mod) #:nodoc:
7
+ enum_mod.module_eval do
8
+ # Now we enter the module FixnumEnumOperands is mixed into.
9
+ class << self
10
+ alias_method :pre_element_included, :included
11
+ def included(mod) #:nodoc:
12
+ mod.module_eval do
13
+ if instance_methods.include? '[]'
14
+ alias_method :pre_element_access, :[]
15
+ end
16
+
17
+ # Produces an IntOperand representing the
18
+ # i:th constant integer in the enumeration, where i is the
19
+ # value of the integer operand used as index. Think of it
20
+ # as array access in the world of constraint programming.
21
+ #
22
+ # ==== Examples
23
+ #
24
+ # # The price of +selected_item+ as described by +prices+ .
25
+ # prices = wrap_enum([500, 24, 4711, 412, 24])
26
+ # prices[selected_item]
27
+ #
28
+ def [](*vars)
29
+ if vars.first.respond_to? :to_int_var
30
+ return Element::ElementIntOperand.new(
31
+ self, vars.first, model)
32
+ else
33
+ pre_element_access(*vars) if respond_to? :pre_element_access
34
+ end
35
+ end
36
+ end
37
+ pre_element_included(mod)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ module Element #:nodoc:
45
+ class ElementIntOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
46
+ def initialize(enum_op, position_int_var_op, model)
47
+ super model
48
+ @enum = enum_op
49
+ @position = position_int_var_op
50
+ end
51
+
52
+ def constrain_equal(int_operand, constrain, propagation_options)
53
+ if constrain
54
+ int_operand.must_be.in @enum
55
+ end
56
+
57
+ Gecode::Raw::element(@model.active_space, @enum,
58
+ @position.to_int_var.bind, int_operand.to_int_var.bind,
59
+ *propagation_options)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,65 @@
1
+ module Gecode::FixnumEnum
2
+ module FixnumEnumOperand
3
+ # Produces a new SetOperand representing the union between this operand,
4
+ # interpreted as a constant set, and +set_operand+.
5
+ #
6
+ # ==== Examples
7
+ #
8
+ # # The union between +fixnum_enum+ and +set+.
9
+ # fixnum_enum.union set
10
+ def union(set_operand)
11
+ set_operation(:union, set_operand)
12
+ end
13
+
14
+ # Produces a new SetOperand representing the disjoint union between
15
+ # this operand, interpreted as a constant set, and
16
+ # +set_operand+. The disjoint union is the union of
17
+ # the disjoint parts of the sets.
18
+ #
19
+ # ==== Examples
20
+ #
21
+ # # The disjoint union between +fixnum_enum+ and +set+.
22
+ # fixnum_enum.disjoint_union set
23
+ def disjoint_union(set_operand)
24
+ set_operation(:disjoint_union, set_operand)
25
+ end
26
+
27
+ # Produces a new SetOperand representing the intersection between
28
+ # this operand, interpreted as a constant set, and
29
+ # +set_operand+.
30
+ #
31
+ # ==== Examples
32
+ #
33
+ # # The intersection between +fixnum_enum+ and +set+.
34
+ # fixnum_enum.intersection set
35
+ def intersection(set_operand)
36
+ set_operation(:intersection, set_operand)
37
+ end
38
+
39
+ # Produces a new SetOperand representing this operand, interpreted
40
+ # as a constant set, minus +set_operand+.
41
+ #
42
+ # ==== Examples
43
+ #
44
+ # # +fixnum_enum+ minus +set+.
45
+ # fixnum_enum.minus set
46
+ def minus(set_operand)
47
+ set_operation(:minus, set_operand)
48
+ end
49
+
50
+ private
51
+
52
+ # Starts a constraint on this set #{name} the specified set.
53
+ def set_operation(operator, operand2)
54
+ unless operand2.respond_to? :to_set_var
55
+ raise TypeError, 'Expected set operand as ' +
56
+ "operand, got \#{operand2.class}."
57
+ end
58
+
59
+ return Operation::OperationSetOperand.new(model, self,
60
+ operator, operand2)
61
+ end
62
+ end
63
+
64
+ Operation = Gecode::Set::Operation
65
+ end
@@ -0,0 +1,42 @@
1
+ # A module containing constraints that have enumerations of instances of
2
+ # Fixnum as left hand side.
3
+ module Gecode::FixnumEnum #:nodoc:
4
+ # A FixnumEnumOperand is a enumeration of Fixnum on which the
5
+ # constraints defined in FixnumEnumConstraintReceiver can be placed.
6
+ # They typically service as constant arrays or constant sets.
7
+ #
8
+ # The fixnum enumeration operands are created by wrapping an enumeration
9
+ # of fixnum Gecode::Model#wrap_enum. The enumerations created that way
10
+ # all respond to the properties defined by FixnumEnumOperand.
11
+ #
12
+ # ==== Examples
13
+ #
14
+ # Uses Gecode::Model#wrap_enum inside a problem formulation to create
15
+ # a FixnumEnumOperand from an existing enumeration of Fixnum:
16
+ #
17
+ # fixnum_enum = wrap_enum([3, 5, 7])
18
+ #
19
+ #--
20
+ # Classes that mix in FixnumEnumOperand must define #model.
21
+ module FixnumEnumOperand
22
+ include Gecode::Operand
23
+
24
+ def method_missing(method, *args) #:nodoc:
25
+ if Gecode::FixnumEnum::Dummy.instance_methods.include? method.to_s
26
+ # Delegate to the fixnum enum.
27
+ to_fixnum_enum.method(method).call(*args)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def construct_receiver(params)
36
+ raise NotImplementedError, 'Fixnum enums do not have constraints.'
37
+ end
38
+ end
39
+ end
40
+
41
+ require 'gecoder/interface/constraints/fixnum_enum/element'
42
+ require 'gecoder/interface/constraints/fixnum_enum/operation'
@@ -1,149 +1,150 @@
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
- # Initiates an arithmetic squared value constraint.
9
- def squared
10
- Gecode::Constraints::Int::Arithmetic::SquaredExpressionStub.new(@model,
11
- :lhs => self)
12
- end
13
-
14
- # Initiates an arithmetic squared root constraint.
15
- def sqrt
16
- Gecode::Constraints::Int::Arithmetic::SquareRootExpressionStub.new(@model,
17
- :lhs => self)
18
- end
19
- alias_method :square_root, :sqrt
20
-
1
+ module Gecode::Int
2
+ module IntOperand
3
+ # Produces an IntOperand representing the absolute value of this
4
+ # operand.
5
+ #
6
+ # ==== Examples
7
+ #
8
+ # # The absolute value of +int_op+.
9
+ # int_op.abs
10
+ def abs
11
+ Arithmetic::IntAbsOperand.new(@model, self)
12
+ end
13
+
14
+ # Produces an IntOperand representing this operand squared.
15
+ #
16
+ # ==== Examples
17
+ #
18
+ # # The value of +int_op*int_op+.
19
+ # int_op.squared
20
+ def squared
21
+ Arithmetic::IntSquaredOperand.new(@model, self)
22
+ end
21
23
 
22
- alias_method :pre_arith_mult, :* if instance_methods.include? '*'
23
-
24
- # Begins a multiplication constraint involving the two int variable.
25
- def *(var)
26
- if var.kind_of? Gecode::FreeIntVar
27
- Gecode::Constraints::Int::Arithmetic::MultExpressionStub.new(
28
- @model, :lhs => self, :var => var)
29
- else
30
- pre_arith_mult(var) if respond_to? :pre_arith_mult
24
+ # Produces an IntOperand representing the square root of this
25
+ # operand rounded down.
26
+ #
27
+ # ==== Examples
28
+ #
29
+ # # The square root of +int_op+, rounded down.
30
+ # int_op.square_root
31
+ def square_root
32
+ Arithmetic::IntSquareRootOperand.new(@model, self)
31
33
  end
32
- end
33
- end
34
+ alias_method :sqrt, :square_root
34
35
 
35
- # A module that gathers the classes and modules used by arithmetic constraints.
36
- module Gecode::Constraints::Int::Arithmetic #:nodoc:
37
- # Describes a CompositeStub for absolute value constraints, which constrain
38
- # the absolute value of an integer variable.
39
- #
40
- # == Examples
41
- #
42
- # # The absolute value of +x+ must be less than 2.
43
- # x.abs.must < 2
44
- #
45
- # # The absolute value of +x+ must be in the range 5..7, with +bool+ as
46
- # # reification variable and +value+ as strength.
47
- # x.abs.must_be.in(5..7, :reify => bool, :strength => :value)
48
- class AbsExpressionStub < Gecode::Constraints::Int::CompositeStub
49
- def constrain_equal(variable, params, constrain)
50
- lhs = @params[:lhs]
51
- if constrain
52
- bounds = [lhs.min.abs, lhs.max.abs]
53
- variable.must_be.in bounds.min..bounds.max
36
+
37
+ alias_method :pre_arith_mult, :*
38
+
39
+ # Produces a new IntOperand representing this operand times
40
+ # +int_operand+.
41
+ #
42
+ # ==== Examples
43
+ #
44
+ # # The value of +int_op1+ times +int_op2+.
45
+ # int_op1 * int_op2
46
+ def *(int_operand)
47
+ if int_operand.respond_to? :to_int_var
48
+ Arithmetic::IntMultOperand.new(@model, self, int_operand)
49
+ else
50
+ pre_arith_mult(int_operand)
54
51
  end
55
-
56
- Gecode::Raw::abs(@model.active_space, lhs.bind, variable.bind,
57
- *propagation_options)
58
52
  end
59
53
  end
60
54
 
61
- # Describes a CompositeStub for multiplication constraint, which constrain
62
- # the value of the multiplication of two variables.
63
- #
64
- # == Examples
65
- #
66
- # # The value of +x*y+ must be equal to their sum.
67
- # (x*y).must == x + y
68
- #
69
- # # The value of +x*y+ must be less than 17, with +bool+ as reification
70
- # # variable and +domain+ as strength.
71
- # (x*y).must_be.less_than(17, :reify => bool, :strength => :domain)
72
- class MultExpressionStub < Gecode::Constraints::Int::CompositeStub
73
- def constrain_equal(variable, params, constrain)
74
- lhs, lhs2 = @params.values_at(:lhs, :var)
75
- if constrain
76
- a_min = lhs.min; a_max = lhs.max
77
- b_min = lhs2.min; b_max = lhs2.max
78
- products = [a_min*b_min, a_min*b_max, a_max*b_min, a_max*b_max]
79
- variable.must_be.in products.min..products.max
55
+ # A module that gathers the classes and modules used by arithmetic
56
+ # constraints.
57
+ module Arithmetic #:nodoc:
58
+ class IntAbsOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
59
+ def initialize(model, int_op)
60
+ super model
61
+ @int = int_op
80
62
  end
81
63
 
82
- Gecode::Raw::mult(@model.active_space, lhs.bind, lhs2.bind,
83
- variable.bind, *propagation_options)
64
+ def constrain_equal(int_operand, constrain, propagation_options)
65
+ int_op = @int.to_int_var
66
+ if constrain
67
+ bounds = [int_op.min.abs, int_op.max.abs]
68
+ bounds << 0 if int_op.min < 0
69
+ int_operand.must_be.in bounds.min..bounds.max
70
+ end
71
+
72
+ Gecode::Raw::abs(@model.active_space, int_op.to_int_var.bind,
73
+ int_operand.to_int_var.bind, *propagation_options)
74
+ end
84
75
  end
85
- end
86
-
87
- # Describes a CompositeStub for the squared constraint, which constrain
88
- # the squared value of the variable.
89
- #
90
- # == Examples
91
- #
92
- # # The value of +x*x+ must be equal to y.
93
- # x.squared.must == y
94
- #
95
- # # The value of +x*x+ must be less than or equal to 16, with +bool+ as
96
- # # reification variable and +domain+ as strength.
97
- # x.squared.must_be.less_or_equal(16, :reify => bool, :strength => :domain)
98
- class SquaredExpressionStub < Gecode::Constraints::Int::CompositeStub
99
- def constrain_equal(variable, params, constrain)
100
- lhs = @params[:lhs]
101
- if constrain
102
- min = lhs.min; max = lhs.max
103
- products = [min*max, min*min, max*max]
104
- variable.must_be.in products.min..products.max
76
+
77
+ class IntMultOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
78
+ def initialize(model, op1, op2)
79
+ super model
80
+ @op1 = op1
81
+ @op2 = op2
105
82
  end
106
83
 
107
- Gecode::Raw::sqr(@model.active_space, lhs.bind, variable.bind,
108
- *propagation_options)
109
- end
110
- end
111
-
112
- # Describes a CompositeStub for the square root constraint, which constrain
113
- # the rounded down square root of the variable.
114
- #
115
- # == Examples
116
- #
117
- # # The square root of +x+, rounded down, must equal y.
118
- # x.square_root.must == y
119
- #
120
- # # The square root of +x+, rounded down, must be larger than 17, with
121
- # # +bool+ as reification variable and +domain+ as strength.
122
- # x.square_root.must_be.larger_than(17, :reify => bool, :strength => :domain)
123
- class SquareRootExpressionStub < Gecode::Constraints::Int::CompositeStub
124
- def constrain_equal(variable, params, constrain)
125
- lhs = @params[:lhs]
126
- if constrain
127
- max = lhs.max
128
- if max < 0
129
- # The left hand side does not have a real valued square root.
130
- upper_bound = 0
131
- else
132
- upper_bound = Math.sqrt(max).floor;
84
+ def constrain_equal(int_operand, constrain, propagation_options)
85
+ int_op1, int_op2 = @op1.to_int_var, @op2.to_int_var
86
+ if constrain
87
+ a_min = int_op1.min; a_max = int_op1.max
88
+ b_min = int_op2.min; b_max = int_op2.max
89
+ products = [a_min*b_min, a_min*b_max, a_max*b_min, a_max*b_max]
90
+ int_operand.must_be.in products.min..products.max
133
91
  end
134
-
135
- min = lhs.min
136
- if min < 0
137
- lower_bound = 0
138
- else
139
- lower_bound = Math.sqrt(min).floor;
92
+
93
+ Gecode::Raw::mult(@model.active_space, int_op1.to_int_var.bind,
94
+ int_op2.to_int_var.bind, int_operand.to_int_var.bind,
95
+ *propagation_options)
96
+ end
97
+ end
98
+
99
+ class IntSquaredOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
100
+ def initialize(model, int_op)
101
+ super model
102
+ @int = int_op
103
+ end
104
+
105
+ def constrain_equal(int_operand, constrain, propagation_options)
106
+ int_op = @int.to_int_var
107
+ if constrain
108
+ min = int_op.min; max = int_op.max
109
+ products = [min*max, min*min, max*max]
110
+ int_operand.must_be.in products.min..products.max
140
111
  end
141
-
142
- variable.must_be.in lower_bound..upper_bound
112
+
113
+ Gecode::Raw::sqr(@model.active_space, int_op.to_int_var.bind,
114
+ int_operand.to_int_var.bind, *propagation_options)
115
+ end
116
+ end
117
+
118
+ class IntSquareRootOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
119
+ def initialize(model, int_op)
120
+ super model
121
+ @int = int_op
143
122
  end
144
123
 
145
- Gecode::Raw::sqrt(@model.active_space, lhs.bind, variable.bind,
146
- *propagation_options)
124
+ def constrain_equal(int_operand, constrain, propagation_options)
125
+ int_op = @int.to_int_var
126
+ if constrain
127
+ max = int_op.max
128
+ if max < 0
129
+ # The left hand side does not have a real valued square root.
130
+ upper_bound = 0
131
+ else
132
+ upper_bound = Math.sqrt(max).floor;
133
+ end
134
+
135
+ min = int_op.min
136
+ if min < 0
137
+ lower_bound = 0
138
+ else
139
+ lower_bound = Math.sqrt(min).floor;
140
+ end
141
+
142
+ int_operand.must_be.in lower_bound..upper_bound
143
+ end
144
+
145
+ Gecode::Raw::sqrt(@model.active_space, int_op.to_int_var.bind,
146
+ int_operand.to_int_var.bind, *propagation_options)
147
+ end
147
148
  end
148
149
  end
149
150
  end