arxpy.bitvector.context module

Provide context managers to modify the default behaviour.

class arxpy.bitvector.context.StatefulContext(new_context)[source]

Bases: contextlib.AbstractContextManager

Base class for context managers with history.

class arxpy.bitvector.context.Cache(new_context)[source]

Bases: arxpy.bitvector.context.StatefulContext

Control the Cache context.

Control whether or not the cache is used operating with bit-vectors. By default, the cache is enabled.

Note that the Cache context cannot be enabled when the Simplification or Evaluation context are disabled.

class arxpy.bitvector.context.Simplification(new_context)[source]

Bases: arxpy.bitvector.context.StatefulContext

Control the Simplification context.

Control whether or not bit-vector expressions are automatically simplified. By default, automatic simplification is enabled.

>>> from arxpy.bitvector.core import Variable
>>> from arxpy.bitvector.context import Simplification
>>> x, y = Variable("x", 8), Variable("y", 8)
>>> (x | y) | x
x | y
>>> with Simplification(False):
...     expr = (x | y) | x
>>> expr
x | x | y

When the Simplification context is disabled, the Cache context is also disabled.

Note

Disabling Simplification and Validation speeds up non-symbolic computations with bit-vectors.

class arxpy.bitvector.context.Evaluation(new_context)[source]

Bases: arxpy.bitvector.context.StatefulContext

Control the Evaluation context.

Control whether or not bit-vector operations are evaluated. By default, bit-vector expressions are evaluated.

>>> from arxpy.bitvector.core import Constant
>>> from arxpy.bitvector.context import Evaluation
>>> Constant(1, 8) + Constant(1, 8)
0x02
>>> with Evaluation(False):
...     expr = Constant(1, 8) + Constant(1, 8)
>>> expr
0x01 + 0x01
>>> expr.doit()
0x02

When the Evaluation context is disabled, the Simplification and Cache contexts are also disabled.

class arxpy.bitvector.context.Validation(new_context)[source]

Bases: arxpy.bitvector.context.StatefulContext

Control the Validation context.

Control whether or not arguments of bit-vector operators are validated. By default, validation of arguments is enabled.

Note that when it is disabled, Automatic Constant Conversion is no longer available (see Operation).

>>> from arxpy.bitvector.core import Constant
>>> from arxpy.bitvector.context import Validation
>>> Constant(1, 8) + 1
0x02
>>> with Validation(False):
...     Constant(1, 5) + 2
Traceback (most recent call last):
 ...
AttributeError: 'int' object has no attribute 'width'

Note

Disabling Simplification and Validation speeds up non-symbolic computations with bit-vectors.

class arxpy.bitvector.context.Memoization(new_context)[source]

Bases: arxpy.bitvector.context.StatefulContext

Control the Memoization context.

Control whether or not bit-vector operations are evaluated in the memoization mode. By default, it is disabled.

In the memoization mode, the result of each bit-vector operation is stored in a table (with an unique identifier). When the same inputs occurs again, the result is retrieved from the table. See also Memoization.

Note that in the memoization mode, bit-vector operations don’t return the actual values but their identifiers in the memoization table. The actual values can be obtained from the MemoizationTable.

>>> from arxpy.bitvector.core import Variable
>>> from arxpy.bitvector.context import Memoization, MemoizationTable
>>> x, y, z = Variable("x", 8), Variable("y", 8), Variable("z", 8),
>>> ~((x + y) ^ (z & y))
~((x + y) ^ (y & z))
>>> lut = MemoizationTable()
>>> with Memoization(lut):
...     expr = ~((x + y) ^ (z & y))
>>> expr
x3
>>> lut
MemoizationTable([(x0, x + y), (x1, y & z), (x2, x0 ^ x1), (x3, ~x2)])

The Memoization context is useful to efficiently compute large symbolic expressions since the identifiers are used instead of the full expressions.

>>> from arxpy.bitvector.core import Variable
>>> from arxpy.bitvector.context import Memoization, MemoizationTable
>>> x = Variable("x", 8)
>>> expr = x
>>> for i in range(3): expr += expr
>>> expr
x + x + x + x + x + x + x + x
>>> lut = MemoizationTable()
>>> with Memoization(lut):
...     expr = x
...     for i in range(3): expr += expr
>>> expr
x2
>>> lut  
MemoizationTable([(x0, x + x), (x1, x0 + x0), (x2, x1 + x1)])

When the Memoization context is enabled, the Simplification and Cache contexts are disabled.

class arxpy.bitvector.context.MemoizationTable(id_prefix='x')[source]

Bases: collections.abc.MutableMapping

Store bit-vector expressions with unique identifiers.

The MemoizationTable is a dictionary-like structure (implementing the usual methods of a dictionary and some additional methods) used for evaluating bit-vector operations in the memoization mode (see Memoization).

>>> from arxpy.bitvector.core import Variable
>>> from arxpy.bitvector.context import Memoization, MemoizationTable
>>> x, y = Variable("x", 8), Variable("y", 8)
>>> lut = MemoizationTable()
>>> with Memoization(lut):
...     expr = ~(x + y)
>>> lut
MemoizationTable([(x0, x + y), (x1, ~x0)])
>>> lut[Variable("x0", 8)]
x + y
>>> lut.get_id(x + y)
x0
>>> lut.add_op(Variable("x1", 8) & Variable("z", 8))
x2
>>> lut
MemoizationTable([(x0, x + y), (x1, ~x0), (x2, x1 & z)])
>>> lut.replace_id(Variable("x0", 8), Variable("x_0", 8))
>>> lut
MemoizationTable([(x_0, x + y), (x1, ~x_0), (x2, x1 & z)])
add_op(expr)[source]

Add an bit-vector expression and return its identifier.

get_id(expr)[source]

Return the identifier of a bit-vector expression.

contain_op(expr)[source]

Check if the bit-vector expression is stored.

replace_id(old_id, new_id)[source]

Replace the old identifier by the given new identifier.

clear()[source]

Empty the table.

class arxpy.bitvector.context.NotEvaluation(new_context)[source]

Bases: arxpy.bitvector.context.StatefulContext

Control the NotEvaluation context.

Control whether or not some operations are not evaluated. By default, all operations are evaluated.

>>> from arxpy.bitvector.core import Constant
>>> from arxpy.bitvector.extraop import PopCount
>>> from arxpy.bitvector.context import NotEvaluation
>>> PopCount(Constant(0b010, 3) + Constant(0b001, 3))
0b10
>>> with NotEvaluation(PopCount):
...     expr = PopCount(Constant(0b010, 3) + Constant(0b001, 3))
>>> expr
PopCount(0b011)
>>> expr.doit()
0b10

When the NotEvaluation context is enable, the Cache is disabled.