From 3e6b581733092ef8492b63e8fd7e7987028cb966 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Fri, 4 Oct 2024 11:18:44 +0200 Subject: [PATCH 01/49] add default value for ServiceCall --- ontopy/ontologenius/compat/ros.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ontopy/ontologenius/compat/ros.py b/ontopy/ontologenius/compat/ros.py index 518d7bea..b975d212 100644 --- a/ontopy/ontologenius/compat/ros.py +++ b/ontopy/ontologenius/compat/ros.py @@ -11,7 +11,7 @@ def __init__(self, srv_name, srv_type): self.srv_name = srv_name self.srv_type = srv_type - def call(self, request, verbose): + def call(self, request, verbose=True): try: response = self._client(request) return response From a13032d8ea4170775792f77fae9c911e331c8b55 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Fri, 4 Oct 2024 11:19:17 +0200 Subject: [PATCH 02/49] setup export sub packages --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 33f7cc5d..0482725f 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from catkin_pkg.python_setup import generate_distutils_setup d = generate_distutils_setup( - packages=['ontologenius'], + packages=['ontologenius','ontologenius.clients','ontologenius.clientsIndex','ontologenius.compat'], package_dir={'': 'ontopy'}, requires=['rospy','ontologenius','ontologenius.srv'] ) From b385a43daf7ec111f923d18999ef59cd5afe0e3c Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Tue, 22 Oct 2024 11:27:18 +0200 Subject: [PATCH 03/49] [SparqlUtils] prevent convertions of empty variables --- include/ontologenius/core/ontologyOperators/SparqlUtils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ontologenius/core/ontologyOperators/SparqlUtils.h b/include/ontologenius/core/ontologyOperators/SparqlUtils.h index dc759fb3..fc563be7 100644 --- a/include/ontologenius/core/ontologyOperators/SparqlUtils.h +++ b/include/ontologenius/core/ontologyOperators/SparqlUtils.h @@ -166,6 +166,7 @@ namespace ontologenius { std::vector res; res.reserve(var_names.size()); for(const auto& var : var_names) + if(var.empty() == false) res.push_back(Resource_t::variables[var]); std::sort(res.begin(), res.end()); return res; From ac42b2b44a07385db94641a5a1e8d57442449e30 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Tue, 22 Oct 2024 14:10:39 +0200 Subject: [PATCH 04/49] [SparqlUtils] convertVariables allows varibale with ? symbol --- .../core/ontologyOperators/SparqlUtils.h | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/include/ontologenius/core/ontologyOperators/SparqlUtils.h b/include/ontologenius/core/ontologyOperators/SparqlUtils.h index fc563be7..ed2a8b57 100644 --- a/include/ontologenius/core/ontologyOperators/SparqlUtils.h +++ b/include/ontologenius/core/ontologyOperators/SparqlUtils.h @@ -1,6 +1,7 @@ #ifndef ONTOLOGENIUS_SPARQLUTILS_H #define ONTOLOGENIUS_SPARQLUTILS_H +#include #include #include #include @@ -167,7 +168,12 @@ namespace ontologenius { res.reserve(var_names.size()); for(const auto& var : var_names) if(var.empty() == false) - res.push_back(Resource_t::variables[var]); + { + if(var.front() == '?') + res.push_back(Resource_t::variables[var.substr(1)]); + else + res.push_back(Resource_t::variables[var]); + } std::sort(res.begin(), res.end()); return res; } @@ -181,17 +187,22 @@ namespace ontologenius { template void filter(std::vector>& res, const std::vector& vars, bool distinct) { + std::cout << "in filter map" << std::endl; if(vars.empty() == false) { if(vars[0] == "*") return; + std::cout << "start to filter" << std::endl; + for(auto& sub_res : res) { for(auto itr = sub_res.cbegin(); itr != sub_res.cend();) itr = (std::find(vars.begin(), vars.end(), "?" + itr->first) == vars.end()) ? sub_res.erase(itr) : std::next(itr); } + std::cout << "done" << std::endl; + if(distinct) removeDuplicate(res); } @@ -200,19 +211,34 @@ namespace ontologenius { template void filter(std::vector>& res, const std::vector& vars, bool distinct) { + std::cout << "in filter vector" << std::endl; if(vars.empty() == false) { if(vars[0] == "*") return; + for(auto& v : vars) + std::cout << "=> \'" << v << "\'" << std::endl; + std::vector var_index = convertVariables(vars); + for(auto& v : var_index) + std::cout << "-> \'" << v << "\'" << std::endl; + + std::cout << "var converted" << std::endl; + for(auto& sub_res : res) { + std::cout << "sub_res size = " << sub_res.size() << std::endl; + for(auto i : var_index) + std::cout << " - " << i << std::endl; + for(auto it = var_index.rbegin(); it != var_index.rend(); ++it) sub_res.erase(sub_res.begin() + *it); } + std::cout << "filtered done" << std::endl; + if(distinct) removeDuplicate(res); } From 3a26bb8abb1de03ac31cb9f6014a67b1204c64ac Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Tue, 22 Oct 2024 14:20:26 +0200 Subject: [PATCH 05/49] [SparqlUtils] fix filtering --- .../core/ontologyOperators/SparqlUtils.h | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/include/ontologenius/core/ontologyOperators/SparqlUtils.h b/include/ontologenius/core/ontologyOperators/SparqlUtils.h index ed2a8b57..f79817ae 100644 --- a/include/ontologenius/core/ontologyOperators/SparqlUtils.h +++ b/include/ontologenius/core/ontologyOperators/SparqlUtils.h @@ -1,8 +1,8 @@ #ifndef ONTOLOGENIUS_SPARQLUTILS_H #define ONTOLOGENIUS_SPARQLUTILS_H -#include #include +#include #include #include #include @@ -178,6 +178,21 @@ namespace ontologenius { return res; } + template + std::set convertVariables2Set(const std::vector& var_names) + { + std::set res; + for(const auto& var : var_names) + if(var.empty() == false) + { + if(var.front() == '?') + res.insert(Resource_t::variables[var.substr(1)]); + else + res.insert(Resource_t::variables[var]); + } + return res; + } + template void removeDuplicate(std::vector>& vect) { @@ -187,22 +202,17 @@ namespace ontologenius { template void filter(std::vector>& res, const std::vector& vars, bool distinct) { - std::cout << "in filter map" << std::endl; if(vars.empty() == false) { if(vars[0] == "*") return; - std::cout << "start to filter" << std::endl; - for(auto& sub_res : res) { for(auto itr = sub_res.cbegin(); itr != sub_res.cend();) itr = (std::find(vars.begin(), vars.end(), "?" + itr->first) == vars.end()) ? sub_res.erase(itr) : std::next(itr); } - std::cout << "done" << std::endl; - if(distinct) removeDuplicate(res); } @@ -211,34 +221,28 @@ namespace ontologenius { template void filter(std::vector>& res, const std::vector& vars, bool distinct) { - std::cout << "in filter vector" << std::endl; if(vars.empty() == false) { if(vars[0] == "*") return; - for(auto& v : vars) - std::cout << "=> \'" << v << "\'" << std::endl; - - std::vector var_index = convertVariables(vars); - - for(auto& v : var_index) - std::cout << "-> \'" << v << "\'" << std::endl; + std::set var_index = convertVariables2Set(vars); - std::cout << "var converted" << std::endl; + std::vector index_to_remove; + if(res.empty() == false) + { + auto front = res.front(); + for(int64_t i = 0; i < (int64_t)front.size(); i++) + if(var_index.find(i) == var_index.end()) + index_to_remove.push_back(i); + } for(auto& sub_res : res) { - std::cout << "sub_res size = " << sub_res.size() << std::endl; - for(auto i : var_index) - std::cout << " - " << i << std::endl; - - for(auto it = var_index.rbegin(); it != var_index.rend(); ++it) + for(auto it = index_to_remove.rbegin(); it != index_to_remove.rend(); ++it) sub_res.erase(sub_res.begin() + *it); } - std::cout << "filtered done" << std::endl; - if(distinct) removeDuplicate(res); } From 1aab6ab9cf3a5dfdd9845a1ec8205c2666768b32 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Tue, 22 Oct 2024 14:30:56 +0200 Subject: [PATCH 06/49] remove implicit inlines --- .../Branchs/RelationsWithInductions.h | 16 ++++++++-------- .../core/ontoGraphs/Branchs/ValuedNode.h | 2 +- .../core/ontoGraphs/Branchs/WordTable.h | 12 ++++++------ .../core/ontoGraphs/Graphs/Graph.h | 18 +++++++++--------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/ontologenius/core/ontoGraphs/Branchs/RelationsWithInductions.h b/include/ontologenius/core/ontoGraphs/Branchs/RelationsWithInductions.h index c7312a48..3214e2a2 100644 --- a/include/ontologenius/core/ontoGraphs/Branchs/RelationsWithInductions.h +++ b/include/ontologenius/core/ontoGraphs/Branchs/RelationsWithInductions.h @@ -28,8 +28,8 @@ namespace ontologenius { RelationsWithInductions(const RelationsWithInductions& other) = delete; ~RelationsWithInductions() { clear(); } - inline size_t size() const { return relations.size(); } - inline bool empty() const { return relations.empty(); } + size_t size() const { return relations.size(); } + bool empty() const { return relations.empty(); } T& operator[](size_t index) { return relations[index]; } size_t pushBack(T& relation) @@ -74,12 +74,12 @@ namespace ontologenius { return std::find(relations.begin(), relations.end(), other); } - inline typename std::vector::iterator begin() { return relations.begin(); } - inline typename std::vector::iterator end() { return relations.end(); } - inline typename std::vector::const_iterator cbegin() const { return relations.cbegin(); } - inline typename std::vector::const_iterator cend() const { return relations.cend(); } - inline typename std::vector::reverse_iterator rbegin() { return relations.rbegin(); } - inline typename std::vector::reverse_iterator rend() { return relations.rend(); } + typename std::vector::iterator begin() { return relations.begin(); } + typename std::vector::iterator end() { return relations.end(); } + typename std::vector::const_iterator cbegin() const { return relations.cbegin(); } + typename std::vector::const_iterator cend() const { return relations.cend(); } + typename std::vector::reverse_iterator rbegin() { return relations.rbegin(); } + typename std::vector::reverse_iterator rend() { return relations.rend(); } }; } // namespace ontologenius diff --git a/include/ontologenius/core/ontoGraphs/Branchs/ValuedNode.h b/include/ontologenius/core/ontoGraphs/Branchs/ValuedNode.h index b39e4554..26e9ba81 100644 --- a/include/ontologenius/core/ontoGraphs/Branchs/ValuedNode.h +++ b/include/ontologenius/core/ontoGraphs/Branchs/ValuedNode.h @@ -42,7 +42,7 @@ namespace ontologenius { Dictionary steady_dictionary_; template - inline void conditionalPushBack(std::vector& vect, const C& data) + void conditionalPushBack(std::vector& vect, const C& data) { if(std::find(vect.begin(), vect.end(), data) == vect.end()) vect.push_back(data); diff --git a/include/ontologenius/core/ontoGraphs/Branchs/WordTable.h b/include/ontologenius/core/ontoGraphs/Branchs/WordTable.h index f43e842a..bb99128f 100644 --- a/include/ontologenius/core/ontoGraphs/Branchs/WordTable.h +++ b/include/ontologenius/core/ontoGraphs/Branchs/WordTable.h @@ -18,34 +18,34 @@ namespace ontologenius { table_.emplace_back(""); // index 0 is reserved for the "no result index" } - inline index_t add(const std::string& value) + index_t add(const std::string& value) { table_.push_back(value); return (index_t)table_.size() - 1; } - inline std::string& get(index_t index) + std::string& get(index_t index) { return table_[index]; } - inline std::string& operator[](index_t index) + std::string& operator[](index_t index) { return table_[index]; } - inline const std::string& operator[](index_t index) const + const std::string& operator[](index_t index) const { return table_[index]; } - inline void index2string(std::unordered_set& res, const std::unordered_set& base) + void index2string(std::unordered_set& res, const std::unordered_set& base) { for(index_t i : base) res.insert(table_[i]); } - inline size_t size() const + size_t size() const { return table_.size(); } diff --git a/include/ontologenius/core/ontoGraphs/Graphs/Graph.h b/include/ontologenius/core/ontoGraphs/Graphs/Graph.h index 0dc68642..b547ef6b 100644 --- a/include/ontologenius/core/ontoGraphs/Graphs/Graph.h +++ b/include/ontologenius/core/ontoGraphs/Graphs/Graph.h @@ -104,7 +104,7 @@ namespace ontologenius { // use std::lock_guard lock(mutex_); to WRITE A DATA // use std::shared_lock lock(mutex_); to READ A DATA - inline void removeFromDictionary(std::map>& dictionary, const std::string& lang, const std::string& word) + void removeFromDictionary(std::map>& dictionary, const std::string& lang, const std::string& word) { if(dictionary.find(lang) != dictionary.end()) { @@ -117,7 +117,7 @@ namespace ontologenius { } template - inline void removeFromVect(std::vector& vect, const T& value) + void removeFromVect(std::vector& vect, const T& value) { for(size_t i = 0; i < vect.size();) if(vect[i] == value) @@ -127,7 +127,7 @@ namespace ontologenius { } template - inline void removeFromElemVect(std::vector>& vect, const T& value) + void removeFromElemVect(std::vector>& vect, const T& value) { for(size_t i = 0; i < vect.size();) if(vect[i].elem == value) @@ -137,7 +137,7 @@ namespace ontologenius { } template - inline void removeFromElemVect(RelationsWithInductions>& vect, const T& value) + void removeFromElemVect(RelationsWithInductions>& vect, const T& value) { for(size_t i = 0; i < vect.size();) if(vect[i].elem == value) @@ -147,7 +147,7 @@ namespace ontologenius { } template - inline void getInMap(T** ptr, const std::string& name, std::map& map) + void getInMap(T** ptr, const std::string& name, std::map& map) { if(*ptr != nullptr) return; @@ -158,7 +158,7 @@ namespace ontologenius { } template - inline bool conditionalPushBack(std::vector& vect, const C& data) + bool conditionalPushBack(std::vector& vect, const C& data) { if(std::find(vect.begin(), vect.end(), data) == vect.end()) { @@ -170,7 +170,7 @@ namespace ontologenius { } template - inline bool conditionalPushBack(RelationsWithInductions& vect, const C& data) + bool conditionalPushBack(RelationsWithInductions& vect, const C& data) { if(std::find(vect.begin(), vect.end(), data) == vect.end()) { @@ -182,7 +182,7 @@ namespace ontologenius { } template - inline bool conditionalPushBack(std::vector>& vect, const SingleElement& data) + bool conditionalPushBack(std::vector>& vect, const SingleElement& data) { auto it = std::find(vect.begin(), vect.end(), data); if(it == vect.end()) @@ -197,7 +197,7 @@ namespace ontologenius { } template - inline bool conditionalPushBack(RelationsWithInductions>& vect, const SingleElement& data) + bool conditionalPushBack(RelationsWithInductions>& vect, const SingleElement& data) { auto it = std::find(vect.begin(), vect.end(), data); if(it == vect.end()) From 3dc9ee76e94f480f4a98a5e1feda3f2a926a9f6d Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 15:39:49 +0200 Subject: [PATCH 07/49] [ClientBase] remove implicit inline --- .../ontologenius/API/ontologenius/clients/ClientBase.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/ontologenius/API/ontologenius/clients/ClientBase.h b/include/ontologenius/API/ontologenius/clients/ClientBase.h index 10ca66f7..12d9cc15 100644 --- a/include/ontologenius/API/ontologenius/clients/ClientBase.h +++ b/include/ontologenius/API/ontologenius/clients/ClientBase.h @@ -50,7 +50,7 @@ namespace onto { /// @param action the query action. /// @param param the query parameters. /// @return Returns a list of string. If the service call fails, the first element of the returned vector is "ERR:SERVICE_FAIL". - inline std::vector call(const std::string& action, const std::string& param, int16_t& code = ignore) + std::vector call(const std::string& action, const std::string& param, int16_t& code = ignore) { cpt++; @@ -96,7 +96,7 @@ namespace onto { /// @param action the query action. /// @param param the query parameters. /// @return Returns a single string. If the service call fails, the returned value is "ERR:SERVICE_FAIL". - inline std::string callStr(const std::string& action, const std::string& param, int16_t& code = ignore) + std::string callStr(const std::string& action, const std::string& param, int16_t& code = ignore) { auto res = this->call(action, param, code); return res.empty() ? "" : res[0]; @@ -106,7 +106,7 @@ namespace onto { /// @param action the query action. /// @param param the query parameters. /// @return Returns false if the service call fails. - inline bool callNR(const std::string& action, const std::string& param) + bool callNR(const std::string& action, const std::string& param) { return this->callStr(action, param) != "ERR:SERVICE_FAIL"; } @@ -115,7 +115,7 @@ namespace onto { /// @param action the query action. /// @param param the query parameters. /// @return Returns false if the service call fails or the result code of the service is different from SUCCESS. - inline bool callBool(const std::string& action, const std::string& param) + bool callBool(const std::string& action, const std::string& param) { int16_t code = 0; auto res = this->callStr(action, param, code); From 56ab99a793c4ecae5448bf623ccb5701e17171cc Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 15:40:17 +0200 Subject: [PATCH 08/49] add subscription srv and msg --- CMakeLists.txt | 6 ++++++ include/ontologenius/compat/ros.h | 6 ++++++ msg/OntologeniusSubscriptionAnswer.msg | 3 +++ srv/OntologeniusSubscription.srv | 4 ++++ srv/OntologeniusUnsubscription.srv | 3 +++ 5 files changed, 22 insertions(+) create mode 100644 msg/OntologeniusSubscriptionAnswer.msg create mode 100644 srv/OntologeniusSubscription.srv create mode 100644 srv/OntologeniusUnsubscription.srv diff --git a/CMakeLists.txt b/CMakeLists.txt index 9652c5a4..2272b28f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,7 @@ if($ENV{ROS_VERSION} STREQUAL "1") OntologeniusSparqlResponse.msg OntologeniusSparqlIndexResponse.msg OntologeniusExplanation.msg + OntologeniusSubscriptionAnswer.msg ) # # Generate services in the 'srv' folder @@ -89,6 +90,8 @@ if($ENV{ROS_VERSION} STREQUAL "1") OntologeniusIndexService.srv OntologeniusSparqlService.srv OntologeniusSparqlIndexService.srv + OntologeniusSubscription.srv + OntologeniusUnsubscription.srv ) # # Generate added messages and services with any dependencies listed here @@ -103,11 +106,14 @@ elseif($ENV{ROS_VERSION} STREQUAL "2") "msg/OntologeniusSparqlIndexResponse.msg" "msg/OntologeniusSparqlResponse.msg" "msg/OntologeniusStampedString.msg" + "msg/OntologeniusSubscriptionAnswer.msg" "srv/OntologeniusConversion.srv" "srv/OntologeniusIndexService.srv" "srv/OntologeniusService.srv" "srv/OntologeniusSparqlIndexService.srv" "srv/OntologeniusSparqlService.srv" + "srv/OntologeniusSubscription.srv" + "srv/OntologeniusUnsubscription.srv" DEPENDENCIES builtin_interfaces std_msgs) endif() diff --git a/include/ontologenius/compat/ros.h b/include/ontologenius/compat/ros.h index 263b1ee2..7af9758c 100644 --- a/include/ontologenius/compat/ros.h +++ b/include/ontologenius/compat/ros.h @@ -13,6 +13,7 @@ #include #include #include +#include #include // User-defined service interfaces @@ -21,6 +22,8 @@ #include #include #include +#include +#include namespace std_msgs_compat = std_msgs; @@ -35,6 +38,7 @@ namespace std_msgs_compat = std_msgs; #include #include #include +#include #include // User-defined service interfaces @@ -43,6 +47,8 @@ namespace std_msgs_compat = std_msgs; #include #include #include +#include +#include namespace std_msgs_compat = std_msgs::msg; diff --git a/msg/OntologeniusSubscriptionAnswer.msg b/msg/OntologeniusSubscriptionAnswer.msg new file mode 100644 index 00000000..262c694c --- /dev/null +++ b/msg/OntologeniusSubscriptionAnswer.msg @@ -0,0 +1,3 @@ +int32 id +string data +bool last diff --git a/srv/OntologeniusSubscription.srv b/srv/OntologeniusSubscription.srv new file mode 100644 index 00000000..e052af57 --- /dev/null +++ b/srv/OntologeniusSubscription.srv @@ -0,0 +1,4 @@ +string data +int32 count +--- +int32 id diff --git a/srv/OntologeniusUnsubscription.srv b/srv/OntologeniusUnsubscription.srv new file mode 100644 index 00000000..e62eb05d --- /dev/null +++ b/srv/OntologeniusUnsubscription.srv @@ -0,0 +1,3 @@ +int32 id +--- +int32 id From 0eeb133bbdb227a0cb055781c944ea482d2e7d6d Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 15:40:31 +0200 Subject: [PATCH 09/49] [Triplet] add TripletStr_t --- .../core/ontoGraphs/Branchs/Triplet.h | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/include/ontologenius/core/ontoGraphs/Branchs/Triplet.h b/include/ontologenius/core/ontoGraphs/Branchs/Triplet.h index bf17ae27..a9a32a2d 100644 --- a/include/ontologenius/core/ontoGraphs/Branchs/Triplet.h +++ b/include/ontologenius/core/ontoGraphs/Branchs/Triplet.h @@ -2,10 +2,48 @@ #define ONTOLOGENIUS_TRIPLET_H #include +#include #include namespace ontologenius { + struct TripletStr_t + { + TripletStr_t(const std::string& subject, + const std::string& predicat, + const std::string& object, + bool add = true) : subject(subject), + predicate(predicat), + object(object), + add(add) + {} + + bool operator==(const TripletStr_t& other) const + { + return ((subject == other.subject) && + (predicate == other.predicate) && + (object == other.object) && + (add == other.add)); + } + + bool valid() const + { + return ((subject.empty() == false) && + (predicate.empty() == false) && + (object.empty() == false)); + } + + std::string toString() const + { + return (add ? "[add]" : "[del]") + subject + "|" + predicate + "|" + object; + } + + std::string subject; + std::string predicate; + std::string object; + bool add; + }; + template struct Triplet_t { From 0170bc1aba2e13ef845c63ea3166451905938b0d Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 15:40:45 +0200 Subject: [PATCH 10/49] [OntoGraph] add isA method --- .../ontologenius/core/ontoGraphs/Graphs/OntoGraph.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h b/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h index 04c12dc3..65df1ff3 100644 --- a/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h +++ b/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h @@ -37,6 +37,9 @@ namespace ontologenius { template std::unordered_set getUpId(const T& value, int depth = -1); + template + bool isA(const T& branch, const T& selector); + template bool existInInheritance(B* branch, const T& selector); @@ -215,6 +218,15 @@ namespace ontologenius { } } + template + template + bool OntoGraph::isA(const T& branch, const T& selector) + { + std::shared_lock lock(Graph::mutex_); + auto* b = this->findBranch(branch); + return existInInheritance(b, selector); + } + template template bool OntoGraph::existInInheritance(B* branch, const T& selector) From 26f6a29e41131fb5097e23f35aa8d31998f2a1c9 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 15:40:57 +0200 Subject: [PATCH 11/49] add subscription mechanism --- CMakeLists.txt | 29 +++- .../core/subscription/IdManager.h | 62 +++++++ .../core/subscription/Subscription.h | 46 +++++ .../core/subscription/SubscriptionManager.h | 56 ++++++ .../core/subscription/SubscriptionPattern.h | 126 ++++++++++++++ include/ontologenius/interface/RosInterface.h | 3 + .../ontoGraphs/Graphs/IndividualGraph.cpp | 1 + src/core/subscription/Subscription.cpp | 162 ++++++++++++++++++ src/core/subscription/SubscriptionManager.cpp | 116 +++++++++++++ src/core/subscription/SubscriptionPattern.cpp | 11 ++ src/interface/RosInterface.cpp | 13 +- 11 files changed, 616 insertions(+), 9 deletions(-) create mode 100644 include/ontologenius/core/subscription/IdManager.h create mode 100644 include/ontologenius/core/subscription/Subscription.h create mode 100644 include/ontologenius/core/subscription/SubscriptionManager.h create mode 100644 include/ontologenius/core/subscription/SubscriptionPattern.h create mode 100644 src/core/subscription/Subscription.cpp create mode 100644 src/core/subscription/SubscriptionManager.cpp create mode 100644 src/core/subscription/SubscriptionPattern.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2272b28f..20f70bf7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,7 +237,7 @@ function(add_ros_library TARGET) if($ENV{ROS_VERSION} STREQUAL "1") add_dependencies(${TARGET} ontologenius_gencpp ${catkin_EXPORTED_TARGETS}) - target_include_directories(${TARGET} PUBLIC + target_include_directories(${TARGET} PUBLIC $ $ ${catkin_INCLUDE_DIRS}) @@ -334,6 +334,18 @@ target_link_libraries(ontologenius_lib ontologenius_plugin_lib ) # ontologenius_interface +# # SUBSCRIPTION +add_ros_library(ontologenius_subscription_lib + src/core/subscription/Subscription.cpp + src/core/subscription/SubscriptionManager.cpp + src/core/subscription/SubscriptionPattern.cpp +) +target_link_libraries(ontologenius_subscription_lib + PUBLIC + ontologenius_compat + ontologenius_ontoGraphs_lib +) + # # INTERFACE add_ros_library(ontologenius_interface src/interface/RosInterface.cpp @@ -346,6 +358,7 @@ target_link_libraries(ontologenius_interface ontologenius_feeder_lib ontologenius_plugin_lib ontologenius_operators + ontologenius_subscription_lib ) # ################################## @@ -476,13 +489,13 @@ if($ENV{ROS_VERSION} STREQUAL "1") # Generate CMake package config file include(CMakePackageConfigHelpers) configure_package_config_file( - cmake/ontologenius_compatConfigIntermediate.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/ontologenius_compatConfigIntermediate.cmake - INSTALL_DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake + cmake/ontologenius_compatConfigIntermediate.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/ontologenius_compatConfigIntermediate.cmake + INSTALL_DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake ) install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/ontologenius_compatConfigIntermediate.cmake - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake + FILES ${CMAKE_CURRENT_BINARY_DIR}/ontologenius_compatConfigIntermediate.cmake + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake ) install( @@ -497,7 +510,7 @@ if($ENV{ROS_VERSION} STREQUAL "1") EXPORT ontologenius_compatTargets FILE ontologenius_compatTargets.cmake NAMESPACE ontologenius:: - DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake + DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake ) install(TARGETS @@ -516,6 +529,7 @@ if($ENV{ROS_VERSION} STREQUAL "1") ontologenius_plugin_lib ontologenius_ontoGraphs_lib ontologenius_reasoner_plugin + ontologenius_subscription_lib ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} @@ -559,6 +573,7 @@ elseif($ENV{ROS_VERSION} STREQUAL "2") ontologenius_feeder_lib ontologenius_plugin_lib ontologenius_ontoGraphs_lib + ontologenius_subscription_lib ontologenius_reasoner_plugin EXPORT ontologenius ARCHIVE DESTINATION lib diff --git a/include/ontologenius/core/subscription/IdManager.h b/include/ontologenius/core/subscription/IdManager.h new file mode 100644 index 00000000..b044c2ff --- /dev/null +++ b/include/ontologenius/core/subscription/IdManager.h @@ -0,0 +1,62 @@ +#ifndef ONTOLOGENIUS_IDMANAGER_H +#define ONTOLOGENIUS_IDMANAGER_H + +#include + +namespace ontologenius { + + template + class IdManager + { + static_assert(std::is_integral::value, "TInteger must be an integral type"); + + public: + IdManager(); + + TInteger getNewId(); + bool removeId(TInteger id); + + std::set getIds() { return ids_; } + + private: + TInteger current_id_; + std::set ids_; + }; + + template + IdManager::IdManager() : current_id_(0) + {} + + template + TInteger IdManager::getNewId() + { + while(ids_.find(current_id_) != ids_.end()) + current_id_++; + + ids_.insert(current_id_); + + TInteger res = current_id_; + current_id_++; + + return (res); + } + + template + bool IdManager::removeId(TInteger id) + { + auto it = ids_.find(id); + if(it == ids_.end()) + return false; + else + { + ids_.erase(it); + if(id < current_id_) + current_id_ = id; + + return true; + } + } + +} // namespace ontologenius + +#endif // ONTOLOGENIUS_IDMANAGER_H diff --git a/include/ontologenius/core/subscription/Subscription.h b/include/ontologenius/core/subscription/Subscription.h new file mode 100644 index 00000000..a0d199a2 --- /dev/null +++ b/include/ontologenius/core/subscription/Subscription.h @@ -0,0 +1,46 @@ +#ifndef ONTOLOGENIUS_SUBSCRIPTION_H +#define ONTOLOGENIUS_SUBSCRIPTION_H + +#include +#include +#include +#include + +#include "ontologenius/core/ontoGraphs/Branchs/Triplet.h" +#include "ontologenius/core/ontoGraphs/Ontology.h" +#include "ontologenius/core/subscription/IdManager.h" +#include "ontologenius/core/subscription/SubscriptionPattern.h" + +namespace ontologenius { + + class Subscription + { + public: + Subscription(Ontology* onto = nullptr) : onto_(onto) {} + + void link(Ontology* onto) { onto_ = onto; } + + size_t subscribe(const SubscriptionPattern& patern, size_t count); + bool unsubscribe(int id); + + bool isFinished(size_t id); + bool empty() { return paterns_.empty(); } + + std::vector evaluate(const TripletStr_t& triplet); + + private: + std::map paterns_; + std::map counts_; + std::mutex map_mut_; + + IdManager id_manager_; + + Ontology* onto_; + + SubscriptionPattern refinePattern(const SubscriptionPattern& triplet); + bool compareToTriplet(const SubscriptionPattern& pattern, const TripletStr_t& triplet); + }; + +} // namespace ontologenius + +#endif // ONTOLOGENIUS_SUBSCRIPTION_H diff --git a/include/ontologenius/core/subscription/SubscriptionManager.h b/include/ontologenius/core/subscription/SubscriptionManager.h new file mode 100644 index 00000000..983e045c --- /dev/null +++ b/include/ontologenius/core/subscription/SubscriptionManager.h @@ -0,0 +1,56 @@ +#ifndef ONTOLOGENIUS_SUBSCRIPTIONMANAGER_H +#define ONTOLOGENIUS_SUBSCRIPTIONMANAGER_H + +#include +#include +#include +#include +#include + +#include "ontologenius/compat/ros.h" +#include "ontologenius/core/ontoGraphs/Branchs/Triplet.h" +#include "ontologenius/core/ontoGraphs/Ontology.h" +#include "ontologenius/core/subscription/Subscription.h" + +namespace ontologenius { + + class SubscriptionManager + { + public: + explicit SubscriptionManager(const std::string& name = ""); + + void link(Ontology* onto) { subscription_.link(onto); } + + void run(); + + void add(const TripletStr_t& triplet); + void add(const std::string& triplet_str); + void add(const std::vector>& explanations); + + void stop() { run_ = false; } + bool isRunning() const { return run_; } + + private: + Subscription subscription_; + std::atomic run_; + + compat::onto_ros::Publisher pub_; + compat::onto_ros::Service sub_service_; + compat::onto_ros::Service unsub_service_; + + std::mutex mutex_; + std::queue triplets_; + + bool subscribeCallback(compat::onto_ros::ServiceWrapper& req, + compat::onto_ros::ServiceWrapper& res); + + bool unsubscribeCallback(compat::onto_ros::ServiceWrapper& req, + compat::onto_ros::ServiceWrapper& res); + + TripletStr_t get(); + bool empty(); + }; + +} // namespace ontologenius + +#endif // ONTOLOGENIUS_SUBSCRIPTIONMANAGER_H diff --git a/include/ontologenius/core/subscription/SubscriptionPattern.h b/include/ontologenius/core/subscription/SubscriptionPattern.h new file mode 100644 index 00000000..5911939f --- /dev/null +++ b/include/ontologenius/core/subscription/SubscriptionPattern.h @@ -0,0 +1,126 @@ +#ifndef ONTOLOGENIUS_SUBSCRIPTIONPATTERN_H +#define ONTOLOGENIUS_SUBSCRIPTIONPATTERN_H + +#include +#include + +#include "ontologenius/core/ontoGraphs/Branchs/Triplet.h" + +namespace ontologenius { + + class SubscriptionPattern + { + public: + SubscriptionPattern(const std::string& subject, + const std::string& predicat, + const std::string& object, + bool add) : triplet_(subject, predicat, object, add), + operator_is_undefined_(false) + { + init(); + } + + SubscriptionPattern(const std::string& subject, + const std::string& predicat, + const std::string& object) : triplet_(subject, predicat, object, true), + operator_is_undefined_(true) + + { + init(); + } + + explicit SubscriptionPattern(const TripletStr_t& triplet) : triplet_(triplet), + operator_is_undefined_(false) + { + init(); + } + + SubscriptionPattern(const SubscriptionPattern& other) = default; + + static SubscriptionPattern deserialize(const std::string& str) + { + if(std::regex_match(str, match, regex)) + { + if(match[1].str() == "?") + return SubscriptionPattern(match[2].str(), match[3].str(), match[4].str()); + else + return SubscriptionPattern(match[2].str(), match[3].str(), match[4].str(), match[1].str() == "A"); + } + else if(std::regex_match(str, match, regex2)) + { + if(match[1].str() == "?") + return SubscriptionPattern(match[2].str(), match[3].str(), match[4].str()); + else + return SubscriptionPattern(match[2].str(), match[3].str(), match[4].str(), (match[1].str() == "ADD") || (match[1].str() == "add")); + } + else + return SubscriptionPattern(TripletStr_t("", "", "")); // invalid triplet + } + + bool fit(const TripletStr_t& other) const + { + return (((triplet_.add == other.add) || operator_is_undefined_) && + ((triplet_.subject == other.subject) || subject_is_undefined_) && + ((triplet_.predicate == other.predicate) || predicat_is_undefined_) && + ((triplet_.object == other.object) || object_is_undefined_)); + } + + void setSubjectAsClass() { subject_is_indiv_ = false; } + void setSubjectAsIndividual() { subject_is_indiv_ = true; } + void setObjectAsClass() { object_is_indiv_ = false; } + void setObjectAsIndividual() { object_is_indiv_ = true; } + void setPredicatAsDataProperty() { predicat_is_object_property_ = false; } + void setPredicatAsObjectProperty() { predicat_is_object_property_ = true; } + + bool isSubjectClass() const { return !subject_is_indiv_; } + bool isSubjectIndividual() const { return subject_is_indiv_; } + bool isObjectClass() const { return !object_is_indiv_; } + bool isObjectIndividual() const { return object_is_indiv_; } + bool isPredicatDataProperty() const { return !predicat_is_object_property_; } + bool isPredicatObjectProperty() const { return predicat_is_object_property_; } + + bool isOperatorUndefined() const { return operator_is_undefined_; } + bool isSubjectUndefined() const { return subject_is_undefined_; } + bool isObjectUndefined() const { return object_is_undefined_; } + bool isPredicatUndefined() const { return predicat_is_undefined_; } + + bool add() const { return triplet_.add; } + const std::string& subject() const { return triplet_.subject; } + const std::string& predicate() const { return triplet_.predicate; } + const std::string& object() const { return triplet_.object; } + const TripletStr_t& getTriplet() const { return triplet_; } + + bool valid() const { return triplet_.valid(); } + + protected: + TripletStr_t triplet_; + + bool subject_is_indiv_; + bool object_is_indiv_; + bool predicat_is_object_property_; + + bool operator_is_undefined_; + bool subject_is_undefined_; + bool object_is_undefined_; + bool predicat_is_undefined_; + + static std::regex regex; + static std::regex regex2; + static std::smatch match; + + private: + void init() + { + subject_is_indiv_ = true; + object_is_indiv_ = true; + predicat_is_object_property_ = true; + + subject_is_undefined_ = (triplet_.subject == "?"); + object_is_undefined_ = (triplet_.object == "?"); + predicat_is_undefined_ = (triplet_.predicate == "?"); + } + }; + +} // namespace ontologenius + +#endif // ONTOLOGENIUS_SUBSCRIPTIONPATTERN_H diff --git a/include/ontologenius/interface/RosInterface.h b/include/ontologenius/interface/RosInterface.h index 677e67b5..c5d60922 100644 --- a/include/ontologenius/interface/RosInterface.h +++ b/include/ontologenius/interface/RosInterface.h @@ -14,6 +14,7 @@ #include "ontologenius/core/ontoGraphs/Ontology.h" #include "ontologenius/core/ontologyOperators/Sparql.h" #include "ontologenius/core/reasoner/Reasoners.h" +#include "ontologenius/core/subscription/SubscriptionManager.h" // #define ONTO_TEST @@ -82,6 +83,8 @@ namespace ontologenius { Reasoners reasoners_; /// @brief Analyses incoming statements and manage the versioning system Feeder feeder_; + /// @brief Allows subscription to triplets patterns + SubscriptionManager subscriber_; /// @brief Republishs the incoming statement and the deduced once FeederEcho feeder_echo_; /// @brief Resolves SPARQL queries. diff --git a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp index fd2dccde..0bc25d37 100644 --- a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp +++ b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/src/core/subscription/Subscription.cpp b/src/core/subscription/Subscription.cpp new file mode 100644 index 00000000..cdff6d5a --- /dev/null +++ b/src/core/subscription/Subscription.cpp @@ -0,0 +1,162 @@ +#include "ontologenius/core/subscription/Subscription.h" + +#include +#include +#include + +#include "ontologenius/core/ontoGraphs/Branchs/Triplet.h" +#include "ontologenius/core/subscription/SubscriptionPattern.h" + +namespace ontologenius { + + size_t Subscription::subscribe(const SubscriptionPattern& patern, size_t count) + { + map_mut_.lock(); + size_t id = id_manager_.getNewId(); + paterns_.insert(std::pair(id, refinePattern(patern))); + counts_[id] = count; + map_mut_.unlock(); + + return id; + } + + bool Subscription::unsubscribe(int id) + { + bool res = true; + map_mut_.lock(); + if(id != -1) + { + if(id_manager_.removeId(id)) + { + paterns_.erase(id); + counts_.erase(id); + } + else + res = false; + } + else + { + auto ids = id_manager_.getIds(); + for(auto id_to_remove : ids) + { + if(id_manager_.removeId(id_to_remove)) + { + paterns_.erase(id_to_remove); + counts_.erase(id_to_remove); + } + else + res = false; + } + } + + map_mut_.unlock(); + return res; + } + + bool Subscription::isFinished(size_t id) + { + bool res = true; + + map_mut_.lock(); + if(counts_.find(id) != counts_.end()) + res = (counts_[id] == 0); + map_mut_.unlock(); + + return res; + } + + std::vector Subscription::evaluate(const TripletStr_t& triplet) + { + std::vector res; + + map_mut_.lock(); + for(auto& it : paterns_) + { + if(compareToTriplet(it.second, triplet)) + { + if(counts_[it.first] != 0) + { + res.push_back(it.first); + counts_[it.first]--; + } + } + } + map_mut_.unlock(); + + return res; + } + + SubscriptionPattern Subscription::refinePattern(const SubscriptionPattern& triplet) + { + SubscriptionPattern pattern = triplet; + if(onto_ != nullptr) + { + if(pattern.isSubjectUndefined() == false) + if(onto_->class_graph_.getUp(triplet.subject()).empty() == false) + pattern.setSubjectAsClass(); + if(pattern.isObjectUndefined() == false) + if(onto_->class_graph_.getUp(triplet.object()).empty() == false) + pattern.setObjectAsClass(); + if(pattern.isPredicatUndefined() == false) + if(onto_->data_property_graph_.getUp(triplet.predicate()).empty() == false) + pattern.setPredicatAsDataProperty(); + } + + return pattern; + } + + bool Subscription::compareToTriplet(const SubscriptionPattern& pattern, const TripletStr_t& triplet) + { + if(onto_ == nullptr) + return pattern.fit(triplet); + + if(!pattern.isOperatorUndefined()) + if(pattern.add() != triplet.add) + return false; + + if(pattern.isSubjectIndividual() && !pattern.isSubjectUndefined()) + { + if(pattern.subject() != triplet.subject) + return false; + } + + if(pattern.isObjectIndividual() && !pattern.isObjectUndefined()) + { + if(pattern.object() != triplet.object) + return false; + } + + if(pattern.isSubjectIndividual() == false) + { + if(onto_->individual_graph_.isA(triplet.subject, pattern.subject()) == false) + return false; + } + // subject match + + if(pattern.isObjectIndividual() == false) + { + if((onto_->individual_graph_.isA(triplet.object, pattern.object()) == false) && + (onto_->class_graph_.isA(triplet.object, pattern.object()) == false)) + return false; + } + // object match + + if((pattern.predicate() != triplet.predicate) && !pattern.isPredicatUndefined()) + { + if(pattern.isPredicatObjectProperty()) + { + if(onto_->object_property_graph_.isA(triplet.predicate, pattern.predicate()) == false) + return false; + } + else + { + if(onto_->data_property_graph_.isA(triplet.predicate, pattern.predicate()) == false) + return false; + } + } + // predicat match + + return true; + } + +} // namespace ontologenius diff --git a/src/core/subscription/SubscriptionManager.cpp b/src/core/subscription/SubscriptionManager.cpp new file mode 100644 index 00000000..6593b180 --- /dev/null +++ b/src/core/subscription/SubscriptionManager.cpp @@ -0,0 +1,116 @@ +#include "ontologenius/core/subscription/SubscriptionManager.h" + +#include +#include +#include +#include + +#include "ontologenius/compat/ros.h" +#include "ontologenius/core/ontoGraphs/Branchs/Triplet.h" +#include "ontologenius/core/ontoGraphs/Ontology.h" +#include "ontologenius/core/subscription/SubscriptionPattern.h" + +namespace ontologenius { + + SubscriptionManager::SubscriptionManager(const std::string& name) : run_(false), + pub_((name.empty()) ? "ontologenius/subscription_answer" : "ontologenius/subscription_answer/" + name, 1000), + sub_service_(name.empty() ? "ontologenius/subscribe" : "ontologenius/subscribe/" + name, &SubscriptionManager::subscribeCallback, this), + unsub_service_(name.empty() ? "ontologenius/unsubscribe" : "ontologenius/unsubscribe/" + name, &SubscriptionManager::unsubscribeCallback, this) + { + } + + void SubscriptionManager::run() + { + run_ = true; + compat::onto_ros::Rate r(50); + + while(compat::onto_ros::Node::ok() && isRunning()) + { + while(empty() == false) + { + TripletStr_t triplet = get(); + if(triplet.valid()) + { + std::vector ids = subscription_.evaluate(triplet); + for(auto id : ids) + { + compat::OntologeniusSubscriptionAnswer msg; + msg.id = (int)id; + msg.data = triplet.toString(); + msg.last = subscription_.isFinished(id); + if(msg.last) + subscription_.unsubscribe((int)id); + pub_.publish(msg); + } + } + } + r.sleep(); + } + } + + void SubscriptionManager::add(const TripletStr_t& triplet) + { + std::lock_guard lock(mutex_); + triplets_.push(triplet); + } + + void SubscriptionManager::add(const std::string& triplet_str) + { + std::lock_guard lock(mutex_); + auto pattern(SubscriptionPattern::deserialize(triplet_str)); + triplets_.push(pattern.getTriplet()); + } + + void SubscriptionManager::add(const std::vector>& explanations) + { + std::lock_guard lock(mutex_); + for(auto& expl : explanations) + { + auto pattern(SubscriptionPattern::deserialize(expl.first)); + triplets_.push(pattern.getTriplet()); + } + } + + bool SubscriptionManager::subscribeCallback(compat::onto_ros::ServiceWrapper& req, + compat::onto_ros::ServiceWrapper& res) + { + return [this](auto&& req, auto&& res) { + auto pattern = SubscriptionPattern::deserialize(req->data); + + if(pattern.valid() == false) + return false; + + res->id = subscription_.subscribe(pattern, req->count); + + return true; + }(compat::onto_ros::getServicePointer(req), compat::onto_ros::getServicePointer(res)); + } + + bool SubscriptionManager::unsubscribeCallback(compat::onto_ros::ServiceWrapper& req, + compat::onto_ros::ServiceWrapper& res) + { + return [this](auto&& req, auto&& res) { + if(subscription_.unsubscribe(req->id)) + res->id = req->id; + else + res->id = -1; + + return true; + }(compat::onto_ros::getServicePointer(req), compat::onto_ros::getServicePointer(res)); + } + + TripletStr_t SubscriptionManager::get() + { + std::lock_guard lock(mutex_); + TripletStr_t res(triplets_.front()); + triplets_.pop(); + return res; + } + + bool SubscriptionManager::empty() + { + std::lock_guard lock(mutex_); + return triplets_.empty(); + } + +} // namespace ontologenius diff --git a/src/core/subscription/SubscriptionPattern.cpp b/src/core/subscription/SubscriptionPattern.cpp new file mode 100644 index 00000000..91b4050b --- /dev/null +++ b/src/core/subscription/SubscriptionPattern.cpp @@ -0,0 +1,11 @@ +#include "ontologenius/core/subscription/SubscriptionPattern.h" + +#include + +namespace ontologenius { + + std::regex SubscriptionPattern::regex(R"((\w)\|(\w+)\|(\w+)\|(\w+))"); + std::regex SubscriptionPattern::regex2(R"(\[([^\]]+)\]([^|]+)\|([^|]+)\|([^|]+))"); + std::smatch SubscriptionPattern::match; + +} // namespace ontologenius diff --git a/src/interface/RosInterface.cpp b/src/interface/RosInterface.cpp index f0613561..78aabbe4 100644 --- a/src/interface/RosInterface.cpp +++ b/src/interface/RosInterface.cpp @@ -10,6 +10,7 @@ #include "ontologenius/compat/ros.h" #include "ontologenius/core/ontoGraphs/Ontology.h" +#include "ontologenius/core/subscription/SubscriptionManager.h" #include "ontologenius/core/utility/error_code.h" #include "ontologenius/graphical/Display.h" @@ -43,6 +44,7 @@ namespace ontologenius { RosInterface::RosInterface(RosInterface& other, const std::string& name) : onto_(new Ontology(*other.onto_)), reasoners_(name), + subscriber_(name), feeder_echo_(getTopicName("insert_echo", name), getTopicName("insert_explanations", name)), #ifdef ONTO_TEST end_feed_(true), @@ -60,9 +62,8 @@ namespace ontologenius { reasoners_.link(onto_); feeder_.link(onto_); feeder_.setVersioning(true); + subscriber_.link(onto_); sparql_.link(onto_); - - // n_.setCallbackQueue(&callback_queue_); } RosInterface::~RosInterface() @@ -152,6 +153,7 @@ namespace ontologenius { std::thread feed_thread(&RosInterface::feedThread, this); std::thread periodic_reasoning_thread(&RosInterface::periodicReasoning, this); + std::thread subscription_thread(&SubscriptionManager::run, &subscriber_); if(name_.empty() == false) Display::info(name_ + " is ready"); @@ -250,6 +252,7 @@ namespace ontologenius { onto_->setDisplay(display_); reasoners_.link(onto_); feeder_.link(onto_); + subscriber_.link(onto_); sparql_.link(onto_); if(onto_->preload(intern_file_) == false) @@ -265,6 +268,7 @@ namespace ontologenius { onto_->setDisplay(display_); reasoners_.link(onto_); feeder_.link(onto_); + subscriber_.link(onto_); sparql_.link(onto_); release(); } @@ -400,6 +404,10 @@ namespace ontologenius { feeder_echo_.add(echo); auto explanations = feeder_.getExplanations(); feeder_echo_.add(explanations); + + subscriber_.add(explanations); + for(auto& fact : echo) + subscriber_.add(fact.first); } else if(feeder_end == false) { @@ -462,6 +470,7 @@ namespace ontologenius { } auto explanations = reasoners_.getExplanations(); + subscriber_.add(explanations); for(auto& explanation : explanations) { expl_msg.fact = explanation.first; From bd1668885bedac55b253c4ecaa388d33af7ceee2 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 15:59:38 +0200 Subject: [PATCH 12/49] [API] add PatternSubscriber for C++ API --- CMakeLists.txt | 1 + .../API/ontologenius/PatternsSubscriber.h | 44 ++++++++ src/API/ontologenius/PatternsSubscriber.cpp | 102 ++++++++++++++++++ 3 files changed, 147 insertions(+) create mode 100644 include/ontologenius/API/ontologenius/PatternsSubscriber.h create mode 100644 src/API/ontologenius/PatternsSubscriber.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 20f70bf7..26aab19b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -325,6 +325,7 @@ add_ros_library(ontologenius_lib src/API/ontologenius/OntologyManipulator.cpp src/API/ontologenius/OntologyManipulatorIndex.cpp src/API/ontologenius/OntologiesManipulator.cpp + src/API/ontologenius/PatternsSubscriber.cpp ) target_include_directories(ontologenius_lib PUBLIC $ $) diff --git a/include/ontologenius/API/ontologenius/PatternsSubscriber.h b/include/ontologenius/API/ontologenius/PatternsSubscriber.h new file mode 100644 index 00000000..4a94c3f8 --- /dev/null +++ b/include/ontologenius/API/ontologenius/PatternsSubscriber.h @@ -0,0 +1,44 @@ +#ifndef ONTOLOGENIUS_PATTERNSSUBSCRIBER_H +#define ONTOLOGENIUS_PATTERNSSUBSCRIBER_H + +#include +#include +#include +#include +#include +#include + +#include "ontologenius/compat/ros.h" + +namespace onto { + + class PatternsSubscriber + { + public: + PatternsSubscriber(const std::function& callback, const std::string& name = ""); + ~PatternsSubscriber(); + + bool subscribe(const std::string& pattern, size_t count = -1); + bool cancel(); + + bool end() const { return ids_.empty(); } + + private: + ontologenius::compat::onto_ros::Subscriber sub_; + ontologenius::compat::onto_ros::Client client_subscribe_; + ontologenius::compat::onto_ros::Client client_cancel_; + + std::atomic need_to_terminate_; + + std::vector ids_; + + void patternCallback(const ontologenius::compat::OntologeniusSubscriptionAnswer& msg); + + std::function callback_; + + void spinThread(); + }; + +} // namespace onto + +#endif // ONTOLOGENIUS_PATTERNSSUBSCRIBER_H diff --git a/src/API/ontologenius/PatternsSubscriber.cpp b/src/API/ontologenius/PatternsSubscriber.cpp new file mode 100644 index 00000000..50b7d89a --- /dev/null +++ b/src/API/ontologenius/PatternsSubscriber.cpp @@ -0,0 +1,102 @@ +#include "ontologenius/API/ontologenius/PatternsSubscriber.h" + +#include +#include +#include +#include + +#include "ontologenius/compat/ros.h" + +namespace onto { + + PatternsSubscriber::PatternsSubscriber(const std::function& callback, const std::string& name) + : sub_(name.empty() ? "ontologenius/subscription_answer" : "ontologenius/subscription_answer/" + name, 1000, &PatternsSubscriber::patternCallback, this), + client_subscribe_(name.empty() ? "ontologenius/subscribe" : "ontologenius/subscribe/" + name), + client_cancel_(name.empty() ? "ontologenius/unsubscribe" : "ontologenius/unsubscribe/" + name), + callback_(callback) + {} + + PatternsSubscriber::~PatternsSubscriber() + { + cancel(); + } + + bool PatternsSubscriber::subscribe(const std::string& pattern, size_t count) + { + auto req = ontologenius::compat::makeRequest(); + auto res = ontologenius::compat::makeResponse(); + + [&](auto&& req) { + req->data = pattern; + req->count = count; + }(ontologenius::compat::onto_ros::getServicePointer(req)); + + using ResultTy = typename decltype(client_subscribe_)::Status_e; + + if(client_subscribe_.call(req, res) != ResultTy::ros_status_failure) + { + ids_.push_back(ontologenius::compat::onto_ros::getServicePointer(res)->id); + return true; + } + else + return false; + } + + bool PatternsSubscriber::cancel() + { + bool done = true; + for(size_t i = 0; i < ids_.size();) + { + auto req = ontologenius::compat::makeRequest(); + auto res = ontologenius::compat::makeResponse(); + + [&](auto&& req) { + req->id = ids_[i]; + }(ontologenius::compat::onto_ros::getServicePointer(req)); + + using ResultTy = typename decltype(client_cancel_)::Status_e; + + if(client_cancel_.call(req, res) != ResultTy::ros_status_failure) + { + if(ontologenius::compat::onto_ros::getServicePointer(res)->id != (int)ids_[i]) + { + done = false; + } + } + else + { + done = false; + } + + if(done) + ids_.erase(ids_.begin() + (int)i); + else + i++; + } + + return done; + } + + void PatternsSubscriber::patternCallback(const ontologenius::compat::OntologeniusSubscriptionAnswer& msg) + { + auto it = std::find(ids_.begin(), ids_.end(), msg.id); + if(it != ids_.end()) + { + callback_(msg.data); + if(msg.last) + ids_.erase(it); + } + } + + void PatternsSubscriber::spinThread() + { + while(ontologenius::compat::onto_ros::Node::ok()) + { + if(need_to_terminate_) + { + break; + } + } + } + +} // namespace onto From b8c0149ad4d98947bf687f086d22eda81ed44b28 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Thu, 24 Oct 2024 17:50:41 +0200 Subject: [PATCH 13/49] [RosInterface] stop subscriber properly --- src/interface/RosInterface.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/interface/RosInterface.cpp b/src/interface/RosInterface.cpp index 78aabbe4..6cb65b31 100644 --- a/src/interface/RosInterface.cpp +++ b/src/interface/RosInterface.cpp @@ -162,6 +162,9 @@ namespace ontologenius { periodic_reasoning_thread.join(); feed_thread.join(); + + subscriber_.stop(); + subscription_thread.join(); } void RosInterface::stop() From 71178c4ebb04766047e5e5e8d5a7d7b57a194c18 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Wed, 30 Oct 2024 13:07:56 +0100 Subject: [PATCH 14/49] [PatternsSubscriber] with dedicaed callback per pattern --- .../API/ontologenius/PatternsSubscriber.h | 10 +-- src/API/ontologenius/PatternsSubscriber.cpp | 73 +++++++++---------- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/include/ontologenius/API/ontologenius/PatternsSubscriber.h b/include/ontologenius/API/ontologenius/PatternsSubscriber.h index 4a94c3f8..025fd188 100644 --- a/include/ontologenius/API/ontologenius/PatternsSubscriber.h +++ b/include/ontologenius/API/ontologenius/PatternsSubscriber.h @@ -15,11 +15,11 @@ namespace onto { class PatternsSubscriber { public: - PatternsSubscriber(const std::function& callback, const std::string& name = ""); + PatternsSubscriber(const std::string& name = ""); ~PatternsSubscriber(); - bool subscribe(const std::string& pattern, size_t count = -1); - bool cancel(); + bool subscribe(const std::string& pattern, const std::function& callback, size_t count = -1); + bool cancel(size_t id); bool end() const { return ids_.empty(); } @@ -30,12 +30,10 @@ namespace onto { std::atomic need_to_terminate_; - std::vector ids_; + std::unordered_map> ids_; void patternCallback(const ontologenius::compat::OntologeniusSubscriptionAnswer& msg); - std::function callback_; - void spinThread(); }; diff --git a/src/API/ontologenius/PatternsSubscriber.cpp b/src/API/ontologenius/PatternsSubscriber.cpp index 50b7d89a..4a435a46 100644 --- a/src/API/ontologenius/PatternsSubscriber.cpp +++ b/src/API/ontologenius/PatternsSubscriber.cpp @@ -1,27 +1,34 @@ #include "ontologenius/API/ontologenius/PatternsSubscriber.h" -#include #include #include #include +#include #include "ontologenius/compat/ros.h" namespace onto { - PatternsSubscriber::PatternsSubscriber(const std::function& callback, const std::string& name) + PatternsSubscriber::PatternsSubscriber(const std::string& name) : sub_(name.empty() ? "ontologenius/subscription_answer" : "ontologenius/subscription_answer/" + name, 1000, &PatternsSubscriber::patternCallback, this), client_subscribe_(name.empty() ? "ontologenius/subscribe" : "ontologenius/subscribe/" + name), - client_cancel_(name.empty() ? "ontologenius/unsubscribe" : "ontologenius/unsubscribe/" + name), - callback_(callback) + client_cancel_(name.empty() ? "ontologenius/unsubscribe" : "ontologenius/unsubscribe/" + name) {} PatternsSubscriber::~PatternsSubscriber() { - cancel(); + std::vector ids; + ids.reserve(ids_.size()); + for(const auto& id : ids_) + ids.push_back(id.first); + + for(auto id : ids) + cancel(id); } - bool PatternsSubscriber::subscribe(const std::string& pattern, size_t count) + bool PatternsSubscriber::subscribe(const std::string& pattern, + const std::function& callback, + size_t count) { auto req = ontologenius::compat::makeRequest(); auto res = ontologenius::compat::makeResponse(); @@ -35,54 +42,46 @@ namespace onto { if(client_subscribe_.call(req, res) != ResultTy::ros_status_failure) { - ids_.push_back(ontologenius::compat::onto_ros::getServicePointer(res)->id); + ids_.emplace(ontologenius::compat::onto_ros::getServicePointer(res)->id, callback); return true; } else return false; } - bool PatternsSubscriber::cancel() + bool PatternsSubscriber::cancel(size_t id) { bool done = true; - for(size_t i = 0; i < ids_.size();) + + auto req = ontologenius::compat::makeRequest(); + auto res = ontologenius::compat::makeResponse(); + + [&](auto&& req) { + req->id = id; + }(ontologenius::compat::onto_ros::getServicePointer(req)); + + using ResultTy = typename decltype(client_cancel_)::Status_e; + + if(client_cancel_.call(req, res) != ResultTy::ros_status_failure) { - auto req = ontologenius::compat::makeRequest(); - auto res = ontologenius::compat::makeResponse(); - - [&](auto&& req) { - req->id = ids_[i]; - }(ontologenius::compat::onto_ros::getServicePointer(req)); - - using ResultTy = typename decltype(client_cancel_)::Status_e; - - if(client_cancel_.call(req, res) != ResultTy::ros_status_failure) - { - if(ontologenius::compat::onto_ros::getServicePointer(res)->id != (int)ids_[i]) - { - done = false; - } - } - else - { + if(ontologenius::compat::onto_ros::getServicePointer(res)->id != (int)id) done = false; - } - - if(done) - ids_.erase(ids_.begin() + (int)i); - else - i++; } + else + done = false; + + if(done) + ids_.erase(id); return done; } void PatternsSubscriber::patternCallback(const ontologenius::compat::OntologeniusSubscriptionAnswer& msg) { - auto it = std::find(ids_.begin(), ids_.end(), msg.id); + auto it = ids_.find(msg.id); if(it != ids_.end()) { - callback_(msg.data); + it->second(msg.data); if(msg.last) ids_.erase(it); } @@ -91,12 +90,8 @@ namespace onto { void PatternsSubscriber::spinThread() { while(ontologenius::compat::onto_ros::Node::ok()) - { if(need_to_terminate_) - { break; - } - } } } // namespace onto From 534e7073d6ef579097ca400c984d6b494feb024b Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Wed, 30 Oct 2024 14:36:08 +0100 Subject: [PATCH 15/49] [ontopy] add PatternsSubscriber --- ontopy/ontologenius/OntologyManipulator.py | 5 +- ontopy/ontologenius/PatternsSubscriber.py | 85 +++++++++++++++++++++ ontopy/ontologenius/__init__.py | 1 + src/API/ontologenius/PatternsSubscriber.cpp | 11 +-- 4 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 ontopy/ontologenius/PatternsSubscriber.py diff --git a/ontopy/ontologenius/OntologyManipulator.py b/ontopy/ontologenius/OntologyManipulator.py index 8a51c103..9a8cc4be 100644 --- a/ontopy/ontologenius/OntologyManipulator.py +++ b/ontopy/ontologenius/OntologyManipulator.py @@ -1,12 +1,14 @@ from .clients import * from .FeederPublisher import FeederPublisher +from .PatternsSubscriber import PatternsSubscriber class OntologyManipulator: """The OntologyManipulator class is just an object to access all API ROS abstraction classes so that you can query and manage ontologenius.""" def __init__(self, name = ''): """Constructs an ontology manipulator with. - Can be used in a multi-ontology mode by specifying the name of the ontology name(str). For classic use, do not specify the ontology name name. + Can be used in a multi-ontology mode by specifying the name of the ontology name(str). + For classic use, do not specify the ontology name name. """ self._name = name self.individuals = IndividualClient(name) @@ -17,6 +19,7 @@ def __init__(self, name = ''): self.reasoners = ReasonerClient(name) self.feeder = FeederPublisher(name) self.sparql = SparqlClient(name) + self.subscriber = PatternsSubscriber(name) self.sparql._client.wait() diff --git a/ontopy/ontologenius/PatternsSubscriber.py b/ontopy/ontologenius/PatternsSubscriber.py new file mode 100644 index 00000000..8b33303c --- /dev/null +++ b/ontopy/ontologenius/PatternsSubscriber.py @@ -0,0 +1,85 @@ +from .compat.ros import Ontoros +import os + +from ontologenius.msg import OntologeniusSubscriptionAnswer +from ontologenius.srv import OntologeniusSubscription, OntologeniusUnsubscription + +if os.environ["ROS_VERSION"] == "1": + from ontologenius.srv import OntologeniusSubscriptionRequest + from ontologenius.srv import OntologeniusUnsubscriptionRequest +else: + from ontologenius.srv._ontologenius_subscription import OntologeniusSubscription_Request as OntologeniusSubscriptionRequest + from ontologenius.srv._ontologenius_unsubscription import OntologeniusUnsubscription_Request as OntologeniusUnsubscriptionRequest + +class PatternsSubscriber: + """The PatternsSubscriber class provides an abstraction ontologenius subscription mechanism. + Querying a knowledge base is interesting but when one is waiting a given fact, pulling + the knowledge base can be an issue. To solve that, Ontologenius provide a subscription + mechanism allowing to subscribe not one only to given facts but also to patterns. + """ + + def __init__(self, name): + """Constructs a PatternsSubscriber. + Can be used in a multi-ontology mode by specifying the name of the ontology name(str). + For classic use, name(str) should be defined as ''. + """ + self._name = name + + self._ids = {} + + sub_topic_name = 'ontologenius/subscription_answer' + if self._name != '': + sub_topic_name += '/' + self._name + self._answer_sub = Ontoros.createSubscriber(sub_topic_name, OntologeniusSubscriptionAnswer, self.patternCallback) + + client_sub_name = 'ontologenius/subscribe' + if self._name != '': + client_sub_name += '/' + self._name + self._sub_client = Ontoros.createService(client_sub_name, OntologeniusSubscription) + + client_unsub_name = 'ontologenius/unsubscribe' + if self._name != '': + client_unsub_name += '/' + self._name + self._unsub_client = Ontoros.createService(client_unsub_name, OntologeniusUnsubscription) + + def __del__(self): + ids = self._ids.keys() + for id in ids: + self.cancel(id) + + self._answer_sub.unregister() + + def subscribe(self, pattern, callback, count = -1): + """Subscribes to a given pattern linked to a callback. + The parameter count can be set to limit the subscription. + Default parameter -1 corresponds to an unlimited subscription. + This function returns the subscription id. This later is only used to manually unsubscribe. + """ + request = OntologeniusSubscriptionRequest(data = pattern, count = count) + response = self._sub_client.call(request, False) + if(response): + self._ids[response.id] = callback + return response.id + else: + return None + + def cancel(self, id): + """Manualy unsubscribe from a pattern using the corresponding subscription id. + Return True if the unsubscription suceeded. + """ + request = OntologeniusUnsubscriptionRequest(id = id) + response = self._unsub_client.call(request, False) + if(response): + if(response.id == id): + self._ids.pop(id) + return True + else: + return False + else: + return False + + def patternCallback(self, msg): + if msg.id in self._ids.keys(): + self._ids[msg.id](msg.data) + if(msg.last): + self._ids.pop(msg.id) \ No newline at end of file diff --git a/ontopy/ontologenius/__init__.py b/ontopy/ontologenius/__init__.py index 5e455c30..846e971f 100644 --- a/ontopy/ontologenius/__init__.py +++ b/ontopy/ontologenius/__init__.py @@ -7,3 +7,4 @@ from .OntologiesManipulator import OntologiesManipulator from .FeederPublisher import FeederPublisher from .ConversionClient import ConversionClient +from .PatternsSubscriber import PatternsSubscriber diff --git a/src/API/ontologenius/PatternsSubscriber.cpp b/src/API/ontologenius/PatternsSubscriber.cpp index 4a435a46..ae2a8d7e 100644 --- a/src/API/ontologenius/PatternsSubscriber.cpp +++ b/src/API/ontologenius/PatternsSubscriber.cpp @@ -26,9 +26,9 @@ namespace onto { cancel(id); } - bool PatternsSubscriber::subscribe(const std::string& pattern, - const std::function& callback, - size_t count) + int PatternsSubscriber::subscribe(const std::string& pattern, + const std::function& callback, + size_t count) { auto req = ontologenius::compat::makeRequest(); auto res = ontologenius::compat::makeResponse(); @@ -42,11 +42,12 @@ namespace onto { if(client_subscribe_.call(req, res) != ResultTy::ros_status_failure) { + size_t id = ontologenius::compat::onto_ros::getServicePointer(res)->id; ids_.emplace(ontologenius::compat::onto_ros::getServicePointer(res)->id, callback); - return true; + return (int)id; } else - return false; + return -1; } bool PatternsSubscriber::cancel(size_t id) From 34814297aceea5dbf338983e47268c12528981dd Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Wed, 30 Oct 2024 14:36:32 +0100 Subject: [PATCH 16/49] [PatternsSubscriber] returns subscription id --- include/ontologenius/API/ontologenius/OntologyManipulator.h | 3 +++ include/ontologenius/API/ontologenius/PatternsSubscriber.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/ontologenius/API/ontologenius/OntologyManipulator.h b/include/ontologenius/API/ontologenius/OntologyManipulator.h index 891d7030..d263dec1 100644 --- a/include/ontologenius/API/ontologenius/OntologyManipulator.h +++ b/include/ontologenius/API/ontologenius/OntologyManipulator.h @@ -5,6 +5,7 @@ #include #include "ontologenius/API/ontologenius/FeederPublisher.h" +#include "ontologenius/API/ontologenius/PatternsSubscriber.h" #include "ontologenius/API/ontologenius/clients/ActionClient.h" #include "ontologenius/API/ontologenius/clients/ReasonerClient.h" #include "ontologenius/API/ontologenius/clients/SparqlClient.h" @@ -59,6 +60,8 @@ namespace onto { FeederPublisher feeder; /// @brief ROS service client to make SPAQRL queries SparqlClient sparql; + /// @brief ROS abstraction to subscribe to fact patterns + PatternsSubscriber subscriber; }; } // namespace onto diff --git a/include/ontologenius/API/ontologenius/PatternsSubscriber.h b/include/ontologenius/API/ontologenius/PatternsSubscriber.h index 025fd188..765437dd 100644 --- a/include/ontologenius/API/ontologenius/PatternsSubscriber.h +++ b/include/ontologenius/API/ontologenius/PatternsSubscriber.h @@ -18,7 +18,7 @@ namespace onto { PatternsSubscriber(const std::string& name = ""); ~PatternsSubscriber(); - bool subscribe(const std::string& pattern, const std::function& callback, size_t count = -1); + int subscribe(const std::string& pattern, const std::function& callback, size_t count = -1); bool cancel(size_t id); bool end() const { return ids_.empty(); } From 764333f933050a87d3b49f66b425ea4126e19969 Mon Sep 17 00:00:00 2001 From: Guillaume Sarthou Date: Wed, 30 Oct 2024 19:03:42 +0100 Subject: [PATCH 17/49] [Doc] CPP API PatternsSubscriber --- docs/cpp_API/ActionClient.html | 92 ++-- docs/cpp_API/ClassClient.html | 108 +++-- docs/cpp_API/ClassIndexClient.html | 112 +++-- docs/cpp_API/ClientBase.html | 84 +++- docs/cpp_API/ClientBaseIndex.html | 94 ++-- docs/cpp_API/ConversionClient.html | 145 ++++-- docs/cpp_API/CppAPI.html | 25 +- docs/cpp_API/DataPropertyClient.html | 71 ++- docs/cpp_API/DataPropertyIndexClient.html | 75 ++- docs/cpp_API/FeederPublisher.html | 188 ++++---- docs/cpp_API/IndividualClient.html | 118 +++-- docs/cpp_API/IndividualIndexClient.html | 120 +++-- docs/cpp_API/ManagerClient.html | 78 +++- docs/cpp_API/ObjectPropertyClient.html | 72 ++- docs/cpp_API/ObjectPropertyIndexClient.html | 74 ++- docs/cpp_API/OntologiesManipulator.html | 83 +++- docs/cpp_API/OntologyClient.html | 100 ++-- docs/cpp_API/OntologyIndexClient.html | 102 +++-- docs/cpp_API/OntologyManipulator.html | 62 ++- docs/cpp_API/OntologyManipulatorIndex.html | 62 ++- docs/cpp_API/PatternsSubscriber.html | 246 ++++++++++ docs/cpp_API/ReasonerClient.html | 68 ++- docs/cpp_API/SparqlClient.html | 61 ++- docs/cpp_API/SparqlIndexClient.html | 47 +- docs/cpp_Tutorials/Tutorials.html | 39 +- .../tutorial1/FindTheIntruder.html | 197 ++++---- .../tutorial1/LaunchTheProgram.html | 240 +++++----- .../tutorial1/ManageTheMultilingual.html | 185 ++++---- .../tutorial1/MostRelevantIntruder.html | 53 +-- .../tutorial1/settingUpTheProgram.html | 297 ++++++------ docs/cpp_Tutorials/tutorial2/FindOurWay.html | 230 +++++----- .../cpp_Tutorials/tutorial2/Presentation.html | 28 +- .../tutorial2/UnderstandOurEnvironment.html | 33 +- .../tutorial3/InsertNewKnowledge.html | 427 +++++++++--------- .../tutorial3/MakeItProactive.html | 77 ++-- .../cpp_Tutorials/tutorial3/Presentation.html | 136 +++--- .../tutorial4/BeliefDivergence.html | 145 +++--- .../tutorial4/CreateMultipleOntologies.html | 103 ++--- .../cpp_Tutorials/tutorial4/Presentation.html | 113 ++--- .../tutorial5/MoveThroughTheAlternatives.html | 199 ++++---- .../cpp_Tutorials/tutorial5/Presentation.html | 123 ++--- docs/cpp_Tutorials/tutorial5/ViewGraph.html | 33 +- docs/cpp_Tutorials/tutorial6/Overview.html | 109 ++--- docs/cpp_Tutorials/tutorial6/Solution.html | 209 ++++----- 44 files changed, 3176 insertions(+), 2087 deletions(-) create mode 100644 docs/cpp_API/PatternsSubscriber.html diff --git a/docs/cpp_API/ActionClient.html b/docs/cpp_API/ActionClient.html index 185a7e6d..81cc0608 100644 --- a/docs/cpp_API/ActionClient.html +++ b/docs/cpp_API/ActionClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ClassClient.html b/docs/cpp_API/ClassClient.html index e959301b..16acca69 100644 --- a/docs/cpp_API/ClassClient.html +++ b/docs/cpp_API/ClassClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ClassIndexClient.html b/docs/cpp_API/ClassIndexClient.html index 0b185d2a..eccbddcb 100644 --- a/docs/cpp_API/ClassIndexClient.html +++ b/docs/cpp_API/ClassIndexClient.html @@ -14,15 +14,15 @@ @@ -248,10 +300,10 @@

std::

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/ClientBase.html b/docs/cpp_API/ClientBase.html index 958999af..d8eee410 100644 --- a/docs/cpp_API/ClientBase.html +++ b/docs/cpp_API/ClientBase.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ClientBaseIndex.html b/docs/cpp_API/ClientBaseIndex.html index e4123a36..30f9b514 100644 --- a/docs/cpp_API/ClientBaseIndex.html +++ b/docs/cpp_API/ClientBaseIndex.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ConversionClient.html b/docs/cpp_API/ConversionClient.html index c8d0ab4f..50218de7 100644 --- a/docs/cpp_API/ConversionClient.html +++ b/docs/cpp_API/ConversionClient.html @@ -14,15 +14,15 @@
@@ -272,10 +345,10 @@

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/CppAPI.html b/docs/cpp_API/CppAPI.html index 3894e800..7fe60fbf 100644 --- a/docs/cpp_API/CppAPI.html +++ b/docs/cpp_API/CppAPI.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/DataPropertyClient.html b/docs/cpp_API/DataPropertyClient.html index 55cd2f20..a6836552 100644 --- a/docs/cpp_API/DataPropertyClient.html +++ b/docs/cpp_API/DataPropertyClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/DataPropertyIndexClient.html b/docs/cpp_API/DataPropertyIndexClient.html index 5bf6d1df..e756b7e5 100644 --- a/docs/cpp_API/DataPropertyIndexClient.html +++ b/docs/cpp_API/DataPropertyIndexClient.html @@ -14,15 +14,15 @@ @@ -184,7 +211,7 @@

std

std::vector<int64_t> DataPropertyIndexClient::getDomain(int64_t index, int depth = -1)

Gives all the domain classes of the property index.

The optional depth parameter can be set to limit tree propagation to a specific value. - The default value -1 represents no propagation limitation while the value 0 corresponds to the direct domains.

+ The default value -1 represents no propagation limitation while the value 0 corresponds to the direct domains.

std::vector<int64_t> DataPropertyIndexClient::getRange(int64_t index)

Gives all the ranges types of the property index.

@@ -201,10 +228,10 @@

std::vect

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/FeederPublisher.html b/docs/cpp_API/FeederPublisher.html index 8864cd88..78565e3f 100644 --- a/docs/cpp_API/FeederPublisher.html +++ b/docs/cpp_API/FeederPublisher.html @@ -8,7 +8,7 @@ + integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> @@ -18,7 +18,7 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ManagerClient.html b/docs/cpp_API/ManagerClient.html index f91bf196..c0828eac 100644 --- a/docs/cpp_API/ManagerClient.html +++ b/docs/cpp_API/ManagerClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ObjectPropertyClient.html b/docs/cpp_API/ObjectPropertyClient.html index 54360095..12079b19 100644 --- a/docs/cpp_API/ObjectPropertyClient.html +++ b/docs/cpp_API/ObjectPropertyClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/ObjectPropertyIndexClient.html b/docs/cpp_API/ObjectPropertyIndexClient.html index 7244f685..e4dddbb3 100644 --- a/docs/cpp_API/ObjectPropertyIndexClient.html +++ b/docs/cpp_API/ObjectPropertyIndexClient.html @@ -14,15 +14,15 @@ @@ -186,12 +214,12 @@

std

std::vector<int64_t> ObjectPropertyIndexClient::getDomain(int64_t index, int depth = -1)

Gives all the domain classes of the property index.

The optional depth parameter can be set to limit tree propagation to a specific value. - The default value -1 represents no propagation limitation while the value 0 corresponds to the direct domains.

+ The default value -1 represents no propagation limitation while the value 0 corresponds to the direct domains.

std::vector<int64_t> ObjectPropertyIndexClient::getRange(int64_t index, int depth = -1)

Gives all the ranges classes of the property index.

The optional depth parameter can be set to limit tree propagation to a specific value. - The default value -1 represents no propagation limitation while the value 0 corresponds to the direct ranges.

+ The default value -1 represents no propagation limitation while the value 0 corresponds to the direct ranges.

std::vector<int64_t> ObjectPropertyIndexClient::getInverse(int64_t index)

Gives all the inverses properties of the property index.

@@ -208,10 +236,10 @@

std::

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/OntologiesManipulator.html b/docs/cpp_API/OntologiesManipulator.html index 65361782..8d152e9d 100644 --- a/docs/cpp_API/OntologiesManipulator.html +++ b/docs/cpp_API/OntologiesManipulator.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/OntologyClient.html b/docs/cpp_API/OntologyClient.html index 71580ca7..08b4abe9 100644 --- a/docs/cpp_API/OntologyClient.html +++ b/docs/cpp_API/OntologyClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/OntologyIndexClient.html b/docs/cpp_API/OntologyIndexClient.html index e271c183..a31a1e23 100644 --- a/docs/cpp_API/OntologyIndexClient.html +++ b/docs/cpp_API/OntologyIndexClient.html @@ -14,15 +14,15 @@ @@ -247,10 +295,10 @@

Muted labels

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_API/OntologyManipulator.html b/docs/cpp_API/OntologyManipulator.html index 9358f5b5..97ecf415 100644 --- a/docs/cpp_API/OntologyManipulator.html +++ b/docs/cpp_API/OntologyManipulator.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/OntologyManipulatorIndex.html b/docs/cpp_API/OntologyManipulatorIndex.html index 3c8b6f72..d54ce397 100644 --- a/docs/cpp_API/OntologyManipulatorIndex.html +++ b/docs/cpp_API/OntologyManipulatorIndex.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/PatternsSubscriber.html b/docs/cpp_API/PatternsSubscriber.html new file mode 100644 index 00000000..4874b3d7 --- /dev/null +++ b/docs/cpp_API/PatternsSubscriber.html @@ -0,0 +1,246 @@ + + + + PatternsSubscriber Class (cpp) | Ontologenius 0.4.2 + + + + + + + + + + + +
+ + + +
+ + +
+

PatternsSubscriber Class

+

The PatternsSubscriber class provides an abstraction ontologenius subscription mechanism.More...

+
+ + + + + + + + + + + +
Header: #include + "ontologenius/PatternsSubscriber.h"
Namespace: onto
+
+ + +

Public Functions

+
+ + + + + + + + + + + + + + + + + + + +
PatternsSubscriber(const + std::string& name)
int subscribe + (const std::string& pattern, + const std::function<void(const std::string&)>& callback, + int count = -1)
boolcancel(size_t id) +
bool end() +
+
+ + +
+

Detailed Description

+

The PatternsSubscriber class provides an abstraction ontologenius subscription mechanism.

+

Querying a knowledge base is interesting but when one is waiting a given fact, pulling + the knowledge base can be an issue. To solve that, Ontologenius provide a subscription + mechanism allowing to subscribe not one only to given facts but also to patterns.

+
+ +
+

Public Function Documentation

+ +

PatternsSubscriber::PatternsSubscriber(const std::string& name) +

+

Constructs a pattern subscriber.

+

Can be used in a multi-ontology mode by specifying the name of the ontology name. For classic use, + name should be defined as "". +

+ +

int + PatternsSubscriber::subscribe(const std::string& + pattern, const std::function<void(const std::string&)>& callback, int count = -1) +

+

Subscribes to a given pattern linked to a callback. Patterns are in the form "[add]subject|property|object". + Subject and object can be set as classes such as "[add]Cube|isOnTopOf|Table" to subscibe to any fact representing a cube being on a table. + In addition, any of the four elements can be setted with question mark which can be read as "any". For example, + "[?]?isOnTopOf|Table" to subscribe to any deletion or addition of any thing being on a entity of type Table.

+

The parameter count can be set to limit the subscription. + Default parameter -1 corresponds to an unlimited subscription.

+

This function returns the subscription id. This later is only used to manually unsubscribe.

+ + +

bool PatternsSubscriber::cancel(size_t id)

+

Manualy unsubscribe from a pattern using the corresponding subscription id.

+

Return True if the unsubscription suceeded.

+ +

bool + PatternsSubscriber::end() +

+

Tests if any subscription is still ongoing.

+ +
+
+
+ +
+ + +
+
+

+ Brought to you by: + +

+
+
+ + \ No newline at end of file diff --git a/docs/cpp_API/ReasonerClient.html b/docs/cpp_API/ReasonerClient.html index 6ecdb2b9..2b0a8c75 100644 --- a/docs/cpp_API/ReasonerClient.html +++ b/docs/cpp_API/ReasonerClient.html @@ -14,15 +14,15 @@ - + \ No newline at end of file diff --git a/docs/cpp_API/SparqlClient.html b/docs/cpp_API/SparqlClient.html index 23335cef..5a48a6dd 100644 --- a/docs/cpp_API/SparqlClient.html +++ b/docs/cpp_API/SparqlClient.html @@ -14,15 +14,15 @@ @@ -185,10 +198,10 @@

Basic query Examples

Brought to you by:

- + \ No newline at end of file diff --git a/docs/cpp_Tutorials/Tutorials.html b/docs/cpp_Tutorials/Tutorials.html index 9629184d..0c624af1 100644 --- a/docs/cpp_Tutorials/Tutorials.html +++ b/docs/cpp_Tutorials/Tutorials.html @@ -16,15 +16,15 @@