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.
- data/CHANGES +15 -0
- data/README +6 -2
- data/example/equation_system.rb +15 -0
- data/example/magic_sequence.rb +7 -7
- data/example/money.rb +36 -0
- data/example/queens.rb +7 -8
- data/example/send_most_money.rb +1 -1
- data/example/square_tiling.rb +2 -2
- data/example/sudoku-set.rb +11 -12
- data/example/sudoku.rb +40 -45
- data/ext/extconf.rb +0 -0
- data/lib/gecoder/bindings.rb +42 -0
- data/lib/gecoder/bindings/bindings.rb +16 -0
- data/lib/gecoder/interface.rb +2 -1
- data/lib/gecoder/interface/branch.rb +16 -9
- data/lib/gecoder/interface/constraints.rb +410 -451
- data/lib/gecoder/interface/constraints/bool/boolean.rb +205 -213
- data/lib/gecoder/interface/constraints/bool/channel.rb +4 -5
- data/lib/gecoder/interface/constraints/bool/linear.rb +192 -21
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +43 -39
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +43 -49
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +38 -71
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +73 -22
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +140 -61
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +4 -4
- data/lib/gecoder/interface/constraints/fixnum_enum/element.rb +63 -0
- data/lib/gecoder/interface/constraints/fixnum_enum/operation.rb +65 -0
- data/lib/gecoder/interface/constraints/fixnum_enum_constraints.rb +42 -0
- data/lib/gecoder/interface/constraints/int/arithmetic.rb +131 -130
- data/lib/gecoder/interface/constraints/int/channel.rb +21 -31
- data/lib/gecoder/interface/constraints/int/domain.rb +45 -42
- data/lib/gecoder/interface/constraints/int/linear.rb +85 -239
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +55 -64
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +35 -37
- data/lib/gecoder/interface/constraints/int_enum/count.rb +53 -78
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +36 -46
- data/lib/gecoder/interface/constraints/int_enum/element.rb +39 -57
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +15 -19
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +65 -72
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +42 -45
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +79 -22
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +215 -44
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +14 -14
- data/lib/gecoder/interface/constraints/selected_set/select.rb +120 -0
- data/lib/gecoder/interface/constraints/selected_set_constraints.rb +75 -0
- data/lib/gecoder/interface/constraints/set/cardinality.rb +43 -53
- data/lib/gecoder/interface/constraints/set/channel.rb +26 -29
- data/lib/gecoder/interface/constraints/set/connection.rb +89 -152
- data/lib/gecoder/interface/constraints/set/domain.rb +112 -65
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +96 -110
- data/lib/gecoder/interface/constraints/set/relation.rb +114 -137
- data/lib/gecoder/interface/constraints/set_elements/relation.rb +116 -0
- data/lib/gecoder/interface/constraints/set_elements_constraints.rb +97 -0
- data/lib/gecoder/interface/constraints/set_enum/channel.rb +23 -27
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +18 -19
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +62 -53
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +73 -23
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +222 -57
- data/lib/gecoder/interface/enum_matrix.rb +4 -4
- data/lib/gecoder/interface/enum_wrapper.rb +71 -22
- data/lib/gecoder/interface/model.rb +167 -12
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +30 -18
- data/lib/gecoder/interface/variables.rb +103 -33
- data/lib/gecoder/version.rb +2 -2
- data/specs/bool_var.rb +19 -12
- data/specs/constraints/{boolean.rb → bool/boolean.rb} +103 -28
- data/specs/constraints/bool/boolean_properties.rb +51 -0
- data/specs/constraints/bool/linear.rb +213 -0
- data/specs/constraints/bool_enum/bool_enum_relation.rb +117 -0
- data/specs/constraints/bool_enum/channel.rb +102 -0
- data/specs/constraints/{extensional.rb → bool_enum/extensional.rb} +32 -101
- data/specs/constraints/constraint_helper.rb +149 -179
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +6 -63
- data/specs/constraints/fixnum_enum/element.rb +58 -0
- data/specs/constraints/fixnum_enum/operation.rb +67 -0
- data/specs/constraints/int/arithmetic.rb +149 -0
- data/specs/constraints/int/channel.rb +101 -0
- data/specs/constraints/int/domain.rb +106 -0
- data/specs/constraints/int/linear.rb +183 -0
- data/specs/constraints/int/linear_properties.rb +97 -0
- data/specs/constraints/int/relation.rb +84 -0
- data/specs/constraints/int_enum/arithmetic.rb +72 -0
- data/specs/constraints/int_enum/channel.rb +57 -0
- data/specs/constraints/int_enum/count.rb +72 -0
- data/specs/constraints/int_enum/distinct.rb +80 -0
- data/specs/constraints/int_enum/element.rb +61 -0
- data/specs/constraints/int_enum/equality.rb +29 -0
- data/specs/constraints/int_enum/extensional.rb +224 -0
- data/specs/constraints/int_enum/sort.rb +167 -0
- data/specs/constraints/operands.rb +264 -0
- data/specs/constraints/property_helper.rb +443 -0
- data/specs/constraints/reification_sugar.rb +4 -5
- data/specs/constraints/selected_set/select.rb +56 -0
- data/specs/constraints/selected_set/select_properties.rb +157 -0
- data/specs/constraints/set/cardinality.rb +58 -0
- data/specs/constraints/set/cardinality_properties.rb +46 -0
- data/specs/constraints/set/channel.rb +77 -0
- data/specs/constraints/set/connection.rb +176 -0
- data/specs/constraints/set/domain.rb +197 -0
- data/specs/constraints/set/include.rb +36 -0
- data/specs/constraints/set/operation.rb +132 -0
- data/specs/constraints/set/relation.rb +117 -0
- data/specs/constraints/set_elements/relation.rb +84 -0
- data/specs/constraints/set_enum/channel.rb +80 -0
- data/specs/constraints/set_enum/distinct.rb +59 -0
- data/specs/constraints/set_enum/operation.rb +111 -0
- data/specs/constraints/set_enum/select.rb +73 -0
- data/specs/enum_wrapper.rb +53 -3
- data/specs/int_var.rb +44 -25
- data/specs/model.rb +58 -1
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +24 -5
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +22 -8
- data/specs/spec_helper.rb +206 -6
- data/tasks/distribution.rake +22 -7
- data/tasks/svn.rake +3 -1
- metadata +218 -134
- data/lib/gecoder/interface/constraints/set_enum/selection.rb +0 -217
- data/specs/constraints/arithmetic.rb +0 -351
- data/specs/constraints/bool_enum_relation.rb +0 -160
- data/specs/constraints/cardinality.rb +0 -157
- data/specs/constraints/channel.rb +0 -454
- data/specs/constraints/connection.rb +0 -369
- data/specs/constraints/count.rb +0 -146
- data/specs/constraints/distinct.rb +0 -164
- data/specs/constraints/element.rb +0 -108
- data/specs/constraints/equality.rb +0 -31
- data/specs/constraints/int_domain.rb +0 -70
- data/specs/constraints/int_relation.rb +0 -82
- data/specs/constraints/linear.rb +0 -340
- data/specs/constraints/selection.rb +0 -292
- data/specs/constraints/set_domain.rb +0 -185
- data/specs/constraints/set_operation.rb +0 -285
- data/specs/constraints/set_relation.rb +0 -197
- 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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
33
|
-
end
|
34
|
+
alias_method :sqrt, :square_root
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
#
|
62
|
-
#
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
83
|
-
|
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
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
|
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
|
-
|
146
|
-
|
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
|