From 6b7c77f3a28d9a44afacb76e3db58a5ff5f59f4d Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 26 Mar 2016 09:40:13 -0400 Subject: Added full hierarchy search for meronymy --- lib/noun_query.cpp | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++- lib/noun_query.h | 12 +++ 2 files changed, 313 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index cb11577..2c3f57c 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp @@ -121,6 +121,14 @@ namespace verbly { return *this; } + noun_query& noun_query::full_part_meronym_of(filter _f) + { + _f.clean(); + _full_part_meronym_of = _f; + + return *this; + } + noun_query& noun_query::is_part_holonym() { _is_part_holonym = true; @@ -136,6 +144,14 @@ namespace verbly { return *this; } + noun_query& noun_query::full_part_holonym_of(filter _f) + { + _f.clean(); + _full_part_holonym_of = _f; + + return *this; + } + noun_query& noun_query::is_substance_meronym() { _is_substance_meronym = true; @@ -151,6 +167,14 @@ namespace verbly { return *this; } + noun_query& noun_query::full_substance_meronym_of(filter _f) + { + _f.clean(); + _full_substance_meronym_of = _f; + + return *this; + } + noun_query& noun_query::is_substance_holonym() { _is_substance_holonym = true; @@ -166,6 +190,14 @@ namespace verbly { return *this; } + noun_query& noun_query::full_substance_holonym_of(filter _f) + { + _f.clean(); + _full_substance_holonym_of = _f; + + return *this; + } + noun_query& noun_query::is_member_meronym() { _is_member_meronym = true; @@ -181,6 +213,14 @@ namespace verbly { return *this; } + noun_query& noun_query::full_member_meronym_of(filter _f) + { + _f.clean(); + _full_member_meronym_of = _f; + + return *this; + } + noun_query& noun_query::is_member_holonym() { _is_member_holonym = true; @@ -196,6 +236,14 @@ namespace verbly { return *this; } + noun_query& noun_query::full_member_holonym_of(filter _f) + { + _f.clean(); + _full_member_holonym_of = _f; + + return *this; + } + noun_query& noun_query::is_proper() { _is_proper = true; @@ -336,7 +384,7 @@ namespace verbly { { std::stringstream construct; - if (!_full_hypernym_of.empty() || !_full_hyponym_of.empty()) + if (!_full_hypernym_of.empty() || !_full_hyponym_of.empty() || !_full_part_meronym_of.empty() || !_full_part_holonym_of.empty() || !_full_substance_meronym_of.empty() || !_full_substance_holonym_of.empty() || !_full_member_meronym_of.empty() || !_full_member_holonym_of.empty()) { construct << "WITH RECURSIVE "; @@ -352,6 +400,36 @@ namespace verbly { ctes.push_back("hyponym_tree_" + std::to_string(hypernym._id) + " AS (SELECT hyponym_id FROM hypernymy WHERE hypernym_id = " + std::to_string(hypernym._id) + " UNION SELECT h.hyponym_id FROM hyponym_tree_" + std::to_string(hypernym._id) + " AS t INNER JOIN hypernymy AS h ON t.hyponym_id = h.hypernym_id)"); } + for (auto holonym : _full_part_meronym_of.uniq_flatten()) + { + ctes.push_back("part_meronym_tree_" + std::to_string(holonym._id) + " AS (SELECT meronym_id FROM part_meronymy WHERE holonym_id = " + std::to_string(holonym._id) + " UNION SELECT h.meronym_id FROM part_meronym_tree_" + std::to_string(holonym._id) + " AS t INNER JOIN part_meronymy AS h ON t.meronym_id = h.holonym_id)"); + } + + for (auto meronym : _full_part_holonym_of.uniq_flatten()) + { + ctes.push_back("part_holonym_tree_" + std::to_string(meronym._id) + " AS (SELECT holonym_id FROM part_meronymy WHERE meronym_id = " + std::to_string(meronym._id) + " UNION SELECT h.holonym_id FROM part_holonym_tree_" + std::to_string(meronym._id) + " AS t INNER JOIN part_meronymy AS h ON t.holonym_id = h.meronym_id)"); + } + + for (auto holonym : _full_substance_meronym_of.uniq_flatten()) + { + ctes.push_back("substance_meronym_tree_" + std::to_string(holonym._id) + " AS (SELECT meronym_id FROM substance_meronymy WHERE holonym_id = " + std::to_string(holonym._id) + " UNION SELECT h.meronym_id FROM substance_meronym_tree_" + std::to_string(holonym._id) + " AS t INNER JOIN substance_meronymy AS h ON t.meronym_id = h.holonym_id)"); + } + + for (auto meronym : _full_substance_holonym_of.uniq_flatten()) + { + ctes.push_back("substance_holonym_tree_" + std::to_string(meronym._id) + " AS (SELECT holonym_id FROM substance_meronymy WHERE meronym_id = " + std::to_string(meronym._id) + " UNION SELECT h.holonym_id FROM substance_holonym_tree_" + std::to_string(meronym._id) + " AS t INNER JOIN substance_meronymy AS h ON t.holonym_id = h.meronym_id)"); + } + + for (auto holonym : _full_member_meronym_of.uniq_flatten()) + { + ctes.push_back("member_meronym_tree_" + std::to_string(holonym._id) + " AS (SELECT meronym_id FROM member_meronymy WHERE holonym_id = " + std::to_string(holonym._id) + " UNION SELECT h.meronym_id FROM member_meronym_tree_" + std::to_string(holonym._id) + " AS t INNER JOIN member_meronymy AS h ON t.meronym_id = h.holonym_id)"); + } + + for (auto meronym : _full_member_holonym_of.uniq_flatten()) + { + ctes.push_back("member_holonym_tree_" + std::to_string(meronym._id) + " AS (SELECT holonym_id FROM member_meronymy WHERE meronym_id = " + std::to_string(meronym._id) + " UNION SELECT h.holonym_id FROM member_holonym_tree_" + std::to_string(meronym._id) + " AS t INNER JOIN member_meronymy AS h ON t.holonym_id = h.meronym_id)"); + } + construct << verbly::implode(std::begin(ctes), std::end(ctes), ", "); construct << " "; } @@ -619,6 +697,43 @@ namespace verbly { conditions.push_back(cond.str()); } + if (!_full_part_meronym_of.empty()) + { + std::function, bool)> recur = [&] (filter f, bool notlogic) -> std::string { + switch (f.get_type()) + { + case filter::type::singleton: + { + if (notlogic == f.get_notlogic()) + { + return "noun_id IN (SELECT meronym_id FROM part_meronym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } else { + return "noun_id NOT IN (SELECT meronym_id FROM part_meronym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } + } + + case filter::type::group: + { + bool truelogic = notlogic != f.get_notlogic(); + + std::list clauses; + std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter f2) { + return recur(f2, truelogic); + }); + + if (truelogic == f.get_orlogic()) + { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; + } else { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + } + } + } + }; + + conditions.push_back(recur(_full_part_meronym_of, false)); + } + if (_is_part_holonym) { conditions.push_back("noun_id IN (SELECT holonym_id FROM part_meronymy)"); @@ -673,6 +788,43 @@ namespace verbly { conditions.push_back(cond.str()); } + if (!_full_part_holonym_of.empty()) + { + std::function, bool)> recur = [&] (filter f, bool notlogic) -> std::string { + switch (f.get_type()) + { + case filter::type::singleton: + { + if (notlogic == f.get_notlogic()) + { + return "noun_id IN (SELECT holonym_id FROM part_holonym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } else { + return "noun_id NOT IN (SELECT holonym_id FROM part_holonym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } + } + + case filter::type::group: + { + bool truelogic = notlogic != f.get_notlogic(); + + std::list clauses; + std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter f2) { + return recur(f2, truelogic); + }); + + if (truelogic == f.get_orlogic()) + { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; + } else { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + } + } + } + }; + + conditions.push_back(recur(_full_part_holonym_of, false)); + } + if (_is_substance_meronym) { conditions.push_back("noun_id IN (SELECT meronym_id FROM substance_meronymy)"); @@ -727,6 +879,43 @@ namespace verbly { conditions.push_back(cond.str()); } + if (!_full_substance_meronym_of.empty()) + { + std::function, bool)> recur = [&] (filter f, bool notlogic) -> std::string { + switch (f.get_type()) + { + case filter::type::singleton: + { + if (notlogic == f.get_notlogic()) + { + return "noun_id IN (SELECT meronym_id FROM substance_meronym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } else { + return "noun_id NOT IN (SELECT meronym_id FROM substance_meronym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } + } + + case filter::type::group: + { + bool truelogic = notlogic != f.get_notlogic(); + + std::list clauses; + std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter f2) { + return recur(f2, truelogic); + }); + + if (truelogic == f.get_orlogic()) + { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; + } else { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + } + } + } + }; + + conditions.push_back(recur(_full_substance_meronym_of, false)); + } + if (_is_substance_holonym) { conditions.push_back("noun_id IN (SELECT holonym_id FROM substance_meronymy)"); @@ -781,6 +970,43 @@ namespace verbly { conditions.push_back(cond.str()); } + if (!_full_substance_holonym_of.empty()) + { + std::function, bool)> recur = [&] (filter f, bool notlogic) -> std::string { + switch (f.get_type()) + { + case filter::type::singleton: + { + if (notlogic == f.get_notlogic()) + { + return "noun_id IN (SELECT holonym_id FROM substance_holonym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } else { + return "noun_id NOT IN (SELECT holonym_id FROM substance_holonym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } + } + + case filter::type::group: + { + bool truelogic = notlogic != f.get_notlogic(); + + std::list clauses; + std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter f2) { + return recur(f2, truelogic); + }); + + if (truelogic == f.get_orlogic()) + { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; + } else { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + } + } + } + }; + + conditions.push_back(recur(_full_substance_holonym_of, false)); + } + if (_is_member_meronym) { conditions.push_back("noun_id IN (SELECT meronym_id FROM member_meronymy)"); @@ -835,6 +1061,43 @@ namespace verbly { conditions.push_back(cond.str()); } + if (!_full_member_meronym_of.empty()) + { + std::function, bool)> recur = [&] (filter f, bool notlogic) -> std::string { + switch (f.get_type()) + { + case filter::type::singleton: + { + if (notlogic == f.get_notlogic()) + { + return "noun_id IN (SELECT meronym_id FROM member_meronym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } else { + return "noun_id NOT IN (SELECT meronym_id FROM member_meronym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } + } + + case filter::type::group: + { + bool truelogic = notlogic != f.get_notlogic(); + + std::list clauses; + std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter f2) { + return recur(f2, truelogic); + }); + + if (truelogic == f.get_orlogic()) + { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; + } else { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + } + } + } + }; + + conditions.push_back(recur(_full_member_meronym_of, false)); + } + if (_is_member_holonym) { conditions.push_back("noun_id IN (SELECT holonym_id FROM member_meronym)"); @@ -889,6 +1152,43 @@ namespace verbly { conditions.push_back(cond.str()); } + if (!_full_member_holonym_of.empty()) + { + std::function, bool)> recur = [&] (filter f, bool notlogic) -> std::string { + switch (f.get_type()) + { + case filter::type::singleton: + { + if (notlogic == f.get_notlogic()) + { + return "noun_id IN (SELECT holonym_id FROM member_holonym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } else { + return "noun_id NOT IN (SELECT holonym_id FROM member_holonym_tree_" + std::to_string(f.get_elem()._id) + ")"; + } + } + + case filter::type::group: + { + bool truelogic = notlogic != f.get_notlogic(); + + std::list clauses; + std::transform(std::begin(f), std::end(f), std::back_inserter(clauses), [&] (filter f2) { + return recur(f2, truelogic); + }); + + if (truelogic == f.get_orlogic()) + { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " AND ") + ")"; + } else { + return "(" + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; + } + } + } + }; + + conditions.push_back(recur(_full_member_holonym_of, false)); + } + if (_is_proper) { conditions.push_back("proper = 1"); diff --git a/lib/noun_query.h b/lib/noun_query.h index 0c41a68..e95e0c0 100644 --- a/lib/noun_query.h +++ b/lib/noun_query.h @@ -25,21 +25,27 @@ namespace verbly { noun_query& is_part_meronym(); noun_query& part_meronym_of(filter _f); + noun_query& full_part_meronym_of(filter _f); noun_query& is_part_holonym(); noun_query& part_holonym_of(filter _f); + noun_query& full_part_holonym_of(filter _f); noun_query& is_substance_meronym(); noun_query& substance_meronym_of(filter _f); + noun_query& full_substance_meronym_of(filter _f); noun_query& is_substance_holonym(); noun_query& substance_holonym_of(filter _f); + noun_query& full_substance_holonym_of(filter _f); noun_query& is_member_meronym(); noun_query& member_meronym_of(filter _f); + noun_query& full_member_meronym_of(filter _f); noun_query& is_member_holonym(); noun_query& member_holonym_of(filter _f); + noun_query& full_member_holonym_of(filter _f); noun_query& is_proper(); noun_query& is_not_proper(); @@ -89,21 +95,27 @@ namespace verbly { bool _is_part_meronym = false; filter _part_meronym_of; + filter _full_part_meronym_of; bool _is_substance_meronym = false; filter _substance_meronym_of; + filter _full_substance_meronym_of; bool _is_member_meronym = false; filter _member_meronym_of; + filter _full_member_meronym_of; bool _is_part_holonym = false; filter _part_holonym_of; + filter _full_part_holonym_of; bool _is_substance_holonym = false; filter _substance_holonym_of; + filter _full_substance_holonym_of; bool _is_member_holonym = false; filter _member_holonym_of; + filter _full_member_holonym_of; bool _is_proper = false; bool _is_not_proper = false; -- cgit 1.4.1