
%{ 

#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>


using namespace std;

vector<int> nodes;
vector<int> clique;
vector<vector<int> > edges;
vector<int> curredge = vector<int>(2);

%}

%x	snode
%x	sedge
%x	sedge2
%x	sclique

%option noyywrap

NUM			[1-9][0-9]*
WHITESPACE		[\r\t ]*

%%

"node("		{ BEGIN(snode); }
"edge("		{ BEGIN(sedge); }
"clique("	{ BEGIN(sclique); }

<snode>{NUM}	{ nodes.push_back(atoi(yytext)); }
<snode>")."	{ BEGIN(INITIAL); }

<sclique>{NUM}	{ clique.push_back(atoi(yytext)); }
<sclique>")."	{ BEGIN(INITIAL); }

<sedge>{NUM}	{ curredge[0] = atoi(yytext); BEGIN(sedge2); }
<sedge2>{NUM}	{ curredge[1] = atoi(yytext); edges.push_back(curredge); }
<sedge2>")."	{ BEGIN(INITIAL); }
<sedge2>","	{  }

{WHITESPACE}	{  }
"\n"		{  }
.		{ cout << "WARN\n"; exit(3); }

%%

int main() {
	yylex();

	if (clique.size() > nodes.size()) {
		cout << "FAIL\n";
		cerr << "There size of the clique cannot exceed the total number of nodes in the graph.\n";
		return 1;  
	}

	if (nodes.size() == 0) {
		cout << "WARN The instance does not contain nodes and thus the result cannot be checked.\n";
		return 3;
	}

	if (clique.size() == 0 && nodes.size() > 0) {
		cout << "WARN The result of an instance with at least one node should be a clique of size at least one (probably the solver did not succeed to find a trivial one).\n";
		return 3;
	}

	{//check for duplicates in the clique-vector
		int oldCliquesize = clique.size();
		vector<int>::const_iterator tempit = unique(clique.begin(), clique.end());
		clique.resize(tempit - clique.begin());
		int newCliquesize = clique.size();

		if (oldCliquesize != newCliquesize) {
			cout << "WARN The result contains duplicate clique/1 predicates.\n";
			return 3;
		}
	}

	if (clique.size() == 1) {
		for (int i = 0; i < nodes.size(); ++i) {
			if (nodes[i] == clique[0]) {
				cout << "OK " << nodes.size() - clique.size() << endl;
				return 0;
			}
		}
		cout << "FAIL\n";
		cerr << "There is no node node(" << clique[0] << ").\n";
		return 1;
	}

	sort(edges.begin(),edges.end());
	sort(clique.begin(),clique.end());

	for(int n = 0; n < clique.size(); ++n) {
		for(int m = n+1; m < clique.size(); ++m) {
			vector<int> test1(2);
			test1[0] = clique[n];
			test1[1] = clique[m];

			vector<vector<int> >::const_iterator it = lower_bound(edges.begin(),edges.end(),test1);

			if(((*it)[0] == clique[n] && (*it)[1] == clique[m]) || ((*it)[0] == clique[m] && (*it)[1] == clique[n])) {
				continue;
			} else {
				cout << "FAIL\n";
				cerr << "There is no edge between " << clique[n] << " and " << clique[m] << ".\n";
				return 1;
			}
		}
	}
	cout << "OK " << nodes.size() - clique.size() << "@0" << endl;
	return 0;
}
