Пример #1
0
Term* Term::multiply(Term* t)
{
	if(t->get_term_type() == CONSTANT_TERM) {
		ConstantTerm* ct = static_cast<ConstantTerm*>(t);
		return multiply(ct->get_constant());
	}

	if(get_term_type() == CONSTANT_TERM) {
		ConstantTerm* ct = static_cast<ConstantTerm*>(this);
		return t->multiply(ct->get_constant());
	}


	// non-linear multiplication: use an uninterpreted function
	vector<Term*> args;
	if(t < this) {
		args.push_back(t);
		args.push_back(this);
	}
	else {
		args.push_back(this);
		args.push_back(t);
	}
	Term* ft = FunctionTerm::make("multiply", args, false);
	return ft;

}
Пример #2
0
void Term::get_vars(set<Term*>& vars)
{


	term_type tt = get_term_type();
	if (tt == CONSTANT_TERM)
		return;
	if (tt == VARIABLE_TERM) {
		VariableTerm* vt = (VariableTerm*) this;
		vars.insert(vt);
		return;
	}
	if (tt == FUNCTION_TERM) {
		FunctionTerm* ft = (FunctionTerm*) this;
		for (unsigned int i = 0; i < ft->get_args().size(); i++) {
			ft->get_args()[i]->get_vars(vars);
		}
	} else {
		assert(tt == ARITHMETIC_TERM);
		ArithmeticTerm* at = (ArithmeticTerm*) this;
		map<Term*, long int>::const_iterator it = at->get_elems().begin();
		for (; it != at->get_elems().end(); it++) {
			it->first->get_vars(vars);
		}
	}
}
Пример #3
0
Term* Term::substitute(Term* (*sub_func)(Term* t, void* data), void* my_data)
{
	Term* new_t = (*sub_func)(this, my_data);
	if(new_t != this) {
		return new_t;
	}
	Term* res = NULL;
	switch (get_term_type()) {
		case CONSTANT_TERM:
		case VARIABLE_TERM: {
			res=  this;
			break;
		}
		case FUNCTION_TERM: {
			FunctionTerm* ft = (FunctionTerm*) this;
			const vector<Term*>& args = ft->get_args();
			vector<Term*> new_args;
			bool changed = false;
			for (unsigned int i = 0; i < args.size(); i++) {
				Term* new_arg = args[i]->substitute(sub_func, my_data);
				if (new_arg != args[i])
					changed = true;
				new_args.push_back(new_arg);
			}

			if (!changed) {
				res = this;
				break;
			}
			res= FunctionTerm::make(ft->get_id(), new_args, ft->is_invertible());

			break;

		}
		case ARITHMETIC_TERM: {
			ArithmeticTerm* at = (ArithmeticTerm*) this;
			bool changed = false;
			map<Term*, long int> new_elems;
			map<Term*, long int>::const_iterator it = at->get_elems().begin();
			for (; it != at->get_elems().end(); it++) {
				Term* new_t = it->first->substitute(sub_func, my_data);
				if (new_t != it->first)
					changed = true;
				new_elems[new_t]+= it->second;
			}
			if (!changed) {
				res =  at;
				break;
			}
			res = ArithmeticTerm::make(new_elems, at->get_constant());
			break;
		}
		default:
			assert(false);
	}
	return res;
}
Пример #4
0
Term* Term::rename_variables(map<int, int>& replacements)
{
	switch (get_term_type()) {
		case CONSTANT_TERM:
			return this;
		case VARIABLE_TERM: {
			VariableTerm* vt = (VariableTerm*) this;
			int var_id = vt->get_var_id();
			if (replacements.count(var_id)==0)
				return this;
			Term* res= VariableTerm::make(replacements[var_id]);
			return res;
		}
		case FUNCTION_TERM: {
			FunctionTerm* ft = (FunctionTerm*) this;
			const vector<Term*>& args = ft->get_args();
			vector<Term*> new_args;
			bool changed = false;
			for (unsigned int i = 0; i < args.size(); i++) {
				Term* new_arg = args[i]->rename_variables(replacements);
				if (new_arg != args[i])
					changed = true;
				new_args.push_back(new_arg);
			}

			if (!changed)
				return this;
			Term* res= FunctionTerm::make(ft->get_id(), new_args,
					ft->is_invertible());
			return res;

		}
		case ARITHMETIC_TERM: {
			ArithmeticTerm* at = (ArithmeticTerm*) this;
			bool changed = false;
			map<Term*, long int> new_elems;
			map<Term*, long int>::const_iterator it = at->get_elems().begin();
			for (; it != at->get_elems().end(); it++) {
				Term* new_t = it->first->rename_variables(replacements);
				if (new_t != it->first)
					changed = true;
				new_elems[new_t] += it->second;
			}
			if (!changed)
				return at;
			Term* res= ArithmeticTerm::make(new_elems, at->get_constant());
			return res;
		}
		default:
			assert(false);
	}
}
Пример #5
0
Term* Term::rename_variable(int old_var_id, int new_var_id)
{
	switch (get_term_type()) {
		case CONSTANT_TERM:
			return this;
		case VARIABLE_TERM: {
			VariableTerm* vt = (VariableTerm*) this;
			if (old_var_id != vt->get_var_id())
				return this;
			Term* res = VariableTerm::make(new_var_id);
			return res;
		}
		case FUNCTION_TERM: {
			FunctionTerm* ft = (FunctionTerm*) this;
			const vector<Term*>& args = ft->get_args();
			map<Term*, Term*> old_to_new;
			bool changed = false;
			for (unsigned int i = 0; i < args.size(); i++) {
				Term* old_arg = args[i];
				Term* new_arg = args[i]->rename_variable(old_var_id, new_var_id);
				if (new_arg != args[i])
					changed = true;
				old_to_new[old_arg] = new_arg;
			}

			if (!changed)
				return this;
			Term* res = ft->substitute(old_to_new);
			return res;

		}
		case ARITHMETIC_TERM: {
			ArithmeticTerm* at = (ArithmeticTerm*) this;
			bool changed = false;
			map<Term*, long int> new_elems;
			map<Term*, long int>::const_iterator it = at->get_elems().begin();
			for (; it != at->get_elems().end(); it++) {
				Term* new_t = it->first->rename_variable(old_var_id, new_var_id);
				if (new_t != it->first)
					changed = true;
				new_elems[new_t] += it->second;
			}
			if (!changed)
				return at;
			Term* res = ArithmeticTerm::make(new_elems, at->get_constant());
			return res;
		}
		default:
			assert(false);
	}
}
Пример #6
0
/**
 * Create a list of terms in the specified condition.
 *
 * If there are no terms in the condition, 'term_list' will be NULL.
 *
 * @param py_dict A Python dict containing terms. Must not be NULL.
 * @param term_list Pointer to a GSList which will be set to the newly
 *                  created list of terms. Must not be NULL.
 *
 * @return SRD_OK upon success, a negative error code otherwise.
 */
static int create_term_list(PyObject *py_dict, GSList **term_list)
{
	Py_ssize_t pos = 0;
	PyObject *py_key, *py_value;
	struct srd_term *term;
	uint64_t num_samples_to_skip;
	char *term_str;

	if (!py_dict || !term_list)
		return SRD_ERR_ARG;

	/* "Create" an empty GSList of terms. */
	*term_list = NULL;

	/* Iterate over all items in the current dict. */
	while (PyDict_Next(py_dict, &pos, &py_key, &py_value)) {
		/* Check whether the current key is a string or a number. */
		if (PyLong_Check(py_key)) {
			/* The key is a number. */
			/* TODO: Check if the number is a valid channel. */
			/* Get the value string. */
			if ((py_pydictitem_as_str(py_dict, py_key, &term_str)) != SRD_OK) {
				srd_err("Failed to get the value.");
				return SRD_ERR;
			}
			term = g_malloc0(sizeof(struct srd_term));
			term->type = get_term_type(term_str);
			term->channel = PyLong_AsLong(py_key);
			g_free(term_str);
		} else if (PyUnicode_Check(py_key)) {
			/* The key is a string. */
			/* TODO: Check if it's "skip". */
			if ((py_pydictitem_as_long(py_dict, py_key, &num_samples_to_skip)) != SRD_OK) {
				srd_err("Failed to get number of samples to skip.");
				return SRD_ERR;
			}
			term = g_malloc0(sizeof(struct srd_term));
			term->type = SRD_TERM_SKIP;
			term->num_samples_to_skip = num_samples_to_skip;
			term->num_samples_already_skipped = 0;
		} else {
			srd_err("Term key is neither a string nor a number.");
			return SRD_ERR;
		}

		/* Add the term to the list of terms. */
		*term_list = g_slist_append(*term_list, term);
	}

	return SRD_OK;
}
Пример #7
0
void Term::get_attributes(set<CNode*> & attributes)
{
	CNode* attrib_c = NULL;
	if(attribute == TERM_ATTRIB_GEQZ) {
		attrib_c = ILPLeaf::make(this, ConstantTerm::make(0), ILP_GEQ);
	}

	else if(attribute == TERM_ATTRIB_GTZ) {

		attrib_c = ILPLeaf::make(this, ConstantTerm::make(0), ILP_GT);
	}
	if(attrib_c != NULL) attributes.insert(attrib_c);


	switch(get_term_type())
	{
	case FUNCTION_TERM:
	{
		FunctionTerm* ft = (FunctionTerm*) this;
		const vector<Term*> & args = ft->get_args();
		for(unsigned int i=0; i<args.size(); i++)
		{
			Term* t = args[i];
			t->get_attributes(attributes);
		}
		break;
	}
	case ARITHMETIC_TERM:
	{
		ArithmeticTerm* at = (ArithmeticTerm*) this;
		const map<Term*, long int> & elems = at->get_elems();
		map<Term*, long int>::const_iterator it= elems.begin();
		for(; it!= elems.end(); it++)
		{
			Term* t = it->first;
			t->get_attributes(attributes);
		}
		break;
	}
	default:
		break;
	}

}
Пример #8
0
void Term::get_nested_terms(set<Term*>& terms, bool include_function_subterms,
		bool include_constants)
{
	if(! include_constants && get_term_type() == CONSTANT_TERM) return;
	if(terms.count(this) > 0) return;
	terms.insert(this);
	switch(this->get_term_type())
	{
	case CONSTANT_TERM:
	case VARIABLE_TERM:
		return;
	case FUNCTION_TERM: {
		if(!include_function_subterms) return;
		FunctionTerm* ft = (FunctionTerm*) this;
		const vector<Term*>& args = ft->get_args();
		for(unsigned int i=0; i< args.size(); i++) {
			args[i]->get_nested_terms(terms, include_function_subterms,
					include_constants);
		}
		return;
	}
	case ARITHMETIC_TERM:
	{
		ArithmeticTerm* at = (ArithmeticTerm*) this;
		const map<Term*, long int>& elems = at->get_elems();
		map<Term*, long int>::const_iterator it = elems.begin();
		for(; it!= elems.end(); it++) {
			it->first->get_nested_terms(terms, include_function_subterms,
					include_constants);
		}
		return;
	}
	default:
		assert(false);
	}
}