Java ANTLR-布尔可满足性

Java ANTLR-布尔可满足性,java,boolean,logic,antlr,satisfiability,Java,Boolean,Logic,Antlr,Satisfiability,我有一个ANTLR表达式解析器,它可以使用生成的访问者计算(a&(B | C))形式的表达式。A、B和C可以取两个值中的任何一个true或false。然而,我面临着一个挑战,即找到表达式为真的a、B和C的所有组合。我试着用下面的方法来解决这个问题 计算3个变量的表达式,每个变量取true和false 这是8个组合,因为2^3是8 我评估给出的值,比如000、001、010。。。。。。。对变量进行修改,并使用访问者进行评估 虽然这是可行的,但随着变量数量的增加,这种方法会变得计算密集。因此,对于具

我有一个ANTLR表达式解析器,它可以使用生成的访问者计算(a&(B | C))形式的表达式。A、B和C可以取两个值中的任何一个
true
false
。然而,我面临着一个挑战,即找到表达式为真的a、B和C的所有组合。我试着用下面的方法来解决这个问题

  • 计算3个变量的表达式,每个变量取true和false
  • 这是8个组合,因为2^3是8
  • 我评估给出的值,比如000、001、010。。。。。。。对变量进行修改,并使用访问者进行评估

  • 虽然这是可行的,但随着变量数量的增加,这种方法会变得计算密集。因此,对于具有20个变量的表达式,需要进行1048576次计算。我如何优化这种复杂性,以便获得所有真实的表达式?我希望这属于它的范畴。如果您被限制为20-30个变量,您可以简单地对所有组合进行强制试验。如果每次尝试需要100ns(即500条机器指令),它将在大约100秒内运行。那比你快

    如果你想解决比这更大的方程,你需要建立一个真正的约束解算器

    编辑因OP评论关于尝试并行以加速暴力强迫答案的Java程序:

    我不知道你怎么表达你的布尔公式。对于暴力,您不想解释公式树或做其他缓慢的事情

    一个关键技巧是快速计算布尔公式。对于大多数编程语言,您应该能够手动将公式编码为该语言中的本机表达式进行测试,将其包装在嵌套循环中并编译整个内容,例如

    A=false;
    do {
         B=false;
         do {
              C= false;
              do { 
                   if (A & (B | C) ) { printf (" %b %b %b\n",A,B,C);
                   C=~C;
                 } until C==false;
              B=~B;
            } until B==false;
         A=~A;
       } until A==false;
    
    经过编译(甚至被Java JITted),我希望Inner循环在每个布尔操作中使用1-2条机器指令,只涉及寄存器或单个缓存行,加上2条用于循环。 对于大约42条机器指令的20个变量,甚至比我在第一段中的粗略估计还要好

    如果坚持的话,可以将最外层的循环(3或4)转换为并行线程,但如果您只需要print语句,我看不出这在实用性方面有什么实际意义


    如果您有许多这样的公式,那么很容易编写一个代码生成器,从公式的任何表示形式(例如,ANTLR解析树)生成这些公式。

    谢谢您的回答。即使对于20个变量,我也对Java程序进行了多线程处理,以更快地获得结果。有开源约束求解库吗?开源约束求解器:这看起来很有希望:非常感谢!!GeCod似乎是一个C++库。我遇到的java库之一是[SAT4j]()。然而,我对这些都是新手,必须看看如何使它们适应我的Java应用程序。文档中说,在使用SAT解算器之前,必须将布尔表达式转换为CNF形式。希望我需要一段时间才能习惯使用搜索产生的[Choco solver]()的惯例,这对我来说似乎是一个有希望的惯例。它使用整数和布尔约束。但我的业务规则也会检查字符串。。我被困在如何将业务问题转化为约束问题上。如果有任何帮助,我们将不胜感激。关于如何使用字符串约束解算器的问题与此不同。你应该开始一个新的问题,并确保你提供了比“检查字符串”更多的细节。如果你在这里留下这个问题的链接,我一定会看的。这是一个非常接近的答案,仍然需要我这边的研究。我在等着看是否会有更多的答案