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/verb_query.cpp | 68 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 6 deletions(-) (limited to 'lib/verb_query.cpp') diff --git a/lib/verb_query.cpp b/lib/verb_query.cpp index 929ecc7..654bc33 100644 --- a/lib/verb_query.cpp +++ b/lib/verb_query.cpp @@ -33,7 +33,7 @@ namespace verbly { verb_query& verb_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; } + verb_query& verb_query::has_rhyming_noun() + { + _has_rhyming_noun = true; + + return *this; + } + + verb_query& verb_query::has_rhyming_adjective() + { + _has_rhyming_adjective = true; + + return *this; + } + + verb_query& verb_query::has_rhyming_adverb() + { + _has_rhyming_adverb = true; + + return *this; + } + + verb_query& verb_query::has_rhyming_verb() + { + _has_rhyming_verb = true; + + return *this; + } + verb_query& verb_query::has_frames() { this->_has_frames = true; @@ -74,16 +102,37 @@ namespace verbly { if (!_rhymes.empty()) { - std::list clauses(_rhymes.size(), "pronunciation LIKE ?"); + std::list clauses(_rhymes.size(), "(prerhyme != ? AND rhyme = ?)"); std::string cond = "verb_id IN (SELECT verb_id FROM verb_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("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN noun_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); + } + + if (_has_rhyming_adjective) + { + conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN adjective_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); + } + + if (_has_rhyming_adverb) + { + conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN adverb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme)"); + } + + if (_has_rhyming_verb) + { + conditions.push_back("verb_id IN (SELECT a.verb_id FROM verbs AS a INNER JOIN verb_pronunciations AS curp ON curp.noun_id = a.adverb_id INNER JOIN verb_pronunciations AS rhmp ON rhmp.prerhyme != curp.prerhyme AND rhmp.rhyme = curp.rhyme AND rhmp.verb_id != curp.verb_id)"); + } + for (auto except : _except) { conditions.push_back("verb_id != ?"); @@ -132,7 +181,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; } @@ -158,7 +207,7 @@ namespace verbly { for (auto& verb : output) { - query = "SELECT pronunciation FROM verb_pronunciations WHERE verb_id = ?"; + query = "SELECT pronunciation, prerhyme, rhyme FROM verb_pronunciations WHERE verb_id = ?"; if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) { throw std::runtime_error(sqlite3_errmsg(_data.ppdb)); @@ -172,6 +221,13 @@ namespace verbly { auto phonemes = verbly::split>(pronunciation, " "); verb.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))); + verb.rhymes.emplace_back(prerhyme, rhyming); + } } sqlite3_finalize(ppstmt); -- cgit 1.4.1