From 90fcaa7612027604251080daf4713349b95223d4 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Wed, 2 Aug 2023 10:09:22 +0200
Subject: [PATCH 01/18] [tests] update sparql test
---
src/tests/sparql.cpp | 58 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 55 insertions(+), 3 deletions(-)
diff --git a/src/tests/sparql.cpp b/src/tests/sparql.cpp
index 5cef7905..90561278 100644
--- a/src/tests/sparql.cpp
+++ b/src/tests/sparql.cpp
@@ -113,6 +113,18 @@ std::vector> runSparqlBase(ontologenius::Spar
return solutions;
}
+std::vector> runSparqlBaseIndex(ontologenius::Sparql& solver, const std::string& query)
+{
+ high_resolution_clock::time_point t1 = high_resolution_clock::now();
+ auto solutions = solver.runIndex(query);
+ high_resolution_clock::time_point t2 = high_resolution_clock::now();
+ duration time_span = duration_cast>(t2 - t1);
+
+ std::cout << "Sparql index has found " << solutions.size() << " solutions in " << time_span.count()*1000 << "ms" << std::endl;
+
+ return solutions;
+}
+
void configureInterface(ontologenius::RosInterface& interface)
{
std::vector files = {
@@ -136,6 +148,22 @@ void configureInterfaceTaboo(ontologenius::RosInterface& interface)
interface.init("en", "none", files, config);
}
+void testInsertIndex(size_t nb)
+{
+ std::unordered_set set;
+ high_resolution_clock::time_point t1 = high_resolution_clock::now();
+
+ for(size_t i = 0; i < nb; i++)
+ {
+ set.insert(i);
+ }
+
+ high_resolution_clock::time_point t2 = high_resolution_clock::now();
+ duration time_span = duration_cast>(t2 - t1);
+
+ std::cout << "Insertion of " << nb << " long in " << time_span.count()*1000 << "ms" << std::endl;
+}
+
int main(int argc, char** argv)
{
signal(SIGSEGV, handler);
@@ -163,9 +191,33 @@ int main(int argc, char** argv)
ontologenius::Sparql sparql_base;
sparql_base.link(onto);
- auto solution_base = runSparqlBase(sparql_base, query);
- compareSolutions(solution_it, solution_base);
+ for(size_t i = 0; i < 3; i++)
+ {
+ query = "SELECT * WHERE {?0 isA movie_actor}";
+ auto solution_base = runSparqlBase(sparql_base, query);
+
+ usleep(1000000);
+
+ query = "SELECT * WHERE {?0 isA " + std::to_string(onto->class_graph_.getIndex("movie_actor")) + "}";
+ auto solution_index = runSparqlBaseIndex(sparql_base, query);
+
+ usleep(1000000);
+
+ query = "SELECT * WHERE {?0 isA movie_director. ?0 movie_performance ?2. ?2 isA movie_performance}";
+ solution_base = runSparqlBase(sparql_base, query);
+
+ usleep(1000000);
+
+ query = "SELECT * WHERE {?0 isA " + std::to_string(onto->class_graph_.getIndex("movie_director")) +
+ ". ?0 " + std::to_string(onto->class_graph_.getIndex("movie_performance")) +
+ " ?2. ?2 isA " + std::to_string(onto->class_graph_.getIndex("movie_performance")) +
+ "}";
+ solution_index = runSparqlBaseIndex(sparql_base, query);
+ }
+
+ interface.stop();
+ onto_thread.join();
return 0;
-}
\ No newline at end of file
+}
From 9830045ab882d1f0a3af63398a88cb57e1f07a94 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Sat, 2 Sep 2023 19:12:00 +0200
Subject: [PATCH 02/18] [IndividualGraph] methos with single same as result
---
.../core/ontoGraphs/Graphs/ClassGraph.h | 4 +-
.../core/ontoGraphs/Graphs/IndividualGraph.h | 19 +++--
src/core/ontoGraphs/Graphs/ClassGraph.cpp | 32 +++++--
.../ontoGraphs/Graphs/IndividualGraph.cpp | 84 +++++++++++++++----
4 files changed, 105 insertions(+), 34 deletions(-)
diff --git a/include/ontologenius/core/ontoGraphs/Graphs/ClassGraph.h b/include/ontologenius/core/ontoGraphs/Graphs/ClassGraph.h
index cd12eadc..f9d086da 100644
--- a/include/ontologenius/core/ontoGraphs/Graphs/ClassGraph.h
+++ b/include/ontologenius/core/ontoGraphs/Graphs/ClassGraph.h
@@ -80,8 +80,8 @@ class ClassGraph : public OntoGraph
std::unordered_set getRangeOf(const std::string& _class, int depth = -1);
std::unordered_set getRangeOf(index_t _class, int depth = -1);
- void getDownIndividual(ClassBranch_t* branch, std::unordered_set& res);
- void getDownIndividual(ClassBranch_t* branch, std::unordered_set& res);
+ void getDownIndividual(ClassBranch_t* branch, std::unordered_set& res, bool single_same = false);
+ void getDownIndividual(ClassBranch_t* branch, std::unordered_set& res, bool single_same = false);
std::unordered_set getDownIndividualPtrSafe(ClassBranch_t* branch);
void getDownIndividualPtrSafe(ClassBranch_t* branch, std::unordered_set& res);
diff --git a/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h b/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h
index b43abf61..a104c265 100644
--- a/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h
+++ b/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h
@@ -88,11 +88,11 @@ class IndividualGraph : public Graph
std::unordered_set getRelatedWith(const std::string& individual); //C3
std::unordered_set getRelatedWith(index_t individual);
std::unordered_set getFrom(const std::string& param);
- std::unordered_set getFrom(const std::string& individual, const std::string& property);
- std::unordered_set getFrom(index_t individual, index_t property);
+ std::unordered_set getFrom(const std::string& individual, const std::string& property, bool single_same = false);
+ std::unordered_set getFrom(index_t individual, index_t property, bool single_same = false);
std::unordered_set getOn(const std::string& param);
- std::unordered_set getOn(const std::string& individual, const std::string& property);
- std::unordered_set getOn(index_t individual, index_t property);
+ std::unordered_set getOn(const std::string& individual, const std::string& property, bool single_same = false);
+ std::unordered_set getOn(index_t individual, index_t property, bool single_same = false);
std::unordered_set getWith(const std::string& param, int depth = -1);
std::unordered_set getWith(const std::string& first_individual, const std::string& second_individual, int depth = -1);
std::unordered_set getWith(index_t first_individual, index_t second_individual, int depth = -1);
@@ -116,8 +116,8 @@ class IndividualGraph : public Graph
std::unordered_set findFuzzy(const std::string& value, bool use_default = true, double threshold = 0.5);
bool touch(const std::string& value);
bool touch(index_t value);
- std::unordered_set getType(const std::string& class_selector);
- std::unordered_set getType(index_t class_selector);
+ std::unordered_set getType(const std::string& class_selector, bool single_same = false);
+ std::unordered_set getType(index_t class_selector, bool single_same = false);
bool relationExists(const std::string& param);
bool relationExists(const std::string& subject, const std::string& property, const std::string& object);
@@ -152,7 +152,9 @@ class IndividualGraph : public Graph
std::vector> getChains(ObjectPropertyBranch_t* base_property);
void getUpPtr(IndividualBranch_t* indiv, std::unordered_set& res, int depth = -1, uint32_t current_depth = 0);
+ void getLowestSame(IndividualBranch_t* individual, std::unordered_set& res);
void getSame(IndividualBranch_t* individual, std::unordered_set& res);
+ void getLowestSame(IndividualBranch_t* individual, std::unordered_set& res);
void getSame(IndividualBranch_t* individual, std::unordered_set& res);
private:
@@ -170,8 +172,8 @@ class IndividualGraph : public Graph
template void getRelatedOn(const T& property, std::unordered_set& res);
template void getUp(IndividualBranch_t* indiv, std::unordered_set& res, int depth = -1, uint32_t current_depth = 0);
template void getRelatedWith(index_t individual, std::unordered_set& res);
- template void getFrom(index_t individual, const T& property, std::unordered_set& res);
- template std::unordered_set getOn(IndividualBranch_t* individual, const T& property);
+ template void getFrom(index_t individual, const T& property, std::unordered_set& res, bool single_same = false);
+ template std::unordered_set getOn(IndividualBranch_t* individual, const T& property, bool single_same = false);
template void getWith(IndividualBranch_t* first_individual, index_t second_individual_index, std::unordered_set& res, int depth);
template void getDomainOf(IndividualBranch_t* individual, std::unordered_set& res, int depth);
template void getRangeOf(IndividualBranch_t* individual, std::unordered_set& res, int depth);
@@ -192,6 +194,7 @@ class IndividualGraph : public Graph
void getDistincts(IndividualBranch_t* individual, std::unordered_set& res);
std::unordered_set getSameId(const std::string& individual);
std::unordered_set getSameId(index_t individual);
+ void getLowestSame(IndividualBranch_t* individual, std::unordered_set& res);
void getSame(IndividualBranch_t* individual, std::unordered_set& res);
void getSame(IndividualBranch_t* individual, std::vector& res);
std::unordered_set getSame(IndividualBranch_t* individual);
diff --git a/src/core/ontoGraphs/Graphs/ClassGraph.cpp b/src/core/ontoGraphs/Graphs/ClassGraph.cpp
index 701d7677..319b8d19 100644
--- a/src/core/ontoGraphs/Graphs/ClassGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/ClassGraph.cpp
@@ -1068,20 +1068,36 @@ void ClassGraph::getRangeOf(ClassBranch_t* branch, std::unordered_set&
}
}
-void ClassGraph::getDownIndividual(ClassBranch_t* branch, std::unordered_set& res)
+void ClassGraph::getDownIndividual(ClassBranch_t* branch, std::unordered_set& res, bool single_same)
{
std::shared_lock lock(Graph::mutex_);
- res.reserve(res.size() + branch->individual_childs_.size() * 1.5);
- for(auto& indiv : branch->individual_childs_)
- individual_graph_->getSame(indiv.elem, res);
+ if(single_same)
+ {
+ res.reserve(res.size() + branch->individual_childs_.size() * 1.5);
+ for(auto& indiv : branch->individual_childs_)
+ individual_graph_->getLowestSame(indiv.elem, res);
+ }
+ else
+ {
+ for(auto& indiv : branch->individual_childs_)
+ individual_graph_->getSame(indiv.elem, res);
+ }
}
-void ClassGraph::getDownIndividual(ClassBranch_t* branch, std::unordered_set& res)
+void ClassGraph::getDownIndividual(ClassBranch_t* branch, std::unordered_set& res, bool single_same)
{
std::shared_lock lock(Graph::mutex_);
- res.reserve(res.size() + branch->individual_childs_.size() * 1.5);
- for(auto& indiv : branch->individual_childs_)
- individual_graph_->getSame(indiv.elem, res);
+ if(single_same)
+ {
+ for(auto& indiv : branch->individual_childs_)
+ individual_graph_->getLowestSame(indiv.elem, res);
+ }
+ else
+ {
+ res.reserve(res.size() + branch->individual_childs_.size() * 1.5);
+ for(auto& indiv : branch->individual_childs_)
+ individual_graph_->getSame(indiv.elem, res);
+ }
}
std::unordered_set ClassGraph::getDownIndividualPtrSafe(ClassBranch_t* branch)
diff --git a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
index 012a7adb..cd7241e3 100644
--- a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
@@ -678,7 +678,7 @@ std::unordered_set IndividualGraph::getFrom(const std::string& para
return {};
}
-std::unordered_set IndividualGraph::getFrom(const std::string& individual, const std::string& property)
+std::unordered_set IndividualGraph::getFrom(const std::string& individual, const std::string& property, bool single_same)
{
std::unordered_set res;
index_t indiv_index = 0;
@@ -698,20 +698,20 @@ std::unordered_set IndividualGraph::getFrom(const std::string& indi
}
}
- getFrom(indiv_index, property, res);
+ getFrom(indiv_index, property, res, single_same);
return res;
}
-std::unordered_set IndividualGraph::getFrom(index_t individual, index_t property)
+std::unordered_set IndividualGraph::getFrom(index_t individual, index_t property, bool single_same)
{
std::unordered_set res;
- getFrom(individual, property, res);
+ getFrom(individual, property, res, single_same);
return res;
}
template
-void IndividualGraph::getFrom(index_t individual, const T& property, std::unordered_set& res)
+void IndividualGraph::getFrom(index_t individual, const T& property, std::unordered_set& res, bool single_same)
{
std::unordered_set object_properties = object_property_graph_->getDownId(property);
std::unordered_set data_properties = data_property_graph_->getDownId(property);
@@ -767,7 +767,12 @@ void IndividualGraph::getFrom(index_t individual, const T& property, std::unorde
}
if(found == true)
- getSame(indiv_i, res);
+ {
+ if(single_same)
+ getLowestSame(indiv_i, res);
+ else
+ getSame(indiv_i, res);
+ }
}
}
@@ -831,24 +836,24 @@ std::unordered_set IndividualGraph::getOn(const std::string& param)
return std::unordered_set();
}
-std::unordered_set IndividualGraph::getOn(const std::string& individual, const std::string& property)
+std::unordered_set IndividualGraph::getOn(const std::string& individual, const std::string& property, bool single_same)
{
std::lock_guard lock(Graph::mutex_);
IndividualBranch_t* indiv = container_.find(individual);
- return getOn(indiv, property);
+ return getOn(indiv, property, single_same);
}
-std::unordered_set IndividualGraph::getOn(index_t individual, index_t property)
+std::unordered_set IndividualGraph::getOn(index_t individual, index_t property, bool single_same)
{
std::lock_guard lock(Graph::mutex_);
IndividualBranch_t* indiv = ordered_individuals_[individual];
- return getOn(indiv, property);
+ return getOn(indiv, property, single_same);
}
template
-std::unordered_set IndividualGraph::getOn(IndividualBranch_t* individual, const T& property)
+std::unordered_set IndividualGraph::getOn(IndividualBranch_t* individual, const T& property, bool single_same)
{
std::unordered_set res;
@@ -866,7 +871,12 @@ std::unordered_set IndividualGraph::getOn(IndividualBranch_t* individual, con
for(IndivObjectRelationElement_t& relation : same_indiv->object_relations_)
for (index_t id : object_properties)
if(relation.first->get() == id)
- getSame(relation.second, res);
+ {
+ if(single_same)
+ getLowestSame(relation.second, res);
+ else
+ getSame(relation.second, res);
+ }
}
}
else
@@ -1113,6 +1123,18 @@ std::unordered_set IndividualGraph::getSameId(index_t individual)
return getSameId(ordered_individuals_[individual]);
}
+void IndividualGraph::getLowestSame(IndividualBranch_t* individual, std::unordered_set& res)
+{
+ if(individual != nullptr)
+ {
+ if(individual->same_as_.size())
+ res.insert(std::min_element(individual->same_as_.cbegin(), individual->same_as_.cend(),
+ [](auto& a, auto& b){ return a.elem->get() < b.elem->get(); })->elem);
+ else
+ res.insert(individual);
+ }
+}
+
void IndividualGraph::getSame(IndividualBranch_t* individual, std::unordered_set& res)
{
if(individual != nullptr)
@@ -1142,6 +1164,21 @@ std::unordered_set IndividualGraph::getSame(IndividualBranch_t* ind
return res;
}
+void IndividualGraph::getLowestSame(IndividualBranch_t* individual, std::unordered_set& res)
+{
+ if(individual != nullptr)
+ {
+ if(individual->same_as_.size())
+ {
+ auto indiv = std::min_element(individual->same_as_.cbegin(), individual->same_as_.cend(),
+ [](auto& a, auto& b){ return a.elem->get() < b.elem->get(); });
+ res.insert(indiv->elem->value());
+ }
+ else
+ res.insert(individual->value());
+ }
+}
+
void IndividualGraph::getSame(IndividualBranch_t* individual, std::unordered_set& res)
{
if(individual != nullptr)
@@ -1160,6 +1197,21 @@ std::unordered_set IndividualGraph::getSameId(IndividualBranch_t* indiv
return res;
}
+void IndividualGraph::getLowestSame(IndividualBranch_t* individual, std::unordered_set& res)
+{
+ if(individual != nullptr)
+ {
+ if(individual->same_as_.size())
+ {
+ auto indiv = std::min_element(individual->same_as_.cbegin(), individual->same_as_.cend(),
+ [](auto& a, auto& b){ return a.elem->get() < b.elem->get(); });
+ res.insert(indiv->elem->get());
+ }
+ else
+ res.insert(individual->get());
+ }
+}
+
void IndividualGraph::getSame(IndividualBranch_t* individual, std::unordered_set& res)
{
if(individual != nullptr)
@@ -1416,7 +1468,7 @@ bool IndividualGraph::touch(index_t value)
return (branch != nullptr);
}
-std::unordered_set IndividualGraph::getType(const std::string& class_selector)
+std::unordered_set IndividualGraph::getType(const std::string& class_selector, bool single_same)
{
std::shared_lock lock_class(class_graph_->mutex_);
@@ -1426,13 +1478,13 @@ std::unordered_set IndividualGraph::getType(const std::string& clas
{
std::unordered_set down_set = class_graph_->getDownPtrSafe(class_branch);
for(auto down : down_set)
- class_graph_->getDownIndividual(down, res);
+ class_graph_->getDownIndividual(down, res, single_same);
}
return res;
}
-std::unordered_set IndividualGraph::getType(index_t class_selector)
+std::unordered_set IndividualGraph::getType(index_t class_selector, bool single_same)
{
std::shared_lock lock_class(class_graph_->mutex_);
@@ -1442,7 +1494,7 @@ std::unordered_set IndividualGraph::getType(index_t class_selector)
{
std::unordered_set down_set = class_graph_->getDownPtrSafe(class_branch);
for(auto down : down_set)
- class_graph_->getDownIndividual(down, res);
+ class_graph_->getDownIndividual(down, res, single_same);
}
return res;
From cd4e1e3d7e2fce646883be67a4527b208ff6280a Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Sat, 2 Sep 2023 19:12:25 +0200
Subject: [PATCH 03/18] [Sparql] use of single same as
---
.../ontologenius/core/ontologyOperators/Sparql.h | 5 +++--
src/core/ontologyOperators/Sparql.cpp | 14 ++++++++------
2 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/include/ontologenius/core/ontologyOperators/Sparql.h b/include/ontologenius/core/ontologyOperators/Sparql.h
index b6f66089..de797ead 100644
--- a/include/ontologenius/core/ontologyOperators/Sparql.h
+++ b/include/ontologenius/core/ontologyOperators/Sparql.h
@@ -17,8 +17,8 @@ class Sparql
Sparql();
void link(Ontology* onto) { onto_ = onto; }
- std::vector> runStr(const std::string& query);
- std::vector> runIndex(const std::string& query);
+ std::vector> runStr(const std::string& query, bool single_same = false);
+ std::vector> runIndex(const std::string& query, bool single_same = false);
std::string getError() { return error_; }
@@ -27,6 +27,7 @@ class Sparql
std::string error_;
std::regex sparql_pattern_;
std::map operators_;
+ bool single_same_;
template std::vector> run(const std::string& query);
diff --git a/src/core/ontologyOperators/Sparql.cpp b/src/core/ontologyOperators/Sparql.cpp
index c0e05c7f..e750e8a5 100644
--- a/src/core/ontologyOperators/Sparql.cpp
+++ b/src/core/ontologyOperators/Sparql.cpp
@@ -12,13 +12,15 @@ namespace ontologenius
operators_["NOT EXISTS"] = sparql_not_exists;
}
- std::vector> Sparql::runStr(const std::string& query)
+ std::vector> Sparql::runStr(const std::string& query, bool single_same)
{
+ single_same_ = single_same;
return run(query);
}
- std::vector> Sparql::runIndex(const std::string& query)
+ std::vector> Sparql::runIndex(const std::string& query, bool single_same)
{
+ single_same_ = single_same;
return run(query);
}
@@ -313,7 +315,7 @@ namespace ontologenius
template
std::unordered_set Sparql::getOn(const triplet_t& triplet, const T& selector)
{
- auto res = onto_->individual_graph_.getOn(triplet.subject.value, triplet.predicat.value);
+ auto res = onto_->individual_graph_.getOn(triplet.subject.value, triplet.predicat.value, single_same_);
if(isSelectorDefined(selector) == false)
return res;
else if(std::find(res.begin(), res.end(), selector) != res.end())
@@ -326,11 +328,11 @@ namespace ontologenius
std::unordered_set Sparql::getFrom(const triplet_t& triplet, const T& selector)
{
if(isSelectorDefined(selector) == false)
- return onto_->individual_graph_.getFrom(triplet.object.value, triplet.predicat.value);
+ return onto_->individual_graph_.getFrom(triplet.object.value, triplet.predicat.value, single_same_);
else
{
// Here we revert the problem as we know what we are expecting for.
- auto res = onto_->individual_graph_.getOn(selector, triplet.predicat.value);
+ auto res = onto_->individual_graph_.getOn(selector, triplet.predicat.value, single_same_);
if(std::find(res.begin(), res.end(), triplet.object.value) != res.end())
return std::unordered_set({selector});
else
@@ -357,7 +359,7 @@ namespace ontologenius
std::unordered_set Sparql::getType(const triplet_t& triplet, const T& selector)
{
if(isSelectorDefined(selector) == false)
- return onto_->individual_graph_.getType(triplet.object.value);
+ return onto_->individual_graph_.getType(triplet.object.value, single_same_);
else
{
auto types = onto_->individual_graph_.getUp(selector);
From 44704ba68a6f0c30fd28fc598d8e06c4e7301cc4 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:18:57 +0200
Subject: [PATCH 04/18] [OntoGraph] existInInheritance
---
.../core/ontoGraphs/Graphs/OntoGraph.h | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h b/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h
index 0711f80d..248f574c 100644
--- a/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h
+++ b/include/ontologenius/core/ontoGraphs/Graphs/OntoGraph.h
@@ -52,6 +52,9 @@ class OntoGraph : public Graph
bool touch(const std::string& value);
bool touch(index_t value);
+ bool existInInheritance(B* branch, const std::string& selector);
+ bool existInInheritance(B* branch, index_t selector);
+
void getDownSafe(B* branch, std::unordered_set& res, int depth = -1, unsigned int current_depth = 0);
void getUpSafe(B* branch, std::unordered_set& res, int depth = -1, unsigned int current_depth = 0);
void getDownSafe(B* branch, std::unordered_set& res, int depth = -1, unsigned int current_depth = 0);
@@ -384,6 +387,34 @@ void OntoGraph::amIA(B** me, std::map& vect, const std::stri
}
}
+template
+bool OntoGraph::existInInheritance(B* branch, const std::string& selector)
+{
+ if(branch->value() == selector)
+ return true;
+ else
+ {
+ for(auto& mother : branch->mothers_)
+ if(existInInheritance(mother.elem, selector))
+ return true;
+ }
+ return false;
+}
+
+template
+bool OntoGraph::existInInheritance(B* branch, index_t selector)
+{
+ if(branch->get() == selector)
+ return true;
+ else
+ {
+ for(auto& mother : branch->mothers_)
+ if(existInInheritance(mother.elem, selector))
+ return true;
+ }
+ return false;
+}
+
template
void OntoGraph::getDownSafe(B* branch, std::unordered_set& res, int depth, unsigned int current_depth)
{
From be4577fe24bb319c38595ff3664edce212d9ddf6 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:19:32 +0200
Subject: [PATCH 05/18] [ClassGraph] getDownIndividual reserve
---
src/core/ontoGraphs/Graphs/ClassGraph.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/core/ontoGraphs/Graphs/ClassGraph.cpp b/src/core/ontoGraphs/Graphs/ClassGraph.cpp
index 319b8d19..ea019ebc 100644
--- a/src/core/ontoGraphs/Graphs/ClassGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/ClassGraph.cpp
@@ -1089,6 +1089,7 @@ void ClassGraph::getDownIndividual(ClassBranch_t* branch, std::unordered_set lock(Graph::mutex_);
if(single_same)
{
+ res.reserve(res.size() + branch->individual_childs_.size());
for(auto& indiv : branch->individual_childs_)
individual_graph_->getLowestSame(indiv.elem, res);
}
From a88a56091f4d85fcd0d85115eb5dc979763fe0ec Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:20:25 +0200
Subject: [PATCH 06/18] [ClassGraph] getOn do not use getUpPtrSafe for depth 1
---
src/core/ontoGraphs/Graphs/ClassGraph.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/core/ontoGraphs/Graphs/ClassGraph.cpp b/src/core/ontoGraphs/Graphs/ClassGraph.cpp
index ea019ebc..73992bbd 100644
--- a/src/core/ontoGraphs/Graphs/ClassGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/ClassGraph.cpp
@@ -847,10 +847,10 @@ void ClassGraph::getOn(ClassBranch_t* class_branch, std::unordered_set&
}
current_depth++;
- std::unordered_set up_set = getUpPtrSafe(class_branch, 1);
- for(ClassBranch_t* up : up_set)
- if(up != class_branch)
- getOn(up, object_properties, data_properties, res, current_depth, found_depth);
+ //std::unordered_set up_set = getUpPtrSafe(class_branch, 1);
+ for(auto& up : class_branch->mothers_)
+ if(up.elem != class_branch)
+ getOn(up.elem, object_properties, data_properties, res, current_depth, found_depth);
}
}
From 24dba2689ae2b3bf8a3ee2534a9026e93dfe8878 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:20:52 +0200
Subject: [PATCH 07/18] [IndividualGraph] isA
---
.../core/ontoGraphs/Graphs/IndividualGraph.h | 2 +
.../ontoGraphs/Graphs/IndividualGraph.cpp | 53 +++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h b/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h
index a104c265..657ee125 100644
--- a/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h
+++ b/include/ontologenius/core/ontoGraphs/Graphs/IndividualGraph.h
@@ -118,6 +118,8 @@ class IndividualGraph : public Graph
bool touch(index_t value);
std::unordered_set getType(const std::string& class_selector, bool single_same = false);
std::unordered_set getType(index_t class_selector, bool single_same = false);
+ bool isA(const std::string& indiv, const std::string& class_selector);
+ bool isA(index_t indiv, index_t class_selector);
bool relationExists(const std::string& param);
bool relationExists(const std::string& subject, const std::string& property, const std::string& object);
diff --git a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
index cd7241e3..e023f780 100644
--- a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
@@ -1500,6 +1500,59 @@ std::unordered_set IndividualGraph::getType(index_t class_selector, boo
return res;
}
+
+bool IndividualGraph::isA(const std::string& indiv, const std::string& class_selector)
+{
+ std::shared_lock lock(Graph::mutex_);
+ IndividualBranch_t* branch = container_.find(indiv);
+ if(branch != nullptr)
+ {
+ std::shared_lock lock_class(class_graph_->mutex_);
+ if(branch->same_as_.size())
+ {
+ std::unordered_set sames;
+ getSame(branch, sames);
+ for(IndividualBranch_t* it : sames)
+ for(auto& is_a : it->is_a_)
+ if(class_graph_->existInInheritance(is_a.elem, class_selector))
+ return true;
+ }
+ else
+ {
+ for(auto& is_a : branch->is_a_)
+ if(class_graph_->existInInheritance(is_a.elem, class_selector))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IndividualGraph::isA(index_t indiv, index_t class_selector)
+{
+ std::shared_lock lock(Graph::mutex_);
+ IndividualBranch_t* branch = ordered_individuals_[indiv];
+ if(branch != nullptr)
+ {
+ std::shared_lock lock_class(class_graph_->mutex_);
+ if(branch->same_as_.size())
+ {
+ std::unordered_set sames;
+ getSame(branch, sames);
+ for(IndividualBranch_t* it : sames)
+ for(auto& is_a : it->is_a_)
+ if(class_graph_->existInInheritance(is_a.elem, class_selector))
+ return true;
+ }
+ else
+ {
+ for(auto& is_a : branch->is_a_)
+ if(class_graph_->existInInheritance(is_a.elem, class_selector))
+ return true;
+ }
+ }
+ return false;
+}
+
bool IndividualGraph::relationExists(const std::string& param)
{
std::string subject;
From 403900297b63ff3753dcf64a37f49672ed6905b3 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:21:24 +0200
Subject: [PATCH 08/18] [IndividualGraph] getUpPtr special case for depth 1
---
.../ontoGraphs/Graphs/IndividualGraph.cpp | 31 ++++++++++++++-----
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
index e023f780..ee87abd3 100644
--- a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
@@ -1084,21 +1084,36 @@ void IndividualGraph::getUp(IndividualBranch_t* indiv, std::unordered_set& re
void IndividualGraph::getUpPtr(IndividualBranch_t* indiv, std::unordered_set& res, int depth, uint32_t current_depth)
{
- current_depth++;
if(indiv != nullptr)
{
- if(indiv->same_as_.size())
+ if(depth != 1)
{
- std::unordered_set sames;
- getSame(indiv, sames);
- for(IndividualBranch_t* it : sames)
- for(auto& is_a : it->is_a_)
+ current_depth++;
+ if(indiv->same_as_.size())
+ {
+ for(auto& it : indiv->same_as_)
+ for(auto& is_a : it.elem->is_a_)
+ class_graph_->getUpPtr(is_a.elem, res, depth, current_depth);
+ }
+ else
+ {
+ for(auto& is_a : indiv->is_a_)
class_graph_->getUpPtr(is_a.elem, res, depth, current_depth);
+ }
}
else
{
- for(auto& is_a : indiv->is_a_)
- class_graph_->getUpPtr(is_a.elem, res, depth, current_depth);
+ if(indiv->same_as_.size())
+ {
+ for(auto& it : indiv->same_as_)
+ for(auto& is_a : it.elem->is_a_)
+ res.insert(is_a.elem);
+ }
+ else
+ {
+ for(auto& is_a : indiv->is_a_)
+ res.insert(is_a.elem);
+ }
}
}
}
From f8dd72d712cf0c8d1497c82c735c0c2f37c89da5 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:21:58 +0200
Subject: [PATCH 09/18] [IndividualGraph] reduce set creation
---
.../ontoGraphs/Graphs/IndividualGraph.cpp | 49 ++++++++++++++-----
1 file changed, 36 insertions(+), 13 deletions(-)
diff --git a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
index ee87abd3..f5c9cf81 100644
--- a/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
+++ b/src/core/ontoGraphs/Graphs/IndividualGraph.cpp
@@ -852,6 +852,8 @@ std::unordered_set IndividualGraph::getOn(index_t individual, index_t p
return getOn(indiv, property, single_same);
}
+// Duplication in this function avoid the creation of the same_as set
+// This for performance issues in the SPARQL solver
template
std::unordered_set IndividualGraph::getOn(IndividualBranch_t* individual, const T& property, bool single_same)
{
@@ -859,16 +861,28 @@ std::unordered_set IndividualGraph::getOn(IndividualBranch_t* individual, con
if(individual != nullptr)
{
- std::unordered_set sames;
- getSame(individual, sames);
-
std::unordered_set object_properties = object_property_graph_->getDownId(property);
std::unordered_set data_properties;
if(object_properties.size())
{
- for(auto same_indiv : sames)
+ if(individual->same_as_.size())
+ {
+ for(auto& same_indiv : individual->same_as_)
+ {
+ for(IndivObjectRelationElement_t& relation : same_indiv.elem->object_relations_)
+ for (index_t id : object_properties)
+ if(relation.first->get() == id)
+ {
+ if(single_same)
+ getLowestSame(relation.second, res);
+ else
+ getSame(relation.second, res);
+ }
+ }
+ }
+ else
{
- for(IndivObjectRelationElement_t& relation : same_indiv->object_relations_)
+ for(IndivObjectRelationElement_t& relation : individual->object_relations_)
for (index_t id : object_properties)
if(relation.first->get() == id)
{
@@ -879,14 +893,24 @@ std::unordered_set IndividualGraph::getOn(IndividualBranch_t* individual, con
}
}
}
- else
+ else
{
data_properties = data_property_graph_->getDownId(property);
if(data_properties.size())
{
- for(auto same_indiv : sames)
+ if(individual->same_as_.size())
{
- for(IndivDataRelationElement_t& relation : same_indiv->data_relations_)
+ for(auto& same_indiv : individual->same_as_)
+ {
+ for(IndivDataRelationElement_t& relation : same_indiv.elem->data_relations_)
+ for (index_t id : data_properties)
+ if(relation.first->get() == id)
+ insert(res, relation.second);
+ }
+ }
+ else
+ {
+ for(IndivDataRelationElement_t& relation : individual->data_relations_)
for (index_t id : data_properties)
if(relation.first->get() == id)
insert(res, relation.second);
@@ -1068,10 +1092,8 @@ void IndividualGraph::getUp(IndividualBranch_t* indiv, std::unordered_set& re
{
if(indiv->same_as_.size())
{
- std::unordered_set sames;
- getSame(indiv, sames);
- for(IndividualBranch_t* it : sames)
- for(auto& is_a : it->is_a_)
+ for(auto& it : indiv->same_as_)
+ for(auto& is_a : it.elem->is_a_)
class_graph_->getUp(is_a.elem, res, depth, current_depth);
}
else
@@ -1507,7 +1529,8 @@ std::unordered_set IndividualGraph::getType(index_t class_selector, boo
ClassBranch_t* class_branch = class_graph_->container_.find(ValuedNode::table_.get(class_selector));
if(class_branch != nullptr)
{
- std::unordered_set down_set = class_graph_->getDownPtrSafe(class_branch);
+ std::unordered_set down_set;
+ class_graph_->getDownPtr(class_branch, down_set);
for(auto down : down_set)
class_graph_->getDownIndividual(down, res, single_same);
}
From 51abdd45da882ae710578199a1a01979b3450095 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 13:22:18 +0200
Subject: [PATCH 10/18] [Sparql] use isA function
---
src/core/ontologyOperators/Sparql.cpp | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/core/ontologyOperators/Sparql.cpp b/src/core/ontologyOperators/Sparql.cpp
index e750e8a5..1a3fe34a 100644
--- a/src/core/ontologyOperators/Sparql.cpp
+++ b/src/core/ontologyOperators/Sparql.cpp
@@ -347,8 +347,9 @@ namespace ontologenius
return onto_->individual_graph_.getUp(triplet.subject.value);
else
{
- auto is = onto_->individual_graph_.getUp(triplet.subject.value);
- if(std::find(is.begin(), is.end(), selector) != is.end())
+ //auto is = onto_->individual_graph_.getUp(triplet.subject.value);
+ //if(std::find(is.begin(), is.end(), selector) != is.end())
+ if(onto_->individual_graph_.isA(triplet.subject.value, selector))
return std::unordered_set({selector});
else
return std::unordered_set();
@@ -362,9 +363,10 @@ namespace ontologenius
return onto_->individual_graph_.getType(triplet.object.value, single_same_);
else
{
- auto types = onto_->individual_graph_.getUp(selector);
- if(std::find(types.begin(), types.end(), triplet.object.value) != types.end())
- return std::unordered_set({selector});
+ //auto types = onto_->individual_graph_.getUp(selector);
+ //if(std::find(types.begin(), types.end(), triplet.object.value) != types.end())
+ if(onto_->individual_graph_.isA(selector, triplet.object.value))
+ return {selector};
else
return std::unordered_set();
}
From 44ad603beaa527be808ad6151251bd06a45210bd Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 14:52:59 +0200
Subject: [PATCH 11/18] [Sparql] update sparql msg to reduce memory use
---
.../API/ontologenius/clients/SparqlClient.h | 2 +-
.../ontologenius/clientsIndex/SparqlIndexClient.h | 2 +-
msg/OntologeniusSparqlIndexResponse.msg | 1 -
msg/OntologeniusSparqlResponse.msg | 1 -
src/API/ontologenius/clients/SparqlClient.cpp | 8 ++++----
.../ontologenius/clientsIndex/SparqlIndexClient.cpp | 6 +++---
src/core/ontologyOperators/SparqlSolver.cpp | 12 ++++++++++--
src/interface/RosInterfaceIndexHandlers.cpp | 11 ++++++++---
src/interface/RosInterfaceStringHandlers.cpp | 11 ++++++++---
srv/OntologeniusSparqlIndexService.srv | 1 +
srv/OntologeniusSparqlService.srv | 1 +
11 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/include/ontologenius/API/ontologenius/clients/SparqlClient.h b/include/ontologenius/API/ontologenius/clients/SparqlClient.h
index 8a807005..131dee43 100644
--- a/include/ontologenius/API/ontologenius/clients/SparqlClient.h
+++ b/include/ontologenius/API/ontologenius/clients/SparqlClient.h
@@ -23,7 +23,7 @@ class SparqlClient
n_ = n;
}
- std::vector call(const std::string& query);
+ std::pair, std::vector> call(const std::string& query);
private:
ros::ServiceClient client;
diff --git a/include/ontologenius/API/ontologenius/clientsIndex/SparqlIndexClient.h b/include/ontologenius/API/ontologenius/clientsIndex/SparqlIndexClient.h
index 44d3f221..cd3eb316 100644
--- a/include/ontologenius/API/ontologenius/clientsIndex/SparqlIndexClient.h
+++ b/include/ontologenius/API/ontologenius/clientsIndex/SparqlIndexClient.h
@@ -23,7 +23,7 @@ class SparqlIndexClient
n_ = n;
}
- std::vector call(const std::string& query);
+ std::pair, std::vector> call(const std::string& query);
private:
ros::ServiceClient client;
diff --git a/msg/OntologeniusSparqlIndexResponse.msg b/msg/OntologeniusSparqlIndexResponse.msg
index ae342c0c..ed137e81 100644
--- a/msg/OntologeniusSparqlIndexResponse.msg
+++ b/msg/OntologeniusSparqlIndexResponse.msg
@@ -1,2 +1 @@
-string[] names
int64[] values
diff --git a/msg/OntologeniusSparqlResponse.msg b/msg/OntologeniusSparqlResponse.msg
index 3c42d55c..b12fe572 100644
--- a/msg/OntologeniusSparqlResponse.msg
+++ b/msg/OntologeniusSparqlResponse.msg
@@ -1,2 +1 @@
-string[] names
string[] values
diff --git a/src/API/ontologenius/clients/SparqlClient.cpp b/src/API/ontologenius/clients/SparqlClient.cpp
index dd76acfc..9e7cf5ab 100644
--- a/src/API/ontologenius/clients/SparqlClient.cpp
+++ b/src/API/ontologenius/clients/SparqlClient.cpp
@@ -2,20 +2,20 @@
namespace onto {
-std::vector SparqlClient::call(const std::string& query)
+std::pair, std::vector> SparqlClient::call(const std::string& query)
{
ontologenius::OntologeniusSparqlService srv;
srv.request.query = query;
if(client.call(srv))
- return srv.response.results;
+ return {srv.response.names, srv.response.results};
else
{
client = n_->serviceClient("ontologenius/" + name_, true);
if(client.call(srv))
- return srv.response.results;
+ return {srv.response.names, srv.response.results};
else
- return {};
+ return {{}, {}};
}
}
diff --git a/src/API/ontologenius/clientsIndex/SparqlIndexClient.cpp b/src/API/ontologenius/clientsIndex/SparqlIndexClient.cpp
index a2741c0c..64ada339 100644
--- a/src/API/ontologenius/clientsIndex/SparqlIndexClient.cpp
+++ b/src/API/ontologenius/clientsIndex/SparqlIndexClient.cpp
@@ -2,18 +2,18 @@
namespace onto {
-std::vector SparqlIndexClient::call(const std::string& query)
+std::pair, std::vector> SparqlIndexClient::call(const std::string& query)
{
ontologenius::OntologeniusSparqlIndexService srv;
srv.request.query = query;
if(client.call(srv))
- return srv.response.results;
+ return {srv.response.names, srv.response.results};
else
{
client = n_->serviceClient("ontologenius/" + name_, true);
if(client.call(srv))
- return srv.response.results;
+ return {srv.response.names, srv.response.results};
else
return {};
}
diff --git a/src/core/ontologyOperators/SparqlSolver.cpp b/src/core/ontologyOperators/SparqlSolver.cpp
index 03bc13ec..560bb439 100644
--- a/src/core/ontologyOperators/SparqlSolver.cpp
+++ b/src/core/ontologyOperators/SparqlSolver.cpp
@@ -3,6 +3,10 @@
#include "ontologenius/utils/String.h"
#include "ontologenius/graphical/Display.h"
+#include "time.h"
+#include
+using namespace std::chrono;
+
namespace ontologenius
{
SparqlSolver::SparqlSolver() : onto_(nullptr),
@@ -17,7 +21,8 @@ namespace ontologenius
SparqlSolution_t initial_solution;
std::smatch match;
- if (std::regex_match(query_, match, sparql_pattern_))
+ bool has_matched = std::regex_match(query_, match, sparql_pattern_);
+ if (has_matched)
{
std::string vars = match[2].str();
removeChar(vars, {'\n', '\r'});
@@ -38,7 +43,6 @@ namespace ontologenius
else if(var != "")
initial_solution.solution_[var.substr(1)] = "";
}
-
}
else
{
@@ -51,7 +55,11 @@ namespace ontologenius
orderVariables(initial_solution);
int index = 0;
+ high_resolution_clock::time_point t1 = high_resolution_clock::now();
stepDown(initial_solution, index);
+ high_resolution_clock::time_point t2 = high_resolution_clock::now();
+ duration time_span = duration_cast>(t2 - t1);
+ std::cout << "took " << time_span.count()*1000 << "ms" << std::endl;
return SparqlSolver::iterator(initial_solution, this);
}
diff --git a/src/interface/RosInterfaceIndexHandlers.cpp b/src/interface/RosInterfaceIndexHandlers.cpp
index 5ad52865..e89ca536 100644
--- a/src/interface/RosInterfaceIndexHandlers.cpp
+++ b/src/interface/RosInterfaceIndexHandlers.cpp
@@ -372,14 +372,19 @@ bool RosInterface::sparqlIndexHandle(ontologenius::OntologeniusSparqlIndexServic
{
std::vector> results = sparql_.runIndex(req.query);
+ if(results.size())
+ {
+ auto first = results.front();
+ for(auto& r : first)
+ res.names.push_back(r.first);
+ }
+
for(auto& result : results)
{
ontologenius::OntologeniusSparqlIndexResponse tmp;
for(auto& r : result)
- {
- tmp.names.push_back(r.first);
tmp.values.push_back(r.second);
- }
+
res.results.push_back(tmp);
}
diff --git a/src/interface/RosInterfaceStringHandlers.cpp b/src/interface/RosInterfaceStringHandlers.cpp
index 2f33db0b..13dbf950 100644
--- a/src/interface/RosInterfaceStringHandlers.cpp
+++ b/src/interface/RosInterfaceStringHandlers.cpp
@@ -372,14 +372,19 @@ bool RosInterface::sparqlHandle(ontologenius::OntologeniusSparqlService::Request
{
std::vector> results = sparql_.runStr(req.query);
+ if(results.size())
+ {
+ auto first = results.front();
+ for(auto& r : first)
+ res.names.push_back(r.first);
+ }
+
for(auto& result : results)
{
ontologenius::OntologeniusSparqlResponse tmp;
for(auto& r : result)
- {
- tmp.names.push_back(r.first);
tmp.values.push_back(r.second);
- }
+
res.results.push_back(tmp);
}
diff --git a/srv/OntologeniusSparqlIndexService.srv b/srv/OntologeniusSparqlIndexService.srv
index 43f482f1..efe0df18 100644
--- a/srv/OntologeniusSparqlIndexService.srv
+++ b/srv/OntologeniusSparqlIndexService.srv
@@ -1,4 +1,5 @@
string query
---
+string[] names
OntologeniusSparqlIndexResponse[] results
string error
diff --git a/srv/OntologeniusSparqlService.srv b/srv/OntologeniusSparqlService.srv
index 30ab729a..7969e493 100644
--- a/srv/OntologeniusSparqlService.srv
+++ b/srv/OntologeniusSparqlService.srv
@@ -1,4 +1,5 @@
string query
---
+string[] names
OntologeniusSparqlResponse[] results
string error
From 8247c97de96c1f7a2c3366ebe3a7589bc1c865c6 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 14:55:12 +0200
Subject: [PATCH 12/18] [ontopy] update SparqlClient
---
ontopy/ontologenius/clients/SparqlClient.py | 4 ++--
ontopy/ontologenius/clientsIndex/SparqlIndexClient.py | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ontopy/ontologenius/clients/SparqlClient.py b/ontopy/ontologenius/clients/SparqlClient.py
index 1089935b..b94b6ec9 100644
--- a/ontopy/ontologenius/clients/SparqlClient.py
+++ b/ontopy/ontologenius/clients/SparqlClient.py
@@ -20,11 +20,11 @@ def __init__(self, name):
def call(self, query):
try:
response = self._client(query)
- return response.results
+ return (response.names, response.results)
except rospy.ServiceException as e:
self._client = rospy.ServiceProxy('ontologenius/' + self._name, OntologeniusSparqlService, True)
try:
response = self._client(query)
- return response.results
+ return (response.names, response.results)
except rospy.ServiceException as e:
return None
diff --git a/ontopy/ontologenius/clientsIndex/SparqlIndexClient.py b/ontopy/ontologenius/clientsIndex/SparqlIndexClient.py
index 28221030..53815390 100644
--- a/ontopy/ontologenius/clientsIndex/SparqlIndexClient.py
+++ b/ontopy/ontologenius/clientsIndex/SparqlIndexClient.py
@@ -20,11 +20,11 @@ def __init__(self, name):
def call(self, query):
try:
response = self._client(query)
- return response.results
+ return (response.names, response.results)
except rospy.ServiceException as e:
self._client = rospy.ServiceProxy('ontologenius/' + self._name, OntologeniusSparqlIndexService, True)
try:
response = self._client(query)
- return response.results
+ return (response.names, response.results)
except rospy.ServiceException as e:
return None
From a7853336d63c2dee5786f39306f98b45d8a6e3d2 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Thu, 7 Sep 2023 15:04:03 +0200
Subject: [PATCH 13/18] [Doc] update SPARQL documentation
---
docs/cpp_API/SparqlClient.html | 109 ++++++++++++-------------
docs/cpp_API/SparqlIndexClient.html | 4 +-
docs/python_API/SparqlClient.html | 107 +++++++++++-------------
docs/python_API/SparqlIndexClient.html | 2 +-
4 files changed, 102 insertions(+), 120 deletions(-)
diff --git a/docs/cpp_API/SparqlClient.html b/docs/cpp_API/SparqlClient.html
index 3520f473..5e1f7282 100644
--- a/docs/cpp_API/SparqlClient.html
+++ b/docs/cpp_API/SparqlClient.html
@@ -135,7 +135,7 @@ Methods
| SparqlClient(ros::NodeHandle* n, const std::string& name) |
- std::vector<OntologeniusSparqlResponse> | call(const std::string& query) |
+ std::pair<std::vector<std::string>, std::vector<OntologeniusSparqlResponse>> | call(const std::string& query) |
@@ -154,7 +154,7 @@ S
Constructs a sparql client.
Can be used in a multi-ontology mode by specifying the name of the ontology name. For classic use, name should be defined as "".
- std::vector<OntologeniusSparqlResponse> call(const std::string& query)
+ std::pair<std::vector<std::string>, std::vector<OntologeniusSparqlResponse>> call(const std::string& query)
Basic query Examples
@@ -168,67 +168,58 @@ Basic query Examples
You can also add the DISTINCT keyword just after the SELECT to ensure unique results.
The following blocks are examples of possible patterns.
-
-
-
results:
-
-
-
names: [type]
-
values: [Room]
-
- Give to class of Bedroom.
+
+
+
names: [type]
+
results:
+
- values: [Room]
+
+ Give to class of Bedroom.
-
-
-
results:
-
-
-
names: [table]
-
values: [Table2]
-
-
-
names: [table]
-
values: [Table1]
-
- Give all the tables.
+
+
+
names: [table]
+
results:
+
- values: [Table2]
+
- values: [Table1]
+
+ Give all the tables.
-
-
-
results:
-
-
-
names: [room]
-
values: [Bedroom]
-
- Give all the individuals for which the individual 'Table1' is in it.
+
+
+
names: [room]
+
results:
+
- values: [Bedroom]
+
+ Give all the individuals for which the individual 'Table1' is in it.
-
-
?object isA Table. ?object isIn ?room
-
-
-
results:
-
-
-
names: [object, room]
-
values: [Table2, LivingRoom]
-
-
-
names: [object, room]
-
values: [Table1, Bedroom]
-
- Give all the individuals that are tables and the room in which they are.
+
+
?object isA Table. ?object isIn ?room
+
+
+
names: [object, room]
+
results:
+
- values: [Table2, LivingRoom]
+
- values: [Table1, Bedroom]
+
+ Give all the individuals that are tables and the room in which they are.
- Query with negation
-
-
?object isA Table NOT EXISTS { ?object isIn LivingRoom }
-
-
-
results:
-
-
-
names: [object]
-
values: [Table1]
-
- Give all the individuals that are tables and not in the living room.
+ Query with negation
+
+
?object isA Table NOT EXISTS { ?object isIn LivingRoom }
+
+
+
names: [object]
+
results:
+
- values: [Table1]
+
+ Give all the individuals that are tables and not in the living room.
diff --git a/docs/cpp_API/SparqlIndexClient.html b/docs/cpp_API/SparqlIndexClient.html
index 874306cb..3c0539c1 100644
--- a/docs/cpp_API/SparqlIndexClient.html
+++ b/docs/cpp_API/SparqlIndexClient.html
@@ -135,7 +135,7 @@ Methods
| SparqlIndexClient(ros::NodeHandle* n, const std::string& name) |
- std::vector<OntologeniusSparqlIndexResponse> | call(const std::string& query) |
+ std::pair<std::vector<std::string>, std::vector<OntologeniusSparqlIndexResponse>> | call(const std::string& query) |
@@ -157,7 +157,7 @@ Constructs a sparql client.
Can be used in a multi-ontology mode by specifying the name of the ontology name. For classic use, name should be defined as "".
- std::vector<OntologeniusSparqlIndexResponse> call(const std::string& query)
+ std::pair<std::vector<std::string>, std::vector<OntologeniusSparqlIndexResponse>> call(const std::string& query)
Basic query Examples
diff --git a/docs/python_API/SparqlClient.html b/docs/python_API/SparqlClient.html
index cb2c0fed..8d804722 100644
--- a/docs/python_API/SparqlClient.html
+++ b/docs/python_API/SparqlClient.html
@@ -134,7 +134,7 @@ Methods
| __init__(self, name) |
- OntologeniusSparqlResponse[] | call(self, query) |
+ (str[], OntologeniusSparqlResponse[]) | call(self, query) |
@@ -167,67 +167,58 @@ Basic query Examples
You can also add the DISTINCT keyword just after the SELECT to ensure unique results.
The following blocks are examples of possible patterns.
-
-
-
results:
-
-
-
names: [type]
-
values: [Room]
-
- Give to class of Bedroom.
+
+
+
names: [type]
+
results:
+
- values: [Room]
+
+ Give to class of Bedroom.
-
-
-
results:
-
-
-
names: [table]
-
values: [Table2]
-
-
-
names: [table]
-
values: [Table1]
-
- Give all the tables.
+
+
+
names: [table]
+
results:
+
- values: [Table2]
+
- values: [Table1]
+
+ Give all the tables.
-
-
-
results:
-
-
-
names: [room]
-
values: [Bedroom]
-
- Give all the individuals for which the individual 'Table1' is in it.
+
+
+
names: [room]
+
results:
+
- values: [Bedroom]
+
+ Give all the individuals for which the individual 'Table1' is in it.
-
-
?object isA Table. ?object isIn ?room
-
-
-
results:
-
-
-
names: [object, room]
-
values: [Table2, Bedroom]
-
-
-
names: [object, room]
-
values: [Table1, Bedroom]
-
- Give all the individuals that are tables and the room in which they are.
+
+
?object isA Table. ?object isIn ?room
+
+
+
names: [object, room]
+
results:
+
- values: [Table2, LivingRoom]
+
- values: [Table1, Bedroom]
+
+ Give all the individuals that are tables and the room in which they are.
- Query with negation
-
-
?object isA Table NOT EXISTS { ?object isIn LivingRoom }
-
-
-
results:
-
-
-
names: [object]
-
values: [Table1]
-
- Give all the individuals that are tables and not in the living room.
+ Query with negation
+
+
?object isA Table NOT EXISTS { ?object isIn LivingRoom }
+
+
+
names: [object]
+
results:
+
- values: [Table1]
+
+ Give all the individuals that are tables and not in the living room.
diff --git a/docs/python_API/SparqlIndexClient.html b/docs/python_API/SparqlIndexClient.html
index 482aed68..2ed9f1f6 100644
--- a/docs/python_API/SparqlIndexClient.html
+++ b/docs/python_API/SparqlIndexClient.html
@@ -134,7 +134,7 @@ Methods
| __init__(self, name) |
- OntologeniusSparqlIndexResponse[] | call(self, query) |
+ (str[], OntologeniusSparqlIndexResponse[]) | call(self, query) |
From dcc1901396392f53e081df9b9b5f5ec892cde98c Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Fri, 8 Sep 2023 18:37:09 +0200
Subject: [PATCH 14/18] [Sparql] change internal structure
---
.../core/ontologyOperators/Sparql.h | 16 +-
.../core/ontologyOperators/SparqlUtils.h | 75 +++++-
src/core/ontologyOperators/Sparql.cpp | 232 ++++++++----------
src/core/ontologyOperators/SparqlSolver.cpp | 32 +--
src/interface/RosInterfaceIndexHandlers.cpp | 14 +-
src/interface/RosInterfaceStringHandlers.cpp | 14 +-
src/tests/sparql.cpp | 14 +-
7 files changed, 210 insertions(+), 187 deletions(-)
diff --git a/include/ontologenius/core/ontologyOperators/Sparql.h b/include/ontologenius/core/ontologyOperators/Sparql.h
index de797ead..1224e706 100644
--- a/include/ontologenius/core/ontologyOperators/Sparql.h
+++ b/include/ontologenius/core/ontologyOperators/Sparql.h
@@ -17,8 +17,8 @@ class Sparql
Sparql();
void link(Ontology* onto) { onto_ = onto; }
- std::vector> runStr(const std::string& query, bool single_same = false);
- std::vector> runIndex(const std::string& query, bool single_same = false);
+ std::pair, std::vector>> runStr(const std::string& query, bool single_same = false);
+ std::pair, std::vector>> runIndex(const std::string& query, bool single_same = false);
std::string getError() { return error_; }
@@ -29,11 +29,11 @@ class Sparql
std::map operators_;
bool single_same_;
- template std::vector> run(const std::string& query);
+ template std::pair, std::vector>> run(const std::string& query);
- template std::vector> resolve(std::vector> query, SparqlOperator_e op = sparql_none, const std::vector>& prev_res = {});
- template std::vector> resolve(const std::vector>& query, const std::map& accu);
- template void resolveSubQuery(triplet_t triplet, const std::map& accu, std::string& var_name, std::unordered_set& values);
+ template std::vector> resolve(std::vector> query, SparqlOperator_e op, const std::vector>& prev_res);
+ template std::vector> resolve(const std::vector>& query, const std::vector& accu);
+ template void resolveSubQuery(triplet_t triplet, const std::vector& accu, int64_t& var_name, std::unordered_set& values);
template std::unordered_set getOn(const triplet_t& triplet, const T& selector);
template std::unordered_set getFrom(const triplet_t& triplet, const T& selector);
@@ -46,8 +46,8 @@ class Sparql
std::vector getBlocks(std::string query);
template std::vector> getTriplets(const std::string& query, const std::string& delim);
- template void mergeNoOp(const std::map& base, std::vector>& res);
- template void mergeNotExists(const std::map& base, std::vector>& res);
+ template void mergeNoOp(const std::vector& base, std::vector>& res);
+ template void mergeNotExists(const std::vector& base, std::vector>& res);
};
} // namespace ontologenius
diff --git a/include/ontologenius/core/ontologyOperators/SparqlUtils.h b/include/ontologenius/core/ontologyOperators/SparqlUtils.h
index 6c52d7ae..c6fdc18b 100644
--- a/include/ontologenius/core/ontologyOperators/SparqlUtils.h
+++ b/include/ontologenius/core/ontologyOperators/SparqlUtils.h
@@ -28,12 +28,26 @@ struct SparqlBlock_t
template
struct resource_t
{
+ resource_t() : variable_id(-1),
+ is_variable(false),
+ regex(false) {}
+
+ static std::unordered_map variables;
+ static std::vector to_variables;
+
std::string name;
T value;
- bool variable;
+ int64_t variable_id;
+ bool is_variable;
bool regex;
};
+template
+std::unordered_map resource_t::variables;
+
+template
+std::vector resource_t::to_variables;
+
template
struct triplet_t
{
@@ -69,12 +83,22 @@ resource_t getResource(std::string resource_txt)
if(resource_txt[0] == '?')
{
- res.variable = true;
+ res.is_variable = true;
resource_txt = resource_txt.substr(1);
+ auto var_it = resource_t::variables.find(resource_txt);
+ if(var_it == resource_t::variables.end())
+ {
+ int64_t index = resource_t::variables.size();
+ resource_t::variables[resource_txt] = index;
+ res.variable_id = index;
+ resource_t::to_variables.push_back(resource_txt);
+ }
+ else
+ res.variable_id = var_it->second;
}
else
{
- res.variable = false;
+ res.is_variable = false;
if(resource_txt != "isA")
res.value = convertResourceValue(resource_txt);
}
@@ -101,7 +125,7 @@ triplet_t getTriplet(const std::string& triplet_txt)
case 1: res.predicat = resource; break;
case 2: res.object = resource; break;
default:
- if(res.object.variable == false)
+ if(res.object.is_variable == false)
res.object.name += " " + resource.name;
else
throw "invalid triplet format in : " + triplet_txt;
@@ -116,9 +140,9 @@ triplet_t getTriplet(const std::string& triplet_txt)
template
std::string toString(const triplet_t& triplet)
{
- return (triplet.subject.variable ? "?" : "") + triplet.subject.name + " " +
- (triplet.predicat.variable ? "?" : "") + triplet.predicat.name + " " +
- (triplet.object.variable ? "?" : "") + triplet.object.name;
+ return (triplet.subject.is_variable ? "?" : "") + triplet.subject.name + " " +
+ (triplet.predicat.is_variable ? "?" : "") + triplet.predicat.name + " " +
+ (triplet.object.is_variable ? "?" : "") + triplet.object.name;
}
template
@@ -133,6 +157,22 @@ void removeDuplicate(std::vector>& vect)
vect.erase(unique(vect.begin(), vect.end(), equalLambda), vect.end());
}
+template
+std::vector convertVariables(const std::vector& var_names)
+{
+ std::vector res;
+ for(auto& var : var_names)
+ res.push_back(resource_t::variables[var]);
+ std::sort(res.begin(), res.end());
+ return res;
+}
+
+template
+void removeDuplicate(std::vector>& vect)
+{
+ vect.erase(unique(vect.begin(), vect.end()), vect.end());
+}
+
template
void filter(std::vector>& res, const std::vector& vars, bool distinct)
{
@@ -152,6 +192,27 @@ void filter(std::vector>& res, const std::vector
+void filter(std::vector>& res, const std::vector& vars, bool distinct)
+{
+ if(vars.size())
+ {
+ if(vars[0] == "*")
+ return;
+
+ std::vector var_index = convertVariables(vars);
+
+ for(auto& sub_res : res)
+ {
+ for(auto it = var_index.rbegin(); it != var_index.rend(); ++it)
+ sub_res.erase(sub_res.begin() + *it);
+ }
+
+ if(distinct)
+ removeDuplicate(res);
+ }
+}
+
} // namespace ontologenius
#endif // ONTOLOGENIUS_SPARQLUTILS_H
\ No newline at end of file
diff --git a/src/core/ontologyOperators/Sparql.cpp b/src/core/ontologyOperators/Sparql.cpp
index 1a3fe34a..631e5888 100644
--- a/src/core/ontologyOperators/Sparql.cpp
+++ b/src/core/ontologyOperators/Sparql.cpp
@@ -12,27 +12,30 @@ namespace ontologenius
operators_["NOT EXISTS"] = sparql_not_exists;
}
- std::vector> Sparql::runStr(const std::string& query, bool single_same)
+ std::pair, std::vector>> Sparql::runStr(const std::string& query, bool single_same)
{
single_same_ = single_same;
return run(query);
}
- std::vector> Sparql::runIndex(const std::string& query, bool single_same)
+ std::pair, std::vector>> Sparql::runIndex(const std::string& query, bool single_same)
{
single_same_ = single_same;
return run(query);
}
template
- std::vector> Sparql::run(const std::string& query)
+ std::pair, std::vector>> Sparql::run(const std::string& query)
{
- std::vector> res;
+ resource_t::variables.clear();
+ resource_t::to_variables.clear();
+
+ std::vector> res;
error_ = "";
if(onto_ == nullptr)
{
error_ = "ontology is undefined";
- return res;
+ return {{}, {}};
}
std::smatch match;
@@ -47,42 +50,58 @@ namespace ontologenius
auto blocks = getBlocks(pattern);
if(error_ != "")
- return res;
+ return {{}, {}};
for(auto& block : blocks)
{
auto triplets = getTriplets(block.raw, ".");
if(error_ != "")
- return res;
+ return {{}, {}};
res = resolve(triplets, block.op, res);
}
filter(res, vars_to_return, match[1].str() != "");
- return res;
+
+ if(vars_to_return.size())
+ {
+ if(vars_to_return[0] == "*")
+ return {resource_t::to_variables, res};
+
+ std::vector var_index = convertVariables(vars_to_return);
+ std::vector ordered_vars;
+ for(auto index : var_index)
+ ordered_vars.push_back(resource_t::to_variables[index]);
+ return {ordered_vars, res};
+ }
+ else
+ return {resource_t::to_variables, std::move(res)};
}
else
{
auto triplets = getTriplets(query, ",");
if(triplets.size())
- return resolve(triplets);
+ {
+ auto values = resolve(triplets, std::vector(resource_t::to_variables.size(), getDefaultSelector()));
+ return {resource_t::to_variables, std::move(values)};
+ }
else
{
Display::error("The query is malformed");
- return {};
+ return {{}, {}};
}
}
}
template
- std::vector> Sparql::resolve(std::vector> query, SparqlOperator_e op, const std::vector>& prev_res)
+ std::vector> Sparql::resolve(std::vector> query, SparqlOperator_e op, const std::vector>& prev_res)
{
- std::vector> res;
+ std::vector> res;
if(prev_res.size())
{
for(auto& prev : prev_res)
{
- std::vector> local_res;
+ std::vector> local_res;
if(query.size())
local_res = resolve(query, prev);
@@ -98,113 +117,92 @@ namespace ontologenius
}
else
{
- std::map empty_accu;
+ std::vector empty_accu(resource_t::to_variables.size(), getDefaultSelector());
return resolve(query, empty_accu);
}
}
+ // accu keep trak of the varaibles already assigned at a given stage
template
- std::vector> Sparql::resolve(const std::vector>& query, const std::map& accu)
+ std::vector> Sparql::resolve(const std::vector>& query, const std::vector& accu)
{
- std::vector> res;
-
std::unordered_set values;
- std::string var_name;
- resolveSubQuery(query[0], accu, var_name, values);
+ int64_t var_index;
+ resolveSubQuery(query[0], accu, var_index, values);
if(values.size() == 0)
- return res;
+ return {};
if(query.size() > 1)
{
std::vector> new_query(query.begin() + 1, query.end());
- auto accu_it = accu.find(var_name);
-
+ std::vector> res;
res.reserve(values.size());
+ std::vector new_accu(accu);
for(auto& value : values)
{
- std::vector> local_res;
- std::map new_accu;
- if(accu_it != accu.end())
+ if(accu[var_index] != getDefaultSelector())
{
- if(accu_it->second != value)
+ if(accu[var_index] != value)
continue;
- else
- new_accu = accu;
}
else
- {
- new_accu = accu;
- new_accu[var_name] = value;
- }
+ new_accu[var_index] = value;
- local_res = resolve(new_query, new_accu);
+ std::vector> local_res = resolve(new_query, new_accu);
if(local_res.size() != 0)
{
for(auto& lr : local_res)
{
- lr[var_name] = value;
- res.push_back(lr);
+ lr[var_index] = value;
+ res.push_back(std::move(lr));
}
}
}
+ return res;
}
else
{
- res.reserve(values.size());
+ std::vector> res(values.size(), std::vector(resource_t::variables.size(), getDefaultSelector()));
+ size_t cpt = 0;
for(auto& value : values)
- res.emplace_back(std::initializer_list>{{var_name, value}});
- }
-
- return res;
+ res[cpt++][var_index] = value;
+ return res;
+ }
}
template
- void Sparql::resolveSubQuery(triplet_t triplet, const std::map& accu, std::string& var_name, std::unordered_set& values)
+ void Sparql::resolveSubQuery(triplet_t triplet, const std::vector& accu, int64_t& var_index, std::unordered_set& values)
{
- if(triplet.predicat.variable)
+ if(triplet.predicat.is_variable)
error_ = "predicat can not be a variable in: " + toString(triplet);
else if(triplet.predicat.name == "isA")
{
- if(triplet.subject.variable && !triplet.object.variable)
+ if(triplet.subject.is_variable && !triplet.object.is_variable)
{
- var_name = triplet.subject.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getType(triplet, var_it->second);
- else
- values = getType(triplet, getDefaultSelector());
+ var_index = triplet.subject.variable_id;
+ values = getType(triplet, accu[var_index]);
}
- else if(!triplet.subject.variable && triplet.object.variable)
+ else if(!triplet.subject.is_variable && triplet.object.is_variable)
{
- var_name = triplet.object.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getUp(triplet, var_it->second);
- else
- values = getUp(triplet, getDefaultSelector());
+ var_index = triplet.object.variable_id;
+ values = getUp(triplet, accu[var_index]);
}
- else if(triplet.subject.variable && triplet.object.variable)
+ else if(triplet.subject.is_variable && triplet.object.is_variable)
{
- var_name = triplet.subject.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
+ var_index = triplet.subject.variable_id;
+ if(accu[var_index] != getDefaultSelector())
{
- triplet.subject.value = var_it->second;
- var_name = triplet.object.name;
- var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getUp(triplet, var_it->second);
- else
- values = getUp(triplet, getDefaultSelector());
+ triplet.subject.value = accu[var_index];
+ var_index = triplet.object.variable_id;
+ values = getUp(triplet, accu[var_index]);
}
else
{
- var_it = accu.find(triplet.object.name);
- if(var_it != accu.end())
+ if(accu[triplet.object.variable_id] != getDefaultSelector())
{
- triplet.object.value = var_it->second;
+ triplet.object.value = accu[triplet.object.variable_id];
values = getType(triplet, getDefaultSelector());
}
else
@@ -217,44 +215,30 @@ namespace ontologenius
// The hasLabel has been removed as it does not work with indexes
/*else if(triplet.predicat.name == "hasLabel")
{
- if(triplet.subject.variable && !triplet.object.variable)
+ if(triplet.subject.is_variable && !triplet.object.is_variable)
{
- var_name = triplet.subject.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = find(triplet, var_it->second);
- else
- values = find(triplet, getDefaultSelector());
+ var_index = triplet.subject.variable_id;
+ values = find(triplet, accu[var_index]);
}
- else if(!triplet.subject.variable && triplet.object.variable)
+ else if(!triplet.subject.is_variable && triplet.object.is_variable)
{
- var_name = triplet.object.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getName(triplet, var_it->second);
- else
- values = getName(triplet, getDefaultSelector());
+ var_index = triplet.object.variable_id;
+ values = getName(triplet, accu[var_index]);
}
- else if(triplet.subject.variable && triplet.object.variable)
+ else if(triplet.subject.is_variable && triplet.object.is_variable)
{
- var_name = triplet.subject.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
+ var_index = triplet.subject.variable_id;
+ if(accu[var_index] != getDefaultSelector())
{
- triplet.subject.name = var_it->second;
- var_name = triplet.object.name;
- var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getName(triplet, var_it->second);
- else
- values = getName(triplet, getDefaultSelector());
+ triplet.subject.name = accu[var_index];
+ var_index = triplet.object.variable_id;
+ values = getName(triplet, accu[var_index]);
}
else
{
- var_it = accu.find(triplet.object.name);
- if(var_it != accu.end())
+ if(accu[triplet.object.name] != getDefaultSelector())
{
- triplet.object.name = var_it->second;
+ triplet.object.name = accu[triplet.object.name];
values = find(triplet, getDefaultSelector());
}
else
@@ -264,44 +248,30 @@ namespace ontologenius
else
error_ = "can not resolve query : " + toString(triplet) + " : No variable";
}*/
- else if(triplet.subject.variable && !triplet.object.variable)
+ else if(triplet.subject.is_variable && !triplet.object.is_variable)
{
- var_name = triplet.subject.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getFrom(triplet, var_it->second);
- else
- values = getFrom(triplet, getDefaultSelector());
+ var_index = triplet.subject.variable_id;
+ values = getFrom(triplet, accu[var_index]);
}
- else if(!triplet.subject.variable && triplet.object.variable)
+ else if(!triplet.subject.is_variable && triplet.object.is_variable)
{
- var_name = triplet.object.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getOn(triplet, var_it->second);
- else
- values = getOn(triplet, getDefaultSelector());
+ var_index = triplet.object.variable_id;
+ values = getOn(triplet, accu[var_index]);
}
- else if(triplet.subject.variable && triplet.object.variable)
+ else if(triplet.subject.is_variable && triplet.object.is_variable)
{
- var_name = triplet.subject.name;
- auto var_it = accu.find(var_name);
- if(var_it != accu.end())
+ var_index = triplet.subject.variable_id;
+ if(accu[var_index] != getDefaultSelector())
{
- triplet.subject.value = var_it->second;
- var_name = triplet.object.name;
- var_it = accu.find(var_name);
- if(var_it != accu.end())
- values = getOn(triplet, var_it->second);
- else
- values = getOn(triplet, getDefaultSelector());
+ triplet.subject.value = accu[var_index];
+ var_index = triplet.object.variable_id;
+ values = getOn(triplet, accu[var_index]);
}
else
{
- var_it = accu.find(triplet.object.name);
- if(var_it != accu.end())
+ if(accu[triplet.object.variable_id] != getDefaultSelector())
{
- triplet.object.value = var_it->second;
+ triplet.object.value = accu[triplet.object.variable_id];
values = getFrom(triplet, getDefaultSelector());
}
else
@@ -513,20 +483,20 @@ namespace ontologenius
}
template
- void Sparql::mergeNoOp(const std::map& base, std::vector>& res)
+ void Sparql::mergeNoOp(const std::vector& base, std::vector>& res)
{
for(auto& r : res)
{
- for(auto& var : base)
+ for(size_t i = 0; i < base.size(); i++)
{
- if(r.find(var.first) == r.end())
- r.insert(var);
+ if(r[i] == getDefaultSelector())
+ r[i] = base[i];
}
}
}
template
- void Sparql::mergeNotExists(const std::map& base, std::vector>& res)
+ void Sparql::mergeNotExists(const std::vector& base, std::vector>& res)
{
if(res.empty())
res.push_back(base);
diff --git a/src/core/ontologyOperators/SparqlSolver.cpp b/src/core/ontologyOperators/SparqlSolver.cpp
index 560bb439..cb5db296 100644
--- a/src/core/ontologyOperators/SparqlSolver.cpp
+++ b/src/core/ontologyOperators/SparqlSolver.cpp
@@ -114,7 +114,7 @@ namespace ontologenius
{
for(auto& triplet : triplets)
{
- if(triplet.object.variable)
+ if(triplet.object.is_variable)
{
auto constraint_it = solution.variable_constraints_.find(triplet.object.name);
if(constraint_it == solution.variable_constraints_.end())
@@ -124,12 +124,12 @@ namespace ontologenius
constraint.operator_ = sparql_operator;
constraint.triplet_ = triplet;
constraint.subject_constraint_ = false;
- constraint.leaf_ = !triplet.subject.variable;
+ constraint.leaf_ = !triplet.subject.is_variable;
constraint_it->second.constraints_.push_back(constraint);
- if(triplet.subject.variable)
+ if(triplet.subject.is_variable)
constraint_it->second.linked_variales_.insert(triplet.subject.name);
}
- else if(triplet.subject.variable)
+ else if(triplet.subject.is_variable)
{
auto constraint_it = solution.variable_constraints_.find(triplet.subject.name);
if(constraint_it == solution.variable_constraints_.end())
@@ -139,10 +139,10 @@ namespace ontologenius
constraint.operator_ = sparql_operator;
constraint.triplet_ = triplet;
constraint.subject_constraint_ = true;
- constraint.leaf_ = !triplet.object.variable;
+ constraint.leaf_ = !triplet.object.is_variable;
constraint_it->second.constraints_.push_back(constraint);
}
- else if(triplet.predicat.variable)
+ else if(triplet.predicat.is_variable)
error_ = "The predicate of a triplet cannot be a variable";
else
error_ = "No variable found in the triplet";
@@ -246,11 +246,11 @@ namespace ontologenius
std::unordered_set SparqlSolver::solveTriplet(strTriplet_t triplet, const std::map& binding)
{
- if(triplet.predicat.variable)
+ if(triplet.predicat.is_variable)
error_ = "predicat can not be a variable in: " + toString(triplet);
else if(triplet.predicat.name == "isA")
{
- if(triplet.subject.variable && !triplet.object.variable)
+ if(triplet.subject.is_variable && !triplet.object.is_variable)
{
auto var_it = binding.find(triplet.subject.name);
if(var_it != binding.end())
@@ -258,7 +258,7 @@ namespace ontologenius
else
return getType(triplet);
}
- else if(!triplet.subject.variable && triplet.object.variable)
+ else if(!triplet.subject.is_variable && triplet.object.is_variable)
{
auto var_it = binding.find(triplet.object.name);
if(var_it != binding.end())
@@ -266,7 +266,7 @@ namespace ontologenius
else
return getUp(triplet);
}
- else if(triplet.subject.variable && triplet.object.variable)
+ else if(triplet.subject.is_variable && triplet.object.is_variable)
{
auto var_it = binding.find(triplet.subject.name);
if(var_it != binding.end())
@@ -295,7 +295,7 @@ namespace ontologenius
}
else if(triplet.predicat.name == "hasLabel")
{
- if(triplet.subject.variable && !triplet.object.variable)
+ if(triplet.subject.is_variable && !triplet.object.is_variable)
{
auto var_it = binding.find(triplet.subject.name);
if(var_it != binding.end())
@@ -303,7 +303,7 @@ namespace ontologenius
else
return find(triplet);
}
- else if(!triplet.subject.variable && triplet.object.variable)
+ else if(!triplet.subject.is_variable && triplet.object.is_variable)
{
auto var_it = binding.find(triplet.object.name);
if(var_it != binding.end())
@@ -311,7 +311,7 @@ namespace ontologenius
else
return getName(triplet);
}
- else if(triplet.subject.variable && triplet.object.variable)
+ else if(triplet.subject.is_variable && triplet.object.is_variable)
{
auto var_it = binding.find(triplet.subject.name);
if(var_it != binding.end())
@@ -338,7 +338,7 @@ namespace ontologenius
else
error_ = "can not resolve query : " + toString(triplet) + " : No variable";
}
- else if(triplet.subject.variable && !triplet.object.variable)
+ else if(triplet.subject.is_variable && !triplet.object.is_variable)
{
auto var_it = binding.find(triplet.subject.name);
if(var_it != binding.end())
@@ -346,7 +346,7 @@ namespace ontologenius
else
return getFrom(triplet);
}
- else if(!triplet.subject.variable && triplet.object.variable)
+ else if(!triplet.subject.is_variable && triplet.object.is_variable)
{
auto var_it = binding.find(triplet.object.name);
if(var_it != binding.end())
@@ -354,7 +354,7 @@ namespace ontologenius
else
return getOn(triplet);
}
- else if(triplet.subject.variable && triplet.object.variable)
+ else if(triplet.subject.is_variable && triplet.object.is_variable)
{
auto var_it = binding.find(triplet.subject.name);
if(var_it != binding.end())
diff --git a/src/interface/RosInterfaceIndexHandlers.cpp b/src/interface/RosInterfaceIndexHandlers.cpp
index e89ca536..366c99e0 100644
--- a/src/interface/RosInterfaceIndexHandlers.cpp
+++ b/src/interface/RosInterfaceIndexHandlers.cpp
@@ -370,20 +370,16 @@ bool RosInterface::individualIndexHandle(ontologenius::OntologeniusIndexService:
bool RosInterface::sparqlIndexHandle(ontologenius::OntologeniusSparqlIndexService::Request& req,
ontologenius::OntologeniusSparqlIndexService::Response& res)
{
- std::vector> results = sparql_.runIndex(req.query);
+ std::pair, std::vector>> results = sparql_.runIndex(req.query);
- if(results.size())
- {
- auto first = results.front();
- for(auto& r : first)
- res.names.push_back(r.first);
- }
+ if(results.second.size())
+ res.names = results.first;
- for(auto& result : results)
+ for(auto& result : results.second)
{
ontologenius::OntologeniusSparqlIndexResponse tmp;
for(auto& r : result)
- tmp.values.push_back(r.second);
+ tmp.values.push_back(r);
res.results.push_back(tmp);
}
diff --git a/src/interface/RosInterfaceStringHandlers.cpp b/src/interface/RosInterfaceStringHandlers.cpp
index 13dbf950..17de2a8b 100644
--- a/src/interface/RosInterfaceStringHandlers.cpp
+++ b/src/interface/RosInterfaceStringHandlers.cpp
@@ -370,20 +370,16 @@ bool RosInterface::individualHandle(ontologenius::OntologeniusService::Request
bool RosInterface::sparqlHandle(ontologenius::OntologeniusSparqlService::Request &req,
ontologenius::OntologeniusSparqlService::Response &res)
{
- std::vector> results = sparql_.runStr(req.query);
+ std::pair, std::vector>> results = sparql_.runStr(req.query);
- if(results.size())
- {
- auto first = results.front();
- for(auto& r : first)
- res.names.push_back(r.first);
- }
+ if(results.second.size())
+ res.names = results.first;
- for(auto& result : results)
+ for(auto& result : results.second)
{
ontologenius::OntologeniusSparqlResponse tmp;
for(auto& r : result)
- tmp.values.push_back(r.second);
+ tmp.values.push_back(r);
res.results.push_back(tmp);
}
diff --git a/src/tests/sparql.cpp b/src/tests/sparql.cpp
index 90561278..1ff271fd 100644
--- a/src/tests/sparql.cpp
+++ b/src/tests/sparql.cpp
@@ -101,28 +101,28 @@ std::vector> runSparqlSolver(ontologenius::Sp
return solutions;
}
-std::vector> runSparqlBase(ontologenius::Sparql& solver, const std::string& query)
+std::vector> runSparqlBase(ontologenius::Sparql& solver, const std::string& query)
{
high_resolution_clock::time_point t1 = high_resolution_clock::now();
auto solutions = solver.runStr(query);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
duration time_span = duration_cast>(t2 - t1);
- std::cout << "Sparql has found " << solutions.size() << " solutions in " << time_span.count()*1000 << "ms" << std::endl;
+ std::cout << "Sparql has found " << solutions.second.size() << " solutions in " << time_span.count()*1000 << "ms" << std::endl;
- return solutions;
+ return solutions.second;
}
-std::vector> runSparqlBaseIndex(ontologenius::Sparql& solver, const std::string& query)
+std::vector> runSparqlBaseIndex(ontologenius::Sparql& solver, const std::string& query)
{
high_resolution_clock::time_point t1 = high_resolution_clock::now();
auto solutions = solver.runIndex(query);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
duration time_span = duration_cast>(t2 - t1);
- std::cout << "Sparql index has found " << solutions.size() << " solutions in " << time_span.count()*1000 << "ms" << std::endl;
+ std::cout << "Sparql index has found " << solutions.second.size() << " solutions in " << time_span.count()*1000 << "ms" << std::endl;
- return solutions;
+ return solutions.second;
}
void configureInterface(ontologenius::RosInterface& interface)
@@ -220,4 +220,4 @@ int main(int argc, char** argv)
onto_thread.join();
return 0;
-}
+}
\ No newline at end of file
From e6c849052ac1f330b48f6361ecc7f437a2d940c6 Mon Sep 17 00:00:00 2001
From: Guillaume Sarthou
Date: Sun, 10 Sep 2023 19:09:20 +0200
Subject: [PATCH 15/18] [SparqlUtils] fix missing include
---
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 c6fdc18b..36705463 100644
--- a/include/ontologenius/core/ontologyOperators/SparqlUtils.h
+++ b/include/ontologenius/core/ontologyOperators/SparqlUtils.h
@@ -4,6 +4,7 @@
#include
#include
#include