Пример #1
0
// ABC doesn't like spaces, nor brackets. in variable names.
//  TODO CHECK that this doesn't cause duplicate names
string symbolToString(const ASTNode& n)
{
  assert(n.GetKind() == SYMBOL);
  std::stringstream output;
  n.nodeprint(output);

  string result = output.str();
  replace(result.begin(), result.end(), ' ', '_');
  replace(result.begin(), result.end(), '(', '_');
  replace(result.begin(), result.end(), ')', '_');

  return result;
}
Пример #2
0
  void Dot_Print1(ostream &os, const ASTNode n, hash_set<int> *alreadyOutput)
  {

    // check if this node has already been printed. If so return.
    if (alreadyOutput->find(n.GetNodeNum()) != alreadyOutput->end())
      return;

    alreadyOutput->insert(n.GetNodeNum());

    os << "n" << n.GetNodeNum() << "[label =\"";
    switch (n.GetKind())
      {
      case SYMBOL:
        n.nodeprint(os);
        break;

      case BITVECTOR:
      case BVCONST:
        outputBitVec(n, os);
        break;

      default:
        os << _kind_names[n.GetKind()];
      }

    os << "\"];" << endl;

    // print the edges to each child.
    ASTVec ch = n.GetChildren();
    ASTVec::iterator itend = ch.end();
    int i = 0;
    for (ASTVec::iterator it = ch.begin(); it < itend; it++)
      {
        os << "n" << n.GetNodeNum() 
           << " -> " << "n" 
           << it->GetNodeNum() 
           << "[label=" << i++ 
           << "];" << endl;
      }

    // print each of the children.
    for (ASTVec::iterator it = ch.begin(); it < itend; it++)
      {
        Dot_Print1(os, *it, alreadyOutput);
      }
  }
Пример #3
0
// helper function for printing C code (copied from PL_Print1())
void C_Print1(ostream& os, const ASTNode n, int indentation, bool letize)
{

  unsigned int upper, lower, num_bytes;
  Kind LHSkind, RHSkind;

  // os << spaces(indentation);
  // os << endl << spaces(indentation);
  if (!n.IsDefined())
  {
    os << "<undefined>";
    return;
  }

  // if this node is present in the letvar Map, then print the letvar
  STPMgr* bm = n.GetSTPMgr();

  // this is to print letvars for shared subterms inside the printing
  // of "(LET v0 = term1, v1=term1@term2,...
  if ((bm->NodeLetVarMap1.find(n) != bm->NodeLetVarMap1.end()) && !letize)
  {
    C_Print1(os, (bm->NodeLetVarMap1[n]), indentation, letize);
    return;
  }

  // this is to print letvars for shared subterms inside the actual
  // term to be printed
  if ((bm->NodeLetVarMap.find(n) != bm->NodeLetVarMap.end()) && letize)
  {
    C_Print1(os, (bm->NodeLetVarMap[n]), indentation, letize);
    return;
  }

  // otherwise print it normally
  Kind kind = n.GetKind();
  const ASTVec& c = n.GetChildren();
  switch (kind)
  {
    case BOOLEXTRACT:
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      C_Print1(os, c[0], indentation, letize);
      os << "{";
      C_Print1(os, c[1], indentation, letize);
      os << "}";
      break;
    case BITVECTOR:
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "BITVECTOR(";
      unsigned char* str;
      str = CONSTANTBV::BitVector_to_Hex(c[0].GetBVConst());
      os << str << ")";
      CONSTANTBV::BitVector_Dispose(str);
      break;
    case BOOLEAN:
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "BOOLEAN";
      break;
    case FALSE:
      os << "0";
      break;
    case TRUE:
      os << "1";
      break;
    case BVCONST:
    case SYMBOL:
      // print in C friendly format:
      n.nodeprint(os, true);
      break;
    case READ:
      C_Print1(os, c[0], indentation, letize);
      os << "[";
      C_Print1(os, c[1], indentation, letize);
      os << "]";
      break;
    case WRITE:
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << " WITH [";
      C_Print1(os, c[1], indentation, letize);
      os << "] := ";
      C_Print1(os, c[2], indentation, letize);
      os << ")";
      os << endl;
      break;
    case BVUMINUS:
      os << kind << "( ";
      C_Print1(os, c[0], indentation, letize);
      os << ")";
      break;
    case NOT:
      os << "!(";
      C_Print1(os, c[0], indentation, letize);
      os << ") " << endl;
      break;
    case BVNEG:
      os << " ~(";
      C_Print1(os, c[0], indentation, letize);
      os << ")";
      break;
    case BVCONCAT:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << " @ ";
      C_Print1(os, c[1], indentation, letize);
      os << ")" << endl;
      break;
    case BVOR:
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << " | ";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVAND:
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << " & ";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVEXTRACT:

      // we only accept indices that are byte-aligned
      // (e.g., [15:8], [23:16])
      // and round down to byte indices rather than bit indices
      upper = c[1].GetUnsignedConst();
      lower = c[2].GetUnsignedConst();
      assert(upper > lower);
      assert(lower % 8 == 0);
      assert((upper + 1) % 8 == 0);
      num_bytes = (upper - lower + 1) / 8;
      assert(num_bytes > 0);

      // for multi-byte extraction, use the ADDRESS
      if (num_bytes > 1)
      {
        os << "&";
        C_Print1(os, c[0], indentation, letize);
        os << "[" << lower / 8 << "]";
      }
      // for single-byte extraction, use the VALUE
      else
      {
        C_Print1(os, c[0], indentation, letize);
        os << "[" << lower / 8 << "]";
      }

      break;
    case BVLEFTSHIFT:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << " << ";
      os << c[1].GetUnsignedConst();
      os << ")";
      break;
    case BVRIGHTSHIFT:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << " >> ";
      os << c[1].GetUnsignedConst();
      os << ")";
      break;
    case BVMULT:
    case BVSUB:
    case BVPLUS:
    case SBVDIV:
    case SBVREM:
    case BVDIV:
    case BVMOD:
      os << kind << "(";
      os << n.GetValueWidth();
      for (ASTVec::const_iterator it = c.begin(), itend = c.end(); it != itend;
           it++)
      {
        os << ", " << endl;
        C_Print1(os, *it, indentation, letize);
      }
      os << ")" << endl;
      break;
    case ITE:
      os << "if (";
      C_Print1(os, c[0], indentation, letize);
      os << ")" << endl;
      os << "{";
      C_Print1(os, c[1], indentation, letize);
      os << endl << "} else {";
      C_Print1(os, c[2], indentation, letize);
      os << endl << "}";
      break;
    case BVLT:
      // convert to UNSIGNED before doing comparison!
      os << "((unsigned char)";
      C_Print1(os, c[0], indentation, letize);
      os << " < ";
      os << "(unsigned char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVLE:
      // convert to UNSIGNED before doing comparison!
      os << "((unsigned char)";
      C_Print1(os, c[0], indentation, letize);
      os << " <= ";
      os << "(unsigned char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVGT:
      // convert to UNSIGNED before doing comparison!
      os << "((unsigned char)";
      C_Print1(os, c[0], indentation, letize);
      os << " > ";
      os << "(unsigned char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVGE:
      // convert to UNSIGNED before doing comparison!
      os << "((unsigned char)";
      C_Print1(os, c[0], indentation, letize);
      os << " >= ";
      os << "(unsigned char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVXOR:
    case BVNAND:
    case BVNOR:
    case BVXNOR:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      break;
    case BVSLT:
      // convert to SIGNED before doing comparison!
      os << "((signed char)";
      C_Print1(os, c[0], indentation, letize);
      os << " < ";
      os << "(signed char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVSLE:
      // convert to SIGNED before doing comparison!
      os << "((signed char)";
      C_Print1(os, c[0], indentation, letize);
      os << " <= ";
      os << "(signed char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVSGT:
      // convert to SIGNED before doing comparison!
      os << "((signed char)";
      C_Print1(os, c[0], indentation, letize);
      os << " > ";
      os << "(signed char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case BVSGE:
      // convert to SIGNED before doing comparison!
      os << "((signed char)";
      C_Print1(os, c[0], indentation, letize);
      os << " >= ";
      os << "(signed char)";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      break;
    case EQ:
      // tricky tricky ... if it's a single-byte comparison,
      // simply do ==, but if it's multi-byte, must do memcmp
      LHSkind = c[0].GetKind();
      RHSkind = c[1].GetKind();

      num_bytes = 0;

      // try to figure out whether it's a single-byte or multi-byte
      // comparison
      if (LHSkind == BVEXTRACT)
      {
        upper = c[0].GetChildren()[1].GetUnsignedConst();
        lower = c[0].GetChildren()[2].GetUnsignedConst();
        num_bytes = (upper - lower + 1) / 8;
      }
      else if (RHSkind == BVEXTRACT)
      {
        upper = c[1].GetChildren()[1].GetUnsignedConst();
        lower = c[1].GetChildren()[2].GetUnsignedConst();
        num_bytes = (upper - lower + 1) / 8;
      }

      if (num_bytes > 1)
      {
        os << "(memcmp(";
        C_Print1(os, c[0], indentation, letize);
        os << ", ";
        C_Print1(os, c[1], indentation, letize);
        os << ", ";
        os << num_bytes;
        os << ") == 0)";
      }
      else if (num_bytes == 1)
      {
        os << "(";
        C_Print1(os, c[0], indentation, letize);
        os << " == ";
        C_Print1(os, c[1], indentation, letize);
        os << ")";
      }
      else
      {
        FatalError("C_Print1: ugh problem in implementing ==");
      }

      break;
    case AND:
    case OR:
    case NAND:
    case NOR:
    case XOR:
    {
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      ASTVec::const_iterator it = c.begin();
      ASTVec::const_iterator itend = c.end();

      it++;
      for (; it != itend; it++)
      {
        switch (kind)
        {
          case AND:
            os << " && ";
            break;
          case OR:
            os << " || ";
            break;
          case NAND:
            FatalError("unsupported boolean type in C_Print1");
            break;
          case NOR:
            FatalError("unsupported boolean type in C_Print1");
            break;
          case XOR:
            FatalError("unsupported boolean type in C_Print1");
            break;
          default:
            FatalError("unsupported boolean type in C_Print1");
        }
        C_Print1(os, *it, indentation, letize);
      }
      os << ")";
      break;
    }
    case IFF:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "(";
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << ")";
      os << " <=> ";
      os << "(";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      os << ")";
      os << endl;
      break;
    case IMPLIES:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      os << "(";
      os << "(";
      C_Print1(os, c[0], indentation, letize);
      os << ")";
      os << " => ";
      os << "(";
      C_Print1(os, c[1], indentation, letize);
      os << ")";
      os << ")";
      os << endl;
      break;
    case BVSX:
      // stopgap for un-implemented features
      FatalError("C_Print1: printing not implemented for this kind: ", n);

      os << kind << "(";
      C_Print1(os, c[0], indentation, letize);
      os << ",";
      os << n.GetValueWidth();
      os << ")" << endl;
      break;
    default:
      // remember to use LispPrinter here. Otherwise this function will
      // go into an infinite loop. Recall that "<<" is overloaded to
      // the lisp printer. FatalError uses lispprinter
      FatalError("C_Print1: printing not implemented for this kind: ", n);
      break;
  }
} // end of C_Print1()
Пример #4
0
  void SMTLIB2_Print1(ostream& os, const ASTNode n, int indentation, bool letize)
  {
    //os << spaces(indentation);
    //os << endl << spaces(indentation);
    if (!n.IsDefined())
      {
        FatalError("<undefined>");
        return;
      }

    //if this node is present in the letvar Map, then print the letvar
    //this is to print letvars for shared subterms inside the printing
    //of "(LET v0 = term1, v1=term1@term2,...
	if ((NodeLetVarMap1.find(n) != NodeLetVarMap1.end()) && !letize)
      {
		SMTLIB2_Print1(os, (NodeLetVarMap1[n]), indentation, letize);
        return;
      }

    //this is to print letvars for shared subterms inside the actual
    //term to be printed
	if ((NodeLetVarMap.find(n) != NodeLetVarMap.end()) && letize)
      {
		SMTLIB2_Print1(os, (NodeLetVarMap[n]), indentation, letize);
        return;
      }

    //otherwise print it normally
	const Kind kind = n.GetKind();
    const ASTVec &c = n.GetChildren();
    switch (kind)
      {
      case BITVECTOR:
      case BVCONST:
    	  outputBitVecSMTLIB2(n, os);
        break;
      case SYMBOL:
        os << "|";
        n.nodeprint(os);
        os << "|";
        break;
      case FALSE:
        os << "false";
        break;
      case NAND: // No NAND, NOR in smtlib format.
      case NOR:
    	  assert(c.size() ==2);
    	  os << "(" << "not ";
    	  if (NAND == kind )
    		  os << "(" << "and ";
    	  else
    		  os << "(" << "or ";
    	  SMTLIB2_Print1(os, c[0], 0, letize);
    	  os << " " ;
    	  SMTLIB2_Print1(os, c[1], 0, letize);
    	  os << "))";
    	  break;
      case TRUE:
        os << "true";
        break;
      case BVSX:
      case BVZX:
        {
          unsigned int amount = c[1].GetUnsignedConst();
          if (BVZX == kind)
            os << "((_ zero_extend ";
          else
            os << "((_ sign_extend ";

          os << (amount - c[0].GetValueWidth()) << ") ";
          SMTLIB2_Print1(os, c[0], indentation, letize);
          os << ")";
        }
        break;
      case BVEXTRACT:
        {
          unsigned int upper = c[1].GetUnsignedConst();
          unsigned int lower = c[2].GetUnsignedConst();
          assert(upper >= lower);
          os << "((_ extract " << upper << " " << lower << ") ";
          SMTLIB2_Print1(os, c[0], indentation, letize);
          os << ")";
        }
        break;
  	default:
  	{
  	    if ((kind == AND  || kind == OR|| kind == XOR) && n.Degree() == 1)
  	    {
  	    	FatalError("Wrong number of arguments to operation (must be >1).", n);
  	    }

  		// SMT-LIB only allows these functions to have two parameters.
  		if ((kind == AND  || kind == OR|| kind == XOR || BVPLUS == kind || kind == BVOR || kind == BVAND)  && n.Degree() > 2)
  		{
  			string close = "";

  			for (long int i =0; i < (long int)c.size()-1; i++)
  			{
  				os << "(" << functionToSMTLIBName(kind,false);
  				os << " ";
  				SMTLIB2_Print1(os, c[i], 0, letize);
  				os << " ";
  				close += ")";
  			}
  			SMTLIB2_Print1(os, c[c.size()-1], 0, letize);
  			os << close;
  		}
  		else
  		{
  			os << "(" << functionToSMTLIBName(kind,false);

  			ASTVec::const_iterator iend = c.end();
  			for (ASTVec::const_iterator i = c.begin(); i != iend; i++)
  			{
  				os << " ";
  				SMTLIB2_Print1(os, *i, 0, letize);
  			}

  			os << ")";
  		}
  	}
      }
  }
Пример #5
0
void GDL_Print1(ostream& os, const ASTNode& n, hash_set<int>* alreadyOutput,
                string (*annotate)(const ASTNode&))
{
  // check if this node has already been printed. If so return.
  if (alreadyOutput->find(n.GetNodeNum()) != alreadyOutput->end())
    return;

  alreadyOutput->insert(n.GetNodeNum());

  os << "node: { title:\"n" << n.GetNodeNum() << "\" label: \"";
  switch (n.GetKind())
  {
    case SYMBOL:
      n.nodeprint(os);
      break;

    case BITVECTOR:
    case BVCONST:
      outputBitVec(n, os);
      break;

    default:
      os << _kind_names[n.GetKind()];
  }

  os << annotate(n);
  os << "\"}" << endl;

  // print the edges to each child.
  const ASTVec ch = n.GetChildren();
  const ASTVec::const_iterator itend = ch.end();

  // If a node has the child 'TRUE' twice, we only want to output one TRUE node.
  ASTNodeSet constantOutput;

  int i = 0;
  for (ASTVec::const_iterator it = ch.begin(); it < itend; it++)
  {
    std::stringstream label;

    if (!isCommutative(n.GetKind()))
      label << " label:\"" << i << "\"";

    if (it->isConstant())
    {
      std::stringstream ss;
      ss << n.GetNodeNum() << "_" << it->GetNodeNum();

      if (constantOutput.end() == constantOutput.find(*it))
      {
        os << "node: { title:\"n";

        os << ss.str() << "\" label: \"";
        if (it->GetType() == BEEV::BOOLEAN_TYPE)
          os << _kind_names[it->GetKind()];
        else
          outputBitVec(*it, os);
        os << "\"}" << endl;
        constantOutput.insert(*it);
      }

      os << "edge: { source:\"n" << n.GetNodeNum() << "\" target: \""
         << "n" << ss.str() << "\"" << label.str() << "}" << endl;
    }
    else
      os << "edge: { source:\"n" << n.GetNodeNum() << "\" target: \""
         << "n" << it->GetNodeNum() << "\"" << label.str() << "}" << endl;
    i++;
  }

  // print each of the children.
  for (ASTVec::const_iterator it = ch.begin(); it < itend; it++)
  {
    if (!it->isConstant())
      GDL_Print1(os, *it, alreadyOutput, annotate);
  }
}