Z3中的Horn子句挂起

时间:2019-08-07 10:38:09

标签: python z3 z3py z3-fixedpoint

我使用最新版本的z3-solver可以正常工作的以下代码:

def test_list_elt_gt_1():
  ll = Datatype('ll')
  ll.declare('empty')
  ll.declare('cons', ('car', IntSort()), ('cdr', ll))
  ll = ll.create()
  list_sum = Function('list_sum', ll, IntSort(), BoolSort())
  list_len = Function('list_len', ll, IntSort(), BoolSort())
  a,e = Consts('a e', ll)
  b,c,d = Ints('b c d')

  fp = Fixedpoint()
  fp.declare_var(a,b,c,d,e)
  fp.register_relation(list_sum, list_len)
  fp.rule(list_sum(a, 0), a == ll.empty)
  fp.rule(list_sum(a, d), [a != ll.empty, b < 1, ll.cons(b, e) == a, list_sum(e, c), b + c == d])
  fp.rule(list_len(a, 0), a == ll.empty)
  fp.rule(list_len(a, d), [a != ll.empty, b < 1, ll.cons(b, e) == a, list_len(e, c), 1 + c == d])
  assert fp.query(And(list_sum(a, b), list_len(a, c), a != ll.empty, b >= c)) == unsat
  assert fp.query(And(list_sum(a, b), list_len(a, c), a != ll.empty, b < c)) == sat

但是,进行了三处细微的调整-在规则中设置b <= 1,在第一个查询中设置b > c,在第二个查询中设置b <= c,它挂起:

def test_list_elt_gt_1():
  ll = Datatype('ll')
  ll.declare('empty')
  ll.declare('cons', ('car', IntSort()), ('cdr', ll))
  ll = ll.create()
  list_sum = Function('list_sum', ll, IntSort(), BoolSort())
  list_len = Function('list_len', ll, IntSort(), BoolSort())
  a,e = Consts('a e', ll)
  b,c,d = Ints('b c d')

  fp = Fixedpoint()
  fp.declare_var(a,b,c,d,e)
  fp.register_relation(list_sum, list_len)
  fp.rule(list_sum(a, 0), a == ll.empty)
  fp.rule(list_sum(a, d), [a != ll.empty, b <= 1, ll.cons(b, e) == a, list_sum(e, c), b + c == d])
  fp.rule(list_len(a, 0), a == ll.empty)
  fp.rule(list_len(a, d), [a != ll.empty, b <= 1, ll.cons(b, e) == a, list_len(e, c), 1 + c == d])
  assert fp.query(And(list_sum(a, b), list_len(a, c), a != ll.empty, b > c)) == unsat
  assert fp.query(And(list_sum(a, b), list_len(a, c), a != ll.empty, b <= c)) == sat

有人为什么会这样吗?

0 个答案:

没有答案
相关问题