LearnTA  0.0.1
symbolic_membership_oracle.hh
1 
6 #pragma once
7 
8 #include "elementary_language.hh"
9 #include "sul.hh"
10 #include "membership_oracle.hh"
11 #include "timed_condition_set.hh"
12 
13 namespace learnta {
18  private:
19  std::unique_ptr<MembershipOracle> membershipOracle;
20  boost::unordered_map<ElementaryLanguage, TimedConditionSet> cache;
21  std::size_t countSymbolic = 0;
22  std::size_t countSymbolicWithCache = 0;
23 
24  [[nodiscard]] bool included(const ElementaryLanguage &elementary) {
25  return this->membershipOracle->answerQuery(elementary.sample());
26  }
27 
28  public:
29  explicit SymbolicMembershipOracle(std::unique_ptr<SUL>&& sul) : membershipOracle(
30  std::make_unique<MembershipOracleCache>(std::make_unique<SULMembershipOracle>(std::move(sul)))) {}
31 
38  ++countSymbolic;
39  auto it = cache.find(elementary);
40  if (it != cache.end()) {
41  return it->second;
42  }
43  ++countSymbolicWithCache;
44  std::list<ElementaryLanguage> includedLanguages;
45  bool allIncluded = true;
46  // Check if each of the simple elementary language is in the target language
47  for (const auto &simple: elementary.enumerate()) {
48  if (this->included(simple)) {
49  includedLanguages.push_back(simple);
50  } else {
51  allIncluded = false;
52  }
53  }
54 
55  // Simplify the result
56  if (includedLanguages.empty()) {
57  cache[elementary] = TimedConditionSet::bottom();
58  return cache[elementary];
59  } else if (allIncluded) {
60  cache[elementary] = TimedConditionSet{elementary.getTimedCondition()};
61  return cache[elementary];
62  } else {
63  auto convexHull = ElementaryLanguage::convexHull(includedLanguages);
64  // Check if the convex hull is the exact union.
65  if (convexHull.enumerate().size() == includedLanguages.size()) {
66  // When the convex hull is the exact union
67  cache[elementary] = TimedConditionSet{convexHull.getTimedCondition()};
68  return cache[elementary];
69  } else {
70  // When the convex hull is an overapproximation
71  cache[elementary] = TimedConditionSet::reduce(std::move(includedLanguages));
72  return cache[elementary];
73  }
74  }
75  }
76 
77  [[nodiscard]] std::size_t count() const override {
78  return this->membershipOracle->count();
79  }
80 
81  [[nodiscard]] bool answerQuery(const TimedWord &timedWord) override {
82  return this->membershipOracle->answerQuery(timedWord);
83  }
84 
85  std::ostream &printStatistics(std::ostream &stream) const override {
86  stream << "Number of symbolic membership queries: " << countSymbolic << "\n";
87  stream << "Number of symbolic membership queries (with cache): " << countSymbolicWithCache << "\n";
88  return this->membershipOracle->printStatistics(stream);
89  }
90  };
91 }
An elementary language.
Definition: elementary_language.hh:23
void enumerate(std::vector< ElementaryLanguage > &result) const
Make a vector of simple elementary languages in this elementary language.
Definition: elementary_language.hh:87
TimedWord sample() const
Return a timed word in this elementary language.
Definition: elementary_language.hh:114
static ElementaryLanguage convexHull(const std::list< ElementaryLanguage > &elementaryLanguages)
Construct a convex-hull of the given timed conditions.
Definition: elementary_language.hh:49
Interface of a membership oracle.
Definition: membership_oracle.hh:17
The oracle to answer symbolic membership queries.
Definition: symbolic_membership_oracle.hh:17
TimedConditionSet query(const ElementaryLanguage &elementary)
Make a symbolic membership query.
Definition: symbolic_membership_oracle.hh:37
A set of timed conditions to represent non-convex constraints.
Definition: timed_condition_set.hh:18
static TimedConditionSet reduce(std::list< ElementaryLanguage > elementaryLanguages)
Construct a timed condition set from a set of simple elementary languages.
Definition: timed_condition_set.hh:40
Definition: experiment_runner.hh:23