1 #include "subcircuit.h"
6 std::vector
<std::string
> readLine()
9 std::vector
<std::string
> tokenList
;
11 while (tokenList
.size() == 0 && fgets(buffer
, sizeof(buffer
), stdin
) != NULL
) {
12 for (char *p
= buffer
; char *tok
= strtok(p
, " \t\r\n"); p
= NULL
) {
13 if (p
!= NULL
&& tok
[0] == '#')
15 tokenList
.push_back(tok
);
25 SubCircuit::Graph
*graph
= NULL
;
26 SubCircuit::Solver solver
;
27 std::map
<std::string
, std::set
<std::string
>> initialMappings
;
28 std::vector
<SubCircuit::Solver::Result
> results
;
29 std::vector
<SubCircuit::Solver::MineResult
> mineResults
;
30 std::vector
<std::string
> cmdBuffer
;
31 bool lastCommandExpect
= false;
35 cmdBuffer
= readLine();
36 if (cmdBuffer
.empty())
39 printf(graph
== NULL
|| cmdBuffer
[0] == "endgraph" ? ">" : "> ");
40 for (const auto &tok
: cmdBuffer
)
41 printf(" %s", tok
.c_str());
44 lastCommandExpect
= false;
48 if (cmdBuffer
[0] == "node" && cmdBuffer
.size() >= 3) {
49 graph
->createNode(cmdBuffer
[1], cmdBuffer
[2]);
50 for (int i
= 3; i
< int(cmdBuffer
.size()); i
++) {
51 std::string portId
= cmdBuffer
[i
];
52 int width
= 1, minWidth
= -1;
53 if (i
+1 < int(cmdBuffer
.size()) && '0' <= cmdBuffer
[i
+1][0] && cmdBuffer
[i
+1][0] <= '9')
54 width
= atoi(cmdBuffer
[++i
].c_str());
55 if (i
+1 < int(cmdBuffer
.size()) && '0' <= cmdBuffer
[i
+1][0] && cmdBuffer
[i
+1][0] <= '9')
56 minWidth
= atoi(cmdBuffer
[++i
].c_str());
57 graph
->createPort(cmdBuffer
[1], portId
, width
, minWidth
);
62 if (cmdBuffer
[0] == "connect" && cmdBuffer
.size() == 5) {
63 graph
->createConnection(cmdBuffer
[1], cmdBuffer
[2], cmdBuffer
[3], cmdBuffer
[4]);
67 if (cmdBuffer
[0] == "connect" && cmdBuffer
.size() == 7) {
68 graph
->createConnection(cmdBuffer
[1], cmdBuffer
[2], atoi(cmdBuffer
[3].c_str()), cmdBuffer
[4], cmdBuffer
[5], atoi(cmdBuffer
[6].c_str()));
72 if (cmdBuffer
[0] == "connect" && cmdBuffer
.size() == 8) {
73 graph
->createConnection(cmdBuffer
[1], cmdBuffer
[2], atoi(cmdBuffer
[3].c_str()), cmdBuffer
[4], cmdBuffer
[5], atoi(cmdBuffer
[6].c_str()), atoi(cmdBuffer
[7].c_str()));
77 if (cmdBuffer
[0] == "constant" && cmdBuffer
.size() == 5) {
78 int constValue
= cmdBuffer
[4].size() > 1 && cmdBuffer
[4][0] == '#' ? atoi(cmdBuffer
[4].c_str()+1) : cmdBuffer
[4][0];
79 graph
->createConstant(cmdBuffer
[1], cmdBuffer
[2], atoi(cmdBuffer
[3].c_str()), constValue
);
83 if (cmdBuffer
[0] == "constant" && cmdBuffer
.size() == 4) {
84 graph
->createConstant(cmdBuffer
[1], cmdBuffer
[2], atoi(cmdBuffer
[3].c_str()));
88 if (cmdBuffer
[0] == "extern" && cmdBuffer
.size() >= 3) {
89 for (int i
= 2; i
< int(cmdBuffer
.size()); i
++) {
90 std::string portId
= cmdBuffer
[i
];
92 if (i
+1 < int(cmdBuffer
.size()) && '0' <= cmdBuffer
[i
+1][0] && cmdBuffer
[i
+1][0] <= '9')
93 bit
= atoi(cmdBuffer
[++i
].c_str());
94 graph
->markExtern(cmdBuffer
[1], portId
, bit
);
99 if (cmdBuffer
[0] == "allextern" && cmdBuffer
.size() == 1) {
100 graph
->markAllExtern();
104 if (cmdBuffer
[0] == "endgraph" && cmdBuffer
.size() == 1) {
105 solver
.addGraph(graphId
, *graph
);
113 if (cmdBuffer
[0] == "graph" && cmdBuffer
.size() == 2) {
114 graph
= new SubCircuit::Graph
;
115 graphId
= cmdBuffer
[1];
119 if (cmdBuffer
[0] == "compatible" && cmdBuffer
.size() == 3) {
120 solver
.addCompatibleTypes(cmdBuffer
[1], cmdBuffer
[2]);
124 if (cmdBuffer
[0] == "constcompat" && cmdBuffer
.size() == 3) {
125 int needleConstValue
= cmdBuffer
[1].size() > 1 && cmdBuffer
[1][0] == '#' ? atoi(cmdBuffer
[1].c_str()+1) : cmdBuffer
[1][0];
126 int haystackConstValue
= cmdBuffer
[2].size() > 1 && cmdBuffer
[2][0] == '#' ? atoi(cmdBuffer
[2].c_str()+1) : cmdBuffer
[2][0];
127 solver
.addCompatibleConstants(needleConstValue
, haystackConstValue
);
131 if (cmdBuffer
[0] == "swapgroup" && cmdBuffer
.size() >= 4) {
132 std::set
<std::string
> ports
;
133 for (int i
= 2; i
< int(cmdBuffer
.size()); i
++)
134 ports
.insert(cmdBuffer
[i
]);
135 solver
.addSwappablePorts(cmdBuffer
[1], ports
);
139 if (cmdBuffer
[0] == "swapperm" && cmdBuffer
.size() >= 4 && cmdBuffer
.size() % 2 == 1 && cmdBuffer
[cmdBuffer
.size()/2 + 1] == ":") {
140 std::map
<std::string
, std::string
> portMapping
;
141 int n
= (cmdBuffer
.size()-3) / 2;
142 for (int i
= 0; i
< n
; i
++)
143 portMapping
[cmdBuffer
[i
+2]] = cmdBuffer
[i
+3+n
];
144 solver
.addSwappablePortsPermutation(cmdBuffer
[1], portMapping
);
148 if (cmdBuffer
[0] == "initmap" && cmdBuffer
.size() >= 4) {
149 for (int i
= 2; i
< int(cmdBuffer
.size()); i
++)
150 initialMappings
[cmdBuffer
[1]].insert(cmdBuffer
[i
]);
154 if (cmdBuffer
[0] == "solve" && 3 <= cmdBuffer
.size() && cmdBuffer
.size() <= 5) {
155 bool allowOverlap
= true;
156 int maxSolutions
= -1;
157 if (cmdBuffer
.size() >= 4)
158 allowOverlap
= cmdBuffer
[3] == "true" || atoi(cmdBuffer
[3].c_str()) ? true : false;
159 if (cmdBuffer
.size() >= 5)
160 maxSolutions
= atoi(cmdBuffer
[4].c_str());
161 solver
.solve(results
, cmdBuffer
[1], cmdBuffer
[2], initialMappings
, allowOverlap
, maxSolutions
);
162 initialMappings
.clear();
166 if (cmdBuffer
[0] == "mine" && 4 <= cmdBuffer
.size() && cmdBuffer
.size() <= 5) {
167 solver
.mine(mineResults
, atoi(cmdBuffer
[1].c_str()), atoi(cmdBuffer
[2].c_str()),
168 atoi(cmdBuffer
[3].c_str()), cmdBuffer
.size() == 5 ? atoi(cmdBuffer
[4].c_str()) : -1);
172 if (cmdBuffer
[0] == "clearoverlap" && cmdBuffer
.size() == 1) {
173 solver
.clearOverlapHistory();
177 if (cmdBuffer
[0] == "clearconfig" && cmdBuffer
.size() == 1) {
178 solver
.clearConfig();
182 if (cmdBuffer
[0] == "verbose" && cmdBuffer
.size() == 1) {
187 if (cmdBuffer
[0] == "expect" && cmdBuffer
.size() == 2) {
188 int expected
= atoi(cmdBuffer
[1].c_str());
189 printf("\n-- Expected %d, Got %d --\n", expected
, int(results
.size()) + int(mineResults
.size()));
190 for (int i
= 0; i
< int(results
.size()); i
++) {
191 printf("\nMatch #%d: (%s in %s)\n", i
, results
[i
].needleGraphId
.c_str(), results
[i
].haystackGraphId
.c_str());
192 for (const auto &it
: results
[i
].mappings
) {
193 printf(" %s -> %s", it
.first
.c_str(), it
.second
.haystackNodeId
.c_str());
194 for (const auto &it2
: it
.second
.portMapping
)
195 printf(" %s:%s", it2
.first
.c_str(), it2
.second
.c_str());
199 for (auto &result
: mineResults
) {
200 printf("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result
.nodes
.size()), result
.totalMatchesAfterLimits
);
201 printf(" primary match in %s:", result
.graphId
.c_str());
202 for (auto &node
: result
.nodes
)
203 printf(" %s", node
.nodeId
.c_str());
205 for (auto &it
: result
.matchesPerGraph
)
206 printf(" matches in %s: %d\n", it
.first
.c_str(), it
.second
);
209 if (expected
!= int(results
.size()) + int(mineResults
.size())) {
210 printf("^^ expected %d, Got %d ^^\n\n", expected
, int(results
.size()) + int(mineResults
.size()));
211 printf(" +----------------+\n");
212 printf(" | \\|/ ____ \\|/ |\n");
213 printf(" | \"@'/ ,. \\`@\" |\n");
214 printf(" | /_| \\__/ |_\\ |\n");
215 printf(" | \\__U_/ |\n");
216 printf(" | | | |\n");
217 printf(" +----------------+\n\n");
222 lastCommandExpect
= true;
227 printf("Invalid input command!\n");
234 if (!lastCommandExpect
) {
235 printf("\n-- Got %d --\n", int(results
.size()) + int(mineResults
.size()));
236 for (int i
= 0; i
< int(results
.size()); i
++) {
237 printf("\nMatch #%d: (%s in %s)\n", i
, results
[i
].needleGraphId
.c_str(), results
[i
].haystackGraphId
.c_str());
238 for (const auto &it
: results
[i
].mappings
) {
239 printf(" %s -> %s", it
.first
.c_str(), it
.second
.haystackNodeId
.c_str());
240 for (const auto &it2
: it
.second
.portMapping
)
241 printf(" %s:%s", it2
.first
.c_str(), it2
.second
.c_str());
245 for (auto &result
: mineResults
) {
246 printf("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result
.nodes
.size()), result
.totalMatchesAfterLimits
);
247 printf(" primary match in %s:", result
.graphId
.c_str());
248 for (auto &node
: result
.nodes
)
249 printf(" %s", node
.nodeId
.c_str());
251 for (auto &it
: result
.matchesPerGraph
)
252 printf(" matches in %s: %d\n", it
.first
.c_str(), it
.second
);