void ModelEnumerator::initProjection(SharedContext& ctx) { if (!project_) { return; } project_->clear(); const SymbolTable& index = ctx.symbolTable(); if (index.type() == SymbolTable::map_indirect) { for (SymbolTable::const_iterator it = index.begin(); it != index.end(); ++it) { if (!it->second.name.empty() && it->second.name[0] != '_') { addProjectVar(ctx, it->second.lit.var(), true); } } for (VarVec::const_iterator it = project_->begin(), end = project_->end(); it != end; ++it) { ctx.unmark(*it); } } else { for (Var v = 1; v < index.size(); ++v) { addProjectVar(ctx, v, false); } } // tag projection nogoods with step literal (if any). addProjectVar(ctx, ctx.stepLiteral().var(), false); if (project_->empty()) { // We project to the empty set. Add true-var so that // we can distinguish this case from unprojected search project_->push_back(0); } }
bool ProgramBuilder::startProgram(SharedContext& ctx) { ctx.report(message(Event::subsystem_load, "Reading")); ctx_ = &ctx; min_ = 0; minCon_ = 0; frozen_ = ctx.frozen(); return ctx_->ok() && doStartProgram(); }
void BasicSatConfig::prepare(SharedContext& ctx) { uint32 warn = 0; for (uint32 i = 0, end = solver_.size(), mod = search_.size(); i != end; ++i) { warn |= solver_[i].prepare(); warn |= search_[i%mod].prepare(solver_[i].search != SolverStrategies::no_learning); } if ((warn & 1) != 0) { ctx.report(warning(Event::subsystem_facade, "Selected heuristic requires lookback strategy!")); } if ((warn & 2) != 0) { ctx.report(warning(Event::subsystem_facade, "Heuristic 'Unit' implies lookahead. Using atom.")); } }
uint32 SharedDependencyGraph::addBody(SharedContext& ctx, PrgBodyNode* b, const AtomList& prgAtoms) { if (b->visited()) { // first time we see this body - b->setVisited(false); // mark as visited and create node b->setUfsNode( (NodeId)bodies_.size(), false ); bodies_.push_back(BodyNode(b)); BodyNode* bn = &bodies_.back(); // Init node VarVec preds, succs; if (bn->scc != PrgNode::noScc) { const bool weights = b->type() == PrgBodyNode::SUM_BODY; for (uint32 p = 0; p != b->posSize(); ++p) { PrgAtomNode* pred = prgAtoms[b->pos(p)]; if (relevantPrgAtom(*ctx.master(), pred) && pred->scc() == bn->scc) { preds.push_back( pred->ufsNode() ); if (weights) { preds.push_back( b->weight(p, true) ); } } } preds.push_back(idMax); if (bn->extended()) { for (uint32 n = 0; n != b->size(); ++n) { PrgAtomNode* pred = prgAtoms[b->goal(n).var()]; Literal lit = b->goal(n).sign() ? ~pred->literal() : pred->literal(); if ( (b->goal(n).sign() || pred->scc() != bn->scc) && !ctx.master()->isFalse(lit) ) { preds.push_back(lit.asUint()); if (weights) { preds.push_back(b->weight(n)); } } } preds.push_back(idMax); } } for (HeadVec::const_iterator it = b->heads_begin(), end = b->heads_end(); it != end; ++it) { PrgAtomNode* a = prgAtoms[it->node()]; if (relevantPrgAtom(*ctx.master(), a)) { NodeId id = a->ufsNode(); VarVec::iterator insPos = bn->scc == a->scc() ? succs.begin() : succs.end(); succs.insert(insPos, id); } } bn->adj_ = new NodeId[succs.size() + bn->extended() + preds.size()]; if (bn->extended()) { *bn->adj_= b->bound(); } bn->sep_ = std::copy(succs.begin(), succs.end(), bn->adj_ + bn->extended()); std::copy(preds.begin(), preds.end(), bn->sep_); ctx.setFrozen(b->var(), true); } return b->ufsNode(); }
void testMiniProject() { SharedContext ctx; Solver& solver = *ctx.master(); builder.startProgram(ctx, ProgramBuilder::EqOptions().noEq().noScc()) .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "_x") .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule() .startRule().addHead(3).addToBody(1, false).endRule() .startRule().addHead(3).addToBody(2, false).endRule() .startRule(OPTIMIZERULE).addToBody(3, true).endRule() ; CPPUNIT_ASSERT_EQUAL(true, builder.endProgram()); std::auto_ptr<BacktrackEnumerator> e(new BacktrackEnumerator(0)); e->setEnableProjection(true); e->enumerate(0); MinimizeBuilder b; builder.addMinimize(b); ctx.addEnumerator(e.release()); ctx.enumerator()->setMinimize(b.build(ctx)); ctx.endInit(); SymbolTable& index = ctx.symTab(); solver.assume(index[1].lit); solver.propagate(); solver.assume(index[2].lit); solver.propagate(); solver.assume(index[3].lit); solver.propagate(); CPPUNIT_ASSERT(solver.numVars() == solver.numAssignedVars()); CPPUNIT_ASSERT_EQUAL(Enumerator::enumerate_continue, ctx.enumerator()->backtrackFromModel(solver)); CPPUNIT_ASSERT(false == solver.propagate()); solver.backtrack(); CPPUNIT_ASSERT(false == solver.propagate() && !solver.resolveConflict()); ctx.detach(solver); }
bool frontend::AnalyzeFunctions(Parser *parser, StackFrame *callerFrame) { TreeContext *tc = parser->tc; SharedContext *sc = tc->sc; if (!tc->functionList) return true; if (!MarkExtensibleScopeDescendants(sc->context, tc->functionList, false)) return false; bool isDirectEval = !!callerFrame; bool isHeavyweight = false; SetFunctionKinds(tc->functionList, &isHeavyweight, sc->inFunction(), isDirectEval); if (isHeavyweight) sc->setFunIsHeavyweight(); return true; }
//calcul du type de menage (suite a la modification d'un menage. exemple : décès, mariage,etc.) void Household::computeHhType(SharedContext<Individual> & agentsInd) { int n_mate = 0; int n_children = 0; int n_adults = 0; char head_gender; this->getIndividuals(agentsInd)[0]->setHhRelationship('H'); // TODO faire attention aux orphelins (et autres adultes)! agentsInd.getAgent(this->getListInd()[0])->setHhRelationship('H'); for (unsigned int i = 1; i < this->getIndividuals(agentsInd).size(); i++) { switch (this->getIndividuals(agentsInd)[i]->getHhRelationship()) { case 'M': n_mate++; break; case 'C': n_children++; break; case 'A': n_adults++; break; default: break; } } head_gender = this->getIndividuals(agentsInd)[0]->getGender(); if (n_mate == 0) { if (n_children == 0) { if (head_gender == 'M') { this->_type = "IH"; } else { this->_type = "IF"; } } else { if (head_gender == 'M') { this->_type = "M"; } else { this->_type = "W"; } } } else { if (n_children == 0) { this->_type = "C"; } else { this->_type = "F"; } } this->_n_children = n_children; this->_n_adults = n_adults; }
bool SolveAlgorithm::solve(SharedContext& ctx, const SolveParams& p, const LitVec& assume) { assumptions_ = assume; if (!isSentinel(ctx.tagLiteral())) { assumptions_.push_back(ctx.tagLiteral()); } bool more = limits_.conflicts == 0 || doSolve(*ctx.master(), p); ctx.enumerator()->reportResult(!more); if (!isSentinel(ctx.tagLiteral())) { assumptions_.pop_back(); } ctx.detach(*ctx.master()); return more; }
//retourne les individus du menage -> doit se faire sous forme de liste //d'id d'agents! -> erreur ici!!!!!!!!! vector<Individual *> Household::getIndividuals(SharedContext<Individual> & agentsInd) { vector<Individual *> individuals; for (unsigned int i = 0; i < this->_list_ind.size(); i++) { individuals.push_back(agentsInd.getAgent(_list_ind[i])); } return individuals; }
void ModelEnumerator::addProjectVar(SharedContext& ctx, Var v, bool tag) { if (ctx.master()->value(v) == value_free && (!tag || !ctx.marked(posLit(v)))) { project_->push_back(v); ctx.setFrozen(v, true); ctx.setProject(v, true); if (tag) { ctx.mark(posLit(v)); ctx.mark(negLit(v)); } } }
void testProjectBug() { SharedContext ctx; Solver& solver = *ctx.master(); builder.startProgram(ctx, ProgramBuilder::EqOptions().noEq().noScc()) .setAtomName(1, "x").setAtomName(2, "y").setAtomName(3, "z").setAtomName(4, "_p").setAtomName(5, "_q").setAtomName(6, "_r") .startRule(CHOICERULE).addHead(1).addHead(2).addHead(4).endRule() // {x,y,_p} .startRule().addHead(5).addToBody(1, true).addToBody(4, true).endRule() // _q :- x,_p. .startRule().addHead(6).addToBody(2, true).addToBody(4, true).endRule() // _r :- y,_p. .startRule().addHead(3).addToBody(5, true).addToBody(6, true).endRule() // z :- _q,_r. ; CPPUNIT_ASSERT_EQUAL(true, builder.endProgram()); std::auto_ptr<BacktrackEnumerator> e(new BacktrackEnumerator(7,0)); e->setEnableProjection(true); e->enumerate(0); ctx.addEnumerator(e.release()); ctx.endInit(); SymbolTable& index = ctx.symTab(); solver.assume(index[1].lit); solver.propagate(); solver.assume(index[2].lit); solver.propagate(); solver.assume(index[4].lit); solver.propagate(); CPPUNIT_ASSERT(solver.numVars() == solver.numAssignedVars()); CPPUNIT_ASSERT_EQUAL(Enumerator::enumerate_continue, ctx.enumerator()->backtrackFromModel(solver)); solver.undoUntil(0); uint32 numT = 0; if (solver.value(index[1].lit.var()) == value_free) { solver.assume(index[1].lit) && solver.propagate(); ++numT; } else if (solver.isTrue(index[1].lit)) { ++numT; } if (solver.value(index[2].lit.var()) == value_free) { solver.assume(index[2].lit) && solver.propagate(); ++numT; } else if (solver.isTrue(index[2].lit)) { ++numT; } if (solver.value(index[4].lit.var()) == value_free) { solver.assume(index[4].lit) && solver.propagate(); } if (solver.isTrue(index[3].lit)) { ++numT; } CPPUNIT_ASSERT(numT < 3); ctx.detach(solver); }
uint32 ReduceParams::getBase(const SharedContext& ctx) const { uint32 st = strategy.estimate != ReduceStrategy::est_dynamic || ctx.isExtended() ? strategy.estimate : (uint32)ReduceStrategy::est_num_constraints; switch(st) { default: case ReduceStrategy::est_dynamic : { uint32 m = std::min(ctx.stats().vars.num, ctx.stats().numConstraints()); uint32 M = std::max(ctx.stats().vars.num, ctx.stats().numConstraints()); return M > (m * 10) ? M : m; } case ReduceStrategy::est_con_complexity : return ctx.stats().complexity; case ReduceStrategy::est_num_constraints: return ctx.stats().numConstraints(); case ReduceStrategy::est_num_vars : return ctx.stats().vars.num; } }
void testTerminateRemovesWatches() { SharedContext ctx; Solver& solver = *ctx.master(); builder.startProgram(ctx, ProgramBuilder::EqOptions().noEq().noScc()) .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d") .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).addHead(4).endRule() ; CPPUNIT_ASSERT_EQUAL(true, builder.endProgram()); ctx.addEnumerator(new RecordEnumerator(0)); ctx.enumerator()->enumerate(0); CPPUNIT_ASSERT_EQUAL(true, ctx.endInit()); SymbolTable& index = ctx.symTab(); solver.assume(index[1].lit) && solver.propagate(); solver.assume(index[2].lit) && solver.propagate(); solver.assume(index[3].lit) && solver.propagate(); solver.assume(index[4].lit) && solver.propagate(); CPPUNIT_ASSERT_EQUAL(uint32(0), solver.numFreeVars()); ctx.enumerator()->backtrackFromModel(solver); uint32 numW = solver.numWatches(index[1].lit) + solver.numWatches(index[2].lit) + solver.numWatches(index[3].lit) + solver.numWatches(index[4].lit); CPPUNIT_ASSERT(numW > 0); ctx.detach(solver); numW = solver.numWatches(index[1].lit) + solver.numWatches(index[2].lit) + solver.numWatches(index[3].lit) + solver.numWatches(index[4].lit); CPPUNIT_ASSERT(numW == 0); }
void ModelEnumerator::initProjection(SharedContext& ctx) { if (!projectionEnabled()) { return; } const OutputTable& out = ctx.output; char const filter = static_cast<char>(options_ >> 24); // Make sure that nogoods are tagged with step literal. addProject(ctx, ctx.stepLiteral().var()); if (out.projectMode() == OutputTable::project_output) { // Mark all relevant output variables. for (OutputTable::pred_iterator it = out.pred_begin(), end = out.pred_end(); it != end; ++it) { if (*it->name != filter) { addProject(ctx, it->cond.var()); } } for (OutputTable::range_iterator it = out.vars_begin(), end = out.vars_end(); it != end; ++it) { for (Var v = it->lo; v != it->hi; ++v) { addProject(ctx, v); } } } else { // Mark explicitly requested variables only. for (OutputTable::lit_iterator it = out.proj_begin(), end = out.proj_end(); it != end; ++it) { addProject(ctx, it->var()); } } domRec_.clear(); }
// Creates a positive-body-atom-dependency graph (PBADG) // The PBADG contains a node for each atom A of a non-trivial SCC and // a node for each body B, s.th. there is a non-trivially connected atom A with // B in body(A). // Pre : a->ignore = 0 for all new and relevant atoms a // Pre : b->visited = 1 for all new and relevant bodies b // Post: a->ignore = 1 for all atoms that were added to the PBADG // Post: b->visited = 0 for all bodies that were added to the PBADG void SharedDependencyGraph::addSccs(SharedContext& ctx, const AtomList& sccAtoms, const AtomList& prgAtoms, const BodyList& prgBodies) { // Pass 1: Create graph atom nodes and estimate number of bodies NodeId atomId = static_cast<NodeId>(atoms_.size()); atoms_.reserve(atoms_.size() + sccAtoms.size()); AtomList::size_type numBodies = 0; for (AtomList::size_type i = 0, end = sccAtoms.size(); i != end; ++i) { PrgAtomNode* a = sccAtoms[i]; if (relevantPrgAtom(*ctx.master(), a)) { // initialize graph atom node atoms_.push_back(AtomNode()); AtomNode& ua = atoms_.back(); ua.lit = a->literal(); ua.scc = a->scc(); numBodies += a->preds.size(); // store link between program node and graph node for later lookup a->setUfsNode(atomId, true); // atom is defined by more than just a bunch of clauses ctx.setFrozen(a->var(), true); ++atomId; } } // Pass 2: Init atom nodes and create body nodes VarVec preds, succs, succsExt; NodeId* temp; bodies_.reserve(bodies_.size() + numBodies/2); for (AtomList::size_type i = 0, end = sccAtoms.size(); i != end; ++i) { PrgAtomNode* a = sccAtoms[i]; if (relevantPrgAtom(*ctx.master(), a)) { AtomNode& ua = atoms_[a->ufsNode()]; for (HeadVec::const_iterator it = a->preds.begin(), endIt = a->preds.end(); it != endIt; ++it) { PrgBodyNode* prgBody = prgBodies[it->node()]; if (relevantPrgBody(*ctx.master(), prgBody)) { NodeId bId = addBody(ctx, prgBody, prgAtoms); VarVec::iterator insPos = prgBody->scc() == a->scc() ? preds.end() : preds.begin(); preds.insert(insPos, bId); if (it->choice()) { ua.type |= Node::type_in_choice; } } } for (VarVec::const_iterator it = a->posDep.begin(), endIt = a->posDep.end(); it != endIt; ++it) { PrgBodyNode* prgBody = prgBodies[*it]; if (prgBody->scc() == a->scc() && relevantPrgBody(*ctx.master(), prgBody)) { NodeId bodyId = addBody(ctx, prgBody, prgAtoms); if (!bodies_[bodyId].extended()) { succs.push_back(bodyId); } else { succsExt.push_back(bodyId); succsExt.push_back(bodies_[bodyId].get_pred_idx(a->ufsNode())); assert(bodies_[bodyId].get_pred(succsExt.back()) == a->ufsNode()); ua.type |= Node::type_ext; } } } succs.push_back(idMax); if (!succsExt.empty()) { succsExt.push_back(idMax); } ua.adj_ = new NodeId[preds.size()+succs.size()+succsExt.size()]; ua.sep_ = std::copy(preds.begin(), preds.end(), ua.adj_); temp = std::copy(succs.begin(), succs.end(), ua.sep_); std::copy(succsExt.begin(), succsExt.end(), temp); preds.clear(); succs.clear(); succsExt.clear(); } } }
void testParallelRecord() { SharedContext ctx; Solver& solver = *ctx.master(); builder.startProgram(ctx, ProgramBuilder::EqOptions().noEq().noScc()) .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c").setAtomName(4, "d") .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).addHead(4).endRule() ; CPPUNIT_ASSERT_EQUAL(true, builder.endProgram()); ctx.setSolvers(2); ctx.addEnumerator(new RecordEnumerator(0)); ctx.enumerator()->enumerate(0); ctx.endInit(); Solver solver2; ctx.attach(solver2); SymbolTable& index = ctx.symTab(); solver.assume(index[1].lit) && solver.propagate(); solver.assume(index[2].lit) && solver.propagate(); solver.assume(index[3].lit) && solver.propagate(); solver.assume(index[4].lit) && solver.propagate(); CPPUNIT_ASSERT_EQUAL(uint32(0), solver.numFreeVars()); ctx.enumerator()->backtrackFromModel(solver); solver.undoUntil(0); CPPUNIT_ASSERT_EQUAL(true, ctx.enumerator()->update(solver2, false)); solver2.assume(index[1].lit) && solver2.propagate(); solver2.assume(index[2].lit) && solver2.propagate(); solver2.assume(index[3].lit) && solver2.propagate(); CPPUNIT_ASSERT(solver2.isFalse(index[4].lit) && solver2.propagate()); CPPUNIT_ASSERT_EQUAL(uint32(0), solver2.numFreeVars()); ctx.enumerator()->backtrackFromModel(solver2); solver.undoUntil(0); CPPUNIT_ASSERT_EQUAL(true, ctx.enumerator()->update(solver, false)); solver.assume(index[1].lit) && solver.propagate(); solver.assume(index[2].lit) && solver.propagate(); CPPUNIT_ASSERT(solver.isFalse(index[3].lit)); ctx.detach(solver2); ctx.detach(solver); solver2.undoUntil(0); ctx.attach(solver2); solver2.assume(index[1].lit) && solver2.propagate(); solver2.assume(index[2].lit) && solver2.propagate(); solver2.assume(index[3].lit) && solver2.propagate(); CPPUNIT_ASSERT(solver2.value(index[4].lit.var()) == value_free); }
void ModelEnumerator::addProject(SharedContext& ctx, Var v) { ctx.setProject(v, true); ctx.setFrozen(v, true); }
void testParallelUpdate() { SharedContext ctx; Solver& solver = *ctx.master(); builder.startProgram(ctx, ProgramBuilder::EqOptions().noEq().noScc()) .setAtomName(1, "a").setAtomName(2, "b").setAtomName(3, "c") .startRule(CHOICERULE).addHead(1).addHead(2).addHead(3).endRule() .startRule(OPTIMIZERULE).addToBody(2, true).endRule() ; CPPUNIT_ASSERT_EQUAL(true, builder.endProgram()); MinimizeBuilder minBuilder; builder.addMinimize(minBuilder); ctx.setSolvers(2); ctx.addEnumerator(new RecordEnumerator(0)); ctx.enumerator()->enumerate(0); ctx.enumerator()->setMinimize(minBuilder.build(ctx)); ctx.endInit(); Solver solver2; ctx.attach(solver2); SymbolTable& index = ctx.symTab(); // a solver.assume(index[1].lit); solver.pushRootLevel(1); solver.propagate(); // ~a solver2.assume(~index[1].lit); solver2.pushRootLevel(1); solver2.propagate(); // M1: ~b, c solver.assume(~index[2].lit); solver.propagate(); solver.assume(index[3].lit); solver.propagate(); CPPUNIT_ASSERT_EQUAL(uint32(0), solver.numFreeVars()); ctx.enumerator()->backtrackFromModel(solver); solver.undoUntil(0); // M2: ~b, ~c solver2.assume(~index[2].lit); solver2.propagate(); solver2.assume(~index[3].lit); solver2.propagate(); // M2 is NOT VALID! CPPUNIT_ASSERT_EQUAL(false, ctx.enumerator()->update(solver2, true)); }
uint32 ReduceParams::getBase(const SharedContext& ctx) const { return strategy.estimate ? ctx.stats().complexity : ctx.stats().size; }