Python 使用PyEDA访问布尔表达式的参数
我是Python的新手,我在玩,我的问题是:我有布尔表达式,比如Python 使用PyEDA访问布尔表达式的参数,python,Python,我是Python的新手,我在玩,我的问题是:我有布尔表达式,比如 Or(And(a,b),Not(b,c,d), ...) 我想访问布尔函数的参数Or,And,Not。可能吗?我试图使用模块检查,但什么也没有得到 我想访问布尔函数的参数,或者,而不是。。。可能吗?我试图使用模块inspect,但一无所获 此处不需要检查模块。调用和(a,b)-或为此编写a&b的结果是一个和对象,它打印为和(a,b)。它有一个args属性,可以为您提供参数列表: >>> a, b, c, d
Or(And(a,b),Not(b,c,d), ...)
我想访问布尔函数的参数Or,And,Not。可能吗?我试图使用模块检查,但什么也没有得到
我想访问布尔函数的参数,或者,而不是。。。可能吗?我试图使用模块inspect
,但一无所获
此处不需要检查
模块。调用和(a,b)
-或为此编写a&b
的结果是一个和对象,它打印为和(a,b)
。它有一个args
属性,可以为您提供参数列表:
>>> a, b, c, d = map(exprvar, 'abcd')
>>> e = Or(And(a,b), Not(b), c, d)
>>> e
Or(~b, c, d, And(a, b))
>>> e.args
(And(a, b), c, d, ~b)
>>> e.args[0].args
(a, b)
请注意,该订单可能与您最初发出的订单不同。由于或
等是可交换和关联的,因此顺序无关紧要,因此pyeda
不会保留它。事实上,它可以进行比重新排序更激进的转换
如果您想遍历整个表达式,您可能需要考虑使用<代码> toast<代码>,而不是递归地切换类型,并使用<代码> ARGs<代码>,但是:
>>> e.to_ast()
('or',
('and', ('var', ('b',), ()), ('var', ('a',), ())),
('var', ('c',), ()),
('var', ('d',), ()),
('not', ('var', ('b',), ())))
事实上,我想用args
做的任何事情都可以通过其他方式做得更好。如果您想递归地向下搜索以找到输入变量,那就是e.inputs
。如果你想要一个很好的人类可读的表示,那就是str(e)
。等等。PyEDA作者在这里
在一篇评论中,您说您希望转换CNF以供pycosat使用。我建议您只使用满足_one
方法,该方法使用PicoSAT SAT解算器(与pycosat使用的引擎相同)
快乐编程:)。你的函数看起来像什么?这类:和(或(a,b,c,d),或(a,~b,c,~d),或(~a,b,~c,d),或(~a,~b,~c,~d)),但可能要复杂得多。你这样做是为了什么?除了枚举最终输入、遍历表达式、生成用户友好的字符串或对表达式进行操作之外,很难想象还有什么其他用途,所有这些都有比迭代参数更简单、更惯用的解决方案。目的是翻译CNF表达式,以便在pycosat请求中使用数字(+5表示变量#5为真或-2表示变量#2为假)。@joel76:那么我认为你的做法是错误的,但是如果没有更多的代码,很难提出任何具体的建议。谢谢,这正是我需要的!谢谢你的建议,pyeda的使用是我项目的下一步。我已经完成了第一步,使用pycosat解算器解数独(非常快:0,03s表示“硬”数独!)我现在将尝试使用pyeda bdd解数独。我用clpb在Prolog中实现了这一点,看到pyeda bdd与SWI Prolog clpb库的比较非常有趣。
>>> from pyeda.inter import *
>>> a, b, c, d = map(exprvar, 'abcd')
>>> F = OneHot(a, b, c, d)
>>> F.is_cnf()
True
>>> F.satisfy_one()
{c: 0, a: 0, b: 0, d: 1}
# If you want to see the numeric encoding given to the SAT solver:
>>> litmap, nvars, clauses = F.encode_cnf()
>>> clauses
{frozenset({1, 2, 3, 4}),
frozenset({-4, -3}),
frozenset({-4, -2}),
frozenset({-4, -1}),
frozenset({-3, -1}),
frozenset({-3, -2}),
frozenset({-2, -1})}