Exemple #1
0
 bool operator()(const Tuple &t1, const Tuple &t2) const {
   vector<size_t>::const_iterator it = this->order.begin();
   for (; it != this->order.end(); ++it) {
     if (*it >= t1.size()) {
       if (*it < t2.size()) {
         return false;
       }
     } else if (*it >= t2.size()) {
       return true;
     } else if (t1[*it] != t2[*it]) {
       return t1[*it] < t2[*it];
     }
   }
   if (this->total_ordering) {
     Tuple::const_iterator cit1 = t1.begin();
     Tuple::const_iterator cit2 = t2.begin();
     while (cit1 != t1.end() && cit2 != t2.end()) {
       if (*cit1 != *cit2) {
         return *cit1 < *cit2;
       }
       ++cit1;
       ++cit2;
     }
     if (cit1 == t1.end()) {
       return cit2 != t2.end();
     }
   }
   return false;
 }
Exemple #2
0
double error_total(double (*efn)(MeshFunction*, MeshFunction*, RefMap*, RefMap*),
		   double (*nfn)(MeshFunction*, RefMap*), Tuple<Solution*>& slns1, Tuple<Solution*>& slns2	)
{
  Tuple<Solution*>::iterator it1, it2;
  double error = 0.0, norm = 0.0;

  for (it1=slns1.begin(), it2=slns2.begin(); it1 < slns1.end(); it1++, it2++) {
    assert(it2 < slns2.end());
    error += sqr(calc_abs_error(efn, *it1, *it2));
    if (nfn) norm += sqr(calc_norm(nfn, *it2));
  }

  return (nfn ? sqrt(error/norm) : sqrt(error));
}
void TupleStorageSubBlock::paranoidInsertTypeCheck(const Tuple &tuple, const AllowedTypeConversion atc) {
#ifdef QUICKSTEP_DEBUG
  assert(relation_.size() == tuple.size());

  Tuple::const_iterator value_it = tuple.begin();
  CatalogRelation::const_iterator attr_it = relation_.begin();

  while (value_it != tuple.end()) {
    switch (atc) {
      case kNone:
        assert(value_it->getType().equals(attr_it->getType()));
        break;
      case kSafe:
        assert(value_it->getType().isSafelyCoercibleTo(attr_it->getType()));
        break;
      case kUnsafe:
        assert(value_it->getType().isCoercibleTo(attr_it->getType()));
        break;
    }

    ++value_it;
    ++attr_it;
  }
#endif
}
	virtual void retrieve(const Query& q, Answer& a) throw (dlvhex::PluginError)
  {
    // get input
    assert(q.input.size() == 1);
    ID pred = q.input[0];

    // get outputs
    assert(q.pattern.size() == outputSize);

    // build unifier
    OrdinaryAtom unifier(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN);
    unifier.tuple.push_back(pred);
    unifier.tuple.insert(unifier.tuple.begin(), q.pattern.begin(), q.pattern.end());

    // check if <pred>(pattern) part of interpretation (=forward <pred> via external atom)
    assert(q.interpretation != 0);
    const Interpretation::Storage& bits = q.interpretation->getStorage();
    for(Interpretation::Storage::enumerator it = bits.first();
        it != bits.end(); ++it)
    {
      const OrdinaryAtom& ogatom = registry->ogatoms.getByID(ID(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, *it));
      if( ogatom.unifiesWith(unifier) )
      {
        Tuple partial;
        partial.insert(partial.begin(), ogatom.tuple.begin()+1, ogatom.tuple.end());
        a.get().push_back(partial);
      }
    }
  }
Exemple #5
0
 bool operator()(const Tuple& tup) const {
   if (tup.size() >= size) {
     auto& tarr = static_types_array<T...>::arr;
     auto begin = tup.begin();
     return std::equal(begin, begin + size, tarr.begin(), types_only_eq);
   }
   return false;
 }
Exemple #6
0
	inline Tuple *replace_tuple(const Tuple *t, size_t pos, const Value &val)
	{
		Tuple *ret = new_tuple(std::max(t->m_count, pos+1));
		std::copy(t->begin(), t->begin() + std::min(pos, t->m_count), ret->m_data);
		if (pos < t->m_count)
			std::copy(t->begin() + pos + 1, t->end(), ret->m_data + pos + 1);
		std::fill(ret->begin() + t->m_count, ret->end(), Nil);
		ret->m_data[pos] = val;
		return ret;
	}
Exemple #7
0
 bool operator()(const Tuple& tup) const {
   auto& tarr = static_types_array<T...>::arr;
   if (tup.size() >= (sizeof...(T) - wc_count)) {
     auto fpush = [](const typename Tuple::const_iterator&) {};
     auto fcommit = [] {};
     auto frollback = [] {};
     return match(tup.begin(), tup.end(), tarr.begin(), tarr.end(),
            fpush, fcommit, frollback);
   }
   return false;
 }
Exemple #8
0
 bool operator()(const Tuple& tup) const {
   auto tup_size = tup.size();
   if (tup_size >= size) {
     auto& tarr = static_types_array<T...>::arr;
     auto begin = tup.begin();
     begin += (tup_size - size);
     return std::equal(begin, tup.end(),
               (tarr.begin() + 1), // skip 'anything'
               types_only_eq);
   }
   return false;
 }
  bool addEntry(const Tuple &tuple) {
	  Tuple::const_iterator attr_it;
	  int bloom_filter_id = 0;
	  for (attr_it = tuple.begin(); attr_it != tuple.end(); ++attr_it, ++bloom_filter_id) {
		  if (!attr_it->isNull()) {
			  ScopedPtr<char> attr_data_ptr(new char[attr_it->getInstanceByteLength()]);
			  attr_it->copyInto(static_cast<void*>(attr_data_ptr.get()));
			  bloom_filters_.get()[bloom_filter_id].insert(attr_data_ptr.get(),
					  	  	  	  	  	  	  	  	 attr_it->getInstanceByteLength());
		  }
	  }
	  return true;
  }
Exemple #10
0
 bool operator()(const Tuple& tup) const {
   if (not tup.dynamically_typed()) {
     // statically typed tuples return &typeid(type_list<T...>)
     // as type token
     return typeid(detail::type_list<T...>)== *(tup.type_token());
   }
   // always use a full dynamic match for dynamic typed tuples
   else if (tup.size() == sizeof...(T)) {
     auto& tarr = static_types_array<T...>::arr;
     return std::equal(tup.begin(), tup.end(), tarr.begin(),
               types_only_eq);
   }
   return false;
 }
/**
 * @brief utility function that prints a Tuple on the specified ostream
 */
void ActionPluginFinalCallback::printTuple(std::ostream& output,
		const Tuple& tuple, const RegistryPtr registryPtr) {
	bool first = true;
	for (Tuple::const_iterator it = tuple.begin(); it != tuple.end(); it++) {
		if (first)
			first = !first;
		else
			output << ", ";
		if (it->isConstantTerm() || it->isVariableTerm())
			output << registryPtr->getTermStringByID(*it);
		else
			output << it->address;
	}
}
Exemple #12
0
  bool operator()(const Tuple& tup, MappingVector& mv) const {
    auto& tarr = static_types_array<T...>::arr;
    if (tup.size() >= (sizeof...(T) - wc_count)) {
      size_t commited_size = 0;
      auto fpush = [&](const typename Tuple::const_iterator& iter) {
        mv.push_back(iter.position());

      };
      auto fcommit = [&] { commited_size = mv.size(); };
      auto frollback = [&] { mv.resize(commited_size); };
      return match(tup.begin(), tup.end(), tarr.begin(), tarr.end(),
             fpush, fcommit, frollback);
    }
    return false;
  }
void TupleStorageSubBlock::paranoidInsertTypeCheck(const Tuple &tuple) {
#ifdef QUICKSTEP_DEBUG
  assert(relation_.size() == tuple.size());

  Tuple::const_iterator value_it = tuple.begin();
  CatalogRelationSchema::const_iterator attr_it = relation_.begin();

  while (value_it != tuple.end()) {
    assert(value_it->isPlausibleInstanceOf(attr_it->getType().getSignature()));

    ++value_it;
    ++attr_it;
  }
#endif
}
Exemple #14
0
 bool operator()(const Tuple& tup) const {
   auto tup_size = tup.size();
   if (tup_size >= (size - 1)) {
     auto& tarr = static_types_array<T...>::arr;
     // first range [0, X1)
     auto begin = tup.begin();
     auto end = begin + wc_pos;
     if (std::equal(begin, end, tarr.begin(), types_only_eq)) {
       // second range [X2, N)
       begin = end = tup.end();
       begin -= (size - (wc_pos + 1));
       auto arr_begin = tarr.begin() + (wc_pos + 1);
       return std::equal(begin, end, arr_begin, types_only_eq);
     }
   }
   return false;
 }
Exemple #15
0
bool
Tuple::operator<(const Tuple& rhs) const
{
  auto iterl = begin();
  auto iterr = rhs.begin();

  while (iterl != end() && iterr != rhs.end())
  {
    if (iterl->first < iterr->first)
    {
      return true;
    }
    else if (iterr->first < iterl->first)
    {
      return false;
    }
    else if (iterl->second < iterr->second)
    {
      return true;
    }
    else if (iterr->second < iterl->second)
    {
      return false;
    }
    //this pair is equal, go to the next one
    ++iterl;
    ++iterr;
  }

  if (iterl == end() && iterr == rhs.end())
  {
    //they must be equal, so return false
    return false;
  }
  else if (iterl == end())
  {
    return true;
  }
  else
  {
    return false;
  }
}
Exemple #16
0
TTailHairpin::TTailHairpin(const Tuple &tuple, const Tuple &size) {
    int len = size[1];
    Tuple t = tuple;
    std::sort(t.begin(), t.end(), std::less<int>{});
    Frag frag;
        for (int i = t[0]; i <= t[1]; i++) {
            frag.push_back(i);
        }
        d_frags.push_back(std::move(frag));
        for (int i = t[2]; i < len; i++) {
            frag.push_back(i);
        }
        d_frags.push_back(std::move(frag));
        d_max_len = std::max(t[1] - t[0] - 1, len - t[2] - 1);
    d_indices = std::make_unique<Mati>(d_max_len, 3);
    for (int i = 0; i < d_max_len; i++) for (int j = 0; j < 3; j++) (*d_indices)(i, j) = -1;
    set_indices(0, d_frags[0].front() + 1, d_frags[0].back() - 1);
    set_indices(1, d_frags[1].front() + 1, len - 1);
}
Exemple #17
0
	void Environment::run(RunningContext *context)
	{
		const Instruction &ins = m_ipos;
		m_context = context;
		if (!context)
		{
			m_running = false;
		} else if (!m_running)
		{
			clear_vstore();
			TRACE_PRINTF(TRACE_VM, TRACE_INFO, "Entering running state with %p\n", context);
			m_running = true;
			const SourcePos *last_pos = NULL; // used for debug output below.
			const Instruction *ipos;
			while (m_context && (ipos = m_context->next()))
			{
				size_t output = -1;
				size_t expected = -1;
#				define CHECK_STACK(in, out) TRACE_OUT(TRACE_VM, TRACE_SPAM) {\
					assert(m_context->stack_count() >= (size_t)(in)); \
					if ((out) != -1) { assert((long)(expected = m_context->stack_count() - (size_t)(in) + (size_t)(out)) >= 0); } \
					tprintf("Stack info: before(%d), in(%d), out(%d), expected(%d)\n", (int)m_context->stack_count(), (int)(in), (int)(out), (int)expected); \
					output = (out); \
				}

				m_ipos = *ipos;

				TRACE_DO(TRACE_VM, TRACE_INFO) {
					const SourcePos &pos = m_context->m_instructions->source_pos(ipos);
					if (!last_pos || *last_pos != pos)
						tprintf("Source Position: %s:%d:%d (%s)\n", pos.file.c_str(), (int)pos.line_num, (int)pos.column, pos.annotation.c_str());
					last_pos = &pos;
				}
				TRACE_OUT(TRACE_VM, TRACE_SPAM) {
					tprintf("Instruction: %s@%d\n",
						inspect(ins).c_str(),
						(int)(ipos - &*m_context->instructions().begin())
						);
					tprintf("Stack: %d deep", (int)m_context->stack_count());

					const Value *it;
					for (it = m_context->stack_begin(); it != m_context->stack_pos(); it++)
					{
						tprintf("\n   %s", inspect(*it).c_str());
					}
					tprintf(" <--\n");
				}

				switch(ins.instruction)
				{
				case NOP:
					CHECK_STACK(0, 0);
					break;
				case DEBUGGER:
					CHECK_STACK(0, 0);
					{
						String *action = ptr<String>(ins.arg1);
						if (*action == "interrupt")
						{
							DO_DEBUG __asm__("int3");
						} else if (*action == "trace_enable") {
							trace_mute = false;
						} else if (*action == "trace_disable") {
							trace_mute = true;
						}
					}
					break;

				case POP:
					CHECK_STACK(1, 0);
					m_context->pop();
					break;
				case PUSH:
					CHECK_STACK(0, 1);
					m_context->push(ins.arg1);
					break;
				case SWAP: {
					CHECK_STACK(2, 2);
					Value tmp1 = m_context->top();
					m_context->pop();
					Value tmp2 = m_context->top();
					m_context->pop();
					m_context->push(tmp1);
					m_context->push(tmp2);
					}
					break;
				case DUP_TOP:
					CHECK_STACK(1, 2);
					m_context->push(m_context->top());
					break;

				case IS: {
					CHECK_STACK(1, 1);
					Value res = bvalue(ins.arg1 == m_context->top());
					m_context->pop();
					m_context->push(res);
					}
					break;
				case IS_EQ: {
					CHECK_STACK(2, 1);
					Value first = m_context->top();
					m_context->pop();
					Value second = m_context->top();
					m_context->pop();
					m_context->push(bvalue(first == second));
					}
					break;
				case IS_NOT: {
					CHECK_STACK(1, 1);
					Value res = bvalue(ins.arg1 != m_context->top());
					m_context->pop();
					m_context->push(res);
					}
					break;
				case IS_NOT_EQ:{
					CHECK_STACK(2, 1);
					Value first = m_context->top();
					m_context->pop();
					Value second = m_context->top();
					m_context->pop();
					m_context->push(bvalue(first != second));
					}
					break;
				case JMP:
					CHECK_STACK(0, 0);

					GC::safe_point();

					m_context->jump(ins.cache.machine_num);
					break;
				case JMP_IF:
					CHECK_STACK(1, 0);

					GC::safe_point();

					if (is_truthy(m_context->top()))
						m_context->jump(ins.cache.machine_num);
					m_context->pop();
					break;
				case JMP_IF_NOT:
					CHECK_STACK(1, 0);

					GC::safe_point();

					if (!is_truthy(m_context->top()))
						m_context->jump(ins.cache.machine_num);
					m_context->pop();
					break;

				case LEXICAL_CLEAN_SCOPE: {
					CHECK_STACK(0, 0);
					VariableFrame *frame = new_variable_frame(m_context->m_instructions);
					m_context->new_scope(frame);
					}
					break;
				case LEXICAL_LINKED_SCOPE: {
					CHECK_STACK(0, 0);
					VariableFrame *frame = new_variable_frame(m_context->m_instructions);
					frame->link_frame(m_context->m_lexicalvars);
					m_context->new_scope(frame);
					}
					break;
				case FRAME_GET: {
					CHECK_STACK(0, 1);
					size_t frameid = (size_t)ins.cache.machine_num;
					TRACE_PRINTF(TRACE_VM, TRACE_SPAM, "Getting frame var %s (%d)\n", ptr<String>(ins.arg1)->c_str(), (int)frameid);
					m_context->push(m_context->get_framevar(frameid));
					}
					break;
				case FRAME_SET: {
					CHECK_STACK(1, 0);
					size_t frameid = (size_t)ins.cache.machine_num;
					TRACE_PRINTF(TRACE_VM, TRACE_SPAM, "Setting frame var %s (%d) to: %s\n", ptr<String>(ins.arg1)->c_str(), (int)frameid, inspect(m_context->top()).c_str());
					m_context->set_framevar(frameid, m_context->top());
					m_context->pop();
					}
					break;
				case LOCAL_GET: {
					CHECK_STACK(0, 1);
					size_t localid = (size_t)ins.cache.machine_num;
					TRACE_PRINTF(TRACE_VM, TRACE_SPAM, "Getting local var %s (%d)\n", ptr<String>(ins.arg1)->c_str(), (int)localid);
					m_context->push(m_context->get_localvar(localid));
					}
					break;
				case LOCAL_SET: {
					CHECK_STACK(1, 0);
					size_t localid = (size_t)ins.cache.machine_num;
					TRACE_PRINTF(TRACE_VM, TRACE_SPAM, "Setting local var %s (%d) to: %s\n", ptr<String>(ins.arg1)->c_str(), (int)localid, inspect(m_context->top()).c_str());
					m_context->set_localvar(localid, m_context->top());
					m_context->pop();
					}
					break;
				case LEXICAL_GET: {
					CHECK_STACK(0, 1);
					size_t depth = ins.arg1.machine_num;
					size_t localid = (size_t)ins.cache.machine_num;
					TRACE_PRINTF(TRACE_VM, TRACE_SPAM, "lexical_get %u@%u: %i\n", (unsigned)localid, (unsigned)depth, type(m_context->get_lexicalvar(localid, depth)));
					if (depth == 0)
						m_context->push(m_context->get_lexicalvar(localid));
					else
						m_context->push(m_context->get_lexicalvar(localid, depth));
					}
					break;
				case LEXICAL_SET: {
					CHECK_STACK(1, 0);
					size_t depth = ins.arg1.machine_num;
					size_t localid = (size_t)ins.cache.machine_num;
					TRACE_PRINTF(TRACE_VM, TRACE_SPAM, "lexical_set %u@%u: %i\n", (unsigned)localid, (unsigned)depth, type(m_context->top()));
					if (depth == 0)
						m_context->set_lexicalvar(localid, m_context->top());
					else
						m_context->set_lexicalvar(localid, depth, m_context->top());
					m_context->pop();
					}
					break;

				case CHANNEL_NEW: {
					CHECK_STACK(0, 1);
					const Value &octx = vstore(value(m_context));
					RunnableContext *nctx = new_context(octx);
					nctx->jump(ins.cache.machine_num);
					m_context->push(value(nctx));
					clear_vstore();
					}
					break;
				case CHANNEL_SPECIAL:
					CHECK_STACK(0, 1);
					m_context->push(special_channel(*ptr<String>(ins.arg1)));
					break;
				case CHANNEL_SEND: {
					CHECK_STACK(3, -1);

					GC::safe_point();

					const Value &val = vstore(m_context->top()); m_context->pop();
					const Value &ret = vstore(m_context->top()); m_context->pop();
					const Value &channel = vstore(m_context->top()); m_context->pop();

					// A context that's been channel_sended from should never be returned to,
					// so invalidate it.
					m_context->invalidate();
					channel_send(this, channel, val, ret);
					clear_vstore();
					}
					break;
				case CHANNEL_CALL:{
					CHECK_STACK(2, -1);

					GC::safe_point();

					const Value &val = vstore(m_context->top()); m_context->pop();
					const Value &channel = vstore(m_context->top()); m_context->pop();
					const Value &ret = vstore(value(m_context));

					channel_send(this, channel, val, ret);
					clear_vstore();
					}
					break;
				case CHANNEL_RET:{
					CHECK_STACK(2, -1);
					const Value &val = vstore(m_context->top()); m_context->pop();
					const Value &channel = vstore(m_context->top()); m_context->pop();

					// A context that's been channel_reted from should never be returned to,
					// so invalidate it.
					m_context->invalidate();
					channel_send(this, channel, val, value(&no_return_ctx));
					clear_vstore();
					}
					break;

				case MESSAGE_NEW: {
					long long id = ins.cache.machine_num;
					long long sysarg_count = ins.arg2.machine_num, sysarg_counter = sysarg_count - 1;
					long long arg_count = ins.arg3.machine_num, arg_counter = arg_count - 1;
					CHECK_STACK(sysarg_count + arg_count, 1);

					Message *msg = new_message(id, sysarg_count, arg_count);

					while (arg_count > 0 && arg_counter >= 0)
					{
						msg->args()[arg_counter] = m_context->top();
						m_context->pop();
						--arg_counter;
					}
					while (sysarg_count > 0 && sysarg_counter >= 0)
					{
						msg->sysargs()[sysarg_counter] = m_context->top();
						m_context->pop();
						--sysarg_counter;
					}

					m_context->push(value(msg));
					}
					break;
				case MESSAGE_SPLAT: {
					CHECK_STACK(2, 1);
					const Tuple &tuple = *ptr<Tuple>(m_context->top()); m_context->pop();
					const Message &msg = *ptr<Message>(m_context->top()); m_context->pop();

					Message *nmsg = new_message(msg.m_id, msg.sysarg_count(), msg.arg_count() + tuple.size());
					std::copy(msg.sysargs(), msg.sysargs_end(), nmsg->sysargs());
					std::copy(msg.args(), msg.args_end(), nmsg->args());
					std::copy(tuple.begin(), tuple.end(), nmsg->args() + msg.arg_count());
					m_context->push(value(nmsg));
					}
					break;
				case MESSAGE_ADD: {
					long long count = ins.arg1.machine_num, counter = 0;
					CHECK_STACK(1 + count, 1);
					const Message &msg = *ptr<Message>(*(m_context->stack_pos() - 1 - count));

					Message *nmsg = new_message(msg.m_id, msg.sysarg_count(), msg.arg_count() + count);
					std::copy(msg.sysargs(), msg.sysargs_end(), nmsg->sysargs());
					std::copy(msg.args(), msg.args_end(), nmsg->args());

					Message::iterator out = nmsg->args() + msg.arg_count();
					while (count > 0 && counter < count)
					{
						*out++ = m_context->top();
						m_context->pop();
						++counter;
					}
					m_context->pop(); // this is the message we pulled directly off the stack before.

					m_context->push(value(nmsg));
					}
					break;
				case MESSAGE_COUNT:
					CHECK_STACK(1, 2);
					m_context->push(value((long long)ptr<Message>(m_context->top())->arg_count()));
					break;
				case MESSAGE_IS:
					CHECK_STACK(1, 2);
					m_context->push(bvalue(ptr<Message>(m_context->top())->m_id == (uint64_t)ins.cache.machine_num));
					break;
				case MESSAGE_IS_PROTO:
					CHECK_STACK(1, 2);
					m_context->push(bvalue(ptr<Message>(m_context->top())->protocol_id() == (uint64_t)ins.cache.machine_num));
					break;
				case MESSAGE_ID:
					{
					CHECK_STACK(1, 2);
					Message *msg = ptr<Message>(m_context->top());
					m_context->push(value((long long)msg->m_id));
					}
					break;
				case MESSAGE_SPLIT_ID:
					{
					CHECK_STACK(1, 3);
					Message *msg = ptr<Message>(m_context->top());
					m_context->push(value((long long)msg->message_id()));
					m_context->push(value((long long)msg->protocol_id()));
					}
					break;
				case MESSAGE_CHECK:
					CHECK_STACK(1, 1);
					if (!is(m_context->top(), MESSAGE))
					{
						m_context->pop();
						m_context->push(False);
					}
					break;
				case MESSAGE_FORWARD: {
					CHECK_STACK(1, 1);

					long long id = ins.cache.machine_num;
					const Message &msg = *ptr<Message>(m_context->top());
					Message *nmsg = new_message(id, msg.sysarg_count(), msg.arg_count() + 1);
					std::copy(msg.sysargs(), msg.sysargs_end(), nmsg->sysargs());
					nmsg->args()[0] = value(new_string(msg.name()));
					std::copy(msg.args(), msg.args_end(), nmsg->args() + 1);
					m_context->pop();
					m_context->push(value(nmsg));
					break;
				}
				case MESSAGE_SYS_PREFIX: {
					long long count = ins.arg1.machine_num, counter = 0;
					CHECK_STACK(1 + count, 1);

					const Value *sdata = m_context->stack_pos() - 1 - count;
					const Message &msg = *ptr<Message>(*sdata++);
					Message *nmsg = new_message(msg.m_id, msg.sysarg_count() + count, msg.arg_count());
					Message::iterator to = nmsg->sysargs();
					while (counter++ < count)
					{
						*to++ = *sdata++;
					}
					std::copy(msg.sysargs(), msg.sysargs_end(), to);
					std::copy(msg.args(), msg.args_end(), nmsg->args());
					while (--counter != 0)
					{
						m_context->pop();
					}
					m_context->pop(); // message we read off stack before.
					m_context->push(value(nmsg));
					break;
				}
				case MESSAGE_SYS_UNPACK: {
					long long count = ins.arg1.machine_num, pos = count - 1;
					CHECK_STACK(1, 1 + count);

					const Message *msg = ptr<Message>(m_context->top());
					Message::const_iterator args = msg->sysargs();
					long long len = (long long)msg->sysarg_count();

					while (pos >= 0)
					{
						if (pos >= len)
							m_context->push(Undef);
						else
							m_context->push(args[pos]);

						pos -= 1;
					}
					}
					break;
				case MESSAGE_UNPACK: {
					long long first_count = ins.arg1.machine_num, first_counter = 0;
					long long splat = ins.arg2.machine_num;
					long long last_count = ins.arg3.machine_num, last_counter = 0;
					CHECK_STACK(1, 1 + first_count + last_count + (splat?1:0));

					const Message *msg = ptr<Message>(m_context->top());
					Message::const_iterator args = msg->args();
					long long len = (long long)msg->arg_count(), pos = len - 1;

					while (last_counter < last_count && pos >= first_count)
					{
						if (pos >= len)
							m_context->push(Nil);
						else
							m_context->push(args[pos]);

						pos -= 1;
						last_counter += 1;
					}

					if (splat != 0)
					{
						if (pos >= first_count)
						{
							Tuple *splat_tuple = new_tuple(pos - first_count + 1);
							Tuple::iterator out = splat_tuple->end();
							while (pos >= first_count)
							{
								--out;
								*out = args[pos];
								pos -= 1;
							}
							m_context->push(value(splat_tuple));
						} else {
							m_context->push(value(new_tuple(0)));
						}
					}

					pos = first_count - 1;

					while (first_counter < first_count && pos >= 0)
					{
						if (pos >= len)
							m_context->push(Nil);
						else
							m_context->push(args[pos]);

						pos -= 1;
						first_counter += 1;
					}
					}
					break;

				case STRING_COERCE: {
					const Value &coerce = ins.arg1;
					const Value &val = vstore(m_context->top());
					if (is(val, STRING))
					{
						CHECK_STACK(1, 2);
						// push a nil like we called the method.
						m_context->push(Nil);
					} else {
						CHECK_STACK(1, -1);
						m_context->pop();
						channel_send(this, val, value(new_message(coerce)), value(m_context));
					}
					}
					clear_vstore();
					break;

				case STRING_NEW: {
					long long count = ins.arg1.machine_num, counter = 0;
					CHECK_STACK(count, 1);
					const Value *sp = m_context->stack_pos() - 1;
					size_t len = 0;
					while (count > 0 && counter < count)
					{
						assert(is(sp[-counter], STRING));
						len += ptr<String>(sp[-counter])->length();
						++counter;
					}
					String *res = new_string(len);
					String::iterator out = res->begin();
					counter = 0;
					while (count > 0 && counter < count)
					{
						const String *val = ptr<String>(m_context->top());
						out = std::copy(val->begin(), val->end(), out);
						m_context->pop();
						++counter;
					}
					m_context->push(value(res));
					}
					break;

				case TUPLE_NEW: {
					long long count = ins.arg1.machine_num, counter = 0;
					CHECK_STACK(count, 1);
					Tuple *tuple = new_tuple(count);
					Tuple::iterator out = tuple->begin();
					while (count > 0 && counter < count)
					{
						*out++ = m_context->top();
						m_context->pop();
						++counter;
					}
					m_context->push(value(tuple));
					}
					break;
				case TUPLE_SPLAT: {
					CHECK_STACK(2, 1);
					const Tuple *tuple2 = ptr<Tuple>(m_context->top()); m_context->pop();
					const Tuple *tuple1 = ptr<Tuple>(m_context->top()); m_context->pop();
					Tuple *tuple = join_tuple(tuple1, tuple2);
					m_context->push(value(tuple));
					}
					break;
				case TUPLE_UNPACK: {
					long long first_count = ins.arg1.machine_num, first_counter = 0;
					long long splat = ins.arg2.machine_num;
					long long last_count = ins.arg3.machine_num, last_counter = 0;
					CHECK_STACK(1, 1 + first_count + last_count + (splat?1:0));

					const Tuple &tuple = *ptr<Tuple>(m_context->top());
					long long len = tuple.size(), pos = tuple.size() - 1;
					while (last_counter < last_count && pos >= first_count)
					{
						if (pos >= len)
							m_context->push(Nil);
						else
							m_context->push(tuple[pos]);

						pos -= 1;
						last_counter += 1;
					}

					if (splat != 0)
					{
						if (pos >= first_count)
						{
							Tuple *splat_tuple = new_tuple(pos - first_count + 1);
							Tuple::iterator out = splat_tuple->end();
							while (pos >= first_count)
							{
								--out;
								*out = tuple[pos];
								pos -= 1;
							}
							m_context->push(value(splat_tuple));
						} else {
							m_context->push(value(new_tuple(0)));
						}
					}

					pos = first_count - 1;

					while (first_counter < first_count && pos >= 0)
					{
						if (pos >= len)
							m_context->push(Nil);
						else
							m_context->push(tuple[pos]);

						pos -= 1;
						first_counter += 1;
					}
					}
					break;
				default:
					printf("Panic! Unknown instruction %d\n", ins.instruction);
					exit(1);
				}

				TRACE_OUT(TRACE_VM, TRACE_SPAM) {
					tprintf("Output: %d", (int)output);
					if ((long)output > 0)
					{
						const Value *it = std::max(
							m_context->stack_begin(), m_context->stack_pos() - output);
						for (; it != m_context->stack_pos(); it++)
						{
							tprintf("\n   %s", inspect(*it).c_str());
						}
					}
					tprintf(" <--\n");
					tprintf("----------------\n");
				}
/**
 * @brief Best Model Selector, Execution Schedule Builder, Execute Actions on Environment
 */
void ActionPluginFinalCallback::operator()() {
	DBGLOG(DBG, "\nActionPluginFinalCallback called");

	if (ctxData.nameBestModelSelectorMap.count(
			ctxData.getBestModelSelectorSelected()) == 0)
		throw PluginError("The BestModelSelector chosen doesn't exist");

	ctxData.nameBestModelSelectorMap[ctxData.getBestModelSelectorSelected()]->getBestModel(
			ctxData.iteratorBestModel, ctxData.bestModelsContainer);

	std::stringstream ss;
	(*ctxData.iteratorBestModel)->interpretation->print(ss);
	DBGLOG(DBG, "\nBestModel selected: " << ss.str());

	DBGLOG(DBG, "\nCall the executionModeController");
	std::multimap<int, Tuple> multimapOfExecution;
	executionModeController(multimapOfExecution);

	DBGLOG(DBG, "\nThe MultiMapOfExecution:");
	DBGLOG(DBG, "Precedence\tTuple");
	std::multimap<int, Tuple>::iterator itMMOE;
	for (itMMOE = multimapOfExecution.begin();
			itMMOE != multimapOfExecution.end(); itMMOE++) {
		const Tuple& tempTuple = itMMOE->second;
		std::stringstream ss;
		printTuple(ss, tempTuple, registryPtr);
		DBGLOG(DBG, itMMOE->first << "\t\t" << ss.str());
	}

	if (ctxData.nameExecutionScheduleBuilderMap.count(
			ctxData.getExecutionScheduleBuilderSelected()) == 0)
		throw PluginError("The ExecutionScheduleBuilder chosen doesn't exist");

	DBGLOG(DBG, "\nCall the executionScheduleBuilder");
	std::list < std::set<Tuple> > listOfExecution;
	ctxData.nameExecutionScheduleBuilderMap[ctxData.getExecutionScheduleBuilderSelected()]->rewrite(
			multimapOfExecution, listOfExecution, (*(ctxData.iteratorBestModel))->interpretation);

	DBGLOG(DBG, "\nThe ListOfExecution:");
	std::list<std::set<Tuple> >::iterator itLOE;
	for (itLOE = listOfExecution.begin(); itLOE != listOfExecution.end();
			itLOE++) {
		std::set < Tuple > &tempSet = (*itLOE);
		for (std::set<Tuple>::iterator itLOEs = tempSet.begin();
				itLOEs != tempSet.end(); itLOEs++) {
			const Tuple& tempTuple = (*itLOEs);
			std::stringstream ss;
			printTuple(ss, tempTuple, registryPtr);
			DBGLOG(DBG, ss.str());
		}
	}

	DBGLOG(DBG,
			"\nControl if the order of Set in the List corresponds to their precedence");
	if (checkIfTheListIsCorrect(multimapOfExecution, listOfExecution)) {
		DBGLOG(DBG, "The List is correct");
	} else {
		DBGLOG(DBG, "The List isn't correct");
		throw PluginError(
				"The order of Set in the ListOfExecution doens't correspond to their precedence");
	}

	DBGLOG(DBG, "\nExecute the actions in the right order");

	for (itLOE = listOfExecution.begin(); itLOE != listOfExecution.end();
			itLOE++) {

		std::set < Tuple > &tempSet = (*itLOE);

		for (std::set<Tuple>::iterator itLOEs = tempSet.begin();
				itLOEs != tempSet.end(); itLOEs++) {

			const Tuple& tempTuple = (*itLOEs);

			if (*tempTuple.begin() == ctxData.getIDContinue()) {
				ctxData.continueIteration = true;
				continue;
			} else if (*tempTuple.begin() == ctxData.getIDStop()) {
				ctxData.stopIteration = true;
				continue;
			}

			Tuple tupleForExecute;
			tupleForExecute.insert(tupleForExecute.begin(),
					tempTuple.begin() + 1, tempTuple.end());

			std::stringstream ss;
			printTuple(ss, tempTuple, registryPtr);
			DBGLOG(DBG, "tupleForExecute: " << ss.str());
			ss.str("");
			printTuple(ss, tupleForExecute, registryPtr);
			DBGLOG(DBG, "tempTuple: " << ss.str());

			std::map<std::string, PluginActionBasePtr>::iterator it =
					ctxData.namePluginActionBaseMap.find(
							registryPtr->getTermStringByID(*tempTuple.begin()));

			if (it != ctxData.namePluginActionBaseMap.end())
				it->second->execute(programCtx,
						(*(ctxData.iteratorBestModel))->interpretation,
						tupleForExecute);
			else
				DBGLOG(DBG,
						"For the action '"
								<< registryPtr->getTermStringByID(
										*tempTuple.begin())
								<< "' wasn't found a definition");

		}
	}

	DBGLOG(DBG, "\nCheck Iteration");
	if (ctxData.getIterationType() == DEFAULT && ctxData.continueIteration)
		programCtx.config.setOption("RepeatEvaluation", 1);
	else if (ctxData.getIterationType() != DEFAULT && ctxData.stopIteration)
		programCtx.config.setOption("RepeatEvaluation", 0);
	else if (ctxData.getIterationType() == INFINITE)
		programCtx.config.setOption("RepeatEvaluation", 1);
	else if (ctxData.getIterationType() == FIXED) {
		if (!ctxData.getTimeDuration().is_not_a_date_time()) {
			boost::posix_time::time_duration diff =
					boost::posix_time::second_clock::local_time()
							- ctxData.getStartingTime();
			if (diff > ctxData.getTimeDuration())
				programCtx.config.setOption("RepeatEvaluation", 0);
			else if (ctxData.getNumberIterations() != -1) {
				programCtx.config.setOption("RepeatEvaluation",
						ctxData.getNumberIterations());
				ctxData.decreaseNumberIterations();
			} else
				programCtx.config.setOption("RepeatEvaluation", 1);
		}
	}

	if (programCtx.config.getOption("RepeatEvaluation") > 0) {

		DBGLOG(DBG, "\nIncrease iteration in the UtilitiesPlugin");
		ctxData.increaseIteration(programCtx);

		DBGLOG(DBG, "\nClear data structures");
		ctxData.clearDataStructures();

		ctxData.continueIteration = false;
		ctxData.stopIteration = false;

		DBGLOG(DBG, "\nReset cache");
		programCtx.resetCacheOfPlugins();

	}

}