--- /dev/null
+#ifndef DIFFICULTYSCORE_H_
+#define DIFFICULTYSCORE_H_
+
+#include "../AST/AST.h"
+#include "../AST/AST.h"
+#include "../AST/ASTKind.h"
+
+// estimate how difficult that input is to solve based on some simple rules.
+
+namespace BEEV
+{
+struct DifficultyScore
+{
+ typedef map<ASTNode,int> Cache;
+
+ static bool isLikeMultiplication(const Kind& k)
+ {
+ return k == BVMULT || k == BVDIV || k == BVMOD || k == SBVDIV || k == SBVREM || k == SBVMOD;
+ }
+
+ static int visit(const ASTNode& b, Cache& cache)
+ {
+ Cache::iterator it;
+
+ if ((it = cache.find(b)) != cache.end())
+ return 0; // already included.
+
+ int score= 0;
+ if (isLikeMultiplication(b.GetKind()))
+ score += (b.GetValueWidth() * b.GetValueWidth() );
+ else
+ score += b.GetValueWidth();
+
+ const ASTVec& c = b.GetChildren();
+ ASTVec::const_iterator itC = c.begin();
+ ASTVec::const_iterator itendC = c.end();
+ for (; itC != itendC; itC++)
+ {
+ score += visit(*itC, cache);
+ }
+
+ cache[b] = score;
+ return score;
+ }
+
+ static int score(const ASTNode& top)
+ {
+ Cache cache;
+ int result = visit(top,cache);
+ return result;
+ }
+};
+};
+
+#endif /* DIFFICULTYSCORE_H_ */
+
+
+
********************************************************************/
#include "STP.h"
+#include "DifficultyScore.h"
namespace BEEV {
bm->ASTNodeStats("input asserts and query: ", inputToSAT);
ASTNode simplified_solved_InputToSAT = inputToSAT;
+
+ long initial_difficulty_score = DifficultyScore::score(original_input);
+
//round of substitution, solving, and simplification. ensures that
//DAG is minimized as much as possibly, and ideally should
//garuntee that all liketerms in BVPLUSes have been combined.
bm->SimplifyWrites_InPlace_Flag = false;
bm->Begin_RemoveWrites = false;
+
+ long final_difficulty_score = DifficultyScore::score(simplified_solved_InputToSAT);
+ if (bm->UserFlags.stats_flag)
+ {
+ cerr << "Initial Difficulty Score:" << initial_difficulty_score <<endl;
+ cerr << "Final Difficulty Score:" << final_difficulty_score <<endl;
+ }
+
+ bool optimize_enabled = bm->UserFlags.optimize_flag;
+ if (final_difficulty_score > 2 *initial_difficulty_score && !containsArrayOps(orig_input))
+ {
+ // If the simplified problem is harder, than the
+ // initial problem we revert back to the initial
+ // problem.
+
+ if (bm->UserFlags.stats_flag)
+ cerr << "simplification made the problem harder, reverting."<<endl;
+ simplified_solved_InputToSAT = original_input;
+
+ // I do this to clear the substitution/solver map.
+ // Not sure what would happen if it contained simplifications
+ // that haven't been applied.
+ simp->ClearAllTables();
+
+ // The arrayTransformer calls simplify. We don't want
+ // it to put back in all the bad simplifications.
+ bm->UserFlags.optimize_flag = false;
+ }
+
simplified_solved_InputToSAT =
arrayTransformer->TransformFormula_TopLevel(simplified_solved_InputToSAT);
bm->ASTNodeStats("after transformation: ", simplified_solved_InputToSAT);
bm->TermsAlreadySeenMap_Clear();
+ bm->UserFlags.optimize_flag = optimize_enabled;
+
SOLVER_RETURN_TYPE res;
if (bm->UserFlags.arrayread_refinement_flag)
{
return substitutionMap.CheckSubstitutionMap(key,output);
}
+ ASTNode Simplifier::applySubstitutionMap(const ASTNode& n)
+ {
+ return substitutionMap.applySubstitutionMap(n);
+ }
+
bool Simplifier::CheckSubstitutionMap(const ASTNode& key)
{
return substitutionMap.CheckSubstitutionMap(key);
Simplifier::SimplifyFormula(const ASTNode& b,
bool pushNeg, ASTNodeMap* VarConstMap)
{
- // if (!optimize_flag)
- // return b;
+ assert(_bm->UserFlags.optimize_flag);
Kind kind = b.GetKind();
if (BOOLEAN_TYPE != b.GetType())
Simplifier::SimplifyTerm(const ASTNode& actualInputterm,
ASTNodeMap* VarConstMap)
{
- if (actualInputterm.isConstant())
+ assert(_bm->UserFlags.optimize_flag);
+
+ if (actualInputterm.isConstant())
return actualInputterm;
ASTNode inputterm(actualInputterm); // mutable local copy.
bool CheckSubstitutionMap(const ASTNode& a);
bool UpdateSubstitutionMap(const ASTNode& e0, const ASTNode& e1);
+ ASTNode applySubstitutionMap(const ASTNode& n);
void ResetSimplifyMaps(void);