📄 named_sc_op.cc
字号:
del_col(c);#ifdef DO_CHECK check();#endif}void align_symcoeff(named_symcoeff_ineq & use, named_symcoeff_ineq & update, boolean * too_messy = NULL) { for(int i=1; i<use.planes().n(); i++) if(update.cols().find(use.planes()[i]) > 0) update.move_col2plane(use.planes()[i], too_messy);} /*************************************************************************** * Align two different sets of inequalities such that n-th column of A * * and B refers to the same variable. * ***************************************************************************/void align(named_symcoeff_ineq & A, named_symcoeff_ineq & B){ align_symcoeff(A, B); align_symcoeff(B, A); name_table & ca = A.cols(); name_table & cb = B.cols(); integer_row ica(ca.n()); integer_row icb(cb.n()); name_table * newcol = name_table::align_tables(ca, cb, ica, icb); name_table & pa = A.planes(); name_table & pb = B.planes(); integer_row ipa(pa.n()); integer_row ipb(pb.n()); name_table * newpln = name_table::align_tables(pa, pb, ipa, ipb); int ap = A.p(); int am = A.m(); int an = A.n(); lin_ineq * AL = A.L; A.L = NULL; A.cols().init(newcol); A.planes().init(newpln); A.initL(am); int p; for(p=0; p<ap; p++) for(int m1=0; m1<am; m1++) for(int n1=0; n1<an; n1++) A[ipa[p]][m1][ica[n1]] = AL[p][m1][n1]; delete[] AL; int bp = B.p(); int bm = B.m(); int bn = B.n(); lin_ineq * BL = B.L; B.L = NULL; B.cols().init(newcol); B.planes().init(newpln); B.initL(bm); for(p=0; p<bp; p++) for(int m2=0; m2<bm; m2++) for(int n2=0; n2<bn; n2++) B[ipb[p]][m2][icb[n2]] = BL[p][m2][n2]; delete[] BL; delete newcol; delete newpln;}void named_symcoeff_ineq::nt_align(name_table * col, name_table * pln){ if(col) if(!name_table::is_aligned(*col, cols())) { name_table * nt = name_table::mk_align(cols(), *col); assert(nt); for(int ip=0; ip<p(); ip++) { named_lin_ineq tmp(cols(), (*this)[ip]); tmp.align(*nt); (*this)[ip] = tmp.ineqs(); } cols().init(*nt); } if(pln) if(!name_table::is_aligned(*pln, planes())) { assert_msg(0, ("To be implemented")); }#ifdef DO_CHECK check();#endif}named_symcoeff_ineq named_symcoeff_ineq::inverse_all(){ named_symcoeff_ineq * ret = new named_symcoeff_ineq(this); for(int ip=0; ip<p(); ip++) (*ret)[ip] *= -1; for(int im=0; im<m(); im++) (*ret)[0][im][0] += -1; return *ret;}/*************************************************************************** * Concatinate two sets of inequalities. * ***************************************************************************/named_symcoeff_ineq named_symcoeff_ineq::operator&(const named_symcoeff_ineq & c){ named_symcoeff_ineq A(this); named_symcoeff_ineq B(c); align(A, B); named_symcoeff_ineq * ret = new named_symcoeff_ineq; ret->cols().init(A.cols()); ret->planes().init(A.planes()); ret->initL(A.m()+B.m()); for(int p=0; p<A.p(); p++) { nim_op O; (*ret)[p] = Compose(2, 1, O.NIM(A[p]), O.NIM(B[p])); } return *ret;}/*************************************************************************** * Add the set of inequalities to self. * ***************************************************************************/named_symcoeff_ineq & named_symcoeff_ineq::operator&=(const named_symcoeff_ineq & c){ named_symcoeff_ineq A(this); named_symcoeff_ineq B(c); align(A, B); cols().init(A.cols()); planes().init(A.planes()); initL(A.m()+B.m()); for(int p=0; p<A.p(); p++) { nim_op O; (*this)[p] = Compose(2, 1, O.NIM(A[p]), O.NIM(B[p])); } return *this;}/*************************************************************************** * Concatinate two sets of inequalities. Either or both sets can be empty. * * If del flag is set, after calling this treat that ineq as gone. * ***************************************************************************/named_symcoeff_ineq * named_symcoeff_ineq::and_(named_symcoeff_ineq * c1, named_symcoeff_ineq * c2, boolean del1, boolean del2){ if((c1 == NULL)&&(c2 == NULL)) return NULL; else if(c1 == NULL) return (del2)?c2:(new named_symcoeff_ineq(c2)); else if(c2 == NULL) return (del1)?c1:(new named_symcoeff_ineq(c1)); else if(del1) { *c1 &= *c2; if(del2) delete c2; return c1; } else if(del2) { *c2 &= *c1; return c2; } else { named_symcoeff_ineq * r = new named_symcoeff_ineq(*c1 & *c2); return r; }}void named_symcoeff_ineq::operator||(named_symcoeff_ineq & c){ align(*this, c);}boolean named_symcoeff_ineq::is_same(named_symcoeff_ineq & c){ if(p() != c.p()) return FALSE; if(m() != c.m()) return FALSE; if(n() != c.n()) return FALSE; if(!name_table::is_aligned(planes(), c.planes())) return FALSE; if(!name_table::is_aligned(cols(), c.cols())) return FALSE; for(int i=0; i<p(); i++) for(int j=0; j<m(); j++) for(int k=0; k<n(); k++) if(c[i][j][k] != (*this)[i][j][k]) return FALSE; return TRUE;}boolean named_symcoeff_ineq::operator==(named_symcoeff_ineq &){ assert(0); return TRUE;}boolean named_symcoeff_ineq::operator>>(named_symcoeff_ineq &){ assert(0); return FALSE;}boolean named_symcoeff_ineq::operator~(){ named_sc_fm fm(this, FALSE); boolean valid = fm.fm_step(0, n()); return (!valid);}/*************************************************************************** *************************************************************************** **** Filter functions **** *************************************************************************** ***************************************************************************/named_symcoeff_ineq named_symcoeff_ineq::filter_thru(constraint * column_kernal, constraint * plane_kernal, int sign) const{ named_symcoeff_ineq ret = filter(column_kernal, plane_kernal, sign, 0); return ret;}named_symcoeff_ineq named_symcoeff_ineq::filter_away(constraint * column_kernal, constraint * plane_kernal, int sign) const{ named_symcoeff_ineq ret = filter(column_kernal, plane_kernal, sign, 1); return ret;}named_symcoeff_ineq named_symcoeff_ineq::filter(constraint * column_kernal, constraint * plane_kernal, int sign, int tora) const{ if(m()==0) { return *this; } int xtora = (tora)?0:1; assert(column_kernal || plane_kernal); int * filt = new int[m()]; for(int i=0; i<m(); i++) filt[i] = tora; if(column_kernal) { for(int ip=0; ip<p(); ip++) { const lin_ineq & leq = r(ip); for(int im=0; im<m(); im++) for(int in=0; in<n(); in++) if((*column_kernal)[in]) { int v = leq.r(im).c(in); if((sign*v > 0)||((sign==0)&&v)) filt[im] = xtora; } } } if(plane_kernal) { for(int ip=0; ip<p(); ip++) if((*plane_kernal)[ip]) { const lin_ineq & leq = r(ip); for(int im=0; im<m(); im++) for(int in=0; in<n(); in++) { int v = leq.r(im).c(in); if((sign*v > 0)||((sign==0)&&v)) filt[im] = xtora; } } } named_symcoeff_ineq * ret = filter(filt); delete filt; named_symcoeff_ineq retcopy(ret); delete ret; return retcopy;}named_lin_ineq * named_symcoeff_ineq::nli() const{ if(p() != 1) return NULL; lin_ineq * lq = get_p(0); named_lin_ineq * ret = new named_lin_ineq(const_cols(), *lq); delete lq; return ret;}/*************************************************************************** * Perform the filtering of inequalities according to filt. If filt[i] * * then, i-th inequality is in the result. * ***************************************************************************/named_symcoeff_ineq * named_symcoeff_ineq::filter(int * filt) const{ int cnt = 0; int i; for(i=0; i<m(); i++) if(filt[i]) cnt++; named_symcoeff_ineq * ret = new named_symcoeff_ineq(); ret->init(p(), cnt, n()); ret->planes().init(const_planes()); ret->cols().init(const_cols()); int xm=0; for(i=0; i<m(); i++) if(filt[i]) { for(int xp = 0; xp < p(); xp++) for(int xn = 0; xn < n(); xn++) (*ret)[xp][xm][xn] = r(xp).r(i).c(xn); xm++; } assert(xm == cnt); return ret;}void named_symcoeff_ineq::cleanup(){ if((m() == 0)||(n() == 0)||(p() == 0)) return; integer_row unused_pln(p()); integer_row unused_col(n()); integer_row unused_ineq(m()); unused_pln = 1; unused_col = 1; unused_ineq = 1; unused_col[0] = 0; unused_pln[0] = 0; for(int ip=0; ip<p(); ip++) for(int im=0; im<m(); im++) for(int in=0; in<n(); in++) if((*this)[ip][im][in]) { unused_pln[ip] = 0; unused_col[in] = 0; unused_ineq[im] = 0; } del_pln(unused_pln); del_ineq(unused_ineq); del_col(unused_col);#ifdef DO_CHECK check();#endif}/*************************************************************************** *************************************************************************** *** *** Creating a named_symcoeff_ieq out of an expression tree *** *************************************************************************** ***************************************************************************/static int is_const(operand op, int *val){ if(!op.is_instr()) return 0; instruction * in = op.instr(); if(!in) return 0; if(in->opcode() == io_cvt) return is_const(((in_rrr *)in)->src1_op(), val); if(in->opcode() != io_ldc) return 0; immed ic = ((in_ldc *) in)->value(); if(ic.kind() == im_int) *val = ic.integer(); return (ic.kind() == im_int);}static tree_for * is_index(var_sym * v, tree_node *tn){ assert(v); for(tree_node *n = tn; n; n = n->parent()->parent()) { if(n->kind() == TREE_FOR && ((tree_for *)n)->index() == v) return (tree_for *) n; if(n->parent()==NULL) break; } return NULL;}boolean is_index_var_in(operand op, tree_node * par){ if(op.is_instr()) for(unsigned i=0; i<op.instr()->num_srcs(); i++) { if(is_index_var_in(op.instr()->src_op(i), par)) return TRUE; } else if(op.is_symbol()) { if(is_index(op.symbol(), par)) return TRUE; } return FALSE;}static void add_sym(named_symcoeff_ineq & res, int & too_messy, var_sym * ind, int int_coeff, named_lin_ineq * sym_coeff){ int xc = -1; int xp = -1; if(ind == NULL) // adding a constant xc = 0; else if((xc = res.cols().find(ind)) == -1) { // not a indvar if((xp = res.planes().find(ind)) == -1) { // not a plane // add as a ind var name_table_entry * nte = new name_table_entry(immed(ind)); res.add_col(*nte, 1); xc = 1; } } if(sym_coeff == NULL) { // no symcoeffs if(xc >= 0) res[0][0][xc] += int_coeff; else res[xp][0][0] += int_coeff; } else { if(xc == -1) { // symcoeffs and ind is symcoeff too!! too_messy++; return; } named_symcoeff_ineq sc; // make symcoeff from input sc.init(sym_coeff->n(), 1, 1); sc.planes().init(sym_coeff->names()); for(int i=0; i < sym_coeff->n(); i++) sc[i][0][0] = sym_coeff->ineqs()[0][i]; align_symcoeff(res, sc, &too_messy); if(too_messy) return; res || sc; if(xc != 0) xc = res.cols().find(ind); if(xc == -1) { too_messy++; return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -