Gecoder C0 Coverage Information - RCov

lib/gecoder/interface/constraints/set_var_constraints.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/gecoder/interface/constraints/set_var_constraints.rb 243 134
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 # A module containing constraints that have set operands as left hand side
2 # (but not enumerations).
3 module Gecode::Set #:nodoc:
4   # A SetOperand is a combination of operands on which the
5   # constraints defined in SetConstraintReceiver can be placed.
6   #
7   # Set operands can be created either by using Gecode::Mixin#set_var et
8   # al, or by using properties that produce set operands. The operands,
9   # no matter how they were created, all respond to the properties
10   # defined by SetOperand.
11   #
12   # ==== Examples 
13   #
14   # Produces a single set operand (more specifically a SetVar), with
15   # greatest lower bound {0} and least upper bound {0, 1, 2}, inside a
16   # problem formulation, using Gecode::Mixin#set_var:
17   #
18   #   set_operand = set_var(0, 0..2)
19   #
20   # Uses the SetOperand#union property to produce a new set operand
21   # representing the union between +set_operand1+ and +set_operand2+: 
22   #
23   #   new_set_operand = set_operand1.union(set_operand2)
24   #
25   # Uses the SetEnumOperand#union property to produce a new set operand
26   # representing the union of the set operands in the enumeration
27   # +set_enum+:
28   # 
29   #   new_set_operand = set_enum.union
30   #
31   # Uses the SetEnumOperand#[] property to produce a new set operand
32   # representing the set operand at the index decided by
33   # +int_operand+ (which can change during search) in the enumeration
34   # +set_enum+:
35   # 
36   #   new_set_operand = set_enum[int_operand]
37   #
38   #--
39   # Classes that mix in SetOperand must define #model and #to_set_var .
40   module SetOperand  
41     include Gecode::Operand 
42 
43     def method_missing(method, *args) #:nodoc:
44       if Gecode::SetVar.instance_methods.include? method.to_s
45         # Delegate to the set var.
46         to_set_var.method(method).call(*args)
47       else
48         super
49       end
50     end
51 
52     private
53 
54     def construct_receiver(params)
55       SetConstraintReceiver.new(model, params)
56     end
57   end
58 
59   # An operand that short circuits set equality.
60   class ShortCircuitEqualityOperand #:nodoc:
61     include Gecode::Set::SetOperand
62     attr :model
63 
64     def initialize(model)
65       @model = model
66     end
67 
68     def construct_receiver(params)
69       params.update(:lhs => self)
70       receiver = SetConstraintReceiver.new(@model, params)
71       op = self
72       receiver.instance_eval{ @short_circuit = op }
73       class <<receiver
74         alias_method :equality_without_short_circuit, :==
75         def ==(operand, options = {})
76           if !@params[:negate] and !options.has_key?(:reify) and 
77               operand.respond_to? :to_set_var
78             # Short circuit the constraint.
79             @params.update Gecode::Util.decode_options(options)
80             @model.add_constraint(Gecode::BlockConstraint.new(
81                 @model, @params) do
82               @short_circuit.constrain_equal(operand, false,
83                 @params.values_at(:strength, :kind))
84             end)
85           else
86             equality_without_short_circuit(operand, options)
87           end
88         end
89         alias_comparison_methods
90       end
91 
92       return receiver
93     end
94 
95     def to_set_var
96       variable = model.set_var
97       options = 
98         Gecode::Set::Util.decode_options(
99           {}).values_at(:strength, :kind)
100       model.add_interaction do
101         constrain_equal(variable, true, options)
102       end
103       return variable
104     end
105 
106     private
107 
108     # Constrains this operand to equal +set_operand+ using the
109     # specified +propagation_options+. If +constrain_domain+ is true
110     # then the method should also attempt to constrain the bounds of the
111     # domain of +set_operand+.
112     def constrain_equal(set_operand, constrain_domain, propagation_options)
113       raise NotImplementedError, 'Abstract method has not been implemented.'
114     end
115   end
116 
117   # An operand that short circuits set non-negated and non-reified versions 
118   # of the relation constraints.
119   class ShortCircuitRelationsOperand #:nodoc:
120     include Gecode::Set::SetOperand
121     attr :model
122 
123     def initialize(model)
124       @model = model
125     end
126 
127     def construct_receiver(params)
128       params.update(:lhs => self)
129       receiver = SetConstraintReceiver.new(@model, params)
130       op = self
131       receiver.instance_eval{ @short_circuit = op }
132       class <<receiver
133         Gecode::Util::SET_RELATION_TYPES.keys.each do |comp|
134           eval <<-end_code
135             alias_method :alias_#{comp.to_i}_without_short_circuit, :#{comp}
136             def #{comp}(operand, options = {})
137               if !@params[:negate] && !options.has_key?(:reify) && 
138                   (operand.respond_to?(:to_set_var) or 
139                   Gecode::Util::constant_set?(operand))
140                 # Short circuit the constraint.
141                 @params.update Gecode::Set::Util.decode_options(options)
142                 @model.add_constraint(
143                   @short_circuit.relation_constraint(
144                     :#{comp}, operand, @params))
145               else
146                 alias_#{comp.to_i}_without_short_circuit(operand, options)
147               end
148             end
149           end_code
150         end
151         alias_comparison_methods
152       end
153 
154       return receiver
155     end
156 
157     def to_set_var
158       variable = model.set_var
159       params = {:lhs => self}
160       params.update Gecode::Set::Util.decode_options({})
161       model.add_constraint relation_constraint(:==, variable, params)
162       return variable
163     end
164 
165     # Returns a constraint that constrains this operand to have relation
166     # +relation+ to +set_operand_or_constant_set+, which is either a set
167     # operand or a constant set, given the specified hash +params+ of 
168     # parameters. The constraints are never negated nor reified.
169     def relation_constraint(relation, set_operand_or_constant_set, params)
170       raise NotImplementedError, 'Abstract method has not been implemented.'
171     end
172   end
173 
174   # SetConstraintReceiver contains all constraints that can be
175   # placed on a SetOperand.
176   #
177   # Constraints are placed by calling SetOperand#must (or any other
178   # of the variations defined in Operand), which produces a 
179   # SetConstraintReceiver from which the desired constraint can be used.
180   #
181   # Most constraint accept :reify option. See ConstraintReceiver for
182   # more information.
183   #
184   # ==== Examples 
185   #
186   # Constrains +set_operand+ to be a subset of {0, 1, 2} using
187   # an alias of SetConstraintReceiver#subset:
188   #
189   #   set_operand.must_be.subset_of 0..2
190   #
191   # Constrains the union of +set_operand1+ and +set_operand2+ to a
192   # subset of {0, 1, 2} using the SetOperand#union property and
193   # SetConstraintReceiver#subset:
194   #
195   #   set_operand1.union(set_operand2).must_be.subset_of 0..2
196   #
197   # Constrains the union of the set operands in +set_enum+ to _not_ 
198   # equal {0, 1, 2} by using the SetEnumOperand#union property and 
199   # an alias of SetConstraintReceiver#==:
200   #
201   #   set_enum.union.must_not == 0..2
202   #
203   # The same as above, but alsa specifying that the constraint should be 
204   # reified with +bool_operand+:
205   #
206   #   set_enum.union.must_not.equal(0..2, :reify => bool_operand)
207   #
208   class SetConstraintReceiver < Gecode::ConstraintReceiver
209     # Raises TypeError unless the left hand side is a set operand.
210     def initialize(model, params) #:nodoc:
211       super
212 
213       unless params[:lhs].respond_to? :to_set_var
214         raise TypeError, 'Must have set operand as left hand side.'
215       end
216     end
217   end
218 
219   # Utility methods for sets.
220   module Util #:nodoc:
221     module_function
222     def decode_options(options)
223       if options.has_key? :strength
224         raise ArgumentError, 'Set constraints do not support the strength ' +
225           'option.'
226       end
227       if options.has_key? :kind
228         raise ArgumentError, 'Set constraints do not support the kind ' +
229           'option.'
230       end
231       
232       Gecode::Util.decode_options(options)
233     end
234   end
235 end
236 
237 require 'gecoder/interface/constraints/set/domain'
238 require 'gecoder/interface/constraints/set/relation'
239 require 'gecoder/interface/constraints/set/cardinality'
240 require 'gecoder/interface/constraints/set/connection'
241 require 'gecoder/interface/constraints/set/include'
242 require 'gecoder/interface/constraints/set/operation'
243 require 'gecoder/interface/constraints/set/channel'

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