ASTNode STP::callSizeReducing(ASTNode inputToSat, BVSolver* bvSolver, PropagateEqualities* pe, const int initial_difficulty_score, int& actualBBSize) { while (true) { ASTNode last = inputToSat; inputToSat = sizeReducing(last, bvSolver, pe); if (last == inputToSat) break; } actualBBSize = -1; // Expensive, so only want to do it once. if (bm->UserFlags.isSet("bitblast-simplification", "1") && initial_difficulty_score < 250000) { BBNodeManagerAIG bitblast_nodemgr; BitBlaster<BBNodeAIG, BBNodeManagerAIG> bb( &bitblast_nodemgr, simp, bm->defaultNodeFactory, &(bm->UserFlags)); ASTNodeMap fromTo; ASTNodeMap equivs; bb.getConsts(inputToSat, fromTo, equivs); if (equivs.size() > 0) { /* These nodes have equivalent AIG representations, so even though they * have different * word level expressions they are identical semantically. So we pick one * of the ASTnodes * and replace the others with it. * TODO: I replace with the lower id node, sometimes though we replace * with much more * difficult looking ASTNodes. */ ASTNodeMap cache; inputToSat = SubstitutionMap::replace(inputToSat, equivs, cache, bm->defaultNodeFactory, false, true); bm->ASTNodeStats(bb_message.c_str(), inputToSat); } if (fromTo.size() > 0) { ASTNodeMap cache; inputToSat = SubstitutionMap::replace( inputToSat, fromTo, cache, bm->defaultNodeFactory); bm->ASTNodeStats(bb_message.c_str(), inputToSat); } actualBBSize = bitblast_nodemgr.totalNumberOfNodes(); } return inputToSat; }
ASTNode STP::callSizeReducing(ASTNode simplified_solved_InputToSAT, BVSolver* bvSolver, const int initial_difficulty_score) { while (true) { ASTNode last = simplified_solved_InputToSAT; simplified_solved_InputToSAT = sizeReducing(last, bvSolver); if (last == simplified_solved_InputToSAT) break; } // Expensive, so only want to do it once. if (bm->UserFlags.isSet("bitblast-simplification", "1") && initial_difficulty_score < 250000) { BBNodeManagerAIG bbnm; SimplifyingNodeFactory nf(*(bm->hashingNodeFactory), *bm); BitBlaster<BBNodeAIG, BBNodeManagerAIG> bb(&bbnm, simp, &nf , &(bm->UserFlags)); ASTNodeMap fromTo; bb.getConsts(simplified_solved_InputToSAT, fromTo); if (fromTo.size() > 0) { ASTNodeMap cache; simplified_solved_InputToSAT = SubstitutionMap::replace(simplified_solved_InputToSAT, fromTo, cache,&nf); bm->ASTNodeStats("After bitblast simplification: ", simplified_solved_InputToSAT); } } return simplified_solved_InputToSAT; }
ASTNode SubstitutionMap::replace(const ASTNode& n, ASTNodeMap& fromTo, ASTNodeMap& cache, NodeFactory* nf) { if (0 == fromTo.size()) return n; else return replace(n, fromTo, cache, nf, false, false); }
// NB: This expects that the constructor was called with teh same node. Sorry. ASTNode ConstantBitPropagation::topLevelBothWays(const ASTNode& top) { assert(top.GetSTPMgr()->UserFlags.bitConstantProp_flag); assert (BOOLEAN_TYPE == top.GetType()); propagate(); status = NO_CHANGE; //Determine what must always be true. ASTNodeMap fromTo = getAllFixed(); if (debug_cBitProp_messages) { cerr << "Number removed by bottom UP:" << fromTo.size() << endl; } setNodeToTrue(top); if (debug_cBitProp_messages) { cerr << "starting propagation" << endl; printNodeWithFixings(); cerr << "Initial Tree:" << endl; cerr << top; } propagate(); if (debug_cBitProp_messages) { cerr << "status:" << status <<endl; cerr << "ended propagation" << endl; printNodeWithFixings(); } // propagate may have stopped with a conflict. if (CONFLICT == status) return top.GetSTPMgr()->CreateNode(FALSE); ASTVec toConjoin; // go through the fixedBits. If a node is entirely fixed. // "and" it onto the top. Creates redundancy. Check that the // node doesn't already depend on "top" directly. for (NodeToFixedBitsMap::NodeToFixedBitsMapType::iterator it = fixedMap->map->begin(); it != fixedMap->map->end(); it++) // iterates through all the pairs of node->fixedBits. { const FixedBits& bits = *it->second; if (!bits.isTotallyFixed()) continue; const ASTNode& node = (it->first); // Don't constrain nodes we already know all about. if (node.isConstant()) continue; // other nodes will contain the same information (the extract doesn't change the fixings). if (BVEXTRACT == node.GetKind() || BVCONCAT == node.GetKind()) continue; // toAssign: conjoin it with the top level. // toReplace: replace all references to it (except the one conjoined to the top) with this. ASTNode propositionToAssert; ASTNode constantToReplaceWith; // skip the assigning and replacing. bool doAssign = true; { // If it is already contained in the fromTo map, then it's one of the values // that have fully been determined (previously). Not conjoined. if (fromTo.find(node) != fromTo.end()) continue; ASTNode constNode = bitsToNode(node,bits); if (node.GetType() == BOOLEAN_TYPE) { if (SYMBOL == node.GetKind()) { bool r = simplifier->UpdateSubstitutionMap(node, constNode); assert(r); doAssign = false; } else if (bits.getValue(0)) { propositionToAssert = node; constantToReplaceWith = constNode; } else { propositionToAssert = nf->CreateNode(NOT, node); constantToReplaceWith = constNode; } } else if (node.GetType() == BITVECTOR_TYPE) { assert(((unsigned)bits.getWidth()) == node.GetValueWidth()); if (SYMBOL == node.GetKind()) { bool r = simplifier->UpdateSubstitutionMap(node, constNode); assert(r); doAssign = false; } else { propositionToAssert = nf->CreateNode(EQ, node, constNode); constantToReplaceWith = constNode; } } else FatalError("sadf234s"); } if (doAssign && top != propositionToAssert && !dependents->nodeDependsOn(top, propositionToAssert)) { assert(!constantToReplaceWith.IsNull()); assert(constantToReplaceWith.isConstant()); assert(propositionToAssert.GetType() == BOOLEAN_TYPE); assert(node.GetValueWidth() == constantToReplaceWith.GetValueWidth()); fromTo.insert(make_pair(node, constantToReplaceWith)); toConjoin.push_back(propositionToAssert); } } // Write the constants into the main graph. ASTNodeMap cache; ASTNode result = SubstitutionMap::replace(top, fromTo, cache,nf); if (0 != toConjoin.size()) { // It doesn't happen very often. But the "toConjoin" might contain a variable // that was added to the substitution map (because the value was determined just now // during propagation. ASTNode conjunct = (1 == toConjoin.size())? toConjoin[0]: nf->CreateNode(AND,toConjoin); conjunct = simplifier->applySubstitutionMap(conjunct); result = nf->CreateNode(AND, result, conjunct); // conjoin the new conditions. } if (debug_print_graph_after) { ofstream file; file.open("afterCbitp.gdl"); PrintingHackfixedMap = fixedMap; printer::GDL_Print(file,top,&toString); file.close(); } assert(BVTypeCheck(result)); assert(status != CONFLICT); // conflict should have been seen earlier. return result; }