在 Z3 中创建传递而不是自反函数 [英] Creating a transitive and not reflexive function in Z3

查看:11
本文介绍了在 Z3 中创建传递而不是自反函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Z3 中创建一个可传递但不具有自反性的函数.IE.如果 (transitive ab)(transitive bc)hold 那么 (transitive ac) 应该成立,但是 (transitive aa)代码>不应该.

I'm trying to create a function in Z3 that is transitive but not reflexive. I.e. if (transitive a b) and (transitive b c)hold then (transitive a c) should hold, but (transitive a a) should not.

我尝试按照以下方式进行,进行了 5 次测试".第一个符合我的预期,但第二个失败并导致 unknown.

I've tried to do it the following way, with 5 "tests". The first does what I expect, but the second one fails and results in unknown.

(declare-datatypes () ((T T1 T2 T3)))

(declare-fun f (T T) Bool)
(assert(f T1 T2))
(assert(f T2 T3))

; Make sure that f is not reflexive
(assert
  (forall ((x T))
    (not (f x x))))

; Now we create the transitivity function ourselves
(define-fun-rec transitive ((x T) (y T)) Bool
    (or 
        (f x y)
        (exists ((z T))
            (and 
                (f x z)
                (transitive z y)))))

; This works and gives sat
(push)
(assert (not (transitive T1 T1)))
(assert (not (transitive T2 T2)))
(assert (not (transitive T3 T3)))
(check-sat)
(pop)

; This fails with "unknown" and the verbose flag gives: (smt.mbqi "max instantiations 1000 reached")
(push)
(assert 
    (forall ((x T))
        (not (transitive x x))))
(check-sat)
(pop)

我的问题是:第二次测试与第一次测试有何不同?为什么最后一个给出 unknown,而前一个工作正常?

My question is: how does the second test differ from the first? Why does the last one give unknown, whereas the one before that works just fine?

推荐答案

这里的详细"消息是一个提示.mbqi 代表基于模型的量词实例化.它是一种在 SMT 求解中处理量词的方法.在第一种情况下,MBQI 设法找到模型.但是你的 transitive 函数对于 MBQI 来说太复杂了,因此它放弃了.增加限制不太可能解决问题,也不是一个长期的解决方案.

The "verbose" message is a hint here. mbqi stands for model-based-quantifier-instantiation. It's a method of dealing with quantifiers in SMT solving. In the first case, MBQI manages to find a model. But your transitive function is just too complicated for MBQI to handle, and thus it gives up. Increasing the limit will not likely address the problem, nor it's a long term solution.

长话短说,递归定义很难处理,带量词的递归定义更难.逻辑变得半可判定,而您受启发式的支配.即使你找到了一种方法让 z3 为此计算模型,它也会很脆弱.这类问题不适合 SMT 解决;最好使用适当的定理证明器,如 Isabelle、Hol、Coq、Lean.Agda 等.几乎所有这些工具都提供了将子目标分派给 SMT 求解器的策略",因此您可以两全其美.(当然,你失去了完全自动化,但有了量词,你不能期待更好.)

Short story long, recursive definitions are difficult to deal with, and recursive definitions with quantifiers are even harder. The logic becomes semi-decidable, and you're at the mercy of heuristics. Even if you found a way to make z3 compute a model for this, it would be brittle. These sorts of problems are just not suitable for SMT solving; better use a proper theorem prover like Isabelle, Hol, Coq, Lean. Agda, etc. Almost all these tools offer "tactics" to dispatch subgoals to SMT solvers, so you have the best of both worlds. (Of course you lose full automation, but with quantifiers present, you can't expect any better.)

这篇关于在 Z3 中创建传递而不是自反函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆