void SimplexDecisionProcedure::addRowSgns(sgn_table& sgns, ArithVar basic, int norm){ for(Tableau::RowIterator i = d_tableau.basicRowIterator(basic); !i.atEnd(); ++i){ const Tableau::Entry& entry = *i; ArithVar v = entry.getColVar(); int sgn = (entry.getCoefficient().sgn()); addSgn(sgns, v, norm * sgn, basic); } }
void FCSimplexDecisionProcedure::loadFocusSigns(){ Assert(d_focusCoefficients.empty()); Assert(d_focusErrorVar != ARITHVAR_SENTINEL); for(Tableau::RowIterator ri = d_tableau.basicRowIterator(d_focusErrorVar); !ri.atEnd(); ++ri){ const Tableau::Entry& e = *ri; ArithVar curr = e.getColVar(); d_focusCoefficients.set(curr, &e.getCoefficient()); } }
UpdateInfo FCSimplexDecisionProcedure::selectPrimalUpdate(ArithVar basic, LinearEqualityModule::UpdatePreferenceFunction upf, LinearEqualityModule::VarPreferenceFunction bpf) { UpdateInfo selected; static int instance = 0 ; ++instance; Debug("arith::selectPrimalUpdate") << "selectPrimalUpdate " << instance << endl << basic << " " << d_tableau.basicRowLength(basic) << " " << d_linEq.debugBasicAtBoundCount(basic) << endl; static const int s_maxCandidatesAfterImprove = 3; bool isFocus = basic == d_focusErrorVar; Assert(isFocus || d_errorSet.inError(basic)); int basicDir = isFocus? 1 : d_errorSet.getSgn(basic); bool dualLike = !isFocus && d_focusSize > 1; if(!isFocus){ loadFocusSigns(); } decreasePenalties(); typedef std::vector<Cand> CandVector; CandVector candidates; for(Tableau::RowIterator ri = d_tableau.basicRowIterator(basic); !ri.atEnd(); ++ri){ const Tableau::Entry& e = *ri; ArithVar curr = e.getColVar(); if(curr == basic){ continue; } int sgn = e.getCoefficient().sgn(); int curr_movement = basicDir * sgn; bool candidate = (curr_movement > 0 && d_variables.cmpAssignmentUpperBound(curr) < 0) || (curr_movement < 0 && d_variables.cmpAssignmentLowerBound(curr) > 0); Debug("arith::selectPrimalUpdate") << "storing " << basic << " " << curr << " " << candidate << " " << e.getCoefficient() << " " << curr_movement << " " << focusCoefficient(curr) << endl; if(!candidate) { continue; } if(!isFocus){ const Rational& focusC = focusCoefficient(curr); Assert(dualLike || !focusC.isZero()); if(dualLike && curr_movement != focusC.sgn()){ Debug("arith::selectPrimalUpdate") << "sgn disagreement " << curr << endl; d_sgnDisagreements.push_back(curr); continue; }else{ candidates.push_back(Cand(curr, penalty(curr), curr_movement, &focusC)); } }else{ candidates.push_back(Cand(curr, penalty(curr), curr_movement, &e.getCoefficient())); } } CompPenaltyColLength colCmp(&d_linEq); CandVector::iterator i = candidates.begin(); CandVector::iterator end = candidates.end(); std::make_heap(i, end, colCmp); bool checkEverything = d_pivots == 0; int candidatesAfterFocusImprove = 0; while(i != end && (checkEverything || candidatesAfterFocusImprove <= s_maxCandidatesAfterImprove)){ std::pop_heap(i, end, colCmp); --end; Cand& cand = (*end); ArithVar curr = cand.d_nb; const Rational& coeff = *cand.d_coeff; LinearEqualityModule::UpdatePreferenceFunction leavingPrefFunc = selectLeavingFunction(curr); UpdateInfo currProposal = d_linEq.speculativeUpdate(curr, coeff, leavingPrefFunc); Debug("arith::selectPrimalUpdate") << "selected " << selected << endl << "currProp " << currProposal << endl << "coeff " << coeff << endl; Assert(!currProposal.uninitialized()); if(candidatesAfterFocusImprove > 0){ candidatesAfterFocusImprove++; } if(selected.uninitialized() || (d_linEq.*upf)(selected, currProposal)){ selected = currProposal; WitnessImprovement w = selected.getWitness(false); Debug("arith::selectPrimalUpdate") << "selected " << w << endl; setPenalty(curr, w); if(improvement(w)){ bool exitEarly; switch(w){ case ConflictFound: exitEarly = true; break; case ErrorDropped: if(checkEverything){ exitEarly = d_errorSize + selected.errorsChange() == 0; Debug("arith::selectPrimalUpdate") << "ee " << d_errorSize << " " << selected.errorsChange() << " " << d_errorSize + selected.errorsChange() << endl; }else{ exitEarly = true; } break; case FocusImproved: candidatesAfterFocusImprove = 1; exitEarly = false; break; default: exitEarly = false; break; } if(exitEarly){ break; } } }else{ Debug("arith::selectPrimalUpdate") << "dropped "<< endl; } } if(!isFocus){ unloadFocusSigns(); } return selected; }