【问题标题】:How to transfer constraints of string type to z3 solver expr in C++?如何在 C++ 中将字符串类型的约束转移到 z3 求解器 expr?
【发布时间】:2021-03-11 12:58:36
【问题描述】:

例如,我有一个约束:“(number

context c;
expr number= c.int_const(number);
expr name = c->string_val(name.c_str());
expr constrain = ***procedure***("(number < 10) && (name == \"hello\")");

我该如何实现这个procedure()

Use a C++ string in z3::expr? 中有一个不完整且未经验证的答案,我仍然不知道如何实现它?

我非常渴望并感谢您的帮助!谢谢!

【问题讨论】:

    标签: c++ string api z3


    【解决方案1】:

    试试:

    #include <z3++.h>
    
    using namespace z3;
    using namespace std;
    
    int main ()
    {
      context c;
      expr number = c.int_const("number");
      expr name   = c.constant(c.str_symbol("name"), c.string_sort());
      expr hello  = c.string_val("hello");
    
      expr constraint = number < 10 && name == hello;
    
      solver s(c);
      s.add(constraint);
      cout << s.check() << "\n";
      cout << s.get_model() << "\n";
    
      return 0;
    };
    

    假设您将上述内容放在名为a.cpp 的文件中,您可以像这样编译它:

    $ g++ -std=c++11 a.cpp -l z3
    

    当运行时,它会产生:

    sat
    (define-fun number () Int
      9)
    (define-fun name () String
      "hello")
    

    使用更高级别的 API

    您无疑已经注意到,使用 C/C++ 对 z3 进行编程非常冗长且极易出错。除非您有其他使用 C/C++ 的理由,否则我建议您使用更高级别的 API,例如 Python 或 Haskell,这在很大程度上简化了 z3 中的编程。

    Python

    例如,您可以像这样在 Python 中编写问题代码:

    from z3 import *
    
    number = Int('number')
    name   = String('name')
    
    s = Solver()
    s.add(number < 10, name == "hello")
    print(s.check())
    print(s.model())
    

    制作:

    sat
    [number = 9, name = "hello"]
    

    哈斯克尔

    在 Haskell 中,它看起来像:

    import Data.SBV
    
    ex :: IO SatResult
    ex = sat $ do number <- sInteger "number"
                  name   <- sString  "name"
    
                  constrain $ number .< 10 .&& name .== literal "hello"
    

    制作:

    *Main> ex
    Satisfiable. Model:
      number =       9 :: Integer
      name   = "hello" :: String
    

    总结

    长话短说,如果您可以使用更高级别的接口,最好避免使用 C/C++ 对 z3 进行编程(尽管完全有可能)。如果一定要坚持C/C++,一定要学习API:https://z3prover.github.io/api/html/namespacez3.html

    【讨论】:

    • 感谢您的回答!但这并不能解决我的问题。在我遇到的场景中,约束是变量。程序应该迭代处理不同的输入约束,所以我必须使用一个字符串变量来接收约束。现在我不知道如何将这个字符串类型的约束转移到上下文表达式?
    • 另外,我想先试试c++中的z3,因为它比python中的效率更高
    • Z3 不知道或不支持您在字符串中使用的语言。您要么必须教它该语言(请参阅@alias 的答案),要么必须使用其他语言(例如 SMT2)。
    • 正如@ChristophWintersteiger 提到的(他是z3 的合著者,所以那里有权威!),z3 怎么知道你的语言是什么意思? parse_string 不会帮助你,即使你坚持使用那种语言的 SMTLib,因为据我所知,它不会为你创建变量;您必须提供所有上下文信息。您确实需要为您的“字符串语言”(无论它是什么)编写一个解析器并将其转换为 z3 调用。
    • Re: 效率:我仍然强烈建议使用 Python/Haskell,甚至 Java 而不是 C。一方面,您从 c/c++ 获得的“效率/”确实被高估了:高级语言中的接口已经走了很长一段路,虽然有一些开销,但如果它对大多数项目都很重要,我会感到惊讶:求解器时间应该主导所有这些。其次,对于解析/表示/编码您的原始问题(无论它可能是什么)的“额外”工作增加了更多的复杂性,以至于您不只是想为此使用低级 API。这是我的经验。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多