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,101 @@
|
|
1
|
+
module Gecode
|
2
|
+
class Model
|
3
|
+
# Specifies an integer regexp that matches +regexp+ repeated between
|
4
|
+
# +at_least+ and +at_most+ times (inclusive). If +at_most+ is
|
5
|
+
# omitted then no upper bound is placed. If both +at_least+ and
|
6
|
+
# +at_most+ are omitted then no bounds are placed.
|
7
|
+
#
|
8
|
+
# See IntEnum::Extensional::RegexpConstraint for the
|
9
|
+
# allowed syntax of +regexp+.
|
10
|
+
def repeat(regexp, at_least = nil, at_most = nil)
|
11
|
+
unless at_least.nil? or at_least.kind_of? Fixnum
|
12
|
+
raise TypeError,
|
13
|
+
"Expected the at_least argument to be a Fixnum, got #{at_least.class}"
|
14
|
+
end
|
15
|
+
unless at_most.nil? or at_most.kind_of?(Fixnum)
|
16
|
+
raise TypeError,
|
17
|
+
"Expected the at_most argument to be a Fixnum, got #{at_most.class}"
|
18
|
+
end
|
19
|
+
|
20
|
+
reg = Util::Extensional.parse_regexp regexp
|
21
|
+
if at_most.nil?
|
22
|
+
if at_least.nil?
|
23
|
+
reg.send '*'
|
24
|
+
else
|
25
|
+
reg.send('()', at_least)
|
26
|
+
end
|
27
|
+
else
|
28
|
+
reg.send('()', at_least, at_most)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Matches +regexp+ repeated zero or one time (i.e. like '?' in normal
|
33
|
+
# regexps). Produces the same result as calling
|
34
|
+
#
|
35
|
+
# repeat(regexp, 0, 1)
|
36
|
+
def at_most_once(regexp)
|
37
|
+
repeat(regexp, 0, 1)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Matches +regexp+ repeated at least one time (i.e. like '+' in normal
|
41
|
+
# regexps). Produces the same result as calling
|
42
|
+
#
|
43
|
+
# repeat(regexp, 1)
|
44
|
+
def at_least_once(regexp)
|
45
|
+
repeat(regexp, 1)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Matches any of the specified +regexps+.
|
49
|
+
def any(*regexps)
|
50
|
+
regexps.inject(Gecode::Raw::REG.new) do |result, regexp|
|
51
|
+
result | Util::Extensional.parse_regexp(regexp)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
module Util::Extensional
|
57
|
+
module_function
|
58
|
+
|
59
|
+
# Parses a regular expression over the integer domain, returning
|
60
|
+
# an instance of Gecode::REG .
|
61
|
+
#
|
62
|
+
# Pseudo-BNF of the integer regexp representation:
|
63
|
+
# regexp ::= <Fixnum> | <TrueClass> | <FalseClass> | <Gecode::Raw::REG>
|
64
|
+
# | [<regexp>, ...]
|
65
|
+
def parse_regexp(regexp)
|
66
|
+
# Check the involved types.
|
67
|
+
unless regexp.kind_of? Enumerable
|
68
|
+
regexp = [regexp]
|
69
|
+
end
|
70
|
+
regexp.to_a.flatten.each do |element|
|
71
|
+
unless element.kind_of?(Fixnum) or element.kind_of?(Gecode::Raw::REG) or
|
72
|
+
element.kind_of?(TrueClass) or element.kind_of?(FalseClass)
|
73
|
+
raise TypeError,
|
74
|
+
"Can't translate #{element.class} into integer or boolean regexp."
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Convert it into a regexp.
|
79
|
+
internal_parse_regexp(regexp)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# Recursively converts arg into an instance of Gecode::REG. It is
|
85
|
+
# assumed that arg is of kind Gecode::Raw::REG, Fixnum, TrueClass,
|
86
|
+
# FalseClass or Enumerable.
|
87
|
+
def self.internal_parse_regexp(arg)
|
88
|
+
case arg
|
89
|
+
when Gecode::Raw::REG: arg
|
90
|
+
when Fixnum: Gecode::Raw::REG.new(arg)
|
91
|
+
when TrueClass: Gecode::Raw::REG.new(1)
|
92
|
+
when FalseClass: Gecode::Raw::REG.new(0)
|
93
|
+
when Enumerable
|
94
|
+
# Recursively convert the elements of the arg.
|
95
|
+
arg.inject(Gecode::Raw::REG.new) do |regexp, element|
|
96
|
+
regexp += internal_parse_regexp(element)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -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'
|
@@ -0,0 +1,150 @@
|
|
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
|
23
|
+
|
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)
|
33
|
+
end
|
34
|
+
alias_method :sqrt, :square_root
|
35
|
+
|
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)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
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
|
62
|
+
end
|
63
|
+
|
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
|
75
|
+
end
|
76
|
+
|
77
|
+
class IntMultOperand < Gecode::Int::ShortCircuitEqualityOperand #:nodoc:
|
78
|
+
def initialize(model, op1, op2)
|
79
|
+
super model
|
80
|
+
@op1 = op1
|
81
|
+
@op2 = op2
|
82
|
+
end
|
83
|
+
|
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
|
91
|
+
end
|
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
|
111
|
+
end
|
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
|
122
|
+
end
|
123
|
+
|
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
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Gecode::Int
|
2
|
+
class IntConstraintReceiver
|
3
|
+
alias_method :pre_channel_equals, :==
|
4
|
+
|
5
|
+
# Constrains the integer operand to be equal to the specified boolean
|
6
|
+
# operand. I.e. constrains the integer operand to be 1 when the boolean
|
7
|
+
# operand is true and 0 if the boolean operand is false.
|
8
|
+
#
|
9
|
+
# ==== Examples
|
10
|
+
#
|
11
|
+
# # The integer operand +int+ must be one exactly when the boolean
|
12
|
+
# # operand +bool+ is true.
|
13
|
+
# int.must == bool
|
14
|
+
def ==(bool, options = {})
|
15
|
+
unless @params[:lhs].respond_to? :to_int_var and
|
16
|
+
bool.respond_to? :to_bool_var
|
17
|
+
return pre_channel_equals(bool, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
if @params[:negate]
|
21
|
+
raise Gecode::MissingConstraintError, 'A negated channel constraint ' +
|
22
|
+
'is not implemented.'
|
23
|
+
end
|
24
|
+
unless options[:reify].nil?
|
25
|
+
raise ArgumentError, 'Reification is not supported by the channel ' +
|
26
|
+
'constraint.'
|
27
|
+
end
|
28
|
+
|
29
|
+
@params.update(Gecode::Util.decode_options(options))
|
30
|
+
@params[:rhs] = bool
|
31
|
+
@model.add_constraint Channel::ChannelConstraint.new(@model, @params)
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_comparison_methods
|
35
|
+
|
36
|
+
# Provides commutativity with BoolEnumConstraintReceiver#channel .
|
37
|
+
provide_commutativity(:channel){ |rhs, _| rhs.respond_to? :to_bool_enum }
|
38
|
+
end
|
39
|
+
|
40
|
+
# A module that gathers the classes and modules used in channel constraints
|
41
|
+
# involving a single integer operand.
|
42
|
+
module Channel #:nodoc:
|
43
|
+
class ChannelConstraint < Gecode::Constraint #:nodoc:
|
44
|
+
def post
|
45
|
+
lhs, rhs = @params.values_at(:lhs, :rhs)
|
46
|
+
Gecode::Raw::channel(@model.active_space, lhs.to_int_var.bind,
|
47
|
+
rhs.to_bool_var.bind, *propagation_options)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|