【问题标题】:Evaluation of a logical formula at many values in Z3在 Z3 中对多个值的逻辑公式进行评估
【发布时间】:2012-05-19 22:52:20
【问题描述】:

我需要使用 Z3 针对各种变量值评估表达式的值。 我知道 Z3 是一个可满足性检查器,但 model.Eval(Args) 会导致对模型生成的变量值的表达式进行评估。

那么我们是否可以迭代各种值来评估表达式。

示例:p 和 q 在所有可能的 p 和 q 值(p,q 为布尔值)

所以在某种意义上,使用某种递归或迭代来创建一个真值表。 Z3有没有办法做到这一点?

对 C# API 的帮助会更好。

谢谢

【问题讨论】:

  • 我已经要求用户输入一个逻辑表达式,并使用 Z3 通过检查其否定的可满足性来检查它是否是重言式。现在我希望用户看到表达式的计算结果总是为真,因此它是重言式,如果不是重言式,那么向用户显示它的计算结果并不总是为真,因此它不是重言式。

标签: c# z3


【解决方案1】:

您可以考虑 C# API 中的方法Substitute。它可用于用值替换 pq 等常量。它还在应用替换后简化/评估公式。

这是一个使用 Substitute 的小型 C# 示例(来自我们的回归套件):

using Microsoft.Z3;
using System;
using System.Collections.Generic;

class Test
{
    public void Run()
    {
        Dictionary<string, string> cfg = new Dictionary<string, string>() { 
            { "AUTO_CONFIG", "true" } };

        using (Context ctx = new Context(cfg))
        {
            IntExpr x = ctx.MkIntConst("x");
            IntExpr y = ctx.MkIntConst("y");

            FuncDecl f = ctx.MkFuncDecl("f", new Sort[] { ctx.IntSort, ctx.IntSort }, ctx.IntSort);
            FuncDecl g = ctx.MkFuncDecl("g", new Sort[] { ctx.IntSort }, ctx.IntSort);
            Expr n = f[f[g[x], g[g[x]]], g[g[y]]];

            Console.WriteLine(n);

            Expr nn = n.Substitute(new Expr[] { g[g[x]], g[y] }, 
                                   new Expr[] { y, ctx.MkAdd(x, ctx.MkInt(1)) } );

            Console.WriteLine(nn);

            Console.WriteLine(n.Substitute(g[g[x]], y));
        }
    }
}

当然,您必须编写一个循环来遍历所有可能的值。 在 Python 中,您可以使用列表推导:http://rise4fun.com/Z3Py/56 另一种选择是使用方法Simplify。此方法可用于评估不包含未解释符号的公式,例如 pq。 这是 Python 中的另一个示例:http://rise4fun.com/Z3Py/PC 我使用 Python 是因为我们不支持在浏览器中运行 C# 示例。 请注意,C# 中的 Z3 API 包含 Python 的所有功能。

最后,另一种可能性是枚举模型。 通过这样做,您基本上生成了满足公式的所有 pq 值(即,使其为真)。这个想法是添加阻止当前模型的新约束,然后再次求解。这是 Python 中的一个小脚本: http://rise4fun.com/Z3Py/PDJ

约束block 用于阻止当前模型。如果我们取消注释print block,我们还可以为Z3生产的每个模型打印它。当然,如果存在满足以下公式的无限模型,则此方法不会终止,如下例所示: http://rise4fun.com/Z3Py/X0l

这些示例可以用 C# 编码。下面是一个 C# 示例,演示了如何迭代模型中的常量(和函数)并获得它们的解释:

using Microsoft.Z3;
using System;

class Test
{

    public void Run()
    {        
        using (Context ctx = new Context())
        {
            Sort U = ctx.MkUninterpretedSort("U");
            FuncDecl f = ctx.MkFuncDecl("f", U, U);
            Expr a = ctx.MkConst("a", U);
            Expr b = ctx.MkConst("b", U);
            Expr c = ctx.MkConst("c", U);

            Solver s = ctx.MkSolver();
            s.Assert(ctx.MkEq(f[f[a]], b),
                     ctx.MkNot(ctx.MkEq(f[b], c)),
                     ctx.MkEq(f[c], c));
            Console.WriteLine(s.Check());
            Model m = s.Model;
            foreach (FuncDecl d in m.Decls)
                if (d.DomainSize == 0)
                    Console.WriteLine(d.Name + " -> " + m.ConstInterp(d));
                else 
                    Console.WriteLine(d.Name + " -> " + m.FuncInterp(d));

            Console.WriteLine(m.NumSorts);
            Console.WriteLine(m.Sorts[0]);

            foreach(Sort srt in m.Sorts)
                Console.WriteLine(srt);

            foreach (Expr v in m.SortUniverse(U))
                Console.WriteLine(v);
        }
    }
}

【讨论】:

  • 对不起!这对您来说可能看起来很愚蠢,但我收到一个错误“错误 1 ​​'Microsoft.Z3.Context' 不包含 'MkUninterpretedSort' 的定义并且没有扩展方法 'MkUninterpretedSort' 接受类型为 'Microsoft.Z3.Context 的第一个参数” ' 可以找到(您是否缺少 using 指令或程序集引用?) C:\Users\Pulkit\Documents\Visual Studio 11\Projects\ConsoleApplication4\ConsoleApplication4\Program.cs 11 26 ConsoleApplication4 和类似的错误。我已经引用了所有 Dll 并将它们粘贴到 bin 和 bin/Debug 目录中。请指引我前进。
  • 这些示例适用于 Z3 4.0,它们基于新的 .NET API。您使用的是哪个版本?以下是新 API 的文档:research.microsoft.com/en-us/um/redmond/projects/z3/…
  • 我尝试添加对 z3-3.2 和 z3-4.0 的引用。没有工作!仍然感谢您的帮助>
  • 能编译Z3 4.0自带的C#例子吗?您是否尝试使用 Visual Studio 命令提示符?要编译使用 Z3 的文件 tst.cs,我使用以下命令行:csc /reference:[Z3_PATH]\bin\microsoft.z3.dll /out:tst.exe tst.cs
  • 不,它也不会在命令提示符下编译并给出相同的错误!!我确实包含了 Microsoft.z3.dll 作为参考
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 2016-05-03
  • 2013-08-25
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2014-05-19
相关资源
最近更新 更多