From 04338f2b040fee5142904c062e0e38c836601034 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sun, 17 Apr 2016 13:44:37 -0400 Subject: Fixed perfect rhyming Rhyme detection now ensures that any rhymes it finds are perfect rhymes and not identical rhymes. Rhyme detection is also now a lot faster because additional information is stored in the datafile. Also fixed a bug in the query interface (and the generator) that could cause incorrect queries to be executed. --- lib/noun_query.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 8 deletions(-) (limited to 'lib/noun_query.cpp') diff --git a/lib/noun_query.cpp b/lib/noun_query.cpp index 19a1297..b4336b6 100644 --- a/lib/noun_query.cpp +++ b/lib/noun_query.cpp @@ -33,7 +33,7 @@ namespace verbly { noun_query& noun_query::rhymes_with(const word& _word) { - for (auto rhyme : _word.rhyme_phonemes()) + for (auto rhyme : _word.get_rhymes()) { _rhymes.push_back(rhyme); } @@ -53,6 +53,34 @@ namespace verbly { return *this; } + noun_query& noun_query::has_rhyming_noun() + { + _has_rhyming_noun = true; + + return *this; + } + + noun_query& noun_query::has_rhyming_adjective() + { + _has_rhyming_adjective = true; + + return *this; + } + + noun_query& noun_query::has_rhyming_adverb() + { + _has_rhyming_adverb = true; + + return *this; + } + + noun_query& noun_query::has_rhyming_verb() + { + _has_rhyming_verb = true; + + return *this; + } + noun_query& noun_query::with_singular_form(std::string _arg) { _with_singular_form.push_back(_arg); @@ -483,16 +511,37 @@ namespace verbly { if (!_rhymes.empty()) { - std::list clauses(_rhymes.size(), "pronunciation LIKE ?"); + std::list clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); std::string cond = "noun_id IN (SELECT noun_id FROM noun_pronunciations WHERE " + verbly::implode(std::begin(clauses), std::end(clauses), " OR ") + ")"; conditions.push_back(cond); - for (auto rhyme : _rhymes) + for (auto rhy : _rhymes) { - bindings.emplace_back("%" + rhyme); + bindings.emplace_back(rhy.get_prerhyme()); + bindings.emplace_back(rhy.get_rhyme()); } } + if (_has_rhyming_noun) + { + conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN noun_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme AND rhmp.noun_id != curp.noun_id)"); + } + + if (_has_rhyming_adjective) + { + conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN adjective_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); + } + + if (_has_rhyming_adverb) + { + conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN adverb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); + } + + if (_has_rhyming_verb) + { + conditions.push_back("noun_id IN (SELECT a.noun_id FROM nouns AS a INNER JOIN noun_pronunciations AS curp ON curp.noun_id = a.noun_id INNER JOIN verb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); + } + for (auto except : _except) { conditions.push_back("noun_id != ?"); @@ -1768,7 +1817,7 @@ namespace verbly { { throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); } - + int i = 1; for (auto& binding : bindings) { @@ -1783,7 +1832,7 @@ namespace verbly { case binding::type::string: { - sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_STATIC); + sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT); break; } @@ -1791,7 +1840,7 @@ namespace verbly { i++; } - + /* for (auto adj : _derived_from_adjective) { @@ -1843,7 +1892,7 @@ namespace verbly { for (auto& noun : output) { - query = "SELECT pronunciation FROM noun_pronunciations WHERE noun_id = ?"; + query = "SELECT pronunciation, prerhyme, rhyme FROM noun_pronunciations WHERE noun_id = ?"; if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) { throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); @@ -1857,6 +1906,14 @@ namespace verbly { auto phonemes = verbly::split>(pronunciation, " "); noun.pronunciations.push_back(phonemes); + + if ((sqlite3_column_type(ppstmt, 1) != SQLITE_NULL) && (sqlite3_column_type(ppstmt, 2) != SQLITE_NULL)) + { + std::string prerhyme(reinterpret_cast(sqlite3_column_text(ppstmt, 1))); + std::string rhyming(reinterpret_cast(sqlite3_column_text(ppstmt, 2))); + + noun.rhymes.emplace_back(prerhyme, rhyming); + } } sqlite3_finalize(ppstmt); -- cgit 1.4.1