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,5 +1,4 @@
|
|
1
|
-
require File.dirname(__FILE__) + '/../
|
2
|
-
require File.dirname(__FILE__) + '/constraint_helper'
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
3
2
|
|
4
3
|
class BoolSampleProblem < Gecode::Model
|
5
4
|
attr :b1
|
@@ -13,29 +12,114 @@ class BoolSampleProblem < Gecode::Model
|
|
13
12
|
end
|
14
13
|
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
@expect_options = option_expectation do |strength, kind, reif_var|
|
29
|
-
@model.allow_space_access do
|
15
|
+
[:true, :false].each do |type|
|
16
|
+
describe Gecode::Bool, " (must be #{type})" do
|
17
|
+
before do
|
18
|
+
@model = Gecode::Model.new
|
19
|
+
@bool = @model.bool_var
|
20
|
+
|
21
|
+
@types = [:bool]
|
22
|
+
@invoke = lambda do |receiver, hash|
|
23
|
+
receiver.method(type).call(hash)
|
24
|
+
@model.solve!
|
25
|
+
end
|
26
|
+
@expect = lambda do |var, opts, reif_var|
|
30
27
|
# We only test the non-MiniModel parts.
|
31
28
|
unless reif_var.nil?
|
32
29
|
Gecode::Raw.should_receive(:rel).once.with(
|
33
30
|
an_instance_of(Gecode::Raw::Space),
|
34
|
-
an_instance_of(Gecode::Raw::BoolVar),
|
35
|
-
|
31
|
+
an_instance_of(Gecode::Raw::BoolVar),
|
32
|
+
(type == :true) ? Gecode::Raw::IRT_EQ : Gecode::Raw::IRT_NQ,
|
33
|
+
reif_var, *opts)
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
37
|
+
|
38
|
+
it "should constrain variables to be #{type}" do
|
39
|
+
@bool.must.method(type).call
|
40
|
+
@model.solve!
|
41
|
+
@bool.value.should == (type == :true)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should make negation constrain variables to not be #{type}" do
|
45
|
+
@bool.must_not.method(type).call
|
46
|
+
@model.solve!
|
47
|
+
@bool.value.should == (type != :true)
|
48
|
+
end
|
49
|
+
|
50
|
+
it_should_behave_like 'reifiable constraint'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe Gecode::Bool, " (implies)" do
|
55
|
+
before do
|
56
|
+
@model = Gecode::Model.new
|
57
|
+
@b1 = @model.bool_var
|
58
|
+
@b2 = @model.bool_var
|
59
|
+
@model.branch_on @model.wrap_enum([@b1, @b2])
|
60
|
+
|
61
|
+
@types = [:bool, :bool]
|
62
|
+
@invoke = lambda do |receiver, op, hash|
|
63
|
+
receiver.imply(op, hash)
|
64
|
+
@model.solve!
|
65
|
+
end
|
66
|
+
@expect = lambda do |var1, var2, opts, reif_var|
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should constrain variables to imply each other" do
|
71
|
+
@b1.must.imply @b2
|
72
|
+
@model.solve!
|
73
|
+
(!@b1.value || @b2.value).should be_true
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should, when negated, constrain variables to not imply each other" do
|
77
|
+
@b1.must_not.imply @b2
|
78
|
+
@model.solve!
|
79
|
+
@b1.value.should be_true
|
80
|
+
@b2.value.should_not be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it_should_behave_like 'reifiable constraint'
|
84
|
+
end
|
85
|
+
|
86
|
+
describe Gecode::Bool, " (equality)" do
|
87
|
+
before do
|
88
|
+
@model = Gecode::Model.new
|
89
|
+
@b1 = @model.bool_var
|
90
|
+
@b2 = @model.bool_var
|
91
|
+
@model.branch_on @model.wrap_enum([@b1, @b2])
|
92
|
+
|
93
|
+
@types = [:bool, :bool]
|
94
|
+
@invoke = lambda do |receiver, op, hash|
|
95
|
+
receiver.equal(op, hash)
|
96
|
+
@model.solve!
|
97
|
+
end
|
98
|
+
@expect = lambda do |var1, var2, opts, reif_var|
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should constrain variables to equal each other" do
|
103
|
+
@b1.must == @b2
|
104
|
+
@model.solve!
|
105
|
+
@b1.value.should == @b2.value
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should, when negated, constrain variables to not equal each other" do
|
109
|
+
@b1.must_not == @b2
|
110
|
+
@model.solve!
|
111
|
+
@b1.value.should_not == @b2.value
|
112
|
+
end
|
113
|
+
|
114
|
+
it_should_behave_like 'reifiable constraint'
|
115
|
+
end
|
116
|
+
|
117
|
+
describe Gecode::Bool do
|
118
|
+
before do
|
119
|
+
@model = BoolSampleProblem.new
|
120
|
+
@b1 = @model.b1
|
121
|
+
@b2 = @model.b2
|
122
|
+
@b3 = @model.b3
|
39
123
|
end
|
40
124
|
|
41
125
|
it 'should handle single variables constrainted to be true' do
|
@@ -229,14 +313,5 @@ describe Gecode::Constraints::Bool do
|
|
229
313
|
sol = @model.solve!
|
230
314
|
sol.b3.value.should be_true
|
231
315
|
end
|
232
|
-
|
233
|
-
it 'should raise error on right hand sides of incorrect type given to #==' do
|
234
|
-
lambda{ @b1.must == 'hello' }.should raise_error(TypeError)
|
235
|
-
end
|
236
|
-
|
237
|
-
it 'should raise error on right hand sides of incorrect type given to #imply' do
|
238
|
-
lambda{ @b1.must.imply 'hello' }.should raise_error(TypeError)
|
239
|
-
end
|
240
|
-
|
241
|
-
it_should_behave_like 'reifiable constraint'
|
242
316
|
end
|
317
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../property_helper'
|
2
|
+
|
3
|
+
[:&, :|, :^].each do |property|
|
4
|
+
describe Gecode::Bool, " (#{property} property)" do
|
5
|
+
before do
|
6
|
+
@model = Gecode::Model.new
|
7
|
+
@b1 = @model.bool_var
|
8
|
+
@b2 = @model.bool_var
|
9
|
+
@model.branch_on @model.wrap_enum([@b1, @b2])
|
10
|
+
|
11
|
+
# For bool operand producing property spec.
|
12
|
+
@property_types = [:bool, :bool]
|
13
|
+
@select_property = lambda do |bool1, bool2|
|
14
|
+
bool1.method(property).call bool2
|
15
|
+
end
|
16
|
+
@selected_property = @b1.method(property).call @b2
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should constrain the conjunction/disjunction/exclusive disjunction' do
|
20
|
+
(@b1.method(property).call @b2).must_be.true
|
21
|
+
@model.solve!
|
22
|
+
@b1.value.method(property).call(@b2.value).should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it_should_behave_like 'property that produces bool operand'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Gecode::Bool, ' (#implies property)' do
|
30
|
+
before do
|
31
|
+
@model = Gecode::Model.new
|
32
|
+
@b1 = @model.bool_var
|
33
|
+
@b2 = @model.bool_var
|
34
|
+
@model.branch_on @model.wrap_enum([@b1, @b2])
|
35
|
+
|
36
|
+
# For bool operand producing property spec.
|
37
|
+
@property_types = [:bool, :bool]
|
38
|
+
@select_property = lambda do |bool1, bool2|
|
39
|
+
bool1.implies bool2
|
40
|
+
end
|
41
|
+
@selected_property = @b1.implies @b2
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should constrain the implication' do
|
45
|
+
(@b1.implies @b2).must_be.true
|
46
|
+
@model.solve!
|
47
|
+
(!@b1.value | @b2.value).should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
it_should_behave_like 'property that produces bool operand'
|
51
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../constraint_helper'
|
2
|
+
|
3
|
+
class BoolLinearSampleProblem < Gecode::Model
|
4
|
+
attr :x
|
5
|
+
attr :y
|
6
|
+
attr :z
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@x = self.bool_var
|
10
|
+
@y = self.bool_var
|
11
|
+
@z = self.bool_var
|
12
|
+
branch_on wrap_enum([@x, @y, @z])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class TrueClass
|
17
|
+
def to_i
|
18
|
+
1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class FalseClass
|
23
|
+
def to_i
|
24
|
+
0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe Gecode::Int::Linear, '(with booleans)' do
|
29
|
+
before do
|
30
|
+
@model = BoolLinearSampleProblem.new
|
31
|
+
@x = @model.x
|
32
|
+
@y = @model.y
|
33
|
+
@z = @model.z
|
34
|
+
@operand = @x + @y
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should handle addition with a variable' do
|
38
|
+
(@x + @y).must == 0
|
39
|
+
sol = @model.solve!
|
40
|
+
x = sol.x.value.to_i
|
41
|
+
y = sol.y.value.to_i
|
42
|
+
(x + y).should be_zero
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should handle reification (1)' do
|
46
|
+
bool = @model.bool_var
|
47
|
+
(@x + @y).must.equal(0, :reify => bool)
|
48
|
+
bool.must_be.false
|
49
|
+
sol = @model.solve!
|
50
|
+
x = sol.x.value.to_i
|
51
|
+
y = sol.y.value.to_i
|
52
|
+
(x + y).should_not be_zero
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should handle reification (2)' do
|
56
|
+
bool = @model.bool_var
|
57
|
+
(@x + @y).must.equal(0, :reify => bool)
|
58
|
+
bool.must_be.true
|
59
|
+
sol = @model.solve!
|
60
|
+
x = sol.x.value.to_i
|
61
|
+
y = sol.y.value.to_i
|
62
|
+
(x + y).should be_zero
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should handle addition with multiple variables' do
|
66
|
+
(@x + @y + @z).must == 0
|
67
|
+
sol = @model.solve!
|
68
|
+
x = sol.x.value.to_i
|
69
|
+
y = sol.y.value.to_i
|
70
|
+
z = sol.z.value.to_i
|
71
|
+
(x + y + z).should be_zero
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should handle subtraction with a variable' do
|
75
|
+
(@x - @y).must == 0
|
76
|
+
sol = @model.solve!
|
77
|
+
x = sol.x.value.to_i
|
78
|
+
y = sol.y.value.to_i
|
79
|
+
(x - y).should be_zero
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should handle non-zero constants as right hand side' do
|
83
|
+
(@x + @y).must == 1
|
84
|
+
sol = @model.solve!
|
85
|
+
x = sol.x.value.to_i
|
86
|
+
y = sol.y.value.to_i
|
87
|
+
(x + y).should equal(1)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should handle single booleans as left hand side' do
|
91
|
+
@x.must == @y + 1
|
92
|
+
sol = @model.solve!
|
93
|
+
x = sol.x.value.to_i
|
94
|
+
y = sol.y.value.to_i
|
95
|
+
x.should equal(y + 1)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should handle single booleans as left hand side (2)' do
|
99
|
+
@x.must == @y + @z
|
100
|
+
sol = @model.solve!
|
101
|
+
x = sol.x.value.to_i
|
102
|
+
y = sol.y.value.to_i
|
103
|
+
z = sol.z.value.to_i
|
104
|
+
x.should equal(y + z)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should handle single booleans as left hand side (3)' do
|
108
|
+
bool = @model.bool_var
|
109
|
+
@x.must.equal(@y + @z, :reify => bool)
|
110
|
+
bool.must_be.false
|
111
|
+
sol = @model.solve!
|
112
|
+
x = sol.x.value.to_i
|
113
|
+
y = sol.y.value.to_i
|
114
|
+
z = sol.z.value.to_i
|
115
|
+
x.should_not equal(y + z)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should handle variables as right hand side' do
|
119
|
+
(@x + @y).must == @z
|
120
|
+
sol = @model.solve!
|
121
|
+
x = sol.x.value.to_i
|
122
|
+
y = sol.y.value.to_i
|
123
|
+
z = sol.z.value.to_i
|
124
|
+
(x + y).should equal(z)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should handle linear expressions as right hand side' do
|
128
|
+
(@x + @y).must == @z + @y
|
129
|
+
sol = @model.solve!
|
130
|
+
x = sol.x.value.to_i
|
131
|
+
y = sol.y.value.to_i
|
132
|
+
z = sol.z.value.to_i
|
133
|
+
(x + y).should equal(z + y)
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should raise error on invalid right hand sides' do
|
137
|
+
lambda do
|
138
|
+
(@x + @y).must == 'z'
|
139
|
+
end.should raise_error(TypeError)
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should raise error if a fixnum is not used in multiplication' do
|
143
|
+
lambda do
|
144
|
+
(@x * @y).must == 0
|
145
|
+
end.should raise_error(TypeError)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should raise error if bools are combined with integer variables' do
|
149
|
+
lambda do
|
150
|
+
(@x + @model.int_var).must == 0
|
151
|
+
end.should raise_error(TypeError)
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'should handle coefficients other than 1' do
|
155
|
+
(@x * 2 + @y).must == 0
|
156
|
+
sol = @model.solve!
|
157
|
+
x = sol.x.value.to_i
|
158
|
+
y = sol.y.value.to_i
|
159
|
+
(2*x + y).should equal(0)
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should handle addition with constants' do
|
163
|
+
(@y + 1).must == 1
|
164
|
+
sol = @model.solve!
|
165
|
+
y = sol.y.value.to_i
|
166
|
+
(y + 1).should equal(1)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should handle subtraction with a constant' do
|
170
|
+
(@x - 1).must == 0
|
171
|
+
sol = @model.solve!
|
172
|
+
x = sol.x.value.to_i
|
173
|
+
(x - 1).should be_zero
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should handle parenthesis' do
|
177
|
+
(@x - (@y + @z)).must == 1
|
178
|
+
sol = @model.solve!
|
179
|
+
x = sol.x.value.to_i
|
180
|
+
y = sol.y.value.to_i
|
181
|
+
z = sol.z.value.to_i
|
182
|
+
(x - (y + z)).should equal(1)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'should handle multiplication of parenthesis' do
|
186
|
+
(((@x + @y*10)*10 + @z)*10).must == 0
|
187
|
+
sol = @model.solve!
|
188
|
+
x = sol.x.value.to_i
|
189
|
+
y = sol.y.value.to_i
|
190
|
+
z = sol.z.value.to_i
|
191
|
+
(((x + y*10)*10 + z)*10).should equal(0)
|
192
|
+
end
|
193
|
+
|
194
|
+
relations = ['>', '>=', '<', '<=', '==']
|
195
|
+
|
196
|
+
relations.each do |relation|
|
197
|
+
it "should handle #{relation} with constant integers" do
|
198
|
+
(@x + @y).must.send(relation, 1)
|
199
|
+
sol = @model.solve!
|
200
|
+
sol.should_not be_nil
|
201
|
+
(sol.x.value.to_i + sol.y.value.to_i).should.send(relation, 1)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
relations.each do |relation|
|
206
|
+
it "should handle negated #{relation} with constant integers" do
|
207
|
+
(@x + @y).must_not.send(relation, 1)
|
208
|
+
sol = @model.solve!
|
209
|
+
sol.should_not be_nil
|
210
|
+
(sol.x.value.to_i + sol.y.value.to_i).should_not.send(relation, 1)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../property_helper'
|
2
|
+
|
3
|
+
class BoolEnumSampleProblem < Gecode::Model
|
4
|
+
attr :bools
|
5
|
+
attr :b1
|
6
|
+
attr :b2
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@bools = bool_var_array(4)
|
10
|
+
@b1 = bool_var
|
11
|
+
@b2 = bool_var
|
12
|
+
branch_on @bools
|
13
|
+
branch_on wrap_enum([@b1, @b2])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Expects @stub, which contains the started constraint and @compute_result
|
18
|
+
# which computes whether the left hand side is true or not.
|
19
|
+
describe 'bool enum relation constraint', :shared => true do
|
20
|
+
it 'should handle being constrained to be true' do
|
21
|
+
@stub.must_be.true
|
22
|
+
@model.solve!
|
23
|
+
@compute_result.call.should be_true
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should handle being constrained to be negated true' do
|
27
|
+
@stub.must_not_be.true
|
28
|
+
@model.solve!
|
29
|
+
@compute_result.call.should_not be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should handle being constrained to be false' do
|
33
|
+
@stub.must_be.false
|
34
|
+
@model.solve!
|
35
|
+
@compute_result.call.should_not be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should handle being constrained to be negated false' do
|
39
|
+
@stub.must_not_be.false
|
40
|
+
@model.solve!
|
41
|
+
@compute_result.call.should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should handle being constrained to be equal to a variable' do
|
45
|
+
@stub.must_be == @b1
|
46
|
+
@model.solve!
|
47
|
+
@compute_result.call.should == @b1.value
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should handle being constrained to not be equal to a variable' do
|
51
|
+
@stub.must_not_be == @b1
|
52
|
+
@model.solve!
|
53
|
+
@compute_result.call.should_not == @b1.value
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should handle being constrained to be equal to be a nested expression' do
|
57
|
+
@stub.must_be == (@b1 | @b2) & @b1
|
58
|
+
@model.solve!
|
59
|
+
@compute_result.call.should == (@b1.value | @b2.value) & @b1.value
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should handle being constrained to not be equal to be a nested expression' do
|
63
|
+
@stub.must_not_be == (@b1 | @b2) & @b1
|
64
|
+
@model.solve!
|
65
|
+
@compute_result.call.should_not == (@b1.value | @b2.value) & @b1.value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe Gecode::BoolEnum::Relation, ' (conjunction)' do
|
70
|
+
before do
|
71
|
+
@model = BoolEnumSampleProblem.new
|
72
|
+
@bools = @model.bools
|
73
|
+
@b1 = @model.b1
|
74
|
+
@b2 = @model.b2
|
75
|
+
|
76
|
+
# For property spec.
|
77
|
+
@property_types = [:bool_enum]
|
78
|
+
@select_property = lambda do |bool_enum|
|
79
|
+
bool_enum.conjunction
|
80
|
+
end
|
81
|
+
@selected_property = @bools.conjunction
|
82
|
+
@constraint_class = Gecode::BlockConstraint
|
83
|
+
|
84
|
+
# For bool enum spec.
|
85
|
+
@stub = @selected_property
|
86
|
+
@compute_result = lambda{ @bools.all?{ |b| b.value } }
|
87
|
+
end
|
88
|
+
|
89
|
+
it_should_behave_like 'bool enum relation constraint'
|
90
|
+
it_should_behave_like(
|
91
|
+
'property that produces bool operand by short circuiting equality')
|
92
|
+
end
|
93
|
+
|
94
|
+
describe Gecode::BoolEnum::Relation, ' (disjunction)' do
|
95
|
+
before do
|
96
|
+
@model = BoolEnumSampleProblem.new
|
97
|
+
@bools = @model.bools
|
98
|
+
@b1 = @model.b1
|
99
|
+
@b2 = @model.b2
|
100
|
+
|
101
|
+
# For constraint option spec.
|
102
|
+
@property_types = [:bool_enum]
|
103
|
+
@select_property = lambda do |bool_enum|
|
104
|
+
bool_enum.disjunction
|
105
|
+
end
|
106
|
+
@selected_property = @bools.disjunction
|
107
|
+
@constraint_class = Gecode::BlockConstraint
|
108
|
+
|
109
|
+
# For bool enum spec.
|
110
|
+
@stub = @selected_property
|
111
|
+
@compute_result = lambda{ @bools.any?{ |b| b.value } }
|
112
|
+
end
|
113
|
+
|
114
|
+
it_should_behave_like 'bool enum relation constraint'
|
115
|
+
it_should_behave_like(
|
116
|
+
'property that produces bool operand by short circuiting equality')
|
117
|
+
end
|