@@ -99,6 +99,123 @@ namespace LogicalExpressionDetail
99
99
}
100
100
};
101
101
102
+ template <typename ContainedClass>
103
+ class FalsifiabilityVisitor ;
104
+
105
+ // / Visitor to test whether expression's value can be true
106
+ template <typename ContainedClass>
107
+ class SatisfiabilityVisitor : public boost ::static_visitor<bool >
108
+ {
109
+ typedef ExpressionBase<ContainedClass> Base;
110
+
111
+ std::function<bool (const typename Base::Value &)> satisfiabilityTest;
112
+ FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor;
113
+
114
+ size_t countSatisfiable (const std::vector<typename Base::Variant> & element) const
115
+ {
116
+ return boost::range::count_if (element, [&](const typename Base::Variant & expr)
117
+ {
118
+ return boost::apply_visitor (*this , expr);
119
+ });
120
+ }
121
+
122
+ size_t countFalsifiable (const std::vector<typename Base::Variant> & element) const
123
+ {
124
+ return boost::range::count_if (element, [&](const typename Base::Variant & expr)
125
+ {
126
+ return boost::apply_visitor (*falsifiabilityVisitor, expr);
127
+ });
128
+ }
129
+
130
+ public:
131
+ SatisfiabilityVisitor (std::function<bool (const typename Base::Value &)> satisfiabilityTest):
132
+ satisfiabilityTest (satisfiabilityTest),
133
+ falsifiabilityVisitor (nullptr )
134
+ {}
135
+
136
+ void setFalsifiabilityVisitor (FalsifiabilityVisitor<ContainedClass> *falsifiabilityVisitor)
137
+ {
138
+ this ->falsifiabilityVisitor = falsifiabilityVisitor;
139
+ }
140
+
141
+ bool operator ()(const typename Base::OperatorAny & element) const
142
+ {
143
+ return countSatisfiable (element.expressions ) != 0 ;
144
+ }
145
+
146
+ bool operator ()(const typename Base::OperatorAll & element) const
147
+ {
148
+ return countSatisfiable (element.expressions ) == element.expressions .size ();
149
+ }
150
+
151
+ bool operator ()(const typename Base::OperatorNone & element) const
152
+ {
153
+ return countFalsifiable (element.expressions ) == element.expressions .size ();
154
+ }
155
+
156
+ bool operator ()(const typename Base::Value & element) const
157
+ {
158
+ return satisfiabilityTest (element);
159
+ }
160
+ };
161
+
162
+ // / Visitor to test whether expression's value can be false
163
+ template <typename ContainedClass>
164
+ class FalsifiabilityVisitor : public boost ::static_visitor<bool >
165
+ {
166
+ typedef ExpressionBase<ContainedClass> Base;
167
+
168
+ std::function<bool (const typename Base::Value &)> falsifiabilityTest;
169
+ SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor;
170
+
171
+ size_t countSatisfiable (const std::vector<typename Base::Variant> & element) const
172
+ {
173
+ return boost::range::count_if (element, [&](const typename Base::Variant & expr)
174
+ {
175
+ return boost::apply_visitor (*satisfiabilityVisitor, expr);
176
+ });
177
+ }
178
+
179
+ size_t countFalsifiable (const std::vector<typename Base::Variant> & element) const
180
+ {
181
+ return boost::range::count_if (element, [&](const typename Base::Variant & expr)
182
+ {
183
+ return boost::apply_visitor (*this , expr);
184
+ });
185
+ }
186
+
187
+ public:
188
+ FalsifiabilityVisitor (std::function<bool (const typename Base::Value &)> falsifiabilityTest):
189
+ falsifiabilityTest (falsifiabilityTest),
190
+ satisfiabilityVisitor (nullptr )
191
+ {}
192
+
193
+ void setFalsifiabilityVisitor (SatisfiabilityVisitor<ContainedClass> *satisfiabilityVisitor)
194
+ {
195
+ this ->satisfiabilityVisitor = satisfiabilityVisitor;
196
+ }
197
+
198
+ bool operator ()(const typename Base::OperatorAny & element) const
199
+ {
200
+ return countFalsifiable (element.expressions ) == element.expressions .size ();
201
+ }
202
+
203
+ bool operator ()(const typename Base::OperatorAll & element) const
204
+ {
205
+ return countFalsifiable (element.expressions ) != 0 ;
206
+ }
207
+
208
+ bool operator ()(const typename Base::OperatorNone & element) const
209
+ {
210
+ return countSatisfiable (element.expressions ) != 0 ;
211
+ }
212
+
213
+ bool operator ()(const typename Base::Value & element) const
214
+ {
215
+ return falsifiabilityTest (element);
216
+ }
217
+ };
218
+
102
219
// / visitor that is trying to generates candidates that must be fulfilled
103
220
// / to complete this expression
104
221
template <typename ContainedClass>
@@ -436,6 +553,30 @@ class LogicalExpression
436
553
return boost::apply_visitor (testVisitor, data);
437
554
}
438
555
556
+ // / calculates if expression can evaluate to "true".
557
+ bool satisfiable (std::function<bool (const Value &)> satisfiabilityTest, std::function<bool(const Value &)> falsifiabilityTest) const
558
+ {
559
+ LogicalExpressionDetail::SatisfiabilityVisitor<Value> satisfiabilityVisitor (satisfiabilityTest);
560
+ LogicalExpressionDetail::FalsifiabilityVisitor<Value> falsifiabilityVisitor (falsifiabilityTest);
561
+
562
+ satisfiabilityVisitor.setFalsifiabilityVisitor (&falsifiabilityVisitor);
563
+ falsifiabilityVisitor.setFalsifiabilityVisitor (&satisfiabilityVisitor);
564
+
565
+ return boost::apply_visitor (satisfiabilityVisitor, data);
566
+ }
567
+
568
+ // / calculates if expression can evaluate to "false".
569
+ bool falsifiable (std::function<bool (const Value &)> satisfiabilityTest, std::function<bool(const Value &)> falsifiabilityTest) const
570
+ {
571
+ LogicalExpressionDetail::SatisfiabilityVisitor<Value> satisfiabilityVisitor (satisfiabilityTest);
572
+ LogicalExpressionDetail::FalsifiabilityVisitor<Value> falsifiabilityVisitor (falsifiabilityTest);
573
+
574
+ satisfiabilityVisitor.setFalsifiabilityVisitor (&falsifiabilityVisitor);
575
+ falsifiabilityVisitor.setFalsifiabilityVisitor (&satisfiabilityVisitor);
576
+
577
+ return boost::apply_visitor (falsifiabilityVisitor, data);
578
+ }
579
+
439
580
// / generates list of candidates that can be fulfilled by caller (like AI)
440
581
std::vector<Value> getFulfillmentCandidates (std::function<bool (const Value &)> toBool) const
441
582
{
0 commit comments