ActionSet Node::compute_enable_set(Core *core) { ActionSet enable; ca::NetDef *def = core->get_net_def(); const std::vector<ca::TransitionDef*> &transitions = def->get_transition_defs(); int enabled_priorities = 0; bool added; for (int p = 0; p < ca::process_count; p++) { if (state->is_process_busy(p)) { continue; } added = false; for (int i = 0; i < def->get_transitions_count(); i++) { if (added && transitions[i]->get_priority() < enabled_priorities) { break; } if (state->is_transition_enabled(p, transitions[i])) { added = true; enabled_priorities = transitions[i]->get_priority(); Action action; action.type = ActionFire; action.data.fire.transition_def = transitions[i]; action.process = p; enable.insert(action); } } } for (int pq = 0; pq < ca::process_count * ca::process_count; pq++) { int target = pq / ca::process_count; int source = pq % ca::process_count; int edge_id = state->get_receiving_edge(target, source, 0); if (edge_id != -1) { Action action; action.type = ActionReceive; action.data.receive.source = source; action.data.receive.edge_id = edge_id; action.process = target; enable.insert(action); } } return enable; }
ActionSet Clingo::availableActions() const throw() { list<AnswerSet> actions = krQuery(generatePlanQuery(vector<AspRule>(), true),1,1,"planQuery.asp",0); ActionSet computed; //the first answer set contains the current state and no actions list<AnswerSet>::iterator act = ++actions.begin(); for (; act != actions.end(); ++act) { computed.insert(act->getFluents().begin(), act->getFluents().end()); } return computed; }
ActionSet Core::compute_ample_set(State *s, const ActionSet &enable) { ActionSet::iterator it; if (cfg_debug) { // print state name char *hashstr = (char*) alloca(mhash_get_block_size(MHASH_MD5) * 2 + 1); hashdigest_to_string(MHASH_MD5, s->compute_hash(MHASH_MD5) , hashstr); printf(">> state: %s: \nenable: { ", hashstr); for (it = enable.begin(); it != enable.end(); it++) { printf("%s ", it->to_string().c_str()); } printf("}\n"); } for (it = enable.begin(); it != enable.end(); it++) { ActionSet ample; ample.insert(*it); if (cfg_debug) { printf(" > ample: { "); for (ActionSet::iterator i = ample.begin(); i != ample.end(); i++) { printf("%s ", i->to_string().c_str()); } printf("}\n"); } if (check_C1(enable, ample, s) && check_C2(ample) && check_C3(s)) { if (cfg_debug) { printf(" This ample set is independent.\n"); } return ample; } if (cfg_wait_for_key) { getchar(); } } return enable; }
bool Core::check_C1(const ActionSet &enabled, const ActionSet &le, State *s) { ActionSet::iterator it1; ActionSet::iterator it2; std::deque<Action> queue; // This assume that there is no optimization for number of tokens in places ActionSet processed = ample; std::vector<bool> receive_blocked(ca::process_count * ca::process_count, false); std::vector<int> enabled_priorities(ca::process_count, 0); std::vector<int> marking = verif_configuration.get_marking(s); if (cfg_debug) { printf(" C1: Marking: {"); int place_count = marking.size() / ca::process_count; for (size_t i = 0; i < marking.size(); i++) { printf(" %d", marking[i]); if ((i + 1) % place_count == 0 && i + 1 != marking.size()) { printf(" |"); } } printf(" }\n"); printf(" C1: starting configuration {"); } for (ActionSet::iterator i = enabled.begin(); i != enabled.end(); i++) { if (ample.find(*i) != ample.end()) { if (i->type == ActionReceive) { receive_blocked[i->process * ca::process_count + i->data.receive.source] = true; } if (i->type == ActionFire) { enabled_priorities[i->process] = i->data.fire.transition_def->get_priority(); } } else { if (i->type == ActionFire) { processed.insert(*i); queue.push_back(*i); if (cfg_debug) { printf(" %s", i->to_string().c_str()); } const std::vector<ca::TransitionDef*> &transitions = net_def->get_transition_defs(); for (int t = 0; t < net_def->get_transitions_count(); t++) { if (transitions[t]->get_priority() >= enabled_priorities[i->process]) continue; if (s->is_transition_enabled(i->process, transitions[t])) { Action a; a.type = ActionFire; a.data.fire.transition_def = transitions[t]; a.process = i->process; processed.insert(a); queue.push_back(a); if (cfg_debug) { printf(" %s", a.to_string().c_str()); } } } continue; } if (i->type == ActionReceive) { const State::PacketQueue& pq = s->get_packets(i->process, i->data.receive.source); for (size_t p = 0; p < pq.size(); p++) { Action a; a.type = ActionReceive; a.process = i->process; a.data.receive.source = i->data.receive.source; ca::Tokens *tokens = (ca::Tokens *) pq[p].data; a.data.receive.edge_id = tokens->edge_id; if (processed.find(a) == processed.end()) { processed.insert(a); queue.push_back(a); if (cfg_debug) { printf(" %s", a.to_string().c_str()); } } } continue; } processed.insert(*i); queue.push_back(*i); if (cfg_debug) { printf(" %s", i->to_string().c_str()); } } } if (cfg_debug) { printf(" }\n"); } while(queue.size() > 0) { for (ActionSet::iterator a = ample.begin(); a != ample.end(); a++) { if (verif_configuration.is_dependent(*a, queue.front(), marking)) { if (cfg_debug) { printf(" C1: %s and %s are dependent.\n", a->to_string().c_str(), queue.front().to_string().c_str()); } return false; } } if (cfg_debug) { size_t i = queue.size(); verif_configuration.compute_successors(queue.front(), queue, processed, receive_blocked, enabled_priorities, marking); printf(" C1: successors of %s: {", queue.front().to_string().c_str()); for (; i < queue.size(); i++) { printf(" %s", queue[i].to_string().c_str()); } printf(" }\n"); } else { verif_configuration.compute_successors(queue.front(), queue, processed, receive_blocked, enabled_priorities, marking); } queue.pop_front(); } return true; }