Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
lib/gecoder/interface/constraints/bool_var_constraints.rb | 155 | 71 | 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 # A module that deals with the operands, properties and constraints of |
2 # boolean operands. |
3 module Gecode::Bool #:nodoc: |
4 # A BoolOperand is a combination of variables on which the |
5 # constraints defined in BoolConstraintReceiver can be placed. |
6 # |
7 # Boolean operands can be created either by using |
8 # Gecode::Mixin#bool_var et al, or by using properties that produce |
9 # boolean operands. The operands, no matter how they were created, |
10 # all respond to the properties defined by BoolOperand. |
11 # |
12 # ==== Examples |
13 # |
14 # Produces a single boolean operand (more specifically a BoolVar) |
15 # inside a problem formulation, using Gecode::Mixin#bool_var: |
16 # |
17 # bool_operand = bool_var |
18 # |
19 # Uses the BoolOperand#& property to produce a new boolean |
20 # operand representing +bool_operand1+ AND +bool_operand2+: |
21 # |
22 # new_bool_operand = bool_operand1 & bool_operand2 |
23 # |
24 # Uses the BoolEnumOperand#conjunction property to produce a new |
25 # boolean operand representing the conjunction of all boolean operands |
26 # in the enumeration +bool_enum+: |
27 # |
28 # new_bool_operand = bool_enum.conjunction |
29 # |
30 #-- |
31 # Classes that mix in BoolOperand must define #model and #to_bool_var . |
32 module BoolOperand |
33 include Gecode::Operand |
34 |
35 def method_missing(method, *args) #:nodoc: |
36 if Gecode::BoolVar.instance_methods.include? method.to_s |
37 # Delegate to the bool var. |
38 to_bool_var.method(method).call(*args) |
39 else |
40 super |
41 end |
42 end |
43 |
44 private |
45 |
46 def construct_receiver(params) |
47 BoolConstraintReceiver.new(@model, params) |
48 end |
49 end |
50 |
51 # BoolConstraintReceiver contains all constraints that can be |
52 # placed on a BoolOperand. |
53 # |
54 # Constraints are placed by calling BoolOperand#must (or any other |
55 # of the variations defined in Operand), which produces a |
56 # BoolConstraintReceiver from which the desired constraint can be used. |
57 # |
58 # Each constraint accepts a number of options. See ConstraintReceiver |
59 # for more information. |
60 # |
61 # ==== Examples |
62 # |
63 # Constrains +bool_operand+ to be true using |
64 # BoolConstraintReceiver#true: |
65 # |
66 # bool_operand.must_be.true |
67 # |
68 # Constrains +bool_operand1+ AND +bool_operand2+ to be true using |
69 # the BoolOperand#& property and BoolConstraintReceiver#true: |
70 # |
71 # (bool_operand1 & bool_operand2).must_be.true |
72 # |
73 # Constrains the conjunction of all boolean operands in +bool_enum+ to |
74 # _not_ imply +bool_operand+ using the |
75 # BoolEnumOperand#conjunction property and BoolConstraintReceiver#imply: |
76 # |
77 # bool_enum.conjunction.must_not.imply bool_operand |
78 # |
79 # The same as above, but specifying that strength :domain should be |
80 # used and that the constraint should be reified with +bool_operand2+: |
81 # |
82 # bool_enum.conjunction.must_not.imply(bool_operand, :strength => :domain, :reify => bool_operand2) |
83 # |
84 class BoolConstraintReceiver < Gecode::ConstraintReceiver |
85 # Raises TypeError unless the left hand side is an bool operand. |
86 def initialize(model, params) #:nodoc: |
87 super |
88 |
89 unless params[:lhs].respond_to? :to_bool_var |
90 raise TypeError, 'Must have bool operand as left hand side.' |
91 end |
92 end |
93 end |
94 |
95 # An operand that short circuits boolean equality. |
96 class ShortCircuitEqualityOperand #:nodoc: |
97 include Gecode::Bool::BoolOperand |
98 attr :model |
99 |
100 def initialize(model) |
101 @model = model |
102 end |
103 |
104 def construct_receiver(params) |
105 params.update(:lhs => self) |
106 receiver = BoolConstraintReceiver.new(@model, params) |
107 op = self |
108 receiver.instance_eval{ @short_circuit = op } |
109 class <<receiver |
110 alias_method :equality_without_short_circuit, :== |
111 def ==(operand, options = {}) |
112 if !@params[:negate] and options[:reify].nil? and |
113 operand.respond_to? :to_bool_var |
114 # Short circuit the constraint. |
115 @params.update Gecode::Util.decode_options(options) |
116 @model.add_constraint(Gecode::BlockConstraint.new( |
117 @model, @params) do |
118 @short_circuit.constrain_equal(operand, false, |
119 @params.values_at(:strength, :kind)) |
120 end) |
121 else |
122 equality_without_short_circuit(operand, options) |
123 end |
124 end |
125 alias_comparison_methods |
126 end |
127 |
128 return receiver |
129 end |
130 |
131 def to_bool_var |
132 variable = model.bool_var |
133 options = |
134 Gecode::Util.decode_options({}).values_at(:strength, :kind) |
135 model.add_interaction do |
136 constrain_equal(variable, true, options) |
137 end |
138 return variable |
139 end |
140 |
141 private |
142 |
143 # Constrains this operand to equal +bool_operand+ using the |
144 # specified +propagation_options+. If +constrain_domain+ is true |
145 # then the method should also attempt to constrain the bounds of the |
146 # domain of +bool_operand+. |
147 def constrain_equal(bool_operand, constrain_domain, propagation_options) |
148 raise NotImplementedError, 'Abstract method has not been implemented.' |
149 end |
150 end |
151 end |
152 |
153 require 'gecoder/interface/constraints/bool/boolean' |
154 require 'gecoder/interface/constraints/bool/linear' |
155 require 'gecoder/interface/constraints/bool/channel' |
Generated on Thu Jan 08 13:27:03 +0100 2015 with rcov 1.0.0