我正在通过一份许可指南,将产品系列表示为行李模型,其中也会考虑事件以提出BDD。
我想在我的问题中加入类似的步骤。文字说
如果我们采用bag-model,除了处理功能的重复之外,实现类似于set-model实现。 ROBDD不允许重复节点。为了处理BDD本身中特征的出现次数,我们设计了 编码它的发生级别。我们编码这个数字二进制。例如,如果我们有一个具有3个特征的产品:x,y和z,以及 一个特征的最大出现次数为7,那么我们需要三个二进制位来对其进行编码。让产品系列W有一个 产品具有三个x功能和六个z功能以及零y功能。我们的产品系列包含由BDD代表的产品Pt 在图3.7中。代表此包的BDD以与设定模型类似的方式描述产品。但是,我们编码 在包含bl,b2和b3的节点级别中出现。我们在图3.7中读到,如果此产品中存在x,那么我们必须这样做 选择bl和b2,但不选择b3。这是分别代表b3,b2和bb的二进制代码011,其携带三个for的出现 X。类似地,对于y存在于此产品中,我们得到二进制出现编码为000,即0次出现。对于z,我们得到了 二进制出现110,其中包含数字6。
因此,对于产品族Z = {{(x,3),(y,0),(z,6)}},相应的bdd将为 - >
对于产品系列W = {{(x,3),(y,1),(z,7)}} BDD将是
但是他是如何提出这些BDD的,必须有一些BDD的基本公式。能否帮助我了解如何为特定家庭达成相同的公式,以便我可以在其他用例中进一步使用它。感谢。
答案 0 :(得分:0)
bag是具有多次出现的元素的集合。 Bags
中的标准模块Temporal Logic of Actions (TLA+)包含与行李相对应的数学定义。
要从binary decision diagram的图形转换为公式,我使用下面的代码。来自OP的第一个BDD的答案是:
/\ b \in 0 .. 7
/\ x \in 0 .. 1
/\ y \in 0 .. 1
/\ z \in 0 .. 1
/\ \/ (b = 0) /\ (y = 1)
\/ (b = 3) /\ (x = 1)
\/ (b = 6) /\ (z = 1)
此表达式以TLA +编写。
上面实际上不是一个包,因为一个包至少包含一个每个元素的出现(所以y
没有出现意味着这不是包;省略y
应将其转换为与行李相对应的BDD。一个包是否适合产品系列是一个单独的问题,我不会讨论。
您可以调整代码以确认第二张图中显示的BDD公式。
以下代码使用Python包omega == 0.1.1
和dd == 0.5.1
(免责声明:我是他们的作者)。这些工作在纯Python中,这对于这个大小的BDD就足够了(否则构建dd.cudd
将允许你使用CUDD
- 当然这对于小到足以手写的BDD没有区别。
#!/usr/bin/env python
"""Convert from a BDD figure to a formula."""
from omega.symbolic import fol
# "bare" BDDs (without integers) can be used also
# via the package `dd`
# from dd import autoref as _bdd
# bdd = _bdd.BDD()
ctx = fol.Context()
ctx.declare(x=(0, 1), y=(0, 1), z=(0, 1), b=(0, 7))
bdd = ctx.bdd
# bdd.declare('x', 'y', 'z', 'b1', 'b2', 'b3')
# level of b3
u1 = bdd.add_expr('b_2')
u2 = bdd.add_expr('~ b_2')
# level of b2
u3 = bdd.add_expr('ite(b_1, {u}, False)'.format(u=u1))
u4 = bdd.add_expr('ite(b_1, False, {u})'.format(u=u2))
u5 = bdd.add_expr('ite(b_1, {u1}, {u2})'.format(u1=u1, u2=u2))
u6 = bdd.add_expr('ite(b_1, {u2}, False)'.format(u2=u2))
# level of b1
u7 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low=u3, high='False'))
u8 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low=u4, high='False'))
u9 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low=u5, high='False'))
u10 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low=u3, high=u6))
u11 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low='False', high=u6))
u12 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low=u4, high=u6))
u13 = bdd.add_expr('ite(b_0, {high}, {low})'.format(
low=u5, high=u6))
# level of z
u14 = bdd.add_expr('ite(z_0, {high}, {low})'.format(
low='False', high=u7))
u15 = bdd.add_expr('ite(z_0, {high}, {low})'.format(
low=u8, high=u9))
u16 = bdd.add_expr('ite(z_0, {high}, {low})'.format(
low=u11, high=u10))
u17 = bdd.add_expr('ite(z_0, {high}, {low})'.format(
low=u12, high=u13))
# level of y
u18 = bdd.add_expr('ite(y_0, {high}, {low})'.format(
low=u14, high=u15))
u19 = bdd.add_expr('ite(y_0, {high}, {low})'.format(
low=u16, high=u17))
# level of x
from_fig = bdd.add_expr('ite(x_0, {high}, {low})'.format(
low=u18, high=u19))
# the variable order from the first figure in the OP
levels = dict(x_0=0, y_0=1, z_0=2, b_0=3, b_1=4, b_2=5)
fol._bdd.reorder(bdd, levels)
bdd.dump('foo_1.png', [from_fig])
# a better variable order
levels = dict(b_0=0, b_1=1, b_2=2, x_0=3, y_0=4, z_0=5)
fol._bdd.reorder(bdd, levels)
bdd.dump('foo_2.png', [from_fig])
# Create the BDD directly from an expression
s = '''
\/ (b = 3 /\ x = 1)
\/ (b = 0 /\ y = 1)
\/ (b = 6 /\ z = 1)
'''
from_formula = ctx.add_expr(s)
assert from_formula == from_fig
# print a minimal formula in disjunctive normal form
# use this to covert BDDs to expressions
print(ctx.to_expr(from_fig, show_dom=True))
可以使用pip
安装依赖项:
pip install dd==0.5.1
pip install omega==0.1.1
通过重新排序上述代码中的变量级别,我们可以获得更小的(RO)BDD:
上述BDD使用negated edges表示,详见tutorial on BDDs。