Commit 79ca5ef9 authored by Adam P. Goucher's avatar Adam P. Goucher

Convert AIG into a circuit of zero-preserving gates

parent 9e00d6bb
Pipeline #56163250 passed with stages
in 7 minutes and 55 seconds
#include <stdint.h>
#include <iostream>
#include <sstream>
#include "../lifetree.h"
#define LGATE_AND 0
#define LGATE_OR 1
#define LGATE_XOR 2
#define LGATE_ANDN 3
#define LGATE_OUT 4
#define LGATE_IN 5
struct zeropres {
uint32_t gatetype;
std::vector<uint32_t> inputs;
zeropres(uint32_t gt, uint32_t ia, uint32_t ib) {
gatetype = gt;
inputs.push_back(ia);
inputs.push_back(ib);
}
zeropres(uint32_t gt, std::vector<uint32_t> in) {
gatetype = gt;
inputs = in;
}
void to_stream(std::ostream &s) {
if (gatetype == LGATE_AND) { s << "and "; }
if (gatetype == LGATE_OR) { s << "or "; }
if (gatetype == LGATE_XOR) { s << "xor "; }
if (gatetype == LGATE_ANDN) { s << "andn"; }
if (gatetype == LGATE_OUT) { s << "out "; }
if (gatetype == LGATE_IN) { s << "in "; }
s << " [";
for (auto it = inputs.begin(); it != inputs.end(); ++it) {
s << " " << (*it);
}
s << " ]" << std::endl;
}
};
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Usage: ./pres0 infile.aag" << std::endl;
return 1;
}
std::unordered_map<uint32_t, uint32_t> x2i;
x2i[0] = 0;
x2i[1] = 1;
int m = 0; int i = 0; int l = 0; int o = 0; int a = 0;
std::ifstream instream(argv[1]);
std::string line;
while (std::getline(instream, line)) {
if (line.empty()) { continue; }
if (line.substr(0, 4) == "aag ") {
std::stringstream s(line.substr(4));
s >> m >> i >> l >> o >> a;
break;
}
}
if (i == 0) {
std::cerr << "Error: no inputs specified" << std::endl;
return 1;
}
std::vector<zeropres> gates;
for (int j = 0; j < i; j++) {
std::getline(instream, line);
int inp = 0;
std::stringstream s(line);
s >> inp;
std::vector<uint32_t> v; v.push_back(0);
gates.emplace_back(LGATE_IN, v);
x2i[inp ] = 2 * (gates.size());
x2i[inp ^ 1] = (2 * (gates.size())) ^ 1;
}
std::vector<uint32_t> outputs;
for (int j = 0; j < o; j++) {
std::getline(instream, line);
int outp = 0;
std::stringstream s(line);
s >> outp;
outputs.emplace_back(outp);
}
for (int j = 0; j < a; j++) {
std::getline(instream, line);
int outp = 0; int in1 = 0; int in2 = 0;
std::stringstream s(line);
s >> outp >> in1 >> in2;
in1 = x2i[in1];
in2 = x2i[in2];
if (in2 < in1) { in2 ^= in1; in1 ^= in2; in2 ^= in1; }
if ((in2 == in1) || (in1 == 1)) {
x2i[outp ] = in2;
x2i[outp ^ 1] = in2 ^ 1;
} else if ((in2 == (in1 ^ 1)) || (in1 == 0)) {
x2i[outp ] = 0;
x2i[outp ^ 1] = 1;
} else if (((in1 & 1) == 0) && ((in2 & 1) == 0)) {
gates.emplace_back(LGATE_AND, in1 >> 1, in2 >> 1);
x2i[outp ] = 2 * (gates.size());
x2i[outp ^ 1] = (2 * (gates.size())) ^ 1;
} else if (((in1 & 1) == 0) && ((in2 & 1) == 1)) {
gates.emplace_back(LGATE_ANDN, in1 >> 1, in2 >> 1);
x2i[outp ] = 2 * (gates.size());
x2i[outp ^ 1] = (2 * (gates.size())) ^ 1;
} else if (((in1 & 1) == 1) && ((in2 & 1) == 0)) {
gates.emplace_back(LGATE_ANDN, in2 >> 1, in1 >> 1);
x2i[outp ] = 2 * (gates.size());
x2i[outp ^ 1] = (2 * (gates.size())) ^ 1;
} else if (((in1 & 1) == 1) && ((in2 & 1) == 1)) {
gates.emplace_back(LGATE_OR, in1 >> 1, in2 >> 1);
x2i[outp ^ 1] = 2 * (gates.size());
x2i[outp ] = (2 * (gates.size())) ^ 1;
}
}
for (int j = 0; j < o; j++) { outputs[j] = x2i[outputs[j]] >> 1; }
gates.emplace_back(LGATE_OUT, outputs);
for (auto it = gates.begin(); it != gates.end(); ++it) {
it->to_stream(std::cout);
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment