25#define PRECISION(max_value) sizeof(max_value) * 8
38 std::string strexp = expression;
39 if (!checkExpression(strexp)) {
46 parseExpression(strexp, root);
50 std::string msg =
"BinaryExpParser: failed to parse the expression";
54 if(invalidOperands.size())
57 std::string msg =
"Invalid operands";
58 for (
const auto& invalidOperand : invalidOperands) {
59 msg +=
" '" + invalidOperand +
"'";
66 createTruthTable(operands.size());
67 int n = truthTable.size();
68 for(
int x = 0; x < (1 << (n-1)); ++x)
70 auto itr = operands.begin();
71 for (
int y = 0; y < (n - 1); ++y) {
72 (*itr++).second = (truthTable[y][x] != 0);
74 truthTable[n-1][x] = evalTree(root, operands);
91 switch((*itr)->getType()) {
94 dot<<
"\""<<node->getLabel()<<
"\"";
95 dot<<
" [label=\""<< node->getName()<<
"\"";
96 dot<<
" shape=circle, fillcolor=lightslategrey, style=filled];\n";
97 for(
int i=0; i<node->sucCount(); i++)
99 Link l = node->getLinkAt(i);
101 dot<<
"\""<<node->getLabel()<<
"\" -> ";
102 dot<<
"\""<<to->getLabel()<<
"\"";
103 dot<<
" [label=\"\"];\n";
109 dot<<
"\""<<node->getLabel()<<
"\"";
110 dot<<
" [label=\""<< node->getName()<<
"\"";
111 dot<<
" shape=square];\n";
124bool BinaryExpParser::evalTree(
BinaryNodePtr node, std::map<std::string, bool>& opnd)
134 if(strcmp(node->
getName(),
"~") == 0)
137 result = !evalTree(left, opnd);
140 else if(strcmp(node->
getName(),
"&") == 0)
144 result = evalTree(left, opnd) && evalTree(right, opnd);
147 else if(strcmp(node->
getName(),
"|") == 0)
151 result = evalTree(left, opnd) || evalTree(right, opnd);
160 return ((c==
'(') || (c==
')'));
163bool BinaryExpParser::checkExpression(std::string& strexp)
167 if(std::count(strexp.begin(), strexp.end(),
'(') !=
168 std::count(strexp.begin(), strexp.end(),
')'))
170 logger->
addError(
"Incorrect expression format! (parentheses do not match)");
173 if(std::count(strexp.begin(), strexp.end(),
IMPLY) != 1 )
175 logger->
addError(
"Incorrect expression format! (no implication ':' found)");
180 strexp.erase(std::remove_if(strexp.begin(), strexp.end(), ::isspace), strexp.end());
183 logger->
addError(
"Empty expression!");
188 std::string dummy = strexp;
190 dummy.erase(std::remove_if(dummy.begin(), dummy.end(),
isParentheses), dummy.end());
191 leftOpr = dummy.substr(0, dummy.find(
IMPLY));
194 logger->
addError(
"Missing operand before ':'");
197 if(dummy.find(
IMPLY) == (dummy.size()-1))
199 logger->
addError(
"Missing operands after ':'");
203 dummy.erase(0, dummy.find(
IMPLY)+1);
204 if(dummy.find(leftOpr) != std::string::npos)
207 msg =
"recursive assignment of operand '" + leftOpr +
"'";
213 size_t n = dummy.find(
EXPNOT);
214 while(n != std::string::npos)
217 bool bError = ((n+1) == dummy.length());
218 if((n+1) < dummy.length())
220 bError |= (dummy[n+1] ==
EXPAND);
221 bError |= (dummy[n+1] ==
EXPOR);
224 bError |= (dummy[n - 1] !=
EXPAND) && (dummy[n - 1] !=
EXPOR);
228 msg<<
"Incorrect expression format of '~' at "<<(int)n;
229 logger->
addError(msg.str().c_str());
232 n = dummy.find(
EXPNOT, n+1);
236 n = dummy.find_first_of(
"&|");
237 while(n != std::string::npos)
240 bool bError = ((n+1) == dummy.length());
241 if((n+1) < dummy.length())
243 bError |= (dummy[n+1] ==
EXPAND);
244 bError |= (dummy[n+1] ==
EXPOR);
249 bError |= (dummy[n-1] ==
EXPAND);
250 bError |= (dummy[n-1] ==
EXPOR);
251 bError |= (dummy[n-1] ==
EXPOR);
255 msg<<
"Incorrect expression format of '&' or '|' at "<<(int)n;
256 logger->
addError(msg.str().c_str());
259 n = dummy.find_first_of(
"&|", n+1);
263 strexp.erase(0, strexp.find(
IMPLY)+1);
267void BinaryExpParser::parseExpression(std::string &strexp,
BinaryNodePtr& node)
271 parseNot(strexp, node);
272 while(!strexp.empty() &&
273 ((*strexp.begin() ==
EXPAND) ||
274 (*strexp.begin() ==
EXPOR)))
276 op = *strexp.begin();
277 strexp.erase(strexp.begin());
278 parseNot(strexp, rightNode);
279 BinaryNode tmpNode(op.c_str(), node, rightNode);
285void BinaryExpParser::parseNot(std::string &strexp,
BinaryNodePtr& node) {
288 if (*strexp.begin() !=
EXPNOT) {
289 parseFactor(strexp, node);
291 while(!strexp.empty() &&
292 (*strexp.begin() ==
EXPNOT))
294 op = *strexp.begin();
295 strexp.erase(strexp.begin());
296 parseFactor(strexp, rightNode);
297 BinaryNode tmpNode(op.c_str(), rightNode,
nullptr);
302void BinaryExpParser::parseFactor(std::string &strexp,
BinaryNodePtr& node) {
303 if(!strexp.empty() && (*strexp.begin() !=
'('))
305 std::string op = popNextOperand(strexp);
308 operands[op] =
false;
309 if(validOperands.size())
311 if (std::find(validOperands.begin(),
314 == validOperands.end()) {
315 invalidOperands.push_back(op);
321 strexp.erase(strexp.begin());
322 parseExpression(strexp, node);
323 strexp.erase(strexp.begin());
328std::string BinaryExpParser::getNextOperand(std::string &strexp) {
330 std::string::iterator it;
331 for (it = strexp.begin(); it != strexp.end(); ++it) {
332 if ((*it !=
EXPAND) && (*it !=
EXPOR) && (*it !=
EXPNOT) && (*it !=
')') && (*it !=
'(')) {
333 token.push_back(*it);
341std::string BinaryExpParser::popNextOperand(std::string &strexp) {
343 std::string::iterator it;
344 for (it = strexp.begin(); it != strexp.end(); ++it) {
345 if ((*it !=
EXPAND) && (*it !=
EXPOR) && (*it !=
EXPNOT) && (*it !=
')') && (*it !=
'(')) {
346 token.push_back(*it);
348 strexp.erase(strexp.begin(), it);
355void BinaryExpParser::createTruthTable(
const int n)
359 yAssert(1 <= (INT_MAX >> (n-1)));
363 truthTable.resize(n+1);
364 for (
int i = 0; i < n + 1; i++) {
365 truthTable[i].resize(1 << n);
367 int num_to_fill = 1 << (n - 1);
368 for(
int col = 0; col < n; ++col, num_to_fill >>= 1)
370 for(
int row = num_to_fill; row < (1 << n); row += (num_to_fill * 2))
372 std::fill_n(&truthTable[col][row], num_to_fill, 1);
377void BinaryExpParser::printTruthTable(std::string lopr)
379 int n = truthTable.size();
383 yAssert(1 <= (INT_MAX >> (n-1)));
385 std::map<std::string, bool>::iterator itr;
386 for (itr = operands.begin(); itr != operands.end(); itr++) {
387 std::cout << (*itr).first <<
"\t";
389 std::cout << lopr <<
'\n';
390 for (
int i = 0; i < (int)operands.size() * 8 + 1; i++) {
395 for(
int x = 0; x < (1<<(n-1)); ++x)
397 for (
int y = 0; y < n; ++y) {
398 std::cout << truthTable[y][x] <<
"\t";
408 int n = truthTable.size();
412 std::fill(alphas.begin(), alphas.end(), 0.0);
415 for(
int i=0; (i<maxIteration) && (sumerr !=0); i++)
419 for(
int x = 0; x < (1 << (n-1)); ++x)
422 double P = truthTable[n-1][x];
424 for (
int y = 0; y < n - 1; ++y) {
425 out = out + ((double)truthTable[y][x] * alphas[y]);
427 out = (out>0) ? 1 : 0;
428 double err = P - out;
431 bias = bias + trainRate * err;
432 for (
int y = 0; y < (n - 1); ++y) {
433 alphas[y] = alphas[y] + (trainRate * err * (double)truthTable[y][x]);
436 errors.push_back(sumerr);
438 return ((
int)errors.size() < maxIteration);
bool isParentheses(char c)
#define PRECISION(max_value)
virtual ~BinaryExpParser()
bool parse(std::string _exp)
bool exportDotGraph(const char *szFileName)
Singleton class ErrorLogger.
void addError(const char *szError)
static ErrorLogger * Instance()
Singleton class ErrorLogger.
Node * addNode(Node *node)
bool train(const std::vector< std::vector< int > > &truthTable)
Link holding all the links of a node.
Link & getLinkAt(int index)
BinaryNode * BinaryNodePtr
std::stringstream OSTRINGSTREAM