⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 item.cc

📁 由matlab开发的hybrid系统的描述语言
💻 CC
字号:
/*	HYSDEL	Copyright (C) 1999-2002  Fabio D. Torrisi	This file is part of HYSDEL.    	HYSDEL is free software; you can redistribute it and/or	modify it under the terms of the GNU General Public	License as published by the Free Software Foundation; either	version 2 of the License, or (at your option) any later version.	HYSDEL is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU	General Public License for more details.	You should have received a copy of the GNU General Public	License along with this library; if not, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA	CONTACT INFORMATION	===================	Fabio D. Torrisi	ETH Zentrum	Physikstrasse. 3 ETL,	CH-8032 Zurich	Switzerland	mailto:torrisi@aut.ee.ethz.ch (preferred)*/#include "Item.h"#include "CNF_clause.h"#include "MLD_representation.h"#include <list>#include <string>#include <stdio.h>#include "Logic_or_clause.h"#include "Logic_literal.h"#include "Number_expr.h"#include "Not_expr.h"#include "Affine_func.h"#include "Affine_addend.h"#include "Var_symbol.h"#include "Neg_expr.h"#include "Min_max_eps.h"#include "Param_symbol.h"#include "Plus_expr.h"#include "Symbol_table.h"#include "Variable_expr.h"#include "Parameter_expr.h"#include "Cmd_options.h"#include "Linear_item.h"#include "Row_information.h"#include "Counter.h"#include "Real_number.h"#include <stdio.h>#include "Globals.h"#include "Problem.h"#include "Problem_handler.h"class MLD_representation;Item::Item(const Globals * glob) {	globals = glob;	group = -1;	subgroup = -1;	unrolled_from = NULL;	section=NULL;}/*Item::~Item(){required.clear();}*/void Item::comp_group_numbers() {	if (group != -1) // already set			return;	if (unrolled_from) {		assert(unrolled_from->group != -1); //fine		group = unrolled_from->group;		subgroup = unrolled_from->subgroup + 1;		source = unrolled_from->source;		source_line = unrolled_from->source_line;	} else {		group = globals->counter->get_cnt();		subgroup = 0;	}}string Item::to_string() const {	string res;	res += "item defined at line ";	res += source_line;	res += ": ";	res += source;	res += "\n";	return res;}void Item::cnf_to_mld(const CNF_clause * cnf, MLD_representation * mld,	int * subind_cnt) const {		Row_information * info;		int ineq, clause_cnt;		list < Logic_or_clause * >::const_iterator clauses;		list < Logic_literal * >::const_iterator literals;		clause_cnt = 0;		for (clauses = cnf->get_or_clauses()->begin();			clauses != cnf->get_or_clauses()->end(); clauses++) {				int neg_cnt = 0;				ineq = mld->new_ineq();				clause_cnt++;				info = new Row_information(this, * subind_cnt);				(* subind_cnt) ++;				mld->set_info_ineq(ineq, info);				for (literals = (* clauses)->get_literals()->begin();					literals != (* clauses)->get_literals()->end();					literals++) {						Expr * e;						if ((* literals)->get_neg()) {							e = new Number_expr(1.0, globals);							neg_cnt++;						} else {							e = new Number_expr(-1.0, globals);						}						mld->set_coeff_ineq_less(ineq,							(* literals)->get_variable(), e);				}				mld->set_coeff_ineq(ineq, NULL,					new Number_expr(neg_cnt					- 1.0, globals));		}}void Item::aff_leq_zero_to_mld(const Affine_func * aff,	MLD_representation * mld, int * subind_cnt) const {		int ineq;		list < Affine_addend * >::const_iterator iter;		Row_information * info;		ineq = mld->new_ineq();		info = new Row_information(this, * subind_cnt);		(* subind_cnt) ++;		mld->set_info_ineq(ineq, info);		for (iter = aff->get_addends()->begin();			iter != aff->get_addends()->end(); iter++) {				mld->set_coeff_ineq_less(ineq, (* iter)->get_var(),					(* iter)->get_coeff()->clone());		}}void Item::aff_to_mld_eq(const Var_symbol * lhs, const Affine_func * aff,	MLD_representation * mld, int * subind_cnt) const {		list < Affine_addend * >::const_iterator iter;		Row_information * info;		info = new Row_information(this, * subind_cnt);		(* subind_cnt) ++;		mld->set_info_eq(lhs, info);		for (iter = aff->get_addends()->begin();			iter != aff->get_addends()->end(); iter++) {				mld->set_coeff_eq(lhs, (* iter)->get_var(),					(* iter)->get_coeff());		}}Min_max_eps * Item::compute_mme_from_aff(const Affine_func * aff) const {	list < Affine_addend * >::const_iterator iter;	Expr * min, * max, * eps;	const Param_symbol * eps_sym;	const Symbol * eps_found;	min = new Number_expr(0.0, globals);	max = new Number_expr(0.0, globals);	for (iter = aff->get_addends()->begin(); iter != aff->get_addends()->end();		iter++) {			min = new Plus_expr(min, (* iter)->find_min(this));			max = new Plus_expr(max, (* iter)->find_max(this));	}	eps_found = globals->symbol_table->find_symbol(MLD_EPSILON_NAME);	if (!eps_found->is_param_symbol()) {		string msg;		char buf[20];		sprintf(buf, "line %d: ", get_source_line());		msg = buf;		msg += string("MLD_epsilon required but is not a parameter");		globals->problem_handler->process(new Problem(ERROR, msg));	}	eps_sym = (const Param_symbol *) eps_found;	eps = eps_sym->get_value();	return new Min_max_eps(min, max, eps, globals);}void Item::check_mme_tight(const Min_max_eps * user_mme,	const Min_max_eps * auto_mme) const {		Expr * amin, * amax, * umin, * umax;		Real_number * ar, * ur;		string msg;		char buf[100];		amin = auto_mme->get_min();		amax = auto_mme->get_max();		umin = user_mme->get_min();		umax = user_mme->get_max();		if (amin->is_number() && umin->is_number()) {			ar = (Real_number *) (amin->compute_number());			ur = (Real_number *) (umin->compute_number());			if (ar->get_double() > ur->get_double()) {				sprintf(buf, "line %d: ", get_source_line());				msg = buf;				msg += string("Lower bound not tight (is ") +					umin->get_source() +					string(" = ") + ur->to_matlab() +					string(", could be ") +					ar->to_matlab() + string(")");				globals->problem_handler->process(					new Problem(WARNING, msg,					BOUND_NOT_TIGHT));			}			delete ar;			delete ur;		}		if (amax->is_number() && umax->is_number()) {			ar = (Real_number *) (amax->compute_number());			ur = (Real_number *) (umax->compute_number());			if (ar->get_double() < ur->get_double()) {				sprintf(buf, "line %d: ", get_source_line());				msg = buf;				msg += string("Upper bound not tight (is ") +					umax->get_source() +					string(" = ") + ur->to_matlab() +					string(", could be ") +					ar->to_matlab() + string(")");				globals->problem_handler->process(					new Problem(WARNING, msg,					BOUND_NOT_TIGHT));			}			delete ar;			delete ur;		}		delete amin;		delete amax;		delete umin;		delete umax;}/** we distinguish the following cases: * 1) it is neither a constant nor simply a variable: unroll as logicif it is a negated variable and B5D5: set -1 in variable, 1 in const * 2) it is just a variable: do not unroll, set a 1 in the MLD matrix * 4) it is a constant and false: create a row of zeros * 5) it is a constant and true: a) if consts_in_eq_as_B5D5: set a 1 in B5/D5 * b) if consts_in_eq_as_auxVar: do as if in case 1 * c) if consts_in_eq_as_error: report error */void // ptr to const Symbol*	Item::construct_logic_eq(const Expr * logic, const Symbol * * upd_var,	Expr * * upd_var_assign, bool * const_value,	Symbol_table * sym_tab) const {		CNF_clause * cnf;		assert(logic->is_logic()); //fine		if (logic->is_variable_expr()) {			* upd_var = ((Variable_expr *) logic)->get_value();			* upd_var_assign = NULL;			*const_value=true;			return;		}				if (logic->is_not_expr() && globals->cmd_options->consts_in_eq_as_B5D5()) {		  const Expr *child=((Not_expr*)logic)->get_child();		  if (child->is_variable_expr()) {		    *upd_var=((const Variable_expr*)child)->get_value();		    *upd_var_assign = NULL;		    *const_value=false;		    return;		  }		}				cnf = logic->compute_CNF();		if (!cnf->is_constant() ||			(cnf->is_constant() && cnf->get_const_value() &&			globals->cmd_options->consts_in_eq_as_auxvar())) {				* upd_var = sym_tab->create_additional(AUX_KIND, BOOL_TYPE);				* upd_var_assign = logic->clone();				*const_value=true;				return;		}		// it is a constant		* upd_var_assign = NULL;		if (cnf->get_const_value()) {			if (globals->cmd_options->consts_in_eq_as_error()) {				string msg;				char buf[20];				sprintf(buf, "line %d: ", get_source_line());				msg = buf;				msg += string("Logic expression in equality is always true, resulting in a constant term");				globals->problem_handler->process(					new Problem(ERROR, msg));			}			if (globals->cmd_options->consts_in_eq_as_B5D5()) {				* upd_var = NULL;				* const_value = true;			}		} else {			* upd_var = NULL;			* const_value = false;		}}Linear_item * Item::extract_const_from_aff(const Expr * affine_expr,	Expr * * lin_expr) const {		Linear_item * cnst_item = NULL;		Expr * lin_part;		Affine_func * aff;		Affine_addend * cnst_add;		Var_symbol * add_var;		aff = affine_expr->compute_affine();		cnst_add = aff->remove_const();		if (cnst_add) {			add_var = (Var_symbol *)				globals->symbol_table->create_additional(				AUX_KIND, REAL_TYPE);			cnst_item = new Linear_item(add_var, cnst_add->to_expr(),				globals);			delete cnst_add;			lin_part = aff->to_expr();			delete aff;			// was a bug: I modified local pointer			* lin_expr = new				Plus_expr(lin_part,				new Variable_expr(add_var, globals));		} else {		  *lin_expr = affine_expr->clone();		}		return cnst_item;}list < Item * > Item::unroll() {	return list < Item * > ();}void Item::add_required(list < const Var_symbol * > & required,	const Expr * e) {		const Var_symbol * s = NULL;		if (e->is_variable_expr())			s = ((const Variable_expr *) e)->get_value();		//	if (e->is_parameter_expr())		//		s=((const Parameter_expr*)e)->get_value();		if (s) {			if (!is_required(required, s)) required.push_back(s);		}		if (e->is_unary_expr())			add_required(required,				((const Unary_expr *) e)->get_child());		if (e->is_binary_expr()) {			add_required(required,				((const Binary_expr *) e)->get_left());			add_required(required,				((const Binary_expr *) e)->get_right());		}}void Item::add_required(list < const Var_symbol * > & required,	const Min_max_eps * mme) {		const Expr * e;		if (mme) {			e = mme->get_min();			if (e) add_required(required, e);			e = mme->get_max();			if (e) add_required(required, e);			e = mme->get_eps();			if (e) add_required(required, e);		}}bool Item::is_required_simu(const Var_symbol * s) const {	list < const Var_symbol * > required;	required = get_required_simu();	return is_required(required, s);}bool Item::is_required(list < const Var_symbol * > required,	const Var_symbol * s) {		for (list < const Var_symbol * >::const_iterator iter =			required.begin(); iter != required.end(); iter++) {				if ((* iter) == s) return true;		}		return false;}string Item::get_source_line_str() const{  char buf[20];  sprintf(buf, "%d", source_line);  return string(buf);}void Item::set_unrolled_from(Item * i) {   source=i->source;  source_line=i->source_line;  section=i->section;  unrolled_from = i; }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -