/// Make all consistent parse decisions. /// \param state The state in which the parse decisions should be made. void Parser::make_all_consistent_decisions(ParseState& state) { Actions actions = state.consistent_actions(); assert(!actions.empty()); Debug::log(3) << "Performing " << actions.size() << " consistent decisions...\n"; Actions legal_actions = state.consistent_legal_actions(); Actions illegal_actions = state.consistent_illegal_actions(); assert(legal_actions.size() + illegal_actions.size() == actions.size()); // Output the confidences *before* actually performing any of the actions. // (Otherwise, the confidences values will be tainted.) for (vector<Action>::const_iterator a = legal_actions.begin(); a != legal_actions.end(); a++) Debug::log(3) << "\t" << a->to_string() << " (conf=" << this->confidence(state, *a) << ")\n"; for (vector<Action>::const_iterator a = illegal_actions.begin(); a != illegal_actions.end(); a++) Debug::log(3) << "\t" << a->to_string() << " (ILLEGAL)\n"; for (vector<Action>::iterator a = actions.begin(); a != actions.end(); a++) { Debug::log(4) << "Actually performing " << a->to_string() << "\n"; // TRACE; cerr << state.to_string() << "\n"; // TRACE; cerr << a->to_string() << "\n"; bool b = state.perform(*a); assert(b); // Debug::log(4) << this->m_items.to_string() << "\n"; // Debug::log(9) << this->to_string() << "\n"; } Debug::log(3) << "...done performing " << actions.size() << " consistent decisions.\n"; }
void Actor::updateEffectors() { GB_ASSERT(m_state,"Actor::updateEffectors: actor doesn't have state"); //delete actions ActionSet::iterator ita = m_actionsToDelete.begin(); ActionSet::iterator enda = m_actionsToDelete.end(); while(ita!=enda) { Action* action = *ita; GB_SAFE_DELETE(action); ita++; } m_actionsToDelete.clear(); //update actions Actions actionsToUpdate; m_rootAction->getChilds(actionsToUpdate, true); /* for (Actions::reverse_iterator rit=actionsToUpdate.rbegin(), rend = actionsToUpdate.rend(); rit!=rend; rit++) */ for (Actions::iterator it=actionsToUpdate.begin(), end = actionsToUpdate.end(); it!=end; it++) { Action* action = *it; //*rit; //check whether action wasn't terminated yet if (action->getTerminationStatus()==Action::NONE) { action->update(); } } //notify actions about acquiring(activating) effectors for (ActivatedEffectorsMap::iterator it = m_activatedEffectors.begin(),end = m_activatedEffectors.end(); it!=end; it++) { Action* action = it->first; EffectorIDVector& effectors = it->second; //check action activity on effectors EffectorIDVector::iterator jt = effectors.begin(); while(jt!=effectors.end()) { Effector* effector = getEffector(*jt); if (effector->isActive(action)) jt++; else jt = effectors.erase(jt); } if (!effectors.empty()) { //GB_INFO("Actor::update: reacquiring %s (%p)",action->getDescString().c_str(), action); action->acquireEffectors(effectors); } } m_activatedEffectors.clear(); }
/// Sort actions by their expected likelihood /// WRITEME more documentation /// \todo Make bucket size a parameter /// \todo Don't hardcode children span frequencies void Parser::sort_actions(Actions& actions) const { /// Put all TOP inferences last (first?) Actions top_actions; vector<Actions> sort; /// \todo Make bucket size a parameter unsigned bucketsize = 1000; sort.resize(bucketsize); for (Actions::const_iterator a = actions.begin(); a != actions.end(); a++) { if (a->label() == Label_TOP()) { top_actions.push_back(*a); continue; } double sizefreq = 0; /// \todo Don't hardcode children span frequencies /// We exclude TOP from these frequencies, since it skews the number of unaries switch(a->children().size()) { case 1: sizefreq = 0.231926; break; case 2: sizefreq = 0.565159; break; case 3: sizefreq = 0.147423; break; case 4: sizefreq = 0.0422515; break; case 5: sizefreq = 0.00985868; break; case 6: sizefreq = 0.00269639; break; case 7: sizefreq = 0.000553723; break; case 8: sizefreq = 3.61124e-05; break; case 9: sizefreq = 6.01873e-05; break; case 10: sizefreq = 1.20375e-05; break; case 11: sizefreq = 2.40749e-05; break; default: sizefreq = 0; break; } sizefreq /= 0.565159; double labelfreq = label_frequency(a->label()) / max_label_frequency(); double freq = sizefreq * labelfreq; unsigned bucket = (unsigned)((bucketsize-1) * freq); assert(bucket >= 0 && bucket < bucketsize); sort.at(bucket).push_back(*a); } unsigned actionsize = actions.size(); actions.clear(); //for(vector<Actions>::const_reverse_iterator as = sort.rbegin(); for(vector<Actions>::reverse_iterator as = sort.rbegin(); as != sort.rend(); as++) { actions.insert(actions.end(), as->begin(), as->end()); } // Insert TOP inferences at the end of the list actions.insert(actions.end(), top_actions.begin(), top_actions.end()); assert(actions.size() == actionsize); }
void Actor::terminateAllActions() { Actions childs; m_rootAction->getChilds(childs); for (Actions::iterator it= childs.begin(),end= childs.end(); it!=end; it++) { Action* action = *it; action->terminate(Action::CANCELED); } }
void Actor::releaseAction(Action* action) { //GB_INFO("ReleaseAction begin: %s (%p)",action->getDescString().c_str(), action); static std::string tabs; //GB_INFO("%sReleaseAction: %s (%p)",tabs.c_str(), action->getDescString().c_str(), action); tabs.append(" "); GB_ASSERT(m_actionsToDelete.find(action) == m_actionsToDelete.end(), "Action has already been deleted. Action logic is corrupted!"); m_actionsToDelete.insert(action); //terminate childs Actions childs; action->getChilds(childs); for (Actions::iterator it=childs.begin(), end=childs.end(); it!=end; it++) { Action* child = *it; child->terminate(Action::CANCELED); } //remove from effectors const EffectorIDVector& effectorIDs = action->getRequiredEffectors(); for (size_t i=0;i<effectorIDs.size();i++) { Effector* effector = getEffector(effectorIDs[i]); GB_ASSERT(effector, format("Actor::getEffector: actor doesn't have effector %s", Effector::convertToString(effectorIDs[i]))); Actions becameActive; effector->removeAction(action,becameActive); for(size_t j=0; j<becameActive.size(); j++) { m_activatedEffectors[becameActive[j]].push_back(effectorIDs[i]); } } tabs.erase(tabs.size()-4,4); //GB_INFO("ReleaseAction end: %s",action->getDescString().c_str()); }
/// Return the action with highest confidence. /// \note This can only score legal actions. [TODO: Check for action legality] /// \todo Tiebreak in favor of more common label? /// \return A pair containing the highest confidence action, and its confidence. pair<Action, double> Parser::best_action(const ParseState& state, Actions& actions) const { unsigned tiecount = 1; // DISABLED FOR NOW assert(parameter::minconf_for_greedy_decision() > 100); //this->sort_actions(actions); pair<Action, double> best; best.second = -BIGVAL; Actions::const_iterator a; for (a = actions.begin(); a != actions.end(); a++) { // Debug::log(5) << "Considering action " << a->to_string() << "...\n"; double conf = this->confidence(state, *a); if (conf > -10) Debug::log(5) << "Action " << a->to_string() << " has conf = " << conf << "\n"; if (best.first.label() == NO_LABEL || conf > best.second) { best = make_pair(*a, conf); tiecount = 1; } else if (fabs(conf - best.second) < parameter::small_epsilon()) { tiecount++; if (drand48() < 1. / tiecount) { best = make_pair(*a, conf); } } if (conf > parameter::minconf_for_greedy_decision()) { assert(*a == best.first); assert(conf == best.second); Debug::log(3) << "Greedily choosing action " << best.first.to_string() << " with conf = " << best.second << " > mingreedyconf " << parameter::minconf_for_greedy_decision() << "\n"; break; } } Debug::log(3) << "Best action " << best.first.to_string() << " with conf = " << best.second << "\n"; return best; }