knowrob  2.1.0
A Knowledge Base System for Cognition-enabled Robots
DependencyGraph.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of KnowRob, please consult
3  * https://github.com/knowrob/knowrob for license details.
4  */
5 
6 #include <gtest/gtest.h>
7 #include "knowrob/formulas/DependencyGraph.h"
8 #include "knowrob/queries/QueryParser.h"
9 
10 using namespace knowrob;
11 
12 static inline bool has_intersection(const std::set<std::string_view> &a, const std::set<std::string_view> &b)
13 {
14  const std::set<std::string_view> &smaller = (a.size()<b.size() ? a : b);
15  const std::set<std::string_view> &larger = ((&smaller == &a) ? b : a);
16  return std::any_of(smaller.cbegin(), smaller.cend(),
17  [larger](auto &v){ return larger.count(v)>0; });
18 }
19 
21 {
22  for (auto &node : nodes_) {
23  node->neighbors_.clear();
24  }
25  nodes_.clear();
26  groups_.clear();
27 }
28 
30 {
31  insert(node);
32 }
33 
34 void DependencyGraph::insert(const std::vector<FirstOrderLiteralPtr> &literals)
35 {
36  for(auto &l : literals)
37  insert(std::make_shared<DependencyNode>(l));
38 }
39 
41 {
42  insert(std::make_shared<DependencyNode>(literal));
43 }
44 
46 {
47  nodes_.push_back(newNode);
48 
49  // find the modal node groups that have a shared variable with newNode.
50  std::list<std::list<DependencyGroup>::iterator > dependencies;
51  for(auto it=groups_.begin(); it!=groups_.end(); ++it) {
52  if(has_intersection(it->variables_, newNode->variables())) {
53  dependencies.push_back(it);
54  }
55  }
56 
57  DependencyGroup *newNodeGroup = nullptr;
58  if(dependencies.empty()) {
59  // the literal does not have a shared variable with an existing group.
60  // create a new one with just the literal as a member.
61  auto &newGroup = groups_.emplace_back();
62  newNodeGroup = &newGroup;
63  }
64  else if(dependencies.size()==1) {
65  // add to group
66  auto &group = *dependencies.front();
67  newNodeGroup = &group;
68  }
69  else {
70  // merge multiple groups into one
71  auto &newGroup = groups_.emplace_back();
72  for(auto groupIterator : dependencies) {
73  newGroup += *groupIterator;
74  groups_.erase(groupIterator);
75  }
76  newNodeGroup = &newGroup;
77  }
78  // update neighbor relation based on shared variables with other nodes
79  for(auto &x : newNodeGroup->member_) {
80  if(has_intersection(x->variables(), newNode->variables())) {
81  x->neighbors_.push_back(newNode);
82  newNode->neighbors_.push_back(x);
83  }
84  }
85  // finally add the new node to the group
86  newNodeGroup->member_.push_back(newNode);
87  newNodeGroup->variables_.insert(newNode->variables().begin(), newNode->variables().end());
88 }
89 
90 
92  : literal_(literal)
93 {
94 }
95 
96 void DependencyNode::addDependency(const std::shared_ptr<DependencyNode> &other)
97 {
98  neighbors_.push_back(other);
99 }
std::list< DependencyGroup > groups_
void insert(const DependencyNodePtr &node)
void operator+=(const DependencyNodePtr &node)
std::list< DependencyNodePtr > nodes_
void addDependency(const std::shared_ptr< DependencyNode > &other)
std::list< std::shared_ptr< DependencyNode > > neighbors_
DependencyNode(const FirstOrderLiteralPtr &literal)
std::shared_ptr< DependencyNode > DependencyNodePtr
std::shared_ptr< FirstOrderLiteral > FirstOrderLiteralPtr
std::list< DependencyNodePtr > member_
std::set< std::string_view > variables_