51 std::vector<NodeData::Key> evaluateMissingAttributes(
53 if (eval_info.inquire_unknown_attributes && eval_info.inquire_outdated_attributes) {
55 if (!data.hasKey(key_) ||
56 !data.isValueUpToDate(key_, eval_info.validity_threshold_timestamp)) {
62 if (eval_info.inquire_unknown_attributes && !eval_info.inquire_outdated_attributes) {
65 if (!data.hasKey(key_)) {
71 if (!eval_info.inquire_unknown_attributes && eval_info.inquire_outdated_attributes) {
74 if (data.hasKey(key_) &&
75 !data.isValueUpToDate(key_, eval_info.validity_threshold_timestamp)) {
81 if (!eval_info.inquire_unknown_attributes && !eval_info.inquire_outdated_attributes) {
86 throw std::logic_error(
"should not be reached");
91 return evaluateExisting(data, eval_info);
94 if (!data.hasKey(key_)) {
95 if (!eval_info.all_information_present && eval_info.inquire_unknown_attributes) {
96 return FuzzyValue::createUndecided();
98 return FuzzyValue::createFalse();
103 if (eval_info.inquire_outdated_attributes &&
104 !data.isValueUpToDate(key_, eval_info.validity_threshold_timestamp)) {
105 if (eval_info.all_information_present) {
106 return FuzzyValue::createFalse();
108 return FuzzyValue::createUndecided();
112 FuzzyValue value = evaluateExisting(data, eval_info);
113 if (value.isUndecided() && !eval_info.inquire_outdated_attributes && eval_info.permissive) {
114 return FuzzyValue::createTrue();
122 uint8_t getDepth()
override {
return 1; }
130 explicit OrExpression(std::shared_ptr<BooleanExpression> expr1,
131 std::shared_ptr<BooleanExpression> expr2)
132 : expr1_(std::move(expr1)), expr2_(std::move(expr2)){};
137 return expr1_->evaluate(data, eval_info) || expr2_->evaluate(data, eval_info);
140 std::vector<NodeData::Key> evaluateMissingAttributes(
143 eval_info_c.all_information_present =
false;
145 auto expr1_eval = expr1_->evaluate(data, eval_info_c);
146 auto expr2_eval = expr2_->evaluate(data, eval_info_c);
148 if (expr1_eval.isTrue() || expr2_eval.isTrue()) {
152 auto missings = expr1_->evaluateMissingAttributes(data, eval_info_c);
153 auto temp_missings = expr2_->evaluateMissingAttributes(data, eval_info_c);
154 missings.insert(missings.end(), temp_missings.begin(), temp_missings.end());
158 std::vector<NodeData::Key> getRelevantKeys()
const override {
159 auto relevants = expr1_->getRelevantKeys();
160 auto temp_relevants = expr2_->getRelevantKeys();
161 relevants.insert(relevants.end(), temp_relevants.begin(), temp_relevants.end());
165 std::vector<NodeData::Key> getRelevantTopicKeys()
const override {
166 auto relevants = expr1_->getRelevantTopicKeys();
167 auto temp_relevants = expr2_->getRelevantTopicKeys();
168 relevants.insert(relevants.end(), temp_relevants.begin(), temp_relevants.end());
172 std::string serialize()
override {
173 return "( " + expr1_->serialize() +
" OR " + expr2_->serialize() +
" )";
176 uint8_t getDepth()
override {
return expr1_->getDepth() + expr2_->getDepth(); }
179 std::shared_ptr<BooleanExpression> expr1_;
180 std::shared_ptr<BooleanExpression> expr2_;
185 explicit AndExpression(std::shared_ptr<BooleanExpression> expr1,
186 std::shared_ptr<BooleanExpression> expr2)
187 : expr1_(std::move(expr1)), expr2_(std::move(expr2)){};
192 return expr1_->evaluate(data, eval_info) && expr2_->evaluate(data, eval_info);
195 std::vector<NodeData::Key> evaluateMissingAttributes(
197 auto missings = expr1_->evaluateMissingAttributes(data, eval_info);
198 auto temp_missings = expr2_->evaluateMissingAttributes(data, eval_info);
199 missings.insert(missings.end(), temp_missings.begin(), temp_missings.end());
203 std::vector<NodeData::Key> getRelevantKeys()
const override {
204 auto relevants = expr1_->getRelevantKeys();
205 auto temp_relevants = expr2_->getRelevantKeys();
206 relevants.insert(relevants.end(), temp_relevants.begin(), temp_relevants.end());
210 std::vector<NodeData::Key> getRelevantTopicKeys()
const override {
211 auto relevants = expr1_->getRelevantTopicKeys();
212 auto temp_relevants = expr2_->getRelevantTopicKeys();
213 relevants.insert(relevants.end(), temp_relevants.begin(), temp_relevants.end());
217 std::string serialize()
override {
218 return "( " + expr1_->serialize() +
" AND " + expr2_->serialize() +
" )";
221 uint8_t getDepth()
override {
return expr1_->getDepth() + expr2_->getDepth(); }
224 std::shared_ptr<BooleanExpression> expr1_;
225 std::shared_ptr<BooleanExpression> expr2_;
230 explicit NotExpression(std::shared_ptr<BooleanExpression> expr) : expr_(std::move(expr)){};
235 auto val_pos = expr_->evaluate(data, eval_info);
236 auto val_neg = !val_pos;
240 std::vector<NodeData::Key> evaluateMissingAttributes(
242 return expr_->evaluateMissingAttributes(data, eval_info);
245 std::vector<NodeData::Key> getRelevantKeys()
const override {
return expr_->getRelevantKeys(); }
246 std::vector<NodeData::Key> getRelevantTopicKeys()
const override {
247 return expr_->getRelevantTopicKeys();
250 std::string serialize()
override {
return "( NOT " + expr_->serialize() +
" )"; }
252 uint8_t getDepth()
override {
return expr_->getDepth(); }
255 std::shared_ptr<BooleanExpression> expr_;
266 if (!data.hasKey(key_)) {
267 return FuzzyValue::createFalse();
270 auto variant = data.getValue(key_);
271 auto pval = std::get_if<bool>(&variant);
272 if (pval !=
nullptr) {
274 return *pval ? FuzzyValue::createTrue() : FuzzyValue::createFalse();
276 return FuzzyValue::createTrue();
279 std::vector<NodeData::Key> getRelevantKeys()
const override {
return {key_}; }
280 std::vector<NodeData::Key> getRelevantTopicKeys()
const override {
return {key_}; }
282 std::string serialize()
override {
return "( HAS " + key_ +
" )"; }
294 if (!data.hasKey(key_)) {
295 return FuzzyValue::createFalse();
297 NodeData::Value variant = data.getValue(key_);
298 auto pval = std::get_if<std::string>(&variant);
299 if (pval !=
nullptr) {
300 if ((*pval) == value_) {
301 return FuzzyValue::createTrue();
305 return FuzzyValue::createFalse();
308 std::vector<NodeData::Key> getRelevantKeys()
const override {
return {key_}; }
309 std::vector<NodeData::Key> getRelevantTopicKeys()
const override {
return {}; }
311 std::string serialize()
override {
return "( " + key_ +
" == " + value_ +
" )"; }
318 static_assert(std::is_same_v<NumericType, int> || std::is_same_v<NumericType, float>,
319 "NumericType must be int or float");
323 NumericType comparison_value)
325 comparison_type_(comparison_type),
326 comparison_value_(comparison_value){};
332 if (!data.hasKey(key_))
return FuzzyValue::createFalse();
334 NodeData::Value variant = data.getValue(key_);
336 bool comparison =
false;
337 bool compared =
false;
340 int int_value = std::get<int>(variant);
341 comparison = applyComparison<int>(int_value);
343 }
catch (std::bad_variant_access
const &ex) {
348 float float_value = std::get<float>(variant);
349 comparison = applyComparison<float>(float_value);
351 }
catch (std::bad_variant_access
const &ex) {
357 return FuzzyValue::createTrue();
359 return FuzzyValue::createFalse();
361 throw std::invalid_argument(
"Could not compare");
364 std::vector<NodeData::Key> getRelevantKeys()
const override {
return {key_}; }
365 std::vector<NodeData::Key> getRelevantTopicKeys()
const override {
return {}; }
367 std::string serialize()
override {
368 std::string comp_str;
369 switch (comparison_type_) {
370 case ComparisonTypes::kEqualTo:
373 case ComparisonTypes::kGreater:
376 case ComparisonTypes::kGreaterThanOrEqualTo:
379 case ComparisonTypes::kLessThan:
382 case ComparisonTypes::kLessThanOrEqualTo:
385 case ComparisonTypes::kNotEqualTo:
390 return "( " + key_ +
" " + comp_str +
" " + std::to_string(comparison_value_) +
" )";
394 ComparisonTypes comparison_type_;
395 NumericType comparison_value_;
397 template <
typename OtherNumericType>
bool applyComparison(OtherNumericType evaluation_value) {
398 static_assert(std::is_arithmetic<OtherNumericType>::value,
"OtherNumericType must be numeric");
400 switch (comparison_type_) {
401 case ComparisonTypes::kEqualTo: {
402 return evaluation_value == comparison_value_;
404 case ComparisonTypes::kNotEqualTo: {
405 return evaluation_value != comparison_value_;
407 case ComparisonTypes::kLessThan: {
408 return evaluation_value < comparison_value_;
410 case ComparisonTypes::kGreater: {
411 return evaluation_value > comparison_value_;
413 case ComparisonTypes::kLessThanOrEqualTo: {
414 return evaluation_value <= comparison_value_;
416 case ComparisonTypes::kGreaterThanOrEqualTo: {
417 return evaluation_value >= comparison_value_;