Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
lib/gecoder/interface/constraints/int_enum/extensional.rb | 187 | 59 | 100.00%
|
100.00%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 module Gecode::IntEnum |
2 class IntEnumConstraintReceiver |
3 # Constrains all the operands in this enumeration to be equal to |
4 # one of the specified tuples. Neither negation nor reification is |
5 # supported. |
6 # |
7 # ==== Examples |
8 # |
9 # # Constrains the two integer operands in +numbers+ to either have |
10 # # values 1 and 7, or values 47 and 11. |
11 # numbers.must_be.in [[1,7], [47,11]] |
12 # |
13 # # The same as above, but preferring speed over low memory usage. |
14 # numbers.must_be.in([[1,7], [47,11]], :kind => :speed) |
15 def in(tuples, options = {}) |
16 if @params[:negate] |
17 raise Gecode::MissingConstraintError, 'A negated tuple constraint is ' + |
18 'not implemented.' |
19 end |
20 unless options[:reify].nil? |
21 raise ArgumentError, 'Reification is not supported by the tuple ' + |
22 'constraint.' |
23 end |
24 |
25 util = Gecode::Util |
26 |
27 # Check that the tuples are correct. |
28 expected_size = @params[:lhs].size |
29 util::Extensional.perform_tuple_checks(tuples, expected_size) do |tuple| |
30 unless tuple.all?{ |x| x.kind_of? Fixnum } |
31 raise TypeError, 'All tuples must contain Fixnum.' |
32 end |
33 end |
34 |
35 @params[:tuples] = tuples |
36 @model.add_constraint Extensional::TupleConstraint.new(@model, |
37 @params.update(util.decode_options(options))) |
38 end |
39 |
40 # Constrains the sequence of operands in this enumeration to match |
41 # a specified regexp in the integer domain. Neither negation nor |
42 # reification is supported. |
43 # |
44 # == Regexp syntax |
45 # |
46 # The regular expressions are specified using arrays, integers and a |
47 # few methods provided by Mixin. Arrays are used to group the |
48 # integers in sequences that must be matched. The following array |
49 # describes a regular expression matching a 1 followed by a 7. |
50 # |
51 # [1, 7] |
52 # |
53 # Arrays can be nested or left out when not needed. I.e. the above |
54 # is semantically equal to |
55 # |
56 # [[[1], 7]] |
57 # |
58 # A couple of methods provided by Mixin are used to express patterns |
59 # beyond mere sequences: |
60 # |
61 # [Mixin#repeat] Used for specifying patterns that include patterns |
62 # that may be repeated a given number of times. The |
63 # number of times to repeat a pattern can be specified |
64 # using a lower and upper bound, but the bounds can be |
65 # omitted to for instance allow an expression to be |
66 # repeated any number of times. |
67 # [Mixin#any] Used for specifying alternatives. |
68 # |
69 # Additionally Mixin#at_least_once and Mixin#at_most_once are |
70 # provided as convenience methods. |
71 # |
72 # ==== Examples |
73 # |
74 # # Matches 1 followed by any number of 2s. |
75 # [1, repeat(2)] |
76 # |
77 # # Semantically the same as above. It just has a bunch of |
78 # # needless brackets thrown in. |
79 # [[1], [repeat([2])]] |
80 # |
81 # # Matches 1 followed by [a 2 followed by a 3] at least two times. |
82 # # Matches e.g. 1, 2, 3, 2, 3 |
83 # [1, repeat([2, 3], 2)] |
84 # |
85 # # Matches between one and two [2 followed by [at least three 1]] |
86 # # followed by between three and four 3. Matches e.g. |
87 # # 2, 1, 1, 1, 2, 1, 1, 1, 3, 3, 3 |
88 # [repeat([2, repeat(1, 3], 1, 2), repeat(3, 3, 4)] |
89 # |
90 # # Matches [1, 2 or 3] followed by 4. Matches e.g. 2, 4 |
91 # [any(1, 2, 3), 4] |
92 # |
93 # # Matches 0 followed by [[1 followed by 2] or [3 followed by 5]]. |
94 # # Matches e.g. 0, 1, 2 as well as 0, 3, 5 |
95 # [0, any([1, 2], [3, 5])] |
96 # |
97 # # Matches 0 followed by [[[1 followed by 7] at least two times] |
98 # # or [[8, 9], at most two times]. Matches e.g. |
99 # # 0, 1, 7, 1, 7, 1, 7 as well as 0, 8, 9 |
100 # [0, any(repeat([1, 7], 2), repeat([8, 9], 0, 2)] |
101 # |
102 # # Matches 0 followed by at least one 1. |
103 # [0, at_least_once(1)] |
104 # |
105 # # Exactly the same as the above. |
106 # [0, repeat(1, 1)] |
107 # |
108 # # Matches 0 followed by at least one [[1 followed by 7] or [3 |
109 # # followed by 2]]. Matches e.g. 0, 1, 7, 3, 2, 1, 7 |
110 # [0, at_least_once(any([1, 7], [3, 2]] |
111 # |
112 # # Matches 0 followed by at either [[1 followed by 7] at least once] |
113 # # or [[3 followed by 2] at least once]. Matches e.g. |
114 # # 0, 1, 7, 1, 7 but does _not_ match 0, 1, 7, 3, 2, 1, 7 |
115 # [0, any(at_least_once([1, 7]), at_least_once([3, 2])] |
116 # |
117 # # Matches 0, followed by at most one 1. Matches 0 as well as |
118 # # 0, 1 |
119 # [0, at_most_once(1)] |
120 # |
121 # # Exactly the same as the above. |
122 # [0, repeat(1, 0, 1)] |
123 # |
124 # ==== Examples |
125 # |
126 # # Constrains the two integer operands in +numbers+ to have |
127 # # values 1 and 7. |
128 # numbers.must.match [1, 7] |
129 # |
130 # # Constrains the integer operands in +numbers+ to contain the |
131 # # value 47 followed by 11, with all other values set to -1. |
132 # numbers.must.match [repeat(-1), 47, 11, repeat(-1)] |
133 # |
134 # # Constrains exactly three of the integer operands in +numbers+ to |
135 # # contain 47 or 11, each followed by at least two |
136 # # operands set to -1. All other operands are constrained to |
137 # # equal -1. |
138 # numbers.must.match repeat([repeat(-1), any(11, 47), |
139 # repeat(-1, 2)], 3, 3) |
140 # |
141 def match(regexp, options = {}) |
142 if @params[:negate] |
143 raise Gecode::MissingConstraintError, 'A negated regexp constraint ' + |
144 'is not implemented.' |
145 end |
146 unless options[:reify].nil? |
147 raise ArgumentError, 'Reification is not supported by the regexp ' + |
148 'constraint.' |
149 end |
150 |
151 @params[:regexp] = |
152 Gecode::Util::Extensional.parse_regexp regexp |
153 @params.update Gecode::Util.decode_options(options) |
154 @model.add_constraint Extensional::RegexpConstraint.new(@model, @params) |
155 end |
156 end |
157 |
158 # A module that gathers the classes and modules used in extensional |
159 # constraints. |
160 module Extensional #:nodoc: |
161 class TupleConstraint < Gecode::Constraint #:nodoc: |
162 def post |
163 # Bind lhs. |
164 lhs = @params[:lhs].to_int_enum.bind_array |
165 |
166 # Create the tuple set. |
167 tuple_set = Gecode::Raw::TupleSet.new |
168 @params[:tuples].each do |tuple| |
169 tuple_set.add tuple |
170 end |
171 tuple_set.finalize |
172 |
173 # Post the constraint. |
174 Gecode::Raw::extensional(@model.active_space, lhs, tuple_set, |
175 *propagation_options) |
176 end |
177 end |
178 |
179 class RegexpConstraint < Gecode::Constraint #:nodoc: |
180 def post |
181 lhs, regexp = @params.values_at(:lhs, :regexp) |
182 Gecode::Raw::extensional(@model.active_space, |
183 lhs.to_int_enum.bind_array, regexp, *propagation_options) |
184 end |
185 end |
186 end |
187 end |
Generated on Thu Jan 08 13:27:03 +0100 2015 with rcov 1.0.0