Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|

lib/gecoder/interface/variables.rb | 306 |
176 |
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 |

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