如何使用 boolector 为我的代码生成模型?

How to generate a model for my code using boolector?

我正在对 boolector 进行一些试验,因此我正在尝试为简单代码创建模型。假设我有以下伪代码:

int a = 5;
int b = 4;
int c = 3;

对于这组简单的说明,我可以创建模型并且一切正常。问题是当我在那之后有其他指令时

b = 10;
c = 20;

显然它无法生成模型,因为 b 不能等于同一模块内的 410。其中一位维护者建议我使用 boolector_pushboolector_pop 以便在需要时创建新的 Context

boolector_push 的代码是:

void
boolector_push (Btor *btor, uint32_t level)
{
  BTOR_ABORT_ARG_NULL (btor);
  BTOR_TRAPI ("%u", level);
  BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
              "incremental usage has not been enabled");

  if (level == 0) return;

  uint32_t i;
  for (i = 0; i < level; i++)
  {
    BTOR_PUSH_STACK (btor->assertions_trail,
                     BTOR_COUNT_STACK (btor->assertions));
  }
  btor->num_push_pop++;
}

而不是 boolector_pop

void
boolector_pop (Btor *btor, uint32_t level)
{
  BTOR_ABORT_ARG_NULL (btor);
  BTOR_TRAPI ("%u", level);
  BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
              "incremental usage has not been enabled");
  BTOR_ABORT (level > BTOR_COUNT_STACK (btor->assertions_trail),
              "can not pop more levels (%u) than created via push (%u).",
              level,
              BTOR_COUNT_STACK (btor->assertions_trail));

  if (level == 0) return;

  uint32_t i, pos;
  BtorNode *cur;

  for (i = 0, pos = 0; i < level; i++)
    pos = BTOR_POP_STACK (btor->assertions_trail);

  while (BTOR_COUNT_STACK (btor->assertions) > pos)
  {
    cur = BTOR_POP_STACK (btor->assertions);
    btor_hashint_table_remove (btor->assertions_cache, btor_node_get_id (cur));
    btor_node_release (btor, cur);
  }
  btor->num_push_pop++;
}

在我看来,这两个函数会跟踪使用 boolector_assert 生成的断言,因此考虑到这一点,如何使用 boolector_pushboolector_pop 获得最终和正确的模型约束会相同吗?

我错过了什么?

谢谢

如您所料,解算器的 pushpop 方法不是您要查找的内容。相反,您必须将正在建模的程序转换为所谓的 SSA(静态单一分配)形式。这是关于它的维基百科文章,内容非常丰富:https://en.wikipedia.org/wiki/Static_single_assignment_form

基本思想是 "treat" 可变变量作为时变值,并在对它们进行多次赋值时赋予它们唯一的名称。因此,以下内容:

a = 5
b = a + 2
c = b + 3
c = c + 1
b = c + 6

变为:

a0 = 5
b0 = a0 + 2
c0 = b0 + 3
c1 = c0 + 1
b1 = c1 + 6

等请注意,条件语句很难处理,并且通常需要所谓的 phi 节点。 (即,合并分支的值。)大多数编译器会自动为您进行这种转换,因为它可以实现许多优化。您可以手动完成,也可以使用算法为您完成,具体取决于您的具体问题。

这是关于堆栈溢出的另一个问题,本质上是在询问类似的问题:Z3 Conditional Statement

希望对您有所帮助!