Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
lib/gecoder/interface/constraints/int_enum/sort.rb | 135 | 80 | 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 the elements in this enumeration to be sorted in ascending |
4 # order. The following options can be given in addition to the |
5 # common constraint options: |
6 # |
7 # [:as] Defines a target (must be an IntEnum) that will |
8 # hold the sorted version of the original enumerable. The original |
9 # enumerable will not be affected (i.e. will not necessarily be |
10 # sorted) |
11 # [:order] Sets an IntEnum that should be used to store the |
12 # order of the original enum's operands when sorted. The original |
13 # enumerable will not be affected (i.e. will not necessarily be |
14 # sorted) |
15 # |
16 # If neither of those options are specified then the original enumerable |
17 # will be constrained to be sorted (otherwise not). Sort constraints with |
18 # options do not allow negation. |
19 # |
20 # ==== Examples |
21 # |
22 # # Constrain +numbers+ to be sorted. |
23 # numbers.must_be.sorted |
24 # |
25 # # Constrain +numbers+ to not be sorted. |
26 # numbers.must_not_be.sorted |
27 # |
28 # # Constrain +sorted_numbers+ to be a sorted version of +numbers+. |
29 # numbers.must_be.sorted(:as => sorted_numbers) |
30 # |
31 # # Constrain +order+ to be the order in which +numbers+ has to be |
32 # # ordered to be sorted. |
33 # numbers.must_be.sorted(:order => order) |
34 # |
35 # # Constrain +sorted_numbers+ to be +numbers+ sorted in the order |
36 # # described by the IntEnum +order+. |
37 # numbers.must_be.sorted(:as => sorted_numbers, :order => order) |
38 # |
39 # # Constrains +numbers+ to be sorted, reifying with the boolean |
40 # # operand +is_sorted+, while selecting +domain+ as strength. |
41 # numbers.must_be.sorted(:reify => :is_sorted, :strength => :domain) |
42 def sorted(options = {}) |
43 # Extract and check options. |
44 target = options.delete(:as) |
45 order = options.delete(:order) |
46 unless target.nil? or target.respond_to? :to_int_enum |
47 raise TypeError, 'Expected int var enum as :as, got ' + |
48 "#{target.class}." |
49 end |
50 unless order.nil? or order.respond_to? :to_int_enum |
51 raise TypeError, 'Expected int var enum as :order, got ' + |
52 "#{order.class}." |
53 end |
54 |
55 # Extract standard options and convert to constraint. |
56 reified = !options[:reify].nil? |
57 @params.update(Gecode::Util.decode_options(options)) |
58 if target.nil? and order.nil? |
59 @model.add_constraint Sort::SortConstraint.new(@model, @params) |
60 else |
61 # Do not allow negation. |
62 if @params[:negate] |
63 raise Gecode::MissingConstraintError, 'A negated sort with options ' + |
64 'is not implemented.' |
65 end |
66 if reified |
67 raise ArgumentError, 'Reification is not supported by the sorted ' + |
68 'constraint.' |
69 end |
70 |
71 @params.update(:target => target, :order => order) |
72 @model.add_constraint Sort::SortConstraintWithOptions.new(@model, |
73 @params) |
74 end |
75 end |
76 end |
77 |
78 # A module that gathers the classes and modules used in sort constraints. |
79 module Sort #:nodoc: |
80 class SortConstraintWithOptions < Gecode::Constraint #:nodoc: |
81 def post |
82 if @params[:target].nil? |
83 # We must have a target. |
84 lhs = @params[:lhs].to_int_enum |
85 @params[:target] = @model.int_var_array(lhs.size, lhs.domain_range) |
86 end |
87 |
88 # Prepare the parameters. |
89 params = @params.values_at(:lhs, :target, :order).map do |param| |
90 if param.respond_to? :to_int_enum |
91 param.to_int_enum.bind_array |
92 else |
93 param |
94 end |
95 end.delete_if{ |param| param.nil? } |
96 params.concat propagation_options |
97 |
98 # Post the constraint. |
99 Gecode::Raw::sorted(@model.active_space, *params) |
100 end |
101 end |
102 |
103 class SortConstraint < Gecode::ReifiableConstraint #:nodoc: |
104 def post |
105 lhs, strength, kind, reif_var = |
106 @params.values_at(:lhs, :strength, :kind, :reif) |
107 using_reification = !reif_var.nil? |
108 |
109 # We translate the constraint into n-1 relation constraints. |
110 options = { |
111 :strength => |
112 Gecode::Util::PROPAGATION_STRENGTHS.invert[strength], |
113 :kind => |
114 Gecode::Util::PROPAGATION_KINDS.invert[kind] |
115 } |
116 if using_reification |
117 reification_variables = @model.bool_var_array(lhs.size - 1) |
118 end |
119 (lhs.size - 1).times do |i| |
120 first, second = lhs[i, 2] |
121 rel_options = options.clone |
122 if using_reification |
123 # Reify each relation constraint and then bind them all together. |
124 rel_options[:reify] = reification_variables[i] |
125 end |
126 first.must_be.less_than_or_equal_to(second, rel_options) |
127 end |
128 if using_reification |
129 reification_variables.conjunction.must == reif_var |
130 end |
131 end |
132 negate_using_reification |
133 end |
134 end |
135 end |
Generated on Thu Jan 08 13:27:03 +0100 2015 with rcov 1.0.0