/*******************************************************************\

Module:

Author: Daniel Kroening, kroening@cs.cmu.edu

\*******************************************************************/

#include <i2string.h>

#include "boolbv.h"

/*******************************************************************\

Function: boolbvt::convert_equality

  Inputs:

 Outputs:

 Purpose:

\*******************************************************************/

literalt boolbvt::convert_equality(const exprt &expr)
{
  if(expr.operands().size()!=2)
    return SUB::convert_rest(expr);

  bool is_equality=(expr.id()=="=");

  if(expr.op0().type()!=expr.op1().type())
  {
    std::cout << expr.pretty() << std::endl;
    throw "equality without matching types";
  }

  // see if it is an unbounded array
  if(is_unbounded_array(expr.op0().type()))
    return record_array_equality(expr);

  bvt bv0, bv1;
  
  if(convert_bv(expr.op0(), bv0))
    return SUB::convert_rest(expr);
  
  if(convert_bv(expr.op1(), bv1))
    return SUB::convert_rest(expr);
    
  if(bv0.size()!=bv1.size())
    throw "unexpected size mismatch";

  if(bv0.size()==0)
    throw "got zero-size BV";

  if(expr.op0().type().id()=="verilogbv")
  {
    // TODO
  }
  else
  {
    literalt literal=bv_utils.equal(bv0, bv1);

    if(prop.has_set_to())
    {
      // unclear if this helps
      if(bv0.size()>8)
      {
        #if 0
        // if it is big, ALSO register it as equality
        literalt l2=equality(expr.op0(), expr.op1());
        prop.l_set_to_true(prop.lequal(literal, l2));
        #endif
      }
    }

    if(!is_equality) literal=prop.lnot(literal);
    return literal;
  }
  
  return SUB::convert_rest(expr);
}
