Skip to main content

A python library for manipulating sequential and-inverter gates.

Project description

py-aiger logo
pyAiger: A python library for manipulating sequential and combinatorial circuits.

Build Status codecov PyPI version License: MIT DOI

Table of Contents

About PyAiger

  1. Q: How is Py-Aiger pronounced? A: Like "pie" + "grrr".
  2. Q: Why python? Aren't you worried about performance?! A: No. The goals of this library are ease of use and hackability.
  3. Q: No, I'm really concerned about performance! A: This library is not suited to implement logic solvers. For everything else, such as the creation and manipulation of circuits with many thousands of gates in between solver calls, the library is really fast enough.
  4. Q: Where does the name come from? A: Aiger is a popular circuit format. The format is used in hardware model checking, synthesis, and is supported by ABC. The name is a combination of AIG (standing for And-Inverter-Graph) and the mountain Eiger.

Installation

If you just need to use aiger, you can just run:

$ pip install py-aiger

For developers, note that this project uses the poetry python package/dependency management tool. Please familarize yourself with it and then run:

$ poetry install

Usage

import aiger

x, y, z, w = aiger.atoms('x', 'y', 'z', 'w')

expr1 = z.implies(x & y)
expr2 = z & w

circ1 = expr1.with_output('z') \      # Get AIG for expr1 with output 'z'.
             .aig
circ2 = circ1 >> circ2                # Feed outputs of circ1 into circ2.

Boolean Expression DSL

While powerful, when writing combinatorial circuits, the Sequential Circuit DSL can be somewhat clumsy. For this common usecase, we have developed the Boolean Expression DSL. All circuits generated this way have a single output.

import aiger
x, y, z = aiger.atoms('x', 'y', 'z')
expr1 = x & y  # circuit with inputs 'x', 'y' and 1 output computing x AND y.
expr2 = x | y  # logical or.
expr3 = x ^ y  # logical xor.
expr4 = x == y  # logical ==, xnor.
expr5 = x.implies(y)
expr6 = ~x  # logical negation.
expr7 = aiger.ite(x, y, z)  # if x then y else z.

# Atoms can be constants.
expr8 = x & True  # Equivalent to just x.
expr9 = x & False # Equivalent to const False.

# Specifying output name of boolean expression.
# - Output is a long uuid otherwise.
expr10 = expr5.with_output('x_implies_y')
assert expr10.output == 'x_implies_y'

# And you can inspect the AIG if needed.
circ = x.aig

# And of course, you can get a BoolExpr from a single output aig.
expr10 = aiger.BoolExpr(circ)

Sequential Circuit DSL

import aiger
from aiger import utils

# Parser for ascii AIGER format.
aig1 = aiger.load(path_to_aig1_file.aag)
aig2 = aiger.load(path_to_aig2_file.aag)

Sequential composition

aig3 = aig1 >> aig2

Parallel composition

aig4 = aig1 | aig2

Circuits with Latches and Delayed Feedback

Sometimes one requires some outputs to be feed back into the circuits as time delayed inputs. This can be accomplished using the loopback method. This method takes in a variable number of dictionaries encoding how to wire an input to an output. The wiring dictionaries with the following keys and default values:

Key Default Meaning
input Input port
output Output port
latch input Latch name
init True Initial latch value
keep_output True Keep loopbacked output as output
# Connect output y to input x with delay, initialized to True.
# (Default initialization is False.)
aig5 = aig1.loopback({
  "input": "x", "output": "y",
})

aig6 = aig1.loopback({
  "input": "x", "output": "y",
}, {
  "input": "z", "output": "z", latch="z_latch",
  "init": False, "keep_outputs": False
})

Relabeling

There are two syntaxes for relabeling. The first uses indexing syntax in a nod to notation often used variable substition in math.

The syntax is the relabel method, which is preferable when one wants to be explicit, even for those not familar with py-aiger.

# Relabel input 'x' to 'z'.
aig1['i', {'x': 'z'}]
aig1.relabel('input', {'x': 'z'})

# Relabel output 'y' to 'w'.
aig1['o', {'y': 'w'}]
aig1.relabel('output', {'y': 'w'})

# Relabel latches 'l1' to 'l2'.
aig1['l', {'l1': 'l2'}]
aig1.relabel('latch', {'l1': 'l2'})

Evaluation

# Combinatoric evaluation.
aig3(inputs={'x':True, 'y':False})

# Sequential evaluation.
sim = aig3.simulate([{'x': 0, 'y': 0}, 
                    {'x': 1, 'y': 2},
                    {'x': 3, 'y': 4}])

# Simulation Coroutine
sim = aig3.simulator()  # Coroutine
next(sim)  # Initialize
print(sim.send({'x': 0, 'y': 0}))
print(sim.send({'x': 1, 'y': 2}))
print(sim.send({'x': 3, 'y': 4}))


# Unroll
aig4 = aig3.unroll(steps=10, init=True)

Useful circuits

# Fix input x to be False.
aig4 = aiger.source({'x': False}) >> aig3

# Remove output y. 
aig4 = aig3 >> aiger.sink(['y'])

# Create duplicate w of output y.
aig4 = aig3 >> aiger.tee({'y': ['y', 'w']})

Extra

aiger.common.eval_order(aig1)  # Returns topological ordering of circuit gates.

# Convert object into an AIG from multiple formats including BoolExpr, AIG, str, and filepaths.
aiger.to_aig(aig1)

Ecosystem

Stable

  • py-aiger-bv: Extension of pyAiger for manipulating sequential bitvector circuits.
  • py-aiger-cnf: BoolExpr to Object representing CNF. Mostly used for interfacing with py-aiger-sat.
  • py-aiger-past-ltl: Converts Past Linear Temporal Logic to aiger circuits.
  • py-aiger-coins: Library for creating circuits that encode discrete distributions.
  • py-aiger-sat: Bridge between py-aiger and py-sat.
  • py-aiger-bdd: Aiger <-> BDD bridge.
  • py-aiger-gridworld: Create aiger circuits representing gridworlds.
  • py-aiger-dfa: Convert between finite automata and sequential circuits.

Underdevelopment

Related Projects

  • pyAig: Another python library for working with AIGER circuits.

Citing

@misc{pyAiger,
  author       = {Marcell Vazquez-Chanlatte},
  title        = {mvcisback/py-aiger},
  month        = aug,
  year         = 2018,
  doi          = {10.5281/zenodo.1326224},
  url          = {https://doi.org/10.5281/zenodo.1326224}
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py-aiger-6.1.12.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_aiger-6.1.12-py3-none-any.whl (18.7 kB view details)

Uploaded Python 3

File details

Details for the file py-aiger-6.1.12.tar.gz.

File metadata

  • Download URL: py-aiger-6.1.12.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.8.5 Linux/5.4.0-58-generic

File hashes

Hashes for py-aiger-6.1.12.tar.gz
Algorithm Hash digest
SHA256 34e16beb54e13449fbd2f513ea5873872afdf530924240f1b7116915297d7a3e
MD5 e59b82d58089c9895bf83fcc0d516b08
BLAKE2b-256 4421018372fe97e1dff0ae0fd2c64e76c565b42c0c89702055d82185befaa3aa

See more details on using hashes here.

File details

Details for the file py_aiger-6.1.12-py3-none-any.whl.

File metadata

  • Download URL: py_aiger-6.1.12-py3-none-any.whl
  • Upload date:
  • Size: 18.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.8.5 Linux/5.4.0-58-generic

File hashes

Hashes for py_aiger-6.1.12-py3-none-any.whl
Algorithm Hash digest
SHA256 456e4d4217777029776dad1d66bdc127d59af69ad86ac21f5f5fb98d20d53a2b
MD5 126a5a1bb31687788909c28105342827
BLAKE2b-256 b74f2da7d985cfe6c0320d167d58da218272def7003e62dabfd2ad2d2f2b59a4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page