gecoder-with-gecode 0.9.0-x86-mswin32-60
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 +137 -0
- data/COPYING +17 -0
- data/LGPL-LICENSE +458 -0
- data/README +58 -0
- data/Rakefile +14 -0
- data/example/equation_system.rb +15 -0
- data/example/example_helper.rb +1 -0
- data/example/magic_sequence.rb +43 -0
- data/example/money.rb +36 -0
- data/example/queens.rb +42 -0
- data/example/send_more_money.rb +43 -0
- data/example/send_most_money.rb +58 -0
- data/example/square_tiling.rb +84 -0
- data/example/sudoku-set.rb +106 -0
- data/example/sudoku.rb +56 -0
- data/lib/gecode.dll +0 -0
- data/lib/gecoder.rb +5 -0
- data/lib/gecoder/bindings.rb +96 -0
- data/lib/gecoder/bindings/bindings.rb +2029 -0
- data/lib/gecoder/interface.rb +9 -0
- data/lib/gecoder/interface/binding_changes.rb +9 -0
- data/lib/gecoder/interface/branch.rb +163 -0
- data/lib/gecoder/interface/constraints.rb +471 -0
- data/lib/gecoder/interface/constraints/bool/boolean.rb +251 -0
- data/lib/gecoder/interface/constraints/bool/channel.rb +7 -0
- data/lib/gecoder/interface/constraints/bool/linear.rb +200 -0
- data/lib/gecoder/interface/constraints/bool_enum/channel.rb +68 -0
- data/lib/gecoder/interface/constraints/bool_enum/extensional.rb +106 -0
- data/lib/gecoder/interface/constraints/bool_enum/relation.rb +55 -0
- data/lib/gecoder/interface/constraints/bool_enum_constraints.rb +84 -0
- data/lib/gecoder/interface/constraints/bool_var_constraints.rb +155 -0
- data/lib/gecoder/interface/constraints/extensional_regexp.rb +101 -0
- 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 +150 -0
- data/lib/gecoder/interface/constraints/int/channel.rb +51 -0
- data/lib/gecoder/interface/constraints/int/domain.rb +80 -0
- data/lib/gecoder/interface/constraints/int/linear.rb +143 -0
- data/lib/gecoder/interface/constraints/int/relation.rb +141 -0
- data/lib/gecoder/interface/constraints/int_enum/arithmetic.rb +63 -0
- data/lib/gecoder/interface/constraints/int_enum/channel.rb +86 -0
- data/lib/gecoder/interface/constraints/int_enum/count.rb +66 -0
- data/lib/gecoder/interface/constraints/int_enum/distinct.rb +64 -0
- data/lib/gecoder/interface/constraints/int_enum/element.rb +64 -0
- data/lib/gecoder/interface/constraints/int_enum/equality.rb +37 -0
- data/lib/gecoder/interface/constraints/int_enum/extensional.rb +187 -0
- data/lib/gecoder/interface/constraints/int_enum/sort.rb +135 -0
- data/lib/gecoder/interface/constraints/int_enum_constraints.rb +95 -0
- data/lib/gecoder/interface/constraints/int_var_constraints.rb +230 -0
- data/lib/gecoder/interface/constraints/reifiable_constraints.rb +78 -0
- 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 +65 -0
- data/lib/gecoder/interface/constraints/set/channel.rb +51 -0
- data/lib/gecoder/interface/constraints/set/connection.rb +130 -0
- data/lib/gecoder/interface/constraints/set/domain.rb +156 -0
- data/lib/gecoder/interface/constraints/set/include.rb +36 -0
- data/lib/gecoder/interface/constraints/set/operation.rb +118 -0
- data/lib/gecoder/interface/constraints/set/relation.rb +155 -0
- 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 +45 -0
- data/lib/gecoder/interface/constraints/set_enum/distinct.rb +43 -0
- data/lib/gecoder/interface/constraints/set_enum/operation.rb +69 -0
- data/lib/gecoder/interface/constraints/set_enum/select.rb +79 -0
- data/lib/gecoder/interface/constraints/set_enum_constraints.rb +84 -0
- data/lib/gecoder/interface/constraints/set_var_constraints.rb +243 -0
- data/lib/gecoder/interface/enum_matrix.rb +64 -0
- data/lib/gecoder/interface/enum_wrapper.rb +205 -0
- data/lib/gecoder/interface/model.rb +453 -0
- data/lib/gecoder/interface/model_sugar.rb +84 -0
- data/lib/gecoder/interface/search.rb +197 -0
- data/lib/gecoder/interface/variables.rb +306 -0
- data/lib/gecoder/version.rb +4 -0
- data/specs/bool_var.rb +81 -0
- data/specs/branch.rb +185 -0
- data/specs/constraints/bool/boolean.rb +317 -0
- 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/bool_enum/extensional.rb +225 -0
- data/specs/constraints/constraint_helper.rb +234 -0
- data/specs/constraints/constraint_receivers.rb +103 -0
- data/specs/constraints/constraints.rb +26 -0
- 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 +69 -0
- 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/distribution.rb +14 -0
- data/specs/enum_matrix.rb +43 -0
- data/specs/enum_wrapper.rb +179 -0
- data/specs/examples.rb +17 -0
- data/specs/int_var.rb +163 -0
- data/specs/logging.rb +24 -0
- data/specs/model.rb +325 -0
- data/specs/model_sugar.rb +30 -0
- data/specs/search.rb +383 -0
- data/specs/selected_set.rb +39 -0
- data/specs/set_elements.rb +34 -0
- data/specs/set_var.rb +82 -0
- data/specs/spec_helper.rb +265 -0
- data/tasks/all_tasks.rb +1 -0
- data/tasks/dependencies.txt +22 -0
- data/tasks/distribution.rake +194 -0
- data/tasks/rcov.rake +18 -0
- data/tasks/specs.rake +21 -0
- data/tasks/svn.rake +16 -0
- data/tasks/website.rake +51 -0
- data/vendor/gecode/win32/lib/libgecodeint.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodekernel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeminimodel.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesearch.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodeset.dll +0 -0
- data/vendor/gecode/win32/lib/libgecodesupport.dll +0 -0
- data/vendor/rust/README +28 -0
- data/vendor/rust/bin/cxxgenerator.rb +93 -0
- data/vendor/rust/include/rust_checks.hh +116 -0
- data/vendor/rust/include/rust_conversions.hh +102 -0
- data/vendor/rust/rust.rb +67 -0
- data/vendor/rust/rust/attribute.rb +51 -0
- data/vendor/rust/rust/bindings.rb +172 -0
- data/vendor/rust/rust/class.rb +337 -0
- data/vendor/rust/rust/constants.rb +48 -0
- data/vendor/rust/rust/container.rb +110 -0
- data/vendor/rust/rust/cppifaceparser.rb +129 -0
- data/vendor/rust/rust/cwrapper.rb +72 -0
- data/vendor/rust/rust/cxxclass.rb +96 -0
- data/vendor/rust/rust/element.rb +81 -0
- data/vendor/rust/rust/enum.rb +63 -0
- data/vendor/rust/rust/function.rb +407 -0
- data/vendor/rust/rust/namespace.rb +61 -0
- data/vendor/rust/rust/templates/AttributeDefinition.rusttpl +17 -0
- data/vendor/rust/rust/templates/AttributeInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/BindingsHeader.rusttpl +24 -0
- data/vendor/rust/rust/templates/BindingsUnit.rusttpl +46 -0
- data/vendor/rust/rust/templates/CWrapperClassDefinitions.rusttpl +64 -0
- data/vendor/rust/rust/templates/ClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/ClassInitialize.rusttpl +6 -0
- data/vendor/rust/rust/templates/ConstructorStub.rusttpl +21 -0
- data/vendor/rust/rust/templates/CxxClassDefinitions.rusttpl +100 -0
- data/vendor/rust/rust/templates/CxxMethodStub.rusttpl +12 -0
- data/vendor/rust/rust/templates/CxxStandaloneClassDefinitions.rusttpl +26 -0
- data/vendor/rust/rust/templates/EnumDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/EnumDefinitions.rusttpl +29 -0
- data/vendor/rust/rust/templates/FunctionDefinition.rusttpl +9 -0
- data/vendor/rust/rust/templates/FunctionInitAlias.rusttpl +5 -0
- data/vendor/rust/rust/templates/FunctionInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/MethodInitBinding.rusttpl +9 -0
- data/vendor/rust/rust/templates/ModuleDeclarations.rusttpl +3 -0
- data/vendor/rust/rust/templates/ModuleDefinitions.rusttpl +3 -0
- data/vendor/rust/rust/templates/StandaloneClassDeclarations.rusttpl +7 -0
- data/vendor/rust/rust/templates/VariableFunctionCall.rusttpl +14 -0
- data/vendor/rust/rust/type.rb +98 -0
- data/vendor/rust/test/Makefile +4 -0
- data/vendor/rust/test/constants.rb +36 -0
- data/vendor/rust/test/cppclass.cc +45 -0
- data/vendor/rust/test/cppclass.hh +67 -0
- data/vendor/rust/test/cppclass.rb +59 -0
- data/vendor/rust/test/cwrapper.c +74 -0
- data/vendor/rust/test/cwrapper.h +41 -0
- data/vendor/rust/test/cwrapper.rb +56 -0
- data/vendor/rust/test/dummyclass.hh +31 -0
- data/vendor/rust/test/lib/extension-test.rb +98 -0
- data/vendor/rust/test/operators.cc +41 -0
- data/vendor/rust/test/operators.hh +39 -0
- data/vendor/rust/test/operators.rb +39 -0
- data/vendor/rust/test/test-constants.rb +43 -0
- data/vendor/rust/test/test-cppclass.rb +82 -0
- data/vendor/rust/test/test-cwrapper.rb +80 -0
- data/vendor/rust/test/test-operators.rb +42 -0
- metadata +393 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
# A module containing constraints that have enumerations of integer
|
2
|
+
# operands as left hand side.
|
3
|
+
module Gecode::IntEnum #:nodoc:
|
4
|
+
# A IntEnumOperand is a enumeration of IntOperand on which the
|
5
|
+
# constraints defined in IntEnumConstraintReceiver can be placed.
|
6
|
+
#
|
7
|
+
# Enumerations of integer operands can be created either by using
|
8
|
+
# Gecode::Model#int_var_array and Gecode::Model#int_var_matrix, or
|
9
|
+
# by wrapping an existing enumeration containing IntOperand using
|
10
|
+
# Gecode::Model#wrap_enum. The enumerations, no matter how they were
|
11
|
+
# created, all respond to the properties defined by IntEnumOperand.
|
12
|
+
#
|
13
|
+
# ==== Examples
|
14
|
+
#
|
15
|
+
# Produces an array of five int operands with domain 0..9 inside a
|
16
|
+
# problem formulation using Gecode::Model#int_var_array:
|
17
|
+
#
|
18
|
+
# int_enum = int_var_array(5, 0..9)
|
19
|
+
#
|
20
|
+
# Uses Gecode::Model#wrap_enum inside a problem formulation to create
|
21
|
+
# a IntEnumOperand from an existing enumeration containing the
|
22
|
+
# integer operands +int_operand1+ and +int_operand2+:
|
23
|
+
#
|
24
|
+
# int_enum = wrap_enum([int_operand1, int_operand2])
|
25
|
+
#
|
26
|
+
#--
|
27
|
+
# Classes that mix in IntEnumOperand must define #model and
|
28
|
+
# #to_int_enum .
|
29
|
+
module IntEnumOperand
|
30
|
+
include Gecode::Operand
|
31
|
+
|
32
|
+
def method_missing(method, *args) #:nodoc:
|
33
|
+
if Gecode::IntEnum::Dummy.instance_methods.include? method.to_s
|
34
|
+
# Delegate to the int enum.
|
35
|
+
to_int_enum.method(method).call(*args)
|
36
|
+
else
|
37
|
+
super
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def construct_receiver(params)
|
44
|
+
IntEnumConstraintReceiver.new(@model, params)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# IntEnumConstraintReceiver contains all constraints that can be
|
49
|
+
# placed on a IntEnumOperand.
|
50
|
+
#
|
51
|
+
# Constraints are placed by calling IntEnumOperand#must (or any other
|
52
|
+
# of the variations defined in Operand), which produces a
|
53
|
+
# IntEnumConstraintReceiver from which the desired constraint can be used.
|
54
|
+
#
|
55
|
+
# Some constraint accepts a number of options. See ConstraintReceiver
|
56
|
+
# for more information.
|
57
|
+
#
|
58
|
+
# ==== Examples
|
59
|
+
#
|
60
|
+
# Constrains the integer operands in +int_enum+ to take on different
|
61
|
+
# values by using IntEnumConstraintReceiver#distinct:
|
62
|
+
#
|
63
|
+
# int_enum.must_be.distinct
|
64
|
+
#
|
65
|
+
# Constrains +int_enum2+ to have the same elements as +int_enum+, but
|
66
|
+
# sorted in ascending order. Uses IntEnumConstraintReceiver#sorted:
|
67
|
+
#
|
68
|
+
# int_enum.must_be.sorted(:as => int_enum2)
|
69
|
+
#
|
70
|
+
# The same as above, but specifying that strength :domain should be
|
71
|
+
# used and that the constraint should be reified with +bool_operand+:
|
72
|
+
#
|
73
|
+
# int_enum.must_be.sorted(:as => int_enum2, :strength => :domain, :reify => bool_operand)
|
74
|
+
#
|
75
|
+
class IntEnumConstraintReceiver < Gecode::ConstraintReceiver
|
76
|
+
# Raises TypeError unless the left hand side is an int enum
|
77
|
+
# operand.
|
78
|
+
def initialize(model, params) #:nodoc:
|
79
|
+
super
|
80
|
+
|
81
|
+
unless params[:lhs].respond_to? :to_int_enum
|
82
|
+
raise TypeError, 'Must have int enum operand as left hand side.'
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
require 'gecoder/interface/constraints/int_enum/distinct'
|
89
|
+
require 'gecoder/interface/constraints/int_enum/equality'
|
90
|
+
require 'gecoder/interface/constraints/int_enum/channel'
|
91
|
+
require 'gecoder/interface/constraints/int_enum/element'
|
92
|
+
require 'gecoder/interface/constraints/int_enum/count'
|
93
|
+
require 'gecoder/interface/constraints/int_enum/sort'
|
94
|
+
require 'gecoder/interface/constraints/int_enum/arithmetic'
|
95
|
+
require 'gecoder/interface/constraints/int_enum/extensional'
|
@@ -0,0 +1,230 @@
|
|
1
|
+
# A module that deals with the operands, properties and constraints of
|
2
|
+
# integer variables.
|
3
|
+
module Gecode::Int #:nodoc:
|
4
|
+
# A IntOperand is a combination of variables on which the
|
5
|
+
# constraints defined in IntConstraintReceiver can be placed.
|
6
|
+
#
|
7
|
+
# Integer operands can be created either by using
|
8
|
+
# Gecode::Model#int_var et al, or by using properties that produce
|
9
|
+
# integer operands. The operands, no matter how they were created,
|
10
|
+
# all respond to the properties defined by IntOperand.
|
11
|
+
#
|
12
|
+
# ==== Examples
|
13
|
+
#
|
14
|
+
# Produces a single integer operand (more specifically an IntVar) with
|
15
|
+
# domain 0..9 inside a problem formulation, using
|
16
|
+
# Gecode::Model#int_var:
|
17
|
+
#
|
18
|
+
# int_operand = int_var(0..9)
|
19
|
+
#
|
20
|
+
# Uses the IntOperand#+ property to produce a new integer
|
21
|
+
# operand representing +int_operand1+ plus +int_operand2+:
|
22
|
+
#
|
23
|
+
# new_int_operand = int_operand1 + int_operand2
|
24
|
+
#
|
25
|
+
# Uses the IntEnumOperand#max property to produce a new
|
26
|
+
# integer operand representing the maximum value of the integer operands
|
27
|
+
# in the enumeration +int_enum+:
|
28
|
+
#
|
29
|
+
# new_int_operand = int_enum.max
|
30
|
+
#
|
31
|
+
# Uses the IntEnumOperand#[] property to produce a new integer operand
|
32
|
+
# representing the integer operand at the index decided by
|
33
|
+
# +int_operand+ (which can change during search) in the enumeration
|
34
|
+
# +int_enum+:
|
35
|
+
#
|
36
|
+
# new_int_operand = int_enum[int_operand]
|
37
|
+
#
|
38
|
+
# Uses the SetOperand#size property to produce a new integer operand
|
39
|
+
# representing the size of +set_operand+:
|
40
|
+
#
|
41
|
+
# new_int_operand = set_operand.size
|
42
|
+
#
|
43
|
+
#--
|
44
|
+
# Classes that mix in IntOperand must define #model and #to_int_var .
|
45
|
+
module IntOperand
|
46
|
+
include Gecode::Operand
|
47
|
+
|
48
|
+
def method_missing(method, *args) #:nodoc:
|
49
|
+
if Gecode::IntVar.instance_methods.include? method.to_s
|
50
|
+
# Delegate to the int var.
|
51
|
+
to_int_var.method(method).call(*args)
|
52
|
+
else
|
53
|
+
super
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def construct_receiver(params)
|
60
|
+
IntConstraintReceiver.new(model, params)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# An operand that short circuits integer equality.
|
65
|
+
class ShortCircuitEqualityOperand #:nodoc:
|
66
|
+
include Gecode::Int::IntOperand
|
67
|
+
attr :model
|
68
|
+
|
69
|
+
def initialize(model)
|
70
|
+
@model = model
|
71
|
+
end
|
72
|
+
|
73
|
+
def construct_receiver(params)
|
74
|
+
params.update(:lhs => self)
|
75
|
+
receiver = IntConstraintReceiver.new(@model, params)
|
76
|
+
op = self
|
77
|
+
receiver.instance_eval{ @short_circuit = op }
|
78
|
+
class <<receiver
|
79
|
+
alias_method :equality_without_short_circuit, :==
|
80
|
+
def ==(operand, options = {})
|
81
|
+
if !@params[:negate] and options[:reify].nil? and
|
82
|
+
operand.respond_to? :to_int_var
|
83
|
+
# Short circuit the constraint.
|
84
|
+
@params.update Gecode::Util.decode_options(options)
|
85
|
+
@model.add_constraint(Gecode::BlockConstraint.new(
|
86
|
+
@model, @params) do
|
87
|
+
@short_circuit.constrain_equal(operand, false,
|
88
|
+
@params.values_at(:strength, :kind))
|
89
|
+
end)
|
90
|
+
else
|
91
|
+
equality_without_short_circuit(operand, options)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
alias_comparison_methods
|
95
|
+
end
|
96
|
+
|
97
|
+
return receiver
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_int_var
|
101
|
+
variable = model.int_var
|
102
|
+
options =
|
103
|
+
Gecode::Util.decode_options({}).values_at(:strength, :kind)
|
104
|
+
model.add_interaction do
|
105
|
+
constrain_equal(variable, true, options)
|
106
|
+
end
|
107
|
+
return variable
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
# Constrains this operand to equal +int_operand+ using the
|
113
|
+
# specified +propagation_options+. If +constrain_domain+ is true
|
114
|
+
# then the method should also attempt to constrain the bounds of the
|
115
|
+
# domain of +int_operand+.
|
116
|
+
def constrain_equal(int_operand, constrain_domain, propagation_options)
|
117
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# An operand that short circuits integer relation constraints.
|
122
|
+
class ShortCircuitRelationsOperand #:nodoc:
|
123
|
+
include Gecode::Int::IntOperand
|
124
|
+
attr :model
|
125
|
+
|
126
|
+
def initialize(model)
|
127
|
+
@model = model
|
128
|
+
end
|
129
|
+
|
130
|
+
def construct_receiver(params)
|
131
|
+
receiver = IntConstraintReceiver.new(@model, params)
|
132
|
+
op = self
|
133
|
+
receiver.instance_eval{ @short_circuit = op }
|
134
|
+
class <<receiver
|
135
|
+
Gecode::Util::COMPARISON_ALIASES.keys.each do |comp|
|
136
|
+
eval <<-end_code
|
137
|
+
alias_method :alias_#{comp.to_i}_without_short_circuit, :#{comp}
|
138
|
+
def #{comp}(operand, options = {})
|
139
|
+
if operand.respond_to?(:to_int_var) or operand.kind_of? Fixnum
|
140
|
+
# Short circuit the constraint.
|
141
|
+
@params.update Gecode::Util.decode_options(options)
|
142
|
+
@model.add_constraint(
|
143
|
+
@short_circuit.relation_constraint(
|
144
|
+
:#{comp}, operand, @params))
|
145
|
+
else
|
146
|
+
alias_#{comp.to_i}_without_short_circuit(operand, options)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end_code
|
150
|
+
end
|
151
|
+
alias_comparison_methods
|
152
|
+
end
|
153
|
+
|
154
|
+
return receiver
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_int_var
|
158
|
+
variable = model.int_var
|
159
|
+
params = {}
|
160
|
+
params.update Gecode::Util.decode_options({})
|
161
|
+
model.add_constraint relation_constraint(:==, variable, params)
|
162
|
+
return variable
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns a constraint that constrains this operand to have relation
|
166
|
+
# +relation+ to +int_operand_or_fix+, which is either an integer
|
167
|
+
# operand or a fixnum, given the specified hash +params+ of parameters.
|
168
|
+
def relation_constraint(relation, int_operand_or_fix, params)
|
169
|
+
raise NotImplementedError, 'Abstract method has not been implemented.'
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# IntConstraintReceiver contains all constraints that can be
|
174
|
+
# placed on an IntOperand.
|
175
|
+
#
|
176
|
+
# Constraints are placed by calling IntOperand#must (or any other
|
177
|
+
# of the variations defined in Operand), which produces a
|
178
|
+
# IntConstraintReceiver from which the desired constraint can be used.
|
179
|
+
#
|
180
|
+
# Each constraint accepts a number of options. See ConstraintReceiver
|
181
|
+
# for more information.
|
182
|
+
#
|
183
|
+
# ==== Examples
|
184
|
+
#
|
185
|
+
# Constrains +int_operand+ to be strictly greater than 5 using
|
186
|
+
# IntConstraintReceiver#>:
|
187
|
+
#
|
188
|
+
# int_operand.must > 5
|
189
|
+
#
|
190
|
+
# Constrains +int_operand1+ plus +int_operand2+ to be strictly
|
191
|
+
# greater than 5 using the IntOperand#+ property and
|
192
|
+
# IntConstraintReceiver#>:
|
193
|
+
#
|
194
|
+
# (int_operand1 + int_operand2).must > 5
|
195
|
+
#
|
196
|
+
# Constrains the maximum value of the integer operands in +int_enum+ to
|
197
|
+
# _not_ be in the range 3..7 using the IntEnumOperand#max property and
|
198
|
+
# IntConstraintReceiver#in:
|
199
|
+
#
|
200
|
+
# int_enum.max.must_not_be.in 3..7
|
201
|
+
#
|
202
|
+
# Constrains the integer operand at position +int_operand+ in
|
203
|
+
# +int_enum+, an enumeration of integer operands, to be greater than
|
204
|
+
# or equal to +int_operand2+. This uses the IntEnumOperand#[] property
|
205
|
+
# and IntConstraintReceiver#>=:
|
206
|
+
#
|
207
|
+
# int_enum[int_operand].must >= int_operand2
|
208
|
+
#
|
209
|
+
# The same as above, but specifying that strength :domain should be
|
210
|
+
# used and that the constraint should be reified with +bool_operand+:
|
211
|
+
#
|
212
|
+
# int_enum[int_operand].must_be.greater_or_equal(int_operand2, :strength => :domain, :reify => bool_operand)
|
213
|
+
#
|
214
|
+
class IntConstraintReceiver < Gecode::ConstraintReceiver
|
215
|
+
# Raises TypeError unless the left hand side is an int operand.
|
216
|
+
def initialize(model, params) #:nodoc:
|
217
|
+
super
|
218
|
+
|
219
|
+
unless params[:lhs].respond_to? :to_int_var
|
220
|
+
raise TypeError, 'Must have int operand as left hand side.'
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
require 'gecoder/interface/constraints/int/relation'
|
227
|
+
require 'gecoder/interface/constraints/int/linear'
|
228
|
+
require 'gecoder/interface/constraints/int/domain'
|
229
|
+
require 'gecoder/interface/constraints/int/arithmetic'
|
230
|
+
require 'gecoder/interface/constraints/int/channel'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module Gecode
|
2
|
+
# Base class for all reifiable constraints.
|
3
|
+
class ReifiableConstraint < Constraint #:nodoc:
|
4
|
+
# Gets the reification operand of the constraint, nil if none exists.
|
5
|
+
def reification_var
|
6
|
+
@params[:reif]
|
7
|
+
end
|
8
|
+
|
9
|
+
# Sets the reification operand of the constraint, nil if none should be
|
10
|
+
# used.
|
11
|
+
def reification_var=(new_var)
|
12
|
+
@params[:reif] = new_var
|
13
|
+
end
|
14
|
+
|
15
|
+
# Produces a disjunction of two reifiable constraints, producing a new
|
16
|
+
# reifiable constraint.
|
17
|
+
def |(constraint)
|
18
|
+
with_reification_operands(constraint) do |b1, b2|
|
19
|
+
# Create the disjunction constraint.
|
20
|
+
(b1 | b2).must_be.true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Produces a conjunction of two reifiable constraints, producing a new
|
25
|
+
# reifiable constraint.
|
26
|
+
def &(constraint)
|
27
|
+
with_reification_operands(constraint) do |b1, b2|
|
28
|
+
# Create the conjunction constraint.
|
29
|
+
(b1 & b2).must_be.true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Yields two boolean operands to the specified block. The first one
|
36
|
+
# is self's reification operand and the second one is the
|
37
|
+
# reification operand of the specified constraint. Reuses
|
38
|
+
# reification operands if possible, otherwise creates new ones.
|
39
|
+
def with_reification_operands(constraint, &block)
|
40
|
+
raise TypeError unless constraint.kind_of? ReifiableConstraint
|
41
|
+
|
42
|
+
# Set up the reification operands, using existing operands if they
|
43
|
+
# exist.
|
44
|
+
con1_holds = self.reification_var
|
45
|
+
con2_holds = constraint.reification_var
|
46
|
+
if con1_holds.nil?
|
47
|
+
con1_holds = @model.bool_var
|
48
|
+
self.reification_var = con1_holds
|
49
|
+
end
|
50
|
+
if con2_holds.nil?
|
51
|
+
con2_holds = @model.bool_var
|
52
|
+
constraint.reification_var = con2_holds
|
53
|
+
end
|
54
|
+
yield(con1_holds, con2_holds)
|
55
|
+
end
|
56
|
+
|
57
|
+
# If called the negation of the constraint will be handled using the
|
58
|
+
# reification operand. This means that the post method (which has to be
|
59
|
+
# defined prior to calling this method) doesn't have to bother about
|
60
|
+
# negation.
|
61
|
+
def self.negate_using_reification
|
62
|
+
class_eval do
|
63
|
+
alias_method :post_without_negation, :post
|
64
|
+
|
65
|
+
def post
|
66
|
+
if @params[:negate]
|
67
|
+
if @params[:reif].nil?
|
68
|
+
# Create a reification variable if none exists.
|
69
|
+
@params[:reif] = @model.bool_var
|
70
|
+
end
|
71
|
+
@params[:reif].must_be.false
|
72
|
+
end
|
73
|
+
post_without_negation
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Gecode::SelectedSet
|
2
|
+
class SelectedSetOperand
|
3
|
+
# Produces a SetOperand representing the selected sets' union.
|
4
|
+
#
|
5
|
+
# ==== Examples
|
6
|
+
#
|
7
|
+
# # The union of all sets selected by +set_enum[set]+.
|
8
|
+
# set_enum[set].union
|
9
|
+
def union
|
10
|
+
Select::SelectedSetUnionOperand.new(model, self)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Produces a SetOperand representing the selected sets' intersection.
|
14
|
+
# The option :with can be used to enumerate the elements in the
|
15
|
+
# universe.
|
16
|
+
#
|
17
|
+
# ==== Examples
|
18
|
+
#
|
19
|
+
# # The intersection of all sets selected by +set_enum[set]+.
|
20
|
+
# set_enum[set].intersection
|
21
|
+
#
|
22
|
+
# # The same intersection as above, but with [3,5,7] as universe.
|
23
|
+
# set_enum[set].intersection(:with => [3,5,7])
|
24
|
+
def intersection(options = {})
|
25
|
+
universe = nil
|
26
|
+
unless options.empty?
|
27
|
+
unless options.size == 1 and options.has_key?(:with)
|
28
|
+
raise ArgumentError, "Expected option key :with, got #{options.keys}."
|
29
|
+
else
|
30
|
+
universe = options[:with]
|
31
|
+
unless universe.kind_of?(Enumerable) and
|
32
|
+
universe.all?{ |element| element.kind_of? Fixnum }
|
33
|
+
raise TypeError, "Expected the universe to be specified as " +
|
34
|
+
"an enumeration of fixnum, got #{universe.class}."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
Select::SelectedSetIntersectionOperand.new(model, self, universe)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class SelectedSetConstraintReceiver
|
44
|
+
# Constrains the selected sets to be pairwise disjoint.
|
45
|
+
#
|
46
|
+
# ==== Examples
|
47
|
+
#
|
48
|
+
# # Constrains all sets selected by +set_enum[set]+ to be pairwise
|
49
|
+
# # disjoint.
|
50
|
+
# set_enum[set].must_be.disjoint
|
51
|
+
def disjoint(options = {})
|
52
|
+
if @params[:negate]
|
53
|
+
raise Gecode::MissingConstraintError, 'A negated disjoint constraint ' +
|
54
|
+
'is not implemented.'
|
55
|
+
end
|
56
|
+
if options.has_key? :reify
|
57
|
+
raise ArgumentError, 'The disjoint constraint does not support the ' +
|
58
|
+
'reification option.'
|
59
|
+
end
|
60
|
+
|
61
|
+
@params.update Gecode::Set::Util.decode_options(options)
|
62
|
+
@model.add_constraint Select::DisjointConstraint.new(@model, @params)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
module Select #:nodoc:
|
67
|
+
class SelectedSetUnionOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
|
68
|
+
def initialize(model, selected_set)
|
69
|
+
super model
|
70
|
+
@selected_set = selected_set
|
71
|
+
end
|
72
|
+
|
73
|
+
def constrain_equal(set_operand, constrain, propagation_options)
|
74
|
+
enum, indices = @selected_set.to_selected_set
|
75
|
+
if constrain
|
76
|
+
set_operand.must_be.subset_of enum.upper_bound_range
|
77
|
+
end
|
78
|
+
|
79
|
+
Gecode::Raw::selectUnion(@model.active_space,
|
80
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind,
|
81
|
+
set_operand.to_set_var.bind)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class SelectedSetIntersectionOperand < Gecode::Set::ShortCircuitEqualityOperand #:nodoc:
|
86
|
+
def initialize(model, selected_set, universe)
|
87
|
+
super model
|
88
|
+
@selected_set = selected_set
|
89
|
+
@universe = universe
|
90
|
+
end
|
91
|
+
|
92
|
+
def constrain_equal(set_operand, constrain, propagation_options)
|
93
|
+
enum, indices = @selected_set.to_selected_set
|
94
|
+
universe = @universe
|
95
|
+
|
96
|
+
# We can't do any useful constraining here since the empty intersection
|
97
|
+
# is the universe.
|
98
|
+
|
99
|
+
if universe.nil?
|
100
|
+
Gecode::Raw::selectInter(@model.active_space,
|
101
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind,
|
102
|
+
set_operand.to_set_var.bind)
|
103
|
+
else
|
104
|
+
Gecode::Raw::selectInterIn(@model.active_space,
|
105
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind,
|
106
|
+
set_operand.to_set_var.bind,
|
107
|
+
Gecode::Util.constant_set_to_int_set(universe))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
class DisjointConstraint < Gecode::Constraint #:nodoc:
|
113
|
+
def post
|
114
|
+
enum, indices = @params[:lhs].to_selected_set
|
115
|
+
Gecode::Raw.selectDisjoint(@model.active_space,
|
116
|
+
enum.to_set_enum.bind_array, indices.to_set_var.bind)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|