Gecoder C0 Coverage Information - RCov

lib/gecoder/interface/variables.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/gecoder/interface/variables.rb 306 176
100.00%
100.00%

Key

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.

Coverage Details

1 module Gecode
2   # Describes a variable that is bound to a model, but not to a particular 
3   # space.  
4   class FreeVarBase #:nodoc:
5     attr_accessor :model
6   
7     # Creates an int variable with the specified index.
8     def initialize(model, index)
9       @model = model
10       @index = index
11       model.track_variable(self)
12     end
13 
14     def inspect
15       if assigned?
16         "#<#{self.class} #{domain_string}>"
17       else
18         "#<#{self.class} #{domain_string}>"
19       end
20     end
21     
22     private
23     
24     # Returns the space that the int variable should bind to when needed.
25     def active_space
26       @model.active_space
27     end
28     
29     # Sends the specified method name and arguments to the bound variable.
30     def send_bound(method_name, *args)
31       @model.allow_space_access do
32         bind.send(method_name, *args)
33       end
34     end
35   end
36   
37   # Creates a class for a free variable that can be bound into the specified
38   # class using the specified method in a space.
39   def Gecode::FreeVar(bound_class, space_bind_method) #:nodoc:
40     clazz = Class.new(FreeVarBase)
41     clazz.class_eval <<-"end_method_definitions"      
42       # Binds the variable to the currently active space of the model, 
43       # returning the bound variable.
44       def bind
45         active_space.method(:#{space_bind_method}).call(@index)
46       end
47       
48       private
49       
50       # Delegates the method with the specified name to a method with the 
51       # specified name when the variable is bound. If the bound method's name
52       # is nil then the same name as the new method's name is assumed.
53       def self.delegate(method_name, bound_method_name = nil)
54         bound_method_name = method_name if bound_method_name.nil?
55         module_eval <<-"end_code"
56           def \#{method_name}(*args)
57             @model.allow_space_access do
58               bind.method(:\#{bound_method_name}).call(*args)
59             end
60           end
61         end_code
62       end
63     end_method_definitions
64     return clazz
65   end
66   
67   IntVar = FreeVar(Gecode::Raw::IntVar, :int_var)
68   # Describes an integer variable. 
69   #
70   # An integer variable can take the value of any integer in its 
71   # domain, which is specified upon constructing the variable and
72   # further constrained by placing constraints on the variable.
73   # An integer variable is said to be assigned once the domain only
74   # contains a single element, at which point #value can be used to
75   # retrieve the value.
76   #
77   # Integer variables are integer operands and hence respond to
78   # everything that Gecode::Int::IntOperand responds to.
79   # Any constraint found in
80   # Gecode::Int::IntConstraintReceiver can thereby be 
81   # placed on integer variables.
82   class IntVar
83     include Gecode::Int::IntOperand
84     attr :model
85 
86     # Gets the minimum value still in the domain of the variable.
87     delegate :min
88     # Gets the maximum value still in the domain of the variable.
89     delegate :max
90     # Gets the number of elements still in the domain of the variable.
91     delegate :size
92     # Gets the width of the variable's domain, i.e. the distance between the
93     # maximum and minimum values.
94     delegate :width
95     # Gets the degree of the variable. The degree is the number of constraints
96     # that are affected by the variable. So if the variable is used in two
97     # constraints then the value will be 2.
98     delegate :degree
99     # Checks whether the domain is a range, i.e. doesn't contain any holes.
100     delegate :range?, :range
101     # Checks whether the variable has been assigned, i.e. its domain only 
102     # contains one element.
103     delegate :assigned?, :assigned
104     # Checks whether a specified integer is in the variable's domain.
105     delegate :include?, :in
106     
107     # Gets the value of the assigned integer variable (a Fixnum). The variable
108     # must be assigned, if it isn't then a RuntimeError is raised.
109     def value
110       raise 'No value is assigned.' unless assigned?
111       send_bound(:val)
112     end
113 
114     # Returns the receiver.
115     def to_int_var
116       self
117     end
118     
119     # Returns an enumeration corresponding to the domain.
120     def domain
121       if range?
122         min..max
123       else
124         (min..max).select do |i|
125           include? i
126         end
127       end
128     end
129 
130     private
131     
132     # Returns a string representation of the range of the variable's domain.
133     def domain_string #:nodoc:
134       if assigned?
135         "range: #{value.to_s}"
136       else
137         "range: #{min}..#{max}"
138       end
139     end
140   end
141   
142   BoolVar = FreeVar(Gecode::Raw::BoolVar, :bool_var)
143   # Describes a boolean variable. 
144   #
145   # A boolean variable can be either true or false.
146   #
147   # Boolean variables are boolean operands and hence respond to
148   # everything that Gecode::Bool::BoolOperand responds to.
149   # Any constraint found in
150   # Gecode::Bool::BoolConstraintReceiver can thereby be 
151   # placed on boolean variables.
152   class BoolVar
153     include Gecode::Bool::BoolOperand
154     attr :model
155 
156     # Checks whether the variable has been assigned.
157     delegate :assigned?, :assigned
158     
159     # Gets the values in the assigned boolean variable (true or false). The 
160     # variable must be assigned, if it isn't then a RuntimeError is raised.
161     def value
162       raise 'No value is assigned.' unless assigned?
163       send_bound(:val) == 1
164     end
165 
166     # Returns the receiver.
167     def to_bool_var
168       self
169     end
170   
171     private
172   
173     # Returns a string representation of the the variable's domain.
174     def domain_string
175       if assigned?
176         value.to_s
177       else
178         'unassigned'
179       end
180     end
181   end
182 
183   SetVar = FreeVar(Gecode::Raw::SetVar, :set_var)
184   # Describes a set variable. 
185   # 
186   # A set variable's domain, i.e. possible values that it can take, are
187   # represented with a greatest lower bound (GLB) and a least upper
188   # bound (LUB).  The set variable may then take any set value S such
189   # that S is a subset of the least upper bound and the greatest lower
190   # bound is a subset of S.
191   #   
192   # If for instance the set has a greatest lower bound {1} and least
193   # upper bound {1,3,5} then the assigned set may be any of the
194   # following four sets: {1}, {1,3}, {1,5}, {1,3,5}. 
195   # 
196   # The domain of a set variable may also specify the cardinality of the
197   # set, i.e. the number of elements that the set may contains.
198   #
199   # Set variables are set operands and hence respond to everything that
200   # Gecode::Set::SetOperand responds to.  Any constraint
201   # found in Gecode::Set::SetConstraintReceiver can thereby
202   # be placed on set variables.
203   class SetVar
204     include Gecode::Set::SetOperand
205     attr :model
206 
207     # Checks whether the variable has been assigned.
208     delegate :assigned?, :assigned
209     # Checks whether a value is included in the set.
210     delegate :in_lower_bound?, :contains
211     # Checks whether a value is not included in the set.
212     delegate :not_in_upper_bound?, :notContains
213 
214     # Gets all the elements located in the greatest lower bound of the set (an 
215     # Enumerable).
216     def lower_bound
217       min = send_bound(:glbMin)
218       max = send_bound(:glbMax)
219       EnumerableView.new(min, max, send_bound(:glbSize)) do
220         (min..max).to_a.delete_if{ |e| not send_bound(:contains, e) }
221       end
222     end
223     
224     # Gets all the elements located in the least upper bound of the set (an 
225     # Enumerable).
226     def upper_bound
227       min = send_bound(:lubMin)
228       max = send_bound(:lubMax)
229       EnumerableView.new(min, max, send_bound(:lubSize)) do
230         (min..max).to_a.delete_if{ |e| send_bound(:notContains, e) }
231       end
232     end
233     
234     # Gets the values in the assigned set variable (an enumerable).
235     def value
236       raise 'No value is assigned.' unless assigned?
237       lower_bound
238     end
239     
240     # Returns a range containing the allowed values for the set's cardinality.
241     def cardinality
242       send_bound(:cardMin)..send_bound(:cardMax)
243     end
244     
245     # Returns the receiver.
246     def to_set_var
247       self
248     end
249     
250     private
251     
252     # Returns a string representation of the the variable's domain.
253     def domain_string
254       if assigned?
255         if lower_bound.size < 100
256           lower_bound.to_a.inspect
257         else
258           "the domain is too large to display"
259         end
260       else
261         if upper_bound.size < 100
262           "glb-range: #{lower_bound.to_a.inspect}, lub-range: #{upper_bound.to_a.inspect}"
263         else
264           "the domain is too large to display"
265         end
266       end
267     end
268   end
269   
270   # Describes an immutable view of an enumerable.
271   class EnumerableView #:nodoc:
272     # Gets the number of elements in the view.
273     attr :size
274     # Gets the minimum element of the view.
275     attr :min
276     # Gets the maximum element of the view.
277     attr :max
278     include Enumerable
279     
280     # Constructs a view with the specified minimum, maximum and size. The block 
281     # should construct an enumerable containing the elements of the set.
282     def initialize(min, max, size, &enum_constructor)
283       @min = min
284       @max = max
285       @size = size
286       @constructor = enum_constructor
287       @enum = nil
288     end
289 
290     # Iterates over every element in the view.
291     def each(&block)
292       enum.each(&block)
293     end
294     
295     private
296     
297     # Gets the enumeration being viewed.
298     def enum
299       if @enum.nil?
300         @enum = @constructor.call
301       else
302         return @enum
303       end
304     end
305   end
306 end

Generated on Thu Jan 08 13:27:03 +0100 2015 with rcov 1.0.0