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
@@ -1,87 +1,54 @@
|
|
1
|
-
module Gecode
|
2
|
-
module
|
3
|
-
# Produces
|
4
|
-
#
|
1
|
+
module Gecode::BoolEnum
|
2
|
+
module BoolEnumOperand
|
3
|
+
# Produces a BoolOperand that represents the conjunction (AND) of all
|
4
|
+
# boolean operands in this enumeration.
|
5
|
+
#
|
6
|
+
# ==== Examples
|
7
|
+
#
|
8
|
+
# # Conjunction of all elements in +bool_enum+.
|
9
|
+
# bool_enum.conjunction
|
5
10
|
def conjunction
|
6
|
-
|
7
|
-
@model, :lhs => self)
|
11
|
+
Relation::BoolEnumConjunctionOperand.new(@model, self)
|
8
12
|
end
|
9
13
|
|
10
|
-
# Produces
|
11
|
-
#
|
14
|
+
# Produces a BoolOperand that represents the disjunction (OR) of all
|
15
|
+
# boolean operands in this enumeration.
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# # Disjunction of all elements in +bool_enum+.
|
20
|
+
# bool_enum.disjunction
|
12
21
|
def disjunction
|
13
|
-
|
14
|
-
@model, :lhs => self)
|
22
|
+
Relation::BoolEnumDisjunctionOperand.new(@model, self)
|
15
23
|
end
|
16
24
|
end
|
17
|
-
end
|
18
25
|
|
19
|
-
module Gecode::Constraints::BoolEnum
|
20
26
|
# A module that gathers the classes and modules used by boolean enumeration
|
21
27
|
# relation constraints.
|
22
28
|
module Relation #:nodoc:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
# bool_enum.conjunction.must == b1
|
34
|
-
#
|
35
|
-
# # The conjunction of all variables in +bool_enum+ must not equal b1 and
|
36
|
-
# # b2. It's reified it with +bool+ and selects the strength +domain+.
|
37
|
-
# bool_enum.conjunction.must_not.equal(b1 & b2, :reify => bool,
|
38
|
-
# :strength => :domain)
|
39
|
-
class ConjunctionStub < Gecode::Constraints::Bool::CompositeStub
|
40
|
-
def constrain_equal(variable, params, constrain)
|
41
|
-
enum = @params[:lhs]
|
42
|
-
|
43
|
-
@model.add_interaction do
|
44
|
-
if variable.respond_to? :bind
|
45
|
-
bound = variable.bind
|
46
|
-
else
|
47
|
-
bound = variable ? 1 : 0
|
48
|
-
end
|
49
|
-
Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_AND,
|
50
|
-
enum.to_bool_var_array, bound, *propagation_options)
|
51
|
-
end
|
52
|
-
return variable
|
29
|
+
class BoolEnumConjunctionOperand < Gecode::Bool::ShortCircuitEqualityOperand #:nodoc:
|
30
|
+
def initialize(model, bool_enum)
|
31
|
+
super model
|
32
|
+
@enum = bool_enum
|
33
|
+
end
|
34
|
+
|
35
|
+
def constrain_equal(bool_operand, constrain_domain, propagation_options)
|
36
|
+
Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_AND,
|
37
|
+
@enum.to_bool_enum.bind_array, bool_operand.to_bool_var.bind,
|
38
|
+
*propagation_options)
|
53
39
|
end
|
54
40
|
end
|
55
41
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# bool_enum.conjunction.must == b1
|
67
|
-
#
|
68
|
-
# # The disjunction of all variables in +bool_enum+ must not equal b1 and
|
69
|
-
# # b2. It's reified it with +bool+ and selects the strength +domain+.
|
70
|
-
# bool_enum.disjunction.must_not.equal(b1 & b2, :reify => bool,
|
71
|
-
# :strength => :domain)
|
72
|
-
class DisjunctionStub < Gecode::Constraints::Bool::CompositeStub
|
73
|
-
def constrain_equal(variable, params, constrain)
|
74
|
-
enum = @params[:lhs]
|
75
|
-
|
76
|
-
@model.add_interaction do
|
77
|
-
if variable.respond_to? :bind
|
78
|
-
bound = variable.bind
|
79
|
-
else
|
80
|
-
bound = variable ? 1 : 0
|
81
|
-
end
|
82
|
-
Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_OR,
|
83
|
-
enum.to_bool_var_array, bound, *propagation_options)
|
84
|
-
end
|
42
|
+
class BoolEnumDisjunctionOperand < Gecode::Bool::ShortCircuitEqualityOperand #:nodoc:
|
43
|
+
def initialize(model, bool_enum)
|
44
|
+
super model
|
45
|
+
@enum = bool_enum
|
46
|
+
end
|
47
|
+
|
48
|
+
def constrain_equal(bool_operand, constrain_domain, propagation_options)
|
49
|
+
Gecode::Raw::rel(@model.active_space, Gecode::Raw::BOT_OR,
|
50
|
+
@enum.to_bool_enum.bind_array, bool_operand.to_bool_var.bind,
|
51
|
+
*propagation_options)
|
85
52
|
end
|
86
53
|
end
|
87
54
|
end
|
@@ -1,28 +1,79 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# A module containing constraints that have enumerations of boolean
|
2
|
+
# operands as left hand side.
|
3
|
+
module Gecode::BoolEnum #:nodoc:
|
4
|
+
# A BoolEnumOperand is a enumeration of BoolOperand on which the
|
5
|
+
# constraints defined in BoolEnumConstraintReceiver can be placed.
|
6
|
+
#
|
7
|
+
# Enumerations of boolean operands can be created either by using
|
8
|
+
# Gecode::Model#bool_var_array and Gecode::Model#bool_var_matrix, or
|
9
|
+
# by wrapping an existing enumeration containing BoolOperand using
|
10
|
+
# Gecode::Model#wrap_enum. The enumerations, no matter how they were
|
11
|
+
# created, all respond to the properties defined by BoolEnumOperand.
|
12
|
+
#
|
13
|
+
# ==== Examples
|
14
|
+
#
|
15
|
+
# Produces an array of five boolean operands inside a problem formulation
|
16
|
+
# using Gecode::Model#bool_var_array:
|
17
|
+
#
|
18
|
+
# bool_enum = bool_var_array(5)
|
19
|
+
#
|
20
|
+
# Uses Gecode::Model#wrap_enum inside a problem formulation to create
|
21
|
+
# a BoolEnumOperand from an existing enumeration containing the
|
22
|
+
# boolean operands +bool_operand1+ and +bool_operand2+:
|
23
|
+
#
|
24
|
+
# bool_enum = wrap_enum([bool_operand1, bool_operand2])
|
25
|
+
#
|
26
|
+
#--
|
27
|
+
# Classes that mix in BoolEnumOperand must define #model and
|
28
|
+
# #to_bool_enum .
|
29
|
+
module BoolEnumOperand
|
30
|
+
include Gecode::Operand
|
31
|
+
|
32
|
+
def method_missing(method, *args) #:nodoc:
|
33
|
+
if Gecode::BoolEnum::Dummy.instance_methods.include? method.to_s
|
34
|
+
# Delegate to the bool enum.
|
35
|
+
to_bool_enum.method(method).call(*args)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
5
41
|
private
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
params.update(:lhs => self)
|
10
|
-
Constraints::BoolEnum::Expression.new(@model, params)
|
42
|
+
|
43
|
+
def construct_receiver(params)
|
44
|
+
BoolEnumConstraintReceiver.new(@model, params)
|
11
45
|
end
|
12
46
|
end
|
13
|
-
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
47
|
+
|
48
|
+
# BoolEnumConstraintReceiver contains all constraints that can be
|
49
|
+
# placed on a BoolEnumOperand.
|
50
|
+
#
|
51
|
+
# Constraints are placed by calling BoolEnumOperand#must (or any other
|
52
|
+
# of the variations defined in Operand), which produces a
|
53
|
+
# BoolEnumConstraintReceiver from which the desired constraint can be
|
54
|
+
# used.
|
55
|
+
#
|
56
|
+
# ==== Examples
|
57
|
+
#
|
58
|
+
# Constrains +bool_enum+, with three boolean operands, to take the
|
59
|
+
# value of the tuples [false, true, false] or [true, false, true]
|
60
|
+
# using BoolEnumConstraintReceiver#in:
|
61
|
+
#
|
62
|
+
# bool_enum.must_be.in [[false, true, false], [true, false, true]]
|
63
|
+
#
|
64
|
+
# Constrains +bool_enum+ to channel +int_operand+ using
|
65
|
+
# BoolEnumConstraintReceiver#channel:
|
66
|
+
#
|
67
|
+
# bool_enum.must.channel int_operand
|
68
|
+
#
|
69
|
+
class BoolEnumConstraintReceiver < Gecode::ConstraintReceiver
|
70
|
+
# Raises TypeError unless the left hand side is an bool enum
|
71
|
+
# operand.
|
72
|
+
def initialize(model, params) #:nodoc:
|
73
|
+
super
|
74
|
+
|
75
|
+
unless params[:lhs].respond_to? :to_bool_enum
|
76
|
+
raise TypeError, 'Must have bool enum operand as left hand side.'
|
26
77
|
end
|
27
78
|
end
|
28
79
|
end
|
@@ -1,72 +1,151 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# A module that deals with the operands, properties and constraints of
|
2
|
+
# boolean operands.
|
3
|
+
module Gecode::Bool #:nodoc:
|
4
|
+
# A BoolOperand is a combination of variables on which the
|
5
|
+
# constraints defined in BoolConstraintReceiver can be placed.
|
6
|
+
#
|
7
|
+
# Boolean operands can be created either by using
|
8
|
+
# Gecode::Model#bool_var et al, or by using properties that produce
|
9
|
+
# boolean operands. The operands, no matter how they were created,
|
10
|
+
# all respond to the properties defined by BoolOperand.
|
11
|
+
#
|
12
|
+
# ==== Examples
|
13
|
+
#
|
14
|
+
# Produces a single boolean operand (more specifically a BoolVar)
|
15
|
+
# inside a problem formulation, using Gecode::Model#bool_var:
|
16
|
+
#
|
17
|
+
# bool_operand = bool_var
|
18
|
+
#
|
19
|
+
# Uses the BoolOperand#& property to produce a new boolean
|
20
|
+
# operand representing +bool_operand1+ AND +bool_operand2+:
|
21
|
+
#
|
22
|
+
# new_bool_operand = bool_operand1 & bool_operand2
|
23
|
+
#
|
24
|
+
# Uses the BoolEnumOperand#conjunction property to produce a new
|
25
|
+
# boolean operand representing the conjunction of all boolean operands
|
26
|
+
# in the enumeration +bool_enum+:
|
27
|
+
#
|
28
|
+
# new_bool_operand = bool_enum.conjunction
|
29
|
+
#
|
30
|
+
#--
|
31
|
+
# Classes that mix in BoolOperand must define #model and #to_bool_var .
|
32
|
+
module BoolOperand
|
33
|
+
include Gecode::Operand
|
34
|
+
|
35
|
+
def method_missing(method, *args) #:nodoc:
|
36
|
+
if Gecode::BoolVar.instance_methods.include? method.to_s
|
37
|
+
# Delegate to the bool var.
|
38
|
+
to_bool_var.method(method).call(*args)
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
5
44
|
private
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
params.update(:lhs => self)
|
10
|
-
Constraints::Bool::Expression.new(@model, params)
|
45
|
+
|
46
|
+
def construct_receiver(params)
|
47
|
+
BoolConstraintReceiver.new(@model, params)
|
11
48
|
end
|
12
49
|
end
|
13
|
-
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
50
|
+
|
51
|
+
# BoolConstraintReceiver contains all constraints that can be
|
52
|
+
# placed on a BoolOperand.
|
53
|
+
#
|
54
|
+
# Constraints are placed by calling BoolOperand#must (or any other
|
55
|
+
# of the variations defined in Operand), which produces a
|
56
|
+
# BoolConstraintReceiver from which the desired constraint can be used.
|
57
|
+
#
|
58
|
+
# Each constraint accepts a number of options. See ConstraintReceiver
|
59
|
+
# for more information.
|
60
|
+
#
|
61
|
+
# ==== Examples
|
62
|
+
#
|
63
|
+
# Constrains +bool_operand+ to be true using
|
64
|
+
# BoolConstraintReceiver#true:
|
65
|
+
#
|
66
|
+
# bool_operand.must_be.true
|
67
|
+
#
|
68
|
+
# Constrains +bool_operand1+ AND +bool_operand2+ to be true using
|
69
|
+
# the BoolOperand#& property and BoolConstraintReceiver#true:
|
70
|
+
#
|
71
|
+
# (bool_operand1 & bool_operand2).must_be.true
|
72
|
+
#
|
73
|
+
# Constrains the conjunction of all boolean operands in +bool_enum+ to
|
74
|
+
# _not_ imply +bool_operand+ using the
|
75
|
+
# BoolEnumOperand#conjunction property and BoolConstraintReceiver#imply:
|
76
|
+
#
|
77
|
+
# bool_enum.conjunction.must_not.imply bool_operand
|
78
|
+
#
|
79
|
+
# The same as above, but specifying that strength :domain should be
|
80
|
+
# used and that the constraint should be reified with +bool_operand2+:
|
81
|
+
#
|
82
|
+
# bool_enum.conjunction.must_not.imply(bool_operand, :strength => :domain, :reify => bool_operand2)
|
83
|
+
#
|
84
|
+
class BoolConstraintReceiver < Gecode::ConstraintReceiver
|
85
|
+
# Raises TypeError unless the left hand side is an bool operand.
|
86
|
+
def initialize(model, params) #:nodoc:
|
87
|
+
super
|
88
|
+
|
89
|
+
unless params[:lhs].respond_to? :to_bool_var
|
90
|
+
raise TypeError, 'Must have bool operand as left hand side.'
|
40
91
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# An operand that short circuits boolean equality.
|
96
|
+
class ShortCircuitEqualityOperand #:nodoc:
|
97
|
+
include Gecode::Bool::BoolOperand
|
98
|
+
attr :model
|
99
|
+
|
100
|
+
def initialize(model)
|
101
|
+
@model = model
|
102
|
+
end
|
103
|
+
|
104
|
+
def construct_receiver(params)
|
105
|
+
params.update(:lhs => self)
|
106
|
+
receiver = BoolConstraintReceiver.new(@model, params)
|
107
|
+
op = self
|
108
|
+
receiver.instance_eval{ @short_circuit = op }
|
109
|
+
class <<receiver
|
110
|
+
alias_method :equality_without_short_circuit, :==
|
111
|
+
def ==(operand, options = {})
|
112
|
+
if !@params[:negate] and options[:reify].nil? and
|
113
|
+
operand.respond_to? :to_bool_var
|
114
|
+
# Short circuit the constraint.
|
115
|
+
@params.update Gecode::Util.decode_options(options)
|
116
|
+
@model.add_constraint(Gecode::BlockConstraint.new(
|
117
|
+
@model, @params) do
|
118
|
+
@short_circuit.constrain_equal(operand, false,
|
119
|
+
@params.values_at(:strength, :kind))
|
120
|
+
end)
|
121
|
+
else
|
122
|
+
equality_without_short_circuit(operand, options)
|
123
|
+
end
|
48
124
|
end
|
125
|
+
alias_comparison_methods
|
49
126
|
end
|
127
|
+
|
128
|
+
return receiver
|
50
129
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
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)
|
130
|
+
|
131
|
+
def to_bool_var
|
132
|
+
variable = model.bool_var
|
133
|
+
options =
|
134
|
+
Gecode::Util.decode_options({}).values_at(:strength, :kind)
|
135
|
+
model.add_interaction do
|
136
|
+
constrain_equal(variable, true, options)
|
69
137
|
end
|
138
|
+
return variable
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# Constrains this operand to equal +bool_operand+ using the
|
144
|
+
# specified +propagation_options+. If +constrain_domain+ is true
|
145
|
+
# then the method should also attempt to constrain the bounds of the
|
146
|
+
# domain of +bool_operand+.
|
147
|
+
def constrain_equal(bool_operand, constrain_domain, propagation_options)
|
148
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
70
149
|
end
|
71
150
|
end
|
72
151
|
end
|
@@ -5,7 +5,7 @@ module Gecode
|
|
5
5
|
# omitted then no upper bound is placed. If both +at_least+ and
|
6
6
|
# +at_most+ are omitted then no bounds are placed.
|
7
7
|
#
|
8
|
-
# See
|
8
|
+
# See IntEnum::Extensional::RegexpConstraint for the
|
9
9
|
# allowed syntax of +regexp+.
|
10
10
|
def repeat(regexp, at_least = nil, at_most = nil)
|
11
11
|
unless at_least.nil? or at_least.kind_of? Fixnum
|
@@ -17,7 +17,7 @@ module Gecode
|
|
17
17
|
"Expected the at_most argument to be a Fixnum, got #{at_most.class}"
|
18
18
|
end
|
19
19
|
|
20
|
-
reg =
|
20
|
+
reg = Util::Extensional.parse_regexp regexp
|
21
21
|
if at_most.nil?
|
22
22
|
if at_least.nil?
|
23
23
|
reg.send '*'
|
@@ -48,12 +48,12 @@ module Gecode
|
|
48
48
|
# Matches any of the specified +regexps+.
|
49
49
|
def any(*regexps)
|
50
50
|
regexps.inject(Gecode::Raw::REG.new) do |result, regexp|
|
51
|
-
result |
|
51
|
+
result | Util::Extensional.parse_regexp(regexp)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
module
|
56
|
+
module Util::Extensional
|
57
57
|
module_function
|
58
58
|
|
59
59
|
# Parses a regular expression over the integer domain, returning
|