void distribute_forall::operator()(expr * f, expr_ref & result) { m_todo.reset(); flush_cache(); m_todo.push_back(f); while (!m_todo.empty()) { expr * e = m_todo.back(); if (visit_children(e)) { m_todo.pop_back(); reduce1(e); } } result = get_cached(f); SASSERT(result!=0); TRACE("distribute_forall", tout << mk_ll_pp(f, m_manager) << "======>\n" << mk_ll_pp(result, m_manager););
Number operator+( Number l, Number r) { int lnum = l.num; int lden = l.denom; int rnum = r.num; int rden = r.denom; // if one is whole number if (lden == 1) { return Number(lnum*rden + rnum, rden); } if (rden == 1) { return Number(rnum*lden + lnum, lden); } // sum of whole numbers int sumWhole = lnum/lden + rnum/rden; // what is left after subtracting whole number lnum = lnum%lden; rnum = rnum%rden; // lMaxMul is the largest integer that you can multiply // by lnum to not go over INT_MAX int lMaxMul = INT_MAX/abs(lnum); int rMaxMul = INT_MAX/abs(rnum); int gcdDenom = gcdFunction(lden,rden); // if numerators will not go over INT_MAX when // multiplied for common denom if (lMaxMul >= rden/gcdDenom && rMaxMul >= lden/gcdDenom) { // if the sum of numerators multiplied by their respective // factors will not go over INT_MAX if ( INT_MAX- lnum*(rden/gcdDenom) >= rnum*(lden/gcdDenom)) { // numerator (without reducing) int OriginalNum = lnum*(rden/gcdDenom) + rnum*(lden/gcdDenom); // reduce with both lden and rden Number reduce1(OriginalNum, lden); Number reduce2(reduce1.numerator(), rden/gcdDenom); return Number(reduce2.numerator() + sumWhole*(reduce1.denominator())*(reduce2.denominator()), (reduce1.denominator())*(reduce2.denominator())); } // if } // if // else, sum of two numbers is over 1 (or under -1) l.num = lnum; r.num = rnum; Number fill = l.fill(); // fill the first number so it reaches 1 or -1 // i.e. if l = 3/5 and r = 4/7, fill = 2/5 // 3/5 + 4/7 = 3/5 + 2/5 - 2/5 + 4/7 // = 1 - 2/5 + 4/7 if (lnum > 0) sumWhole++; else sumWhole--; Number wholeNumber(sumWhole, 1); Number sumFractions = r - fill; return wholeNumber + sumFractions; }