PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lv2-c++-tools-1.0.4/libraries/paq/query.cpp

#
C++ | 629 lines | 382 code | 195 blank | 52 comment | 54 complexity | 1963c61e289aeed2c744eb24215a8369 MD5 | raw file
Possible License(s): GPL-3.0
  1. /****************************************************************************
  2. query.cpp - Query engine for RDF data
  3. Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
  15. ****************************************************************************/
  16. #include <algorithm>
  17. #include "query.hpp"
  18. using namespace std;
  19. namespace PAQ {
  20. RDFTerm* QueryResult::operator[](size_t i) {
  21. return m_data[i];
  22. }
  23. RDFTerm* QueryResult::operator[](Variable& var) {
  24. return m_data[m_variables[&var]];
  25. }
  26. LangMatches::LangMatches(Variable& var, const std::string& lang)
  27. : m_var(&var),
  28. m_lang(lang) {
  29. }
  30. void LangMatches::set_variable_indices(Query& query) {
  31. RDFTerm* t = query.data.add_variable(m_var);
  32. m_index = t->index;
  33. m_var = 0;
  34. }
  35. bool LangMatches::execute(QueryEngine& engine) {
  36. RDFTerm* t = engine.N1[engine.mapping[m_index]];
  37. return (t->lang == m_lang);
  38. }
  39. Filter* lang_matches(Variable& var, const std::string& lang) {
  40. return new LangMatches(var, lang);
  41. }
  42. TermEquality::TermEquality(Variable& var1, Variable& var2)
  43. : m_var1(&var1),
  44. m_var2(&var2) {
  45. }
  46. void TermEquality::set_variable_indices(Query& query) {
  47. RDFTerm* t = query.data.add_variable(m_var1);
  48. m_index1 = t->index;
  49. m_var1 = 0;
  50. t = query.data.add_variable(m_var2);
  51. m_index2 = t->index;
  52. m_var2 = 0;
  53. }
  54. bool TermEquality::execute(QueryEngine& engine) {
  55. return (engine.mapping[m_index1] == engine.mapping[m_index2]);
  56. }
  57. Filter* operator==(Variable& var1, Variable& var2) {
  58. return new TermEquality(var1, var2);
  59. }
  60. UnaryFilter::UnaryFilter(Variable& var)
  61. : m_var(&var) {
  62. }
  63. void UnaryFilter::set_variable_indices(Query& query) {
  64. RDFTerm* t = query.data.add_variable(m_var);
  65. m_index = t->index;
  66. m_var = 0;
  67. }
  68. bool IsURI::execute(QueryEngine& engine) {
  69. return (engine.N1[engine.mapping[m_index]]->type == RDFTerm::URIRef);
  70. }
  71. Filter* is_uriref(Variable& var) {
  72. return new IsURI(var);
  73. }
  74. bool IsLiteral::execute(QueryEngine& engine) {
  75. return (engine.N1[engine.mapping[m_index]]->type == RDFTerm::Literal);
  76. }
  77. Filter* is_literal(Variable& var) {
  78. return new IsLiteral(var);
  79. }
  80. bool IsNumeric::execute(QueryEngine& engine) {
  81. RDFTerm* t = engine.N1[engine.mapping[m_index]];
  82. if (t->type == RDFTerm::Literal &&
  83. t->datatype &&
  84. (t->datatype->name == "<http://www.w3.org/2001/XMLSchema#integer>" ||
  85. t->datatype->name == "<http://www.w3.org/2001/XMLSchema#decimal>" ||
  86. t->datatype->name == "<http://www.w3.org/2001/XMLSchema#double>"))
  87. return true;
  88. return false;
  89. }
  90. Filter* is_numeric(Variable& var) {
  91. return new IsNumeric(var);
  92. }
  93. bool IsInteger::execute(QueryEngine& engine) {
  94. RDFTerm* t = engine.N1[engine.mapping[m_index]];
  95. if (t->type == RDFTerm::Literal &&
  96. t->datatype &&
  97. t->datatype->name == "<http://www.w3.org/2001/XMLSchema#integer>")
  98. return true;
  99. return false;
  100. }
  101. Filter* is_integer(Variable& var) {
  102. return new IsInteger(var);
  103. }
  104. Negation::Negation(Filter* f)
  105. : m_filter(f) {
  106. }
  107. Negation::~Negation() {
  108. delete m_filter;
  109. }
  110. void Negation::set_variable_indices(Query& q) {
  111. m_filter->set_variable_indices(q);
  112. }
  113. bool Negation::execute(QueryEngine& engine) {
  114. return !m_filter->execute(engine);
  115. }
  116. Filter* no(Filter* filter) {
  117. return new Negation(filter);
  118. }
  119. Aggregate::Aggregate(Filter* f1, Filter* f2)
  120. : m_f1(f1),
  121. m_f2(f2) {
  122. }
  123. Aggregate::~Aggregate() {
  124. delete m_f1;
  125. delete m_f2;
  126. }
  127. void Aggregate::set_variable_indices(Query& q) {
  128. m_f1->set_variable_indices(q);
  129. m_f2->set_variable_indices(q);
  130. }
  131. Or::Or(Filter* f1, Filter* f2)
  132. : Aggregate(f1, f2) {
  133. }
  134. bool Or::execute(QueryEngine& engine) {
  135. return m_f1->execute(engine) || m_f2->execute(engine);
  136. }
  137. Filter* or_filter(Filter* f1, Filter* f2) {
  138. return new Or(f1, f2);
  139. }
  140. And::And(Filter* f1, Filter* f2)
  141. : Aggregate(f1, f2) {
  142. }
  143. bool And::execute(QueryEngine& engine) {
  144. return m_f1->execute(engine) && m_f2->execute(engine);
  145. }
  146. Filter* and_filter(Filter* f1, Filter* f2) {
  147. return new And(f1, f2);
  148. }
  149. NumericCompare::NumericCompare(Variable& var, double value)
  150. : m_var(&var),
  151. m_value(value) {
  152. }
  153. void NumericCompare::set_variable_indices(Query& query) {
  154. RDFTerm* t = query.data.add_variable(m_var);
  155. m_index = t->index;
  156. m_var = 0;
  157. }
  158. bool NumericLess::execute(QueryEngine& engine) {
  159. return (engine.N1[engine.mapping[m_index]]->get_numeric_value() < m_value);
  160. }
  161. Filter* operator<(Variable& var, double value) {
  162. return new NumericLess(var, value);
  163. }
  164. Filter* operator>=(double value, Variable& var) {
  165. return new NumericLess(var, value);
  166. }
  167. bool NumericLessEqual::execute(QueryEngine& engine) {
  168. return (engine.N1[engine.mapping[m_index]]->get_numeric_value() <= m_value);
  169. }
  170. Filter* operator<=(Variable& var, double value) {
  171. return new NumericLessEqual(var, value);
  172. }
  173. Filter* operator>(double value, Variable& var) {
  174. return new NumericLessEqual(var, value);
  175. }
  176. bool NumericGreater::execute(QueryEngine& engine) {
  177. return (engine.N1[engine.mapping[m_index]]->get_numeric_value() > m_value);
  178. }
  179. Filter* operator>(Variable& var, double value) {
  180. return new NumericGreater(var, value);
  181. }
  182. Filter* operator<=(double value, Variable& var) {
  183. return new NumericGreater(var, value);
  184. }
  185. bool NumericGreaterEqual::execute(QueryEngine& engine) {
  186. return (engine.N1[engine.mapping[m_index]]->get_numeric_value() >= m_value);
  187. }
  188. Filter* operator>=(Variable& var, double value) {
  189. return new NumericGreaterEqual(var, value);
  190. }
  191. Filter* operator<(double value, Variable& var) {
  192. return new NumericGreaterEqual(var, value);
  193. }
  194. bool NumericEquality::execute(QueryEngine& engine) {
  195. return (engine.N1[engine.mapping[m_index]]->get_numeric_value() == m_value);
  196. }
  197. Filter* operator==(Variable& var, double value) {
  198. return new NumericEquality(var, value);
  199. }
  200. Filter* operator==(double value, Variable& var) {
  201. return new NumericEquality(var, value);
  202. }
  203. Filter* operator!=(Variable& var, double value) {
  204. return no(new NumericEquality(var, value));
  205. }
  206. Filter* operator!=(double value, Variable& var) {
  207. return no(new NumericEquality(var, value));
  208. }
  209. StringEquality::StringEquality(Variable& var, const std::string& value)
  210. : m_var(&var),
  211. m_value(value) {
  212. }
  213. void StringEquality::set_variable_indices(Query& query) {
  214. RDFTerm* t = query.data.add_variable(m_var);
  215. m_index = t->index;
  216. m_var = 0;
  217. }
  218. bool StringEquality::execute(QueryEngine& engine) {
  219. return (engine.N1[engine.mapping[m_index]]->name == m_value);
  220. }
  221. Filter* operator==(Variable& var, const std::string& value) {
  222. return new StringEquality(var, value);
  223. }
  224. Filter* operator==(const std::string& value, Variable& var) {
  225. return new StringEquality(var, value);
  226. }
  227. Filter* operator!=(Variable& var, const std::string& value) {
  228. return no(new StringEquality(var, value));
  229. }
  230. Filter* operator!=(const std::string& value, Variable& var) {
  231. return no(new StringEquality(var, value));
  232. }
  233. BinaryFilter::BinaryFilter(Variable& var1, Variable& var2)
  234. : m_var1(&var1),
  235. m_var2(&var2) {
  236. }
  237. void BinaryFilter::set_variable_indices(Query& query) {
  238. RDFTerm* t = query.data.add_variable(m_var1);
  239. m_index1 = t->index;
  240. m_var1 = 0;
  241. t = query.data.add_variable(m_var2);
  242. m_index2 = t->index;
  243. m_var2 = 0;
  244. }
  245. Query::Query() {
  246. }
  247. Query& Query::where(Variable& s, Variable& p, Variable& o) {
  248. data.add_triple(data.add_variable(&s),
  249. data.add_variable(&p),
  250. data.add_variable(&o));
  251. return *this;
  252. }
  253. Query& Query::where(const std::string& s, Variable& p, Variable& o) {
  254. data.add_triple(add_term(s),
  255. data.add_variable(&p),
  256. data.add_variable(&o));
  257. return *this;
  258. }
  259. Query& Query::where(Variable& s, const std::string& p, Variable& o) {
  260. data.add_triple(data.add_variable(&s),
  261. add_term(p),
  262. data.add_variable(&o));
  263. return *this;
  264. }
  265. Query& Query::where(Variable& s, Variable& p, const std::string& o) {
  266. data.add_triple(data.add_variable(&s),
  267. data.add_variable(&p),
  268. add_term(o));
  269. return *this;
  270. }
  271. Query& Query::where(const std::string& s, const std::string& p, Variable& o) {
  272. data.add_triple(add_term(s),
  273. add_term(p),
  274. data.add_variable(&o));
  275. return *this;
  276. }
  277. Query& Query::where(Variable& s, const std::string& p, const std::string& o) {
  278. data.add_triple(data.add_variable(&s),
  279. add_term(p),
  280. add_term(o));
  281. return *this;
  282. }
  283. Query& Query::where(const std::string& s, Variable& p, const std::string& o) {
  284. data.add_triple(add_term(s),
  285. data.add_variable(&p),
  286. add_term(o));
  287. return *this;
  288. }
  289. Query& Query::where(const std::string& s,const std::string& p,
  290. const std::string& o) {
  291. data.add_triple(add_term(s),
  292. add_term(p),
  293. add_term(o));
  294. return *this;
  295. }
  296. Query& Query::filter(Filter* f) {
  297. f->set_variable_indices(*this);
  298. filters.push_back(f);
  299. return *this;
  300. }
  301. vector<QueryResult> Query::run(RDFData& data) {
  302. QueryEngine qe(*this, data);
  303. return qe.run();
  304. }
  305. Query::Query(Variable& var1, Variable& var2, Variable& var3, Variable& var4) {
  306. if (&var1 != &Variable::nil) {
  307. RDFTerm* var = data.add_variable(&var1);
  308. selected[&var1] = var->index;
  309. if (&var2 != &Variable::nil) {
  310. var = data.add_variable(&var2);
  311. selected[&var2] = var->index;
  312. if (&var3 != &Variable::nil) {
  313. var = data.add_variable(&var3);
  314. selected[&var3] = var->index;
  315. if (&var4 != &Variable::nil) {
  316. var = data.add_variable(&var4);
  317. selected[&var4] = var->index;
  318. }
  319. }
  320. }
  321. }
  322. }
  323. RDFTerm* Query::add_term(const std::string& str) {
  324. if (str.size() > 0 && str[0] == '<')
  325. return data.add_uriref(str);
  326. if (str.substr(0, 3) == "__:")
  327. return data.add_bnode(str);
  328. return data.add_literal(str);
  329. }
  330. Query select(Variable& var1, Variable& var2, Variable& var3, Variable& var4) {
  331. return Query(var1, var2, var3, var4);
  332. }
  333. QueryEngine::QueryEngine(Query& q, RDFData& d)
  334. : N1(d.get_terms()),
  335. N2(q.data.get_terms()),
  336. T1(d.triples),
  337. T2(q.data.triples),
  338. query(q) {
  339. NULL_NODE = N1.size();
  340. NULL_NODE = N2.size() > NULL_NODE ? N2.size() : NULL_NODE;
  341. mapping.resize(N2.size(), NULL_NODE);
  342. }
  343. std::vector<QueryResult> QueryEngine::run() {
  344. match(0);
  345. return result;
  346. }
  347. void QueryEngine::match(size_t depth) {
  348. //cerr<<endl<<"depth = "<<depth<<endl<<endl;
  349. // found a match, check it and add it to the result vector
  350. if (depth == T2.size()) {
  351. for (size_t i = 0; i < query.filters.size(); ++i) {
  352. if (!query.filters[i]->execute(*this))
  353. return;
  354. }
  355. //cerr<<"***** ***** ****** ***** ***** ***** ***** ***** *****"<<endl;
  356. //cerr<<"***** ***** RESULT ***** ***** ***** ***** ***** *****"<<endl;
  357. //cerr<<"***** ***** ****** ***** ***** ***** ***** ***** *****"<<endl;
  358. QueryResult qr;
  359. for (size_t i = 0; i < query.selected.size(); ++i) {
  360. qr.m_data.push_back(N1[mapping[i]]);
  361. /*
  362. cerr<<" "<<N2[i]->name<<" ("<<i<<")"<<endl
  363. <<" -> "<<N1[mapping[i]]->name<<" ("<<mapping[i]<<")"<<endl;
  364. */
  365. }
  366. qr.m_variables = query.selected;
  367. //cerr<<"size: "<<result.size()<<endl;
  368. result.push_back(qr);
  369. return;
  370. }
  371. // iterate over all triples in the target to see if any of them
  372. // match the current triplet in the pattern
  373. size_t b1, b2, b3;
  374. for (size_t i = 0; i < T1.size(); ++i) {
  375. /*
  376. cerr<<endl<<"Trying to match "<<endl<<"("
  377. <<T2[depth]->subject->name<<" ("<<T2[depth]->subject->index<<"),"<<endl
  378. <<T2[depth]->predicate->name<<" ("<<T2[depth]->predicate->index<<"),"<<endl
  379. <<T2[depth]->object->name<<" ("<<T2[depth]->object->index<<")"<<") "
  380. <<endl<<"to "<<endl<<"("
  381. <<T1[i]->subject->name<<" ("<<T1[i]->subject->index<<"),"<<endl
  382. <<T1[i]->predicate->name<<" ("<<T1[i]->predicate->index<<"),"<<endl
  383. <<T1[i]->object->name<<" ("<<T1[i]->object->index<<")"<<") "<<endl<<endl;
  384. */
  385. b1 = NULL_NODE;
  386. b2 = NULL_NODE;
  387. b3 = NULL_NODE;
  388. if (match_node(T2[depth]->subject, T1[i]->subject, b1)) {
  389. if (match_node(T2[depth]->predicate, T1[i]->predicate, b2)) {
  390. if (match_node(T2[depth]->object, T1[i]->object, b3)) {
  391. match(depth + 1);
  392. }
  393. }
  394. }
  395. if (b1 != NULL_NODE)
  396. mapping[b1] = NULL_NODE;
  397. if (b2 != NULL_NODE)
  398. mapping[b2] = NULL_NODE;
  399. if (b3 != NULL_NODE)
  400. mapping[b3] = NULL_NODE;
  401. }
  402. }
  403. bool QueryEngine::match_node(RDFTerm* p, RDFTerm* t, size_t& bound) {
  404. // if the pattern node is mapped already, just check if it's mapped to
  405. // the target node
  406. if (mapping[p->index] == t->index) {
  407. //cerr<<p->name<<" ("<<p->index<<") is already mapped to "<<t->name<<endl;
  408. return true;
  409. }
  410. // if it's unmapped and is a variable, map it to the target node
  411. // without checking anything
  412. if (p->type == RDFTerm::Variable && mapping[p->index] == NULL_NODE) {
  413. //cerr<<"mapping variable "<<p->index<<" to "<<t->name<<endl;
  414. mapping[p->index] = t->index;
  415. bound = p->index;
  416. return true;
  417. }
  418. // map the pattern node to the target node if they are equivalent
  419. if ((p->type == t->type) && (p->name == t->name)) {
  420. //cerr<<"mapping "<<p->name<<" ("<<p->index<<") to "<<t->name<<endl;
  421. mapping[p->index] = t->index;
  422. bound = p->index;
  423. return true;
  424. }
  425. //cerr<<"no match"<<endl;
  426. return false;
  427. }
  428. }