From 1c30fe15bbb7adedf6631c9432f8e20b75e6f3bd Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 24 Mar 2016 23:19:07 -0400 Subject: Added support for participle phrases --- furries.cpp | 416 +++++++++++++++++++++++++++++++++++++++++++++++++++------- vendor/verbly | 2 +- 2 files changed, 371 insertions(+), 47 deletions(-) diff --git a/furries.cpp b/furries.cpp index e09732c..712ef7c 100644 --- a/furries.cpp +++ b/furries.cpp @@ -16,19 +16,151 @@ class fill_blanks { } - void visit(std::unique_ptr& it) + verbly::filter parse_selrestrs(verbly::frame::selrestr selrestr) { - switch (it->token_type()) + switch (selrestr.get_type()) + { + case verbly::frame::selrestr::type::empty: + { + return verbly::filter{}; + } + + case verbly::frame::selrestr::type::singleton: + { + verbly::noun n; + + if (selrestr.get_restriction() == "concrete") + { + n = database.nouns().with_singular_form("physical entity").limit(1).run().front(); + } else if (selrestr.get_restriction() == "time") + { + n = database.nouns().with_singular_form("time").limit(1).run().front(); + } else if (selrestr.get_restriction() == "state") + { + n = database.nouns().with_singular_form("state").limit(1).run().front(); + } else if (selrestr.get_restriction() == "abstract") + { + n = database.nouns().with_singular_form("abstract entity").limit(1).run().front(); + } else if (selrestr.get_restriction() == "time") + { + n = database.nouns().with_singular_form("time").limit(1).run().front(); + } else if (selrestr.get_restriction() == "scalar") + { + n = database.nouns().with_singular_form("number").limit(1).run().front(); + } else if (selrestr.get_restriction() == "currency") + { + auto nn2 = database.nouns().with_singular_form("currency").limit(2).run(); + std::vector nn(std::begin(nn2), std::end(nn2)); + n = nn[1]; + } else if (selrestr.get_restriction() == "location") + { + n = database.nouns().with_singular_form("location").limit(1).run().front(); + } else if (selrestr.get_restriction() == "organization") + { + n = database.nouns().with_singular_form("organization").limit(1).run().front(); + } else if (selrestr.get_restriction() == "int_control") + { + n = database.nouns().with_singular_form("causal agent").limit(1).run().front(); + } else if (selrestr.get_restriction() == "natural") + { + n = database.nouns().with_singular_form("natural object").limit(1).run().front(); + } else if (selrestr.get_restriction() == "phys_obj") + { + n = database.nouns().with_singular_form("physical object").limit(1).run().front(); + } else if (selrestr.get_restriction() == "solid") + { + n = database.nouns().with_singular_form("solid").limit(1).run().front(); + } else if (selrestr.get_restriction() == "shape") + { + n = database.nouns().with_singular_form("shape").limit(1).run().front(); + } else if (selrestr.get_restriction() == "substance") + { + n = database.nouns().with_singular_form("substance").limit(1).run().front(); + } else if (selrestr.get_restriction() == "idea") + { + n = database.nouns().with_singular_form("idea").limit(1).run().front(); + } else if (selrestr.get_restriction() == "sound") + { + auto nn2 = database.nouns().with_singular_form("sound").limit(4).run(); + std::vector nn(std::begin(nn2), std::end(nn2)); + n = nn[3]; + } else if (selrestr.get_restriction() == "communication") + { + n = database.nouns().with_singular_form("communication").limit(1).run().front(); + } else if (selrestr.get_restriction() == "region") + { + n = database.nouns().with_singular_form("region").limit(1).run().front(); + } else if (selrestr.get_restriction() == "place") + { + n = database.nouns().with_singular_form("place").limit(1).run().front(); + } else if (selrestr.get_restriction() == "machine") + { + n = database.nouns().with_singular_form("machine").limit(1).run().front(); + } else if (selrestr.get_restriction() == "animate") + { + n = database.nouns().with_singular_form("animate being").limit(1).run().front(); + } else if (selrestr.get_restriction() == "plant") + { + auto nn2 = database.nouns().with_singular_form("plant").limit(2).run(); + std::vector nn(std::begin(nn2), std::end(nn2)); + n = nn[1]; + } else if (selrestr.get_restriction() == "comestible") + { + n = database.nouns().with_singular_form("food").limit(1).run().front(); + } else if (selrestr.get_restriction() == "artifact") + { + n = database.nouns().with_singular_form("artifact").limit(1).run().front(); + } else if (selrestr.get_restriction() == "vehicle") + { + n = database.nouns().with_singular_form("vehicle").limit(1).run().front(); + } else if (selrestr.get_restriction() == "human") + { + n = database.nouns().with_singular_form("person").limit(1).run().front(); + } else if (selrestr.get_restriction() == "animal") + { + n = database.nouns().with_singular_form("animal").limit(1).run().front(); + } else if (selrestr.get_restriction() == "body_part") + { + n = database.nouns().with_singular_form("body part").limit(1).run().front(); + } else if (selrestr.get_restriction() == "garment") + { + n = database.nouns().with_singular_form("clothing").limit(1).run().front(); + } else if (selrestr.get_restriction() == "tool") + { + n = database.nouns().with_singular_form("tool").limit(1).run().front(); + } else { + return verbly::filter{}; + } + + return verbly::filter{n, !selrestr.get_pos()}; + } + + case verbly::frame::selrestr::type::group: + { + verbly::filter ret; + ret.set_orlogic(selrestr.get_orlogic()); + + std::transform(std::begin(selrestr), std::end(selrestr), std::back_inserter(ret), [&] (verbly::frame::selrestr sr) { + return parse_selrestrs(sr); + }); + + return ret; + } + } + } + + void visit(verbly::token& it) + { + switch (it.get_type()) { case verbly::token::type::utterance: { - auto& action = *dynamic_cast(it.get()); - for (auto& tkn : action) + for (auto& tkn : it) { - if (!tkn->complete()) + if (!tkn.is_complete()) { visit(tkn); - + break; } } @@ -38,46 +170,249 @@ class fill_blanks { case verbly::token::type::fillin: { - auto& tkn = *dynamic_cast(it.get()); - switch (tkn.get_fillin_type()) + switch (it.get_fillin_type()) { - case verbly::fillin_type::participle_phrase: + case verbly::token::fillin_type::participle_phrase: + { + for (;;) + { + verbly::verb v = database.verbs().has_frames().random().limit(1).run().front(); + auto frames = v.frames().run(); + std::vector filtered; + std::remove_copy_if(std::begin(frames), std::end(frames), std::back_inserter(filtered), [] (verbly::frame& f) { + if (f.parts().size() < 2) + { + return true; + } + + if (f.parts()[0].get_type() != verbly::frame::part::type::noun_phrase) + { + return true; + } + + if (f.parts()[0].get_role() != "Agent") + { + return true; + } + + if (f.parts()[1].get_type() != verbly::frame::part::type::verb) + { + return true; + } + + return false; + }); + + if (filtered.empty()) + { + continue; + } + + verbly::frame fr = filtered[rand() % filtered.size()]; + verbly::token utter; + for (auto part : fr.parts()) + { + switch (part.get_type()) + { + case verbly::frame::part::type::noun_phrase: + { + if (part.get_role() == "Agent") + { + continue; + } + + if (part.get_synrestrs().count("adjp") == 1) + { + utter << verbly::token{verbly::token::fillin_type::adjective_phrase}; + + continue; + } else if ((part.get_synrestrs().count("be_sc_ing") == 1) + || (part.get_synrestrs().count("ac_ing") == 1) + || (part.get_synrestrs().count("sc_ing") == 1) + || (part.get_synrestrs().count("np_omit_ing") == 1) + || (part.get_synrestrs().count("oc_ing") == 1)) + { + utter << verbly::token{verbly::token::fillin_type::participle_phrase}; + + continue; + } else if ((part.get_synrestrs().count("poss_ing") == 1) + || (part.get_synrestrs().count("possing") == 1) + || (part.get_synrestrs().count("pos_ing") == 1)) + { + utter << verbly::token{"their"}; + utter << verbly::token{verbly::token::fillin_type::participle_phrase}; + + continue; + } else if (part.get_synrestrs().count("genitive") == 1) + { + utter << verbly::token{"their"}; + + continue; + } else if (part.get_synrestrs().count("adv_loc") == 1) + { + if (rand() % 2 == 0) + { + utter << verbly::token{"here"}; + } else { + utter << verbly::token{"there"}; + } + + continue; + } else if (part.get_synrestrs().count("refl") == 1) + { + utter << verbly::token{"themselves"}; + + continue; + } else if ((part.get_synrestrs().count("sc_to_inf") == 1) + || (part.get_synrestrs().count("ac_to_inf") == 1) + || (part.get_synrestrs().count("vc_to_inf") == 1) + || (part.get_synrestrs().count("rs_to_inf") == 1) + || (part.get_synrestrs().count("oc_to_inf") == 1)) + { + utter << verbly::token{verbly::token::fillin_type::infinitive_phrase}; + + continue; + } else if (part.get_synrestrs().count("oc_bare_inf") == 1) + { + verbly::token tkn{verbly::token::fillin_type::infinitive_phrase}; + tkn.set_extra(1); + + utter << tkn; + + continue; + } + + auto selrestrs = fr.roles()[part.get_role()]; + auto query = database.nouns().limit(1).random().is_not_proper().full_hyponym_of(parse_selrestrs(selrestrs)); + verbly::noun n = query.run().front(); + if ((rand() % 2 == 0) && (part.get_synrestrs().count("definite") == 0)) + { + utter << verbly::token{"the"}; + } else { + if (n.starts_with_vowel_sound()) + { + utter << verbly::token{"an"}; + } else { + utter << verbly::token{"a"}; + } + } + + if (part.get_synrestrs().count("plural") == 1) + { + utter << verbly::token{n, verbly::token::noun_inflection::plural}; + } else { + utter << verbly::token{n}; + } + + if (part.get_synrestrs().count("acc_ing") == 1) + { + utter << verbly::token{verbly::token::fillin_type::participle_phrase}; + } + + break; + } + + case verbly::frame::part::type::verb: + { + utter << verbly::token{v, verbly::token::verb_inflection::ing_form}; + + break; + } + + case verbly::frame::part::type::literal_preposition: + { + utter << verbly::token{part.get_choices()[rand() % part.get_choices().size()]}; + + break; + } + + case verbly::frame::part::type::selection_preposition: + { + auto query = database.prepositions(); + for (auto preprestr : part.get_preprestrs()) + { + query.in_group(preprestr); + } + utter << verbly::token{query.random().limit(1).run().front()}; + + break; + } + + case verbly::frame::part::type::adjective: + { + utter << verbly::token{verbly::token::fillin_type::adjective_phrase}; + + break; + } + + case verbly::frame::part::type::adverb: + { + utter << verbly::token{verbly::token::fillin_type::adverb_phrase}; + + break; + } + + case verbly::frame::part::type::literal: + { + utter << verbly::token{part.get_literal()}; + + break; + } + } + } + + it = utter; + + break; + } + + break; + } + + case verbly::token::fillin_type::adjective_phrase: { - verbly::verb v = database.verbs().random(true).limit(1).run().front(); - /*verbly::utterance_token phrase = verbly::random(v.frames).make_utterance(); - while (std::begin(phrase)->token_type() != verbly::type::verb) + verbly::token phrase; + + if (rand() % 4 == 0) { - phrase.erase(std::begin(phrase)); + phrase << verbly::token{verbly::token::fillin_type::adverb_phrase}; } - - *std::begin(phrase) = verbly::verb_token(v).conjugate(verbly::conjugation::present_participle); - *it = phrase;*/ - auto avt = std::make_unique(v); - avt->inflect(verbly::verb_token::inflection::ing_form); - it = std::move(avt); - + + if (rand() % 2 == 0) + { + phrase << verbly::token{verbly::token::fillin_type::participle_phrase}; + } else { + phrase << verbly::token{database.adjectives().random().limit(1).run().front()}; + } + + it = phrase; + break; } - case verbly::fillin_type::adjective: + case verbly::token::fillin_type::adverb_phrase: { - verbly::adjective adj = database.adjectives().random(true).limit(1).run().front(); - it = std::make_unique(adj.base_form()); + it = verbly::token{database.adverbs().random().limit(1).run().front()}; break; } - case verbly::fillin_type::adverb: + case verbly::token::fillin_type::infinitive_phrase: { - verbly::adverb adv = database.adverbs().random(true).limit(1).run().front(); - it = std::make_unique(adv.base_form()); + verbly::token utter; + if (it.get_extra() != 1) + { + utter << verbly::token{"to"}; + } + + utter << verbly::token{database.verbs().random().limit(1).run().front()}; break; } default: { - it = std::make_unique("*the reality of the situation*"); + it = verbly::token{"*the reality of the situation*"}; break; } @@ -105,30 +440,19 @@ int main(int argc, char** argv) { std::cout << "Generating tweet" << std::endl; - std::vector forms; - forms.push_back({ - new verbly::string_token("the furries are"), - new verbly::fillin_token(verbly::fillin_type::participle_phrase) - }); - forms.push_back({ - new verbly::string_token("the furries are"), - new verbly::fillin_token(verbly::fillin_type::adjective) - }); - forms.push_back({ - new verbly::string_token("the furries are"), - new verbly::fillin_token(verbly::fillin_type::adverb), - new verbly::fillin_token(verbly::fillin_type::adjective) - }); - verbly::data database {"data.sqlite3"}; + fill_blanks yeah {database}; - std::unique_ptr action = std::make_unique(forms[rand() % forms.size()]); - while (!action->complete()) + verbly::token action{ + {"the furries are"}, + {verbly::token::fillin_type::adjective_phrase} + }; + while (!action.is_complete()) { yeah.visit(action); } - std::string result = action->compile(); + std::string result = action.compile(); result.resize(140); std::string replyMsg; @@ -142,6 +466,6 @@ int main(int argc, char** argv) } std::cout << "Waiting" << std::endl; - sleep(60 * 60 * 3); + sleep(60 * 60 * 2); } } diff --git a/vendor/verbly b/vendor/verbly index dc210ee..eef5de6 160000 --- a/vendor/verbly +++ b/vendor/verbly @@ -1 +1 @@ -Subproject commit dc210ee6eba3b1d173808bd858113f6abd90bff1 +Subproject commit eef5de613c75661e5d94baa086f6f2ddc26c7ed0 -- cgit 1.4.1