28 #define PRECISION(max_value) sizeof(max_value) * 8
35 BinaryExpParser::BinaryExpParser() =
default;
37 BinaryExpParser::~BinaryExpParser() =
default;
39 bool BinaryExpParser::parse(
string _exp)
42 string strexp = expression;
43 if(!checkExpression(strexp))
49 parseExpression(strexp, root);
53 string msg =
"BinaryExpParser: failed to parse the expression";
57 if(invalidOperands.size())
60 string msg =
"Invalid operands";
61 for(
const auto& invalidOperand : invalidOperands)
62 msg +=
" '" + invalidOperand +
"'";
68 createTruthTable(operands.size());
69 int n = truthTable.size();
70 for(
int x = 0; x < (1 << (n-1)); ++x)
72 auto itr = operands.begin();
73 for(
int y = 0; y < (n-1); ++y)
74 (*itr++).second = (truthTable[y][x] != 0);
75 truthTable[n-1][x] = evalTree(root, operands);
88 dot<<
"digraph G {"<<endl;
89 for(
GraphIterator itr=binTree.begin(); itr!=binTree.end(); itr++)
91 switch((*itr)->getType()) {
94 dot<<
"\""<<node->getLabel()<<
"\"";
95 dot<<
" [label=\""<< node->getName()<<
"\"";
96 dot<<
" shape=circle, fillcolor=lightslategrey, style=filled];"<<endl;
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=\"\"];"<<endl;
109 dot<<
"\""<<node->getLabel()<<
"\"";
110 dot<<
" [label=\""<< node->getName()<<
"\"";
111 dot<<
" shape=square];"<<endl;
124 bool 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==
')'));
163 bool 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 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) != string::npos)
207 msg =
"recursive assignment of operand '" + leftOpr +
"'";
213 size_t n = dummy.find(
EXPNOT);
214 while(n != 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);
227 msg<<
"Incorrect expression format of '~' at "<<(int)n;
228 logger->
addError(msg.str().c_str());
231 n = dummy.find(
EXPNOT, n+1);
235 n = dummy.find_first_of(
"&|");
236 while(n != string::npos)
239 bool bError = ((n+1) == dummy.length());
240 if((n+1) < dummy.length())
242 bError |= (dummy[n+1] ==
EXPAND);
243 bError |= (dummy[n+1] ==
EXPOR);
248 bError |= (dummy[n-1] ==
EXPAND);
249 bError |= (dummy[n-1] ==
EXPOR);
250 bError |= (dummy[n-1] ==
EXPOR);
254 msg<<
"Incorrect expression format of '&' or '|' at "<<(int)n;
255 logger->
addError(msg.str().c_str());
258 n = dummy.find_first_of(
"&|", n+1);
262 strexp.erase(0, strexp.find(
IMPLY)+1);
266 void BinaryExpParser::parseExpression(std::string &strexp,
BinaryNodePtr& node)
270 parseNot(strexp, node);
271 while(!strexp.empty() &&
272 ((*strexp.begin() ==
EXPAND) ||
273 (*strexp.begin() ==
EXPOR)))
275 op = *strexp.begin();
276 strexp.erase(strexp.begin());
277 parseNot(strexp, rightNode);
278 BinaryNode tmpNode(op.c_str(), node, rightNode);
284 void BinaryExpParser::parseNot(std::string &strexp,
BinaryNodePtr& node) {
287 if(*strexp.begin() !=
EXPNOT)
288 parseFactor(strexp, node);
289 while(!strexp.empty() &&
290 (*strexp.begin() ==
EXPNOT))
292 op = *strexp.begin();
293 strexp.erase(strexp.begin());
294 parseFactor(strexp, rightNode);
295 BinaryNode tmpNode(op.c_str(), rightNode,
nullptr);
300 void BinaryExpParser::parseFactor(std::string &strexp,
BinaryNodePtr& node) {
301 if(!strexp.empty() && (*strexp.begin() !=
'('))
303 string op = popNextOperand(strexp);
306 operands[op] =
false;
307 if(validOperands.size())
309 if(std::find(validOperands.begin(),
310 validOperands.end(), op) == validOperands.end())
311 invalidOperands.push_back(op);
316 strexp.erase(strexp.begin());
317 parseExpression(strexp, node);
318 strexp.erase(strexp.begin());
323 std::string BinaryExpParser::getNextOperand(std::string &strexp) {
325 std::string::iterator it;
326 for (it=strexp.begin(); it!=strexp.end(); ++it)
328 (*it !=
')') && (*it !=
'('))
329 token.push_back(*it);
335 std::string BinaryExpParser::popNextOperand(std::string &strexp) {
337 std::string::iterator it;
338 for (it=strexp.begin(); it!=strexp.end(); ++it)
340 (*it !=
')') && (*it !=
'('))
341 token.push_back(*it);
344 strexp.erase(strexp.begin(), it);
350 void BinaryExpParser::createTruthTable(
const int n)
354 yAssert(1 <= (INT_MAX >> (n-1)));
358 truthTable.resize(n+1);
359 for(
int i=0; i<n+1; i++)
360 truthTable[i].resize(1 << n);
361 int num_to_fill = 1 << (n - 1);
362 for(
int col = 0; col < n; ++col, num_to_fill >>= 1)
364 for(
int row = num_to_fill; row < (1 << n); row += (num_to_fill * 2))
366 std::fill_n(&truthTable[col][row], num_to_fill, 1);
371 void BinaryExpParser::printTruthTable(std::string lopr)
373 int n = truthTable.size();
377 yAssert(1 <= (INT_MAX >> (n-1)));
379 map<string, bool>::iterator itr;
380 for(itr=operands.begin(); itr!=operands.end(); itr++)
381 cout<<(*itr).first<<
"\t";
383 for(
int i=0; i<(int)operands.size()*8+1; i++)
387 for(
int x = 0; x < (1<<(n-1)); ++x)
389 for(
int y = 0; y < n; ++y)
390 std::cout<< truthTable[y][x] <<
"\t";
391 std::cout<<std::endl;
396 bool LinkTrainer::train(
const std::vector<std::vector<int> >& truthTable)
399 int n = truthTable.size();
403 std::fill(alphas.begin(), alphas.end(), 0.0);
406 for(
int i=0; (i<maxIteration) && (sumerr !=0); i++)
410 for(
int x = 0; x < (1 << (n-1)); ++x)
413 double P = truthTable[n-1][x];
415 for(
int y = 0; y < n-1; ++y)
416 out = out + ((
double)truthTable[y][x] * alphas[y]);
417 out = (out>0) ? 1 : 0;
418 double err = P - out;
421 bias = bias + trainRate * err;
422 for(
int y = 0; y < (n-1); ++y)
423 alphas[y] = alphas[y] + (trainRate * err * (
double)truthTable[y][x]);
425 errors.push_back(sumerr);
427 return ((
int)errors.size() < maxIteration);