评估 OCaml 中所有可能的解释
我需要评估两个公式是否等价。这里我用一个简单的公式定义,就是前缀公式。
例如,And(Atom("b"), True)
表示 b 和 true
,而 And(Atom("b"), Or(Atom( "c"), Not(Atom("c"))))
表示 (b 和 (c 或 not c))
我的想法很简单,获取所有原子,应用每个组合(对于我的情况,我将有 4 种组合,即真-真、真-假、假-真和假-假)。问题是,我不知道如何创建这些组合。
现在,我已经知道如何获得所有涉及的原子,所以如果有 5 个原子,我应该创建 32 种组合。如何在 OCaml 中做到这一点?
I need to evaluate whether two formulas are equivalent or not. Here, I use a simple definition of formula, which is a prefix formula.
For example, And(Atom("b"), True)
means b and true
, while And(Atom("b"), Or(Atom("c"), Not(Atom("c"))))
means (b and (c or not c))
My idea is simple, get all atoms, apply every combination (for my cases, I will have 4 combination, which are true-true, true-false, false-true, and false-false). The thing is, I don't know how to create these combinations.
For now, I have known how to get all involving atoms, so in case of there are 5 atoms, I should create 32 combinations. How to do it in OCaml?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好的,所以您需要的是一个函数
combinations n
,它将生成长度n
的所有布尔组合;让我们将它们表示为布尔值列表的列表(即,变量的单个赋值将是布尔值列表)。那么这个函数就可以完成这项工作:只有一个长度为
0
的空组合,并且n > 为 1。 0
我们生成n-1
的组合,并在它们前面加上false
和true
来生成长度为的所有可能组合>n
。您可以编写一个函数来打印此类组合,比方说:
然后使用: 进行测试
以获取:
Ok, so what you need is a function
combinations n
that will produce all the booleans combinations of lengthn
; let's represent them as lists of lists of booleans (i.e. a single assignment of variables will be a list of booleans). Then this function would do the job:There is only one empty combination of length
0
and forn > 0
we produce combinations ofn-1
and prefix them withfalse
and withtrue
to produce all possible combinations of lengthn
.You could write a function to print such combinations, let's say:
and then test it all with:
to get:
如果您将布尔值列表视为固定长度的位列表,那么有一个非常简单的解决方案:计数!
如果您想要 4 个布尔值的所有组合,请从 0 数到 15 (2^4 - 1)——然后将每一位解释为布尔值之一。为简单起见,我将使用 for 循环,但您也可以通过递归来完成:
当然,您可以使循环体更加通用,以便它根据上面给出的大小创建布尔值列表/数组ETC。;
关键是您可以通过枚举您正在搜索的所有值来解决这个问题。如果是这种情况,请计算所有整数直至您的问题大小。编写一个函数,从整数生成原始问题的值。把它们放在一起。
此方法的优点是您不需要在开始计算之前首先创建所有组合。对于大问题,这很可能会拯救你。对于相当小的 size=16,您将需要 65535 * sizeof(type) 内存 - 并且随着大小呈指数增长!上述解决方案仅需要 sizeof(type) 的恒定内存量。
为了科学的缘故:你的问题是NP完全,所以如果你想要精确的解决方案,它将需要指数时间。
If you think of a list of booleans as a list of bits of fixed length, there is a very simple solution: Count!
If you want to have all combinations of 4 booleans, count from 0 to 15 (2^4 - 1) -- then interpret each bit as one of the booleans. For simplicity I'll use a for-loop, but you can also do it with a recursion:
Of course you can make the body of the loop more general so that it e.g. creates a list/array of booleans depending on the size given above etc.;
The point is that you can solve this problem by enumerating all values you are searching for. If this is the case, compute all integers up to your problem size. Write a function that generates a value of your original problem from an integer. Put it all together.
This method has the advantage that you do not need to first create all combinations, before starting your computation. For large problems this might well save you. For rather small size=16 you will already need 65535 * sizeof(type) memory -- and this is growing exponentially with the size! The above solution will require only a constant amount of memory of sizeof(type).
And for science's sake: Your problem is NP-complete, so if you want the exact solution, it will take exponential time.