1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 package org.sat4j.reader;
31
32 import java.io.IOException;
33 import java.io.PrintWriter;
34
35 import org.sat4j.core.VecInt;
36 import org.sat4j.specs.ContradictionException;
37 import org.sat4j.specs.IProblem;
38 import org.sat4j.specs.ISolver;
39 import org.sat4j.specs.IVecInt;
40 import org.sat4j.tools.GateTranslator;
41
42
43
44
45
46
47
48 public class AAGReader extends Reader {
49
50 private static final int FALSE = 0;
51
52 private static final int TRUE = 1;
53
54 private final GateTranslator solver;
55
56 private int maxvarid;
57
58 private int nbinputs;
59
60 AAGReader(ISolver s) {
61 this.solver = new GateTranslator(s);
62 }
63
64 @Override
65 public String decode(int[] model) {
66 StringBuffer stb = new StringBuffer();
67 for (int i = 0; i < this.nbinputs; i++) {
68 stb.append(model[i] > 0 ? 1 : 0);
69 }
70 return stb.toString();
71 }
72
73 @Override
74 public void decode(int[] model, PrintWriter out) {
75 for (int i = 0; i < this.nbinputs; i++) {
76 out.print(model[i] > 0 ? 1 : 0);
77 }
78 }
79
80 @Override
81 public IProblem parseInstance(java.io.InputStream in)
82 throws ParseFormatException, ContradictionException, IOException {
83 EfficientScanner scanner = new EfficientScanner(in);
84 String prefix = scanner.next();
85 if (!"aag".equals(prefix)) {
86 throw new ParseFormatException("AAG format only!");
87 }
88 this.maxvarid = scanner.nextInt();
89 this.nbinputs = scanner.nextInt();
90 int nblatches = scanner.nextInt();
91 int nboutputs = scanner.nextInt();
92 if (nboutputs > 1) {
93 throw new ParseFormatException(
94 "CNF conversion allowed for single output circuit only!");
95 }
96 int nbands = scanner.nextInt();
97 this.solver.newVar(this.maxvarid + 1);
98 this.solver.setExpectedNumberOfClauses(3 * nbands + 2);
99 readInput(this.nbinputs, scanner);
100 assert nblatches == 0;
101 if (nboutputs > 0) {
102 int output0 = readOutput(nboutputs, scanner);
103 readAnd(nbands, output0, scanner);
104 }
105 return this.solver;
106 }
107
108 private void readAnd(int nbands, int output0, EfficientScanner scanner)
109 throws ContradictionException, IOException, ParseFormatException {
110
111 for (int i = 0; i < nbands; i++) {
112 int lhs = scanner.nextInt();
113 int rhs0 = scanner.nextInt();
114 int rhs1 = scanner.nextInt();
115 this.solver.and(toDimacs(lhs), toDimacs(rhs0), toDimacs(rhs1));
116 }
117 this.solver.gateTrue(this.maxvarid + 1);
118 this.solver.gateTrue(toDimacs(output0));
119 }
120
121 private int toDimacs(int v) {
122 if (v == FALSE) {
123 return -(this.maxvarid + 1);
124 }
125 if (v == TRUE) {
126 return this.maxvarid + 1;
127 }
128 int var = v >> 1;
129 if ((v & 1) == 0) {
130 return var;
131 }
132 return -var;
133 }
134
135 private int readOutput(int nboutputs, EfficientScanner scanner)
136 throws IOException, ParseFormatException {
137 IVecInt outputs = new VecInt(nboutputs);
138 for (int i = 0; i < nboutputs; i++) {
139 outputs.push(scanner.nextInt());
140 }
141 return outputs.get(0);
142 }
143
144 private IVecInt readInput(int numberOfInputs, EfficientScanner scanner)
145 throws IOException, ParseFormatException {
146 IVecInt inputs = new VecInt(numberOfInputs);
147 for (int i = 0; i < numberOfInputs; i++) {
148 inputs.push(scanner.nextInt());
149 }
150 return inputs;
151 }
152 }