Exemple #1
0
void equality_domaint::project_on_vars(
  valuet &value,
  const var_sett &vars,
  exprt &result)
{
#if 0
  if(templ.size()==0)
    return domaint::project_on_vars(value, vars, result);
#endif

  equ_valuet &v=static_cast<equ_valuet &>(value);

  exprt::operandst c;
  for(unsigned index=0; index<templ.size(); index++)
  {
    const var_pairt &vv=templ[index].var_pair;

#if 0
    std::cout << vv.second << std::endl;
#endif
    if(vars.find(vv.first)==vars.end() ||
       (vars.find(vv.second)==vars.end() &&
        !(vv.second.id()==ID_constant &&
          to_constant_expr(vv.second).get_value()=="NULL")))
      continue;

    if(v.equs.same_set(vv.first, vv.second))
    {
      if(templ[index].kind==LOOP)
        c.push_back(
          implies_exprt(
            templ[index].pre_guard,
            equal_exprt(vv.first, vv.second)));
      else
        c.push_back(equal_exprt(vv.first, vv.second));
    }
  }

  for(index_sett::const_iterator it=v.disequs.begin();
      it!=v.disequs.end(); it++)
  {
    const var_pairt &vv=templ[*it].var_pair;

    if(vars.find(vv.first)==vars.end() ||
       (vars.find(vv.second)==vars.end() &&
        !(vv.second.id()==ID_constant &&
          to_constant_expr(vv.second).get_value()=="NULL")))
      continue;

    if(templ[*it].kind==LOOP)
      c.push_back(
        implies_exprt(
          templ[*it].pre_guard,
          notequal_exprt(vv.first, vv.second)));
    else
      c.push_back(notequal_exprt(vv.first, vv.second));
  }
  result=conjunction(c);
}
Exemple #2
0
exprt equality_domaint::get_pre_disequ_constraint(unsigned index)
{
  assert(index<templ.size());
  const template_rowt &templ_row=templ[index];
  if(templ_row.kind==OUT || templ_row.kind==OUTL)
    return true_exprt();

  const var_pairt &vv=templ_row.var_pair;
  return
    implies_exprt(templ_row.pre_guard, notequal_exprt(vv.first, vv.second));
}
/// add axioms stating that the result is true exactly when the strings
/// represented by the arguments are equal
/// \par parameters: function application with two string arguments
/// \return a expression of Boolean type
exprt string_constraint_generatort::add_axioms_for_equals(
  const function_application_exprt &f)
{
  assert(f.type()==bool_typet() || f.type().id()==ID_c_bool);
  symbol_exprt eq=fresh_boolean("equal");
  typecast_exprt tc_eq(eq, f.type());

  string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]);
  string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]);
  typet index_type=s1.length().type();

  // We want to write:
  // eq <=> (s1.length=s2.length  &&forall i<s1.length. s1[i]=s2[i])
  // We add axioms:
  // a1 : eq => s1.length=s2.length
  // a2 : forall i<s1.length. eq => s1[i]=s2[i]
  // a3 : !eq => s1.length!=s2.length
  //       || (witness<s1.length &&s1[witness]!=s2[witness])

  implies_exprt a1(eq, s1.axiom_for_has_same_length_as(s2));
  axioms.push_back(a1);

  symbol_exprt qvar=fresh_univ_index("QA_equal", index_type);
  string_constraintt a2(qvar, s1.length(), eq, equal_exprt(s1[qvar], s2[qvar]));
  axioms.push_back(a2);

  symbol_exprt witness=fresh_exist_index("witness_unequal", index_type);
  exprt zero=from_integer(0, index_type);
  and_exprt bound_witness(
    binary_relation_exprt(witness, ID_lt, s1.length()),
    binary_relation_exprt(witness, ID_ge, zero));
  and_exprt witnessing(bound_witness, notequal_exprt(s1[witness], s2[witness]));
  implies_exprt a3(
    not_exprt(eq),
    or_exprt(notequal_exprt(s1.length(), s2.length()), witnessing));
  axioms.push_back(a3);

  return tc_eq;
}
/// add axioms corresponding to the String.equalsIgnoreCase java function
/// \par parameters: function application with two string arguments
/// \return a Boolean expression
exprt string_constraint_generatort::add_axioms_for_equals_ignore_case(
  const function_application_exprt &f)
{
  assert(f.type()==bool_typet() || f.type().id()==ID_c_bool);

  symbol_exprt eq=fresh_boolean("equal_ignore_case");
  typecast_exprt tc_eq(eq, f.type());
  string_exprt s1=add_axioms_for_string_expr(args(f, 2)[0]);
  string_exprt s2=add_axioms_for_string_expr(args(f, 2)[1]);
  typet char_type=to_refined_string_type(s1.type()).get_char_type();
  exprt char_a=constant_char('a', char_type);
  exprt char_A=constant_char('A', char_type);
  exprt char_Z=constant_char('Z', char_type);
  typet index_type=s1.length().type();

  // We add axioms:
  // a1 : eq => |s1|=|s2|
  // a2 : forall qvar, 0<=qvar<|s1|,
  //  eq => char_equal_ignore_case(s1[qvar],s2[qvar]);
  // a3 : !eq => |s1|!=s2 || (0 <=witness<|s1| &&!char_equal_ignore_case)

  implies_exprt a1(eq, s1.axiom_for_has_same_length_as(s2));
  axioms.push_back(a1);

  symbol_exprt qvar=fresh_univ_index("QA_equal_ignore_case", index_type);
  exprt constr2=character_equals_ignore_case(
    s1[qvar], s2[qvar], char_a, char_A, char_Z);
  string_constraintt a2(qvar, s1.length(), eq, constr2);
  axioms.push_back(a2);

  symbol_exprt witness=fresh_exist_index(
    "witness_unequal_ignore_case", index_type);
  exprt zero=from_integer(0, witness.type());
  and_exprt bound_witness(
    binary_relation_exprt(witness, ID_lt, s1.length()),
    binary_relation_exprt(witness, ID_ge, zero));
  exprt witness_eq=character_equals_ignore_case(
    s1[witness], s2[witness], char_a, char_A, char_Z);
  not_exprt witness_diff(witness_eq);
  implies_exprt a3(
    not_exprt(eq),
    or_exprt(
      notequal_exprt(s1.length(), s2.length()),
      and_exprt(bound_witness, witness_diff)));
  axioms.push_back(a3);

  return tc_eq;
}
Exemple #5
0
exprt equality_domaint::get_post_not_disequ_constraint(unsigned index)
{
  assert(index<templ.size());
  const template_rowt &templ_row=templ[index];
  if(templ_row.kind==IN)
    return true_exprt();

  const var_pairt &vv=templ_row.var_pair;
  exprt c=
    and_exprt(
      templ_row.aux_expr,
      not_exprt(
        implies_exprt(
          templ_row.post_guard,
          notequal_exprt(vv.first, vv.second))));
  rename(c);
  return c;
}