cloud9_root/src/third_party/stp/src/simplifier/simplifier.cpp
//THis function accepts a BVMULT(t1,t2) and distributes the mult
//over plus if either or both t1 and t2 are BVPLUSes.
//
// x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn
//
// (y1 + y2 + ...+ yn)*x <==> x*y1 + x*y2 + ... + x*yn
//
// The function assumes that the BVPLUSes have been flattened
THis function accepts a BVMULT(t1,t2) and distributes the mult
over plus if either or both t1 and t2 are BVPLUSes.





The function assumes that the BVPLUSes have been flattened
THis function accepts a BVMULT ( t1 t2 ) and distributes the mult over plus if either or both t1 and t2 are BVPLUSes . The function assumes that the BVPLUSes have been flattened
ASTNode
  Simplifier::DistributeMultOverPlus(const ASTNode& a, bool startdistribution)
  {
    if (!startdistribution)
      return a;
    Kind k = a.GetKind();
    if (BVMULT != k)
      return a;
    assert(a.Degree() == 2);
    ASTNode left = a[0];
    ASTNode right = a[1];
    Kind left_kind = left.GetKind();
    Kind right_kind = right.GetKind();
    ASTNode output;
    if (CheckSimplifyMap(a, output, false))
      {
        return output;
      }
    if (BVCONST == left_kind && BVMULT == right_kind && BVCONST == right[0].GetKind())
      {
        ASTNode c = BVConstEvaluator(nf->CreateTerm(BVMULT, a.GetValueWidth(), left, right[0]));
        c = nf->CreateTerm(BVMULT, a.GetValueWidth(), c, right[1]);
        return c;
        left = c[0];
        right = c[1];
        left_kind = left.GetKind();
        right_kind = right.GetKind();
      }
    if (BVCONST == left_kind && BVMULT == right_kind && BVCONST == right[1].GetKind())
      {
        ASTNode c = BVConstEvaluator(nf->CreateTerm(BVMULT, a.GetValueWidth(), left, right[1]));
        c = nf->CreateTerm(BVMULT, a.GetValueWidth(), c, right[0]);
        return c;
        left = c[0];
        right = c[1];
        left_kind = left.GetKind();
        right_kind = right.GetKind();
      }
    if (!(BVPLUS == left_kind || BVPLUS == right_kind))
      {
        return a;
      }
    ASTNode swap;
    if (BVPLUS == left_kind && BVPLUS != right_kind)
      {
        swap = left;
        left = right;
        right = swap;
      }
    left_kind = left.GetKind();
    right_kind = right.GetKind();
    ASTVec rightnodes = right.GetChildren();
    ASTVec outputvec;
    unsigned len = a.GetValueWidth();
    ASTNode zero = _bm->CreateZeroConst(len);
    ASTNode one = _bm->CreateOneConst(len);
    if (BVPLUS != left_kind)
      {
        if (zero == left)
          {
            outputvec.push_back(zero);
          }
        else if (one == left)
          {
            outputvec.push_back(left);
          }
        else
          {
            for (ASTVec::iterator j = rightnodes.begin(), jend = rightnodes.end(); j != jend; j++)
              {
                ASTNode out = SimplifyTerm(nf->CreateTerm(BVMULT, len, left, *j));
                outputvec.push_back(out);
              }
          }
      }
    else
      {
        ASTVec leftnodes = left.GetChildren();
        for (ASTVec::iterator i = leftnodes.begin(), iend = leftnodes.end(); i != iend; i++)
          {
            ASTNode multiplier = *i;
            for (ASTVec::iterator j = rightnodes.begin(), jend = rightnodes.end(); j != jend; j++)
              {
                ASTNode out = SimplifyTerm(nf->CreateTerm(BVMULT, len, multiplier, *j));
                outputvec.push_back(out);
              }
          }
      }
    if (outputvec.size() > 1)
      {
        output = CombineLikeTerms(nf->CreateTerm(BVPLUS, len, outputvec));
        output = SimplifyTerm(output);
      }
    else
      output = SimplifyTerm(outputvec[0]);
    return output;
  }
ASTNode Simplifier :: DistributeMultOverPlus ( const ASTNode & a , bool startdistribution ) { if ( ! startdistribution ) return a ; Kind k = a . GetKind ( ) ; if ( BVMULT != k ) return a ; assert ( a . Degree ( ) == 2 ) ; ASTNode left = a [ 0 ] ; ASTNode right = a [ 1 ] ; Kind left_kind = left . GetKind ( ) ; Kind right_kind = right . GetKind ( ) ; ASTNode output ; if ( CheckSimplifyMap ( a , output , false ) ) { return output ; } if ( BVCONST == left_kind && BVMULT == right_kind && BVCONST == right [ 0 ] . GetKind ( ) ) { ASTNode c = BVConstEvaluator ( nf -> CreateTerm ( BVMULT , a . GetValueWidth ( ) , left , right [ 0 ] ) ) ; c = nf -> CreateTerm ( BVMULT , a . GetValueWidth ( ) , c , right [ 1 ] ) ; return c ; left = c [ 0 ] ; right = c [ 1 ] ; left_kind = left . GetKind ( ) ; right_kind = right . GetKind ( ) ; } if ( BVCONST == left_kind && BVMULT == right_kind && BVCONST == right [ 1 ] . GetKind ( ) ) { ASTNode c = BVConstEvaluator ( nf -> CreateTerm ( BVMULT , a . GetValueWidth ( ) , left , right [ 1 ] ) ) ; c = nf -> CreateTerm ( BVMULT , a . GetValueWidth ( ) , c , right [ 0 ] ) ; return c ; left = c [ 0 ] ; right = c [ 1 ] ; left_kind = left . GetKind ( ) ; right_kind = right . GetKind ( ) ; } if ( ! ( BVPLUS == left_kind || BVPLUS == right_kind ) ) { return a ; } ASTNode swap ; if ( BVPLUS == left_kind && BVPLUS != right_kind ) { swap = left ; left = right ; right = swap ; } left_kind = left . GetKind ( ) ; right_kind = right . GetKind ( ) ; ASTVec rightnodes = right . GetChildren ( ) ; ASTVec outputvec ; unsigned len = a . GetValueWidth ( ) ; ASTNode zero = _bm -> CreateZeroConst ( len ) ; ASTNode one = _bm -> CreateOneConst ( len ) ; if ( BVPLUS != left_kind ) { if ( zero == left ) { outputvec . push_back ( zero ) ; } else if ( one == left ) { outputvec . push_back ( left ) ; } else { for ( ASTVec :: iterator j = rightnodes . begin ( ) , jend = rightnodes . end ( ) ; j != jend ; j ++ ) { ASTNode out = SimplifyTerm ( nf -> CreateTerm ( BVMULT , len , left , * j ) ) ; outputvec . push_back ( out ) ; } } } else { ASTVec leftnodes = left . GetChildren ( ) ; for ( ASTVec :: iterator i = leftnodes . begin ( ) , iend = leftnodes . end ( ) ; i != iend ; i ++ ) { ASTNode multiplier = * i ; for ( ASTVec :: iterator j = rightnodes . begin ( ) , jend = rightnodes . end ( ) ; j != jend ; j ++ ) { ASTNode out = SimplifyTerm ( nf -> CreateTerm ( BVMULT , len , multiplier , * j ) ) ; outputvec . push_back ( out ) ; } } } if ( outputvec . size ( ) > 1 ) { output = CombineLikeTerms ( nf -> CreateTerm ( BVPLUS , len , outputvec ) ) ; output = SimplifyTerm ( output ) ; } else output = SimplifyTerm ( outputvec [ 0 ] ) ; return output ; }
THis function accepts a BVMULT(t1,t2) and distributes the mult
over plus if either or both t1 and t2 are BVPLUSes.
THis function accepts a BVMULT ( t1 t2 ) and distributes the mult over plus if either or both t1 and t2 are BVPLUSes .
//check memo table //cerr << "output of SimplifyTerm Cache: " << output << endl; //special case optimization: c1*(c2*t1) <==> (c1*c2)*t1 //special case optimization: c1*(t1*c2) <==> (c1*c2)*t1 //atleast one of left or right have to be BVPLUS //if left is BVPLUS and right is not, then swap left and right. we //can do this since BVMULT is communtative //by this point we are gauranteed that right is a BVPLUS, but left //may not be //if the multiplier is not a BVPLUS then we have a special case // x*(y1 + y2 + ...+ yn) <==> x*y1 + x*y2 + ... + x*yn // (x1 + x2 + ... + xm)*(y1 + y2 + ...+ yn) <==> x1*y1 + x1*y2 + // ... + x2*y1 + ... + xm*yn //compute output here //memoize //UpdateSimplifyMap(a,output,false);