在一个输出的逻辑电路中,如何得到产生一定输出的所有输入组合?(无蛮力)[已结束]

In logic circuit with one output , how to get all combination of input which produces a certain output ? (Without brute forcing) [closed]

提问人:i'm ashamed with what i asked 提问时间:11/2/2021 最后编辑:i'm ashamed with what i asked 更新时间:11/4/2021 访问量:394

问:


想改进这个问题吗?通过编辑这篇文章来更新问题,使其仅关注一个问题。

2年前关闭。

假设我有一个逻辑电路,逻辑电路由输入、静态位值(0或1)和逻辑门组成。逻辑电路中的所有逻辑门都接受两个输入并产生一个输出(例如,1 和 0 = 0)。逻辑电路仅产生一个输出(0或1)。

逻辑电路仅由三个基本逻辑门(NOT、或、AND)组成。

如何获得逻辑电路中导致逻辑电路产生特定输出的所有输入组合?例如,我想得到所有输入的组合,这导致逻辑电路产生输出 1。

我知道我可以通过蛮力来做到这一点,尝试输入的每一种组合。但是,对于大量输入,蛮力方法可能不可行。所以我想知道我是否可以在没有蛮力方法的情况下做到这一点?

我用python编写了一些逻辑电路的脚本实现。但它是一堵代码墙(超过一百行),可能不是世界上最好的逻辑电路实现。所以我觉得没有必要在这里发布代码。但是,如果需要我的代码,请在评论中告诉我,如果我看到足够的需求,那么我会在这里发布。

python 运算符 逻辑 电路

评论

0赞 Ulises Bussi 11/2/2021
大电路是什么意思?我认为您有 2 个选择,尝试蛮力或尝试做一些向后分析。最后一个可能非常困难,我不知道你是否可以利用一些现有的库来让你构建一些管道来工作
0赞 i'm ashamed with what i asked 11/2/2021
@UlisesBussi大电路意味着逻辑电路包含大量的逻辑门和输入
0赞 Charles Duffy 11/2/2021
您可以将逻辑编程系统视为一个起点。这些是如何开发的,是书籍中真正写的话题 - 对于Stack Overflow问题来说,它太宽泛了。但是,如果你能在 prolog 或其他为归纳逻辑构建的系统中对逻辑进行建模,它就可以找到一条最佳路径来计算满足你的谓词的输入。
1赞 Charles Duffy 11/2/2021
...回复:广度,实际上问题在于,最适合解决这个问题的工具是在一整个学期的课程中教授的。我们不能用 SO 答案教他们;要涵盖的内容实在太多了。
1赞 Charles Duffy 11/2/2021
(顺便说一句,Clojure 的 core.logic 是我个人最有经验的特定现代逻辑编程系统;minikanren.org 是它所模仿的基础,后者的网站有书籍/论文/等的链接)。

答:

1赞 alias 11/3/2021 #1

这最好使用 SAT/SMT 求解器来完成,例如 Microsoft 的 z3:https://github.com/Z3Prover

它可以从 python 编写脚本,您可以要求它查找为您提供所需输出的输入值。下面是一个非常简单的示例:

from z3 import *

in1, in2 = Bools("in1 in2")
out = Bool("out")

s = Solver()

# Encode your circuit here. We'll just do out = in1 \/ in2
s.add(out == Or(in1, in2))

# require output to be true.
# You could also set it to False, if that's what you're looking for.
s.add(out == True)

print(s.check())
print(s.model())

当我运行它时,我得到:

sat
[in1 = True, in2 = False, out = True]

第一行说,这意味着问题确实是可以解决的。(否则你会得到 。satunsat

第二行是用于获取此所需输出的赋值。您还可以通过编程来枚举所有可能的解决方案,当然,如果有很多解决方案,这可能会导致很长的运行循环。

有关如何对电路进行编码以使其适合此类分析的详细信息,您应该查找 Tseytin Encoding: https://en.wikipedia.org/wiki/Tseytin_transformation

我应该强调的是,如果你试图“逆向工程”一个单向函数(即,如果你的电路正在计算某种加密算法,如AES/DES,或者进行类似SHA的散列),所有这些都将是徒劳的。目前还没有SAT求解器(或任何其他工具)可以处理这类问题。我在这里谈论的电路类型是常规函数,例如算术或其他常规数据路径。你从来没有说过你正在处理什么样的电路,但请记住这一点。

评论

0赞 i'm ashamed with what i asked 11/3/2021
我查了一下文档,库使用递归。我将要使用的逻辑电路是脚本生成的,并且会非常大。库很可能会因堆栈溢出错误而崩溃。我可以尝试盲目猜测我需要的堆栈大小以防止堆栈溢出,但是我创建的逻辑电路的数量是脚本生成的,因此我找不到猜测堆栈大小的好方法。
0赞 alias 11/3/2021
SAT 求解器经过精心设计,可以处理非常大的输入。我怀疑只要你练习共同的良好编码风格,这就会成为一个问题。试一试,看看你发现了什么。如果尺寸确实是一个问题,您还可以使用所谓的 DIMACS 格式,z3 开箱即用且更紧凑:cs.utexas.edu/users/moore/acl2/manuals/current/manual/...