Ejemplo n.º 1
0
// Test single clauses
void QueryEvaluatorTest::testEvaluator() {
	QueryEvaluator e = *new QueryEvaluator();

	// Test Follows(a1, a2)
	FollowsClause* fol = new FollowsClause();
	fol->setFirstArg("a1");
	fol->setSecondArg("a2");
	fol->setFirstArgFixed(false);
	fol->setSecondArgFixed(false);
	fol->setFirstArgType(ARG_ASSIGN);
	fol->setSecondArgType(ARG_ASSIGN);
	
	StringPair p = *new StringPair();
	p.setFirst("a2");
	p.setSecond(ARG_STATEMENT);

	Query q = *new Query();
	q.addSelectSynonym(p);
	q.addClause(fol);

	set<string> res = e.evaluateQuery(q);
	
	CPPUNIT_ASSERT(res.size() == 1);

	// test Follows(_,_)
	FollowsClause* fol2 = new FollowsClause();
	fol2->setFirstArgFixed(false);
	fol2->setSecondArgFixed(false);
	fol2->setFirstArgType(ARG_GENERIC);
	fol2->setSecondArgType(ARG_GENERIC);
	fol2->isValid();

	StringPair p6 = *new StringPair();
	p6.setFirst("s");
	p6.setSecond(ARG_STATEMENT);

	Query q6 = *new Query();
	q6.addSelectSynonym(p6);
	q6.addClause(fol2);

	set<string> res6 = e.evaluateQuery(q6);

	CPPUNIT_ASSERT(res6.size() == 7);

	//test ParentStar FixedSyn With While
	ParentStarClause* m1 = new ParentStarClause();
	m1->setFirstArg("w");
	m1->setFirstArgFixed(false);
	m1->setFirstArgType(ARG_STATEMENT);
	m1->setSecondArg("5");
	m1->setSecondArgFixed(true);
	m1->setSecondArgType(ARG_WHILE);
	
	StringPair p2 = *new StringPair();
	p2.setFirst("w");
	p2.setSecond(ARG_WHILE);

	Query q2 = *new Query();
	q2.addSelectSynonym(p2);
	q2.addClause(m1);

	Results r = m1->evaluate();

	set<string> res2 = e.evaluateQuery(q2);

	CPPUNIT_ASSERT(res2.size() == 2);

	//test ParentStar FixedSyn With While
	ParentStarClause* m2 = new ParentStarClause();
	m2->setFirstArg("w1");
	m2->setFirstArgFixed(false);
	m2->setFirstArgType(ARG_STATEMENT);
	m2->setSecondArg("5");
	m2->setSecondArgFixed(true);
	m2->setSecondArgType(ARG_WHILE);
	
	StringPair p3 = *new StringPair();
	p3.setFirst("w");
	p3.setSecond(ARG_WHILE);

	Query q3 = *new Query();
	q3.addSelectSynonym(p3);
	q3.addClause(m2);

	set<string> res3 = e.evaluateQuery(q3);
	
	CPPUNIT_ASSERT(res3.size() == 2);

	// Test FollowsStar
	FollowsStarClause* f1 = new FollowsStarClause();
	f1->setFirstArg("3");
	f1->setFirstArgFixed(true);
	f1->setFirstArgType(ARG_STATEMENT);
	f1->setSecondArg("a");
	f1->setSecondArgFixed(false);
	f1->setSecondArgType(ARG_STATEMENT);

	StringPair p4 = *new StringPair();
	p4.setFirst("a");
	p4.setSecond(ARG_STATEMENT);

	Query q4 = *new Query();
	q4.addSelectSynonym(p4);
	q4.addClause(f1);

	set<string> res4 = e.evaluateQuery(q4);

	CPPUNIT_ASSERT(res4.size() == 2);

	// Test FollowsStar with select type constant
	FollowsStarClause* f2 = new FollowsStarClause();
	f2->setFirstArg("3");
	f2->setFirstArgFixed(true);
	f2->setFirstArgType(ARG_STATEMENT);
	f2->setSecondArg("a");
	f2->setSecondArgFixed(false);
	f2->setSecondArgType(ARG_STATEMENT);

	StringPair p5 = *new StringPair();
	p5.setFirst("c");
	p5.setSecond(ARG_CONSTANT);

	Query q5 = *new Query();
	q5.addSelectSynonym(p5);
	q5.addClause(f2);

	set<string> res5 = e.evaluateQuery(q5);
	/*
	for (set<string>::iterator iter=res5.begin(); iter != res5.end(); iter++) {
		cout << "result: " << *iter << "!";
	}
	*/
	// to check
	CPPUNIT_ASSERT(res5.size() == 5);

}
Ejemplo n.º 2
0
// Test 2 clauses
void QueryEvaluatorTest::testEvaluator2() {
	QueryEvaluator e = *new QueryEvaluator();
	// Test all syn different 
	ParentStarClause* m1 = new ParentStarClause();
	m1->setFirstArg("w");
	m1->setFirstArgFixed(false);
	m1->setFirstArgType(ARG_WHILE);
	m1->setSecondArg("5");
	m1->setSecondArgFixed(true);
	m1->setSecondArgType(ARG_STATEMENT);

	PatternAssgClause* p1 = new PatternAssgClause("a");
	p1->setVar("_");
	p1->setVarFixed(true);
	p1->setExpression("_");

	StringPair pr1 = *new StringPair();
	pr1.setFirst("s");
	pr1.setSecond(ARG_ASSIGN);

	Query q1 = *new Query();
	q1.addSelectSynonym(pr1);
	q1.addClause(m1);
	q1.addClause(p1);

	set<string> res = e.evaluateQuery(q1);
	
	CPPUNIT_ASSERT(res.size() == 5);

	// Test 1 same fixed syn between 2 clauses
	// Select a s.t. Modifies(5, "i") pattern a("i",_)
	ModifiesClause* m2 = new ModifiesClause();
	m2->setFirstArg("5");
	m2->setFirstArgFixed(true);
	m2->setFirstArgType(ARG_STATEMENT);
	m2->setSecondArg("i");
	m2->setSecondArgFixed(true);
	m2->setSecondArgType(ARG_VARIABLE);

	PatternAssgClause* p2 = new PatternAssgClause("a");
	p2->setVar("i");
	p2->setVarFixed(true);
	p2->setExpression("_");

	StringPair pr2 = *new StringPair();
	pr2.setFirst("a");
	pr2.setSecond(ARG_VARIABLE);

	Query q2 = *new Query();
	q2.addSelectSynonym(pr2);
	q2.addClause(m2);
	q2.addClause(p2);

	set<string> res2 = e.evaluateQuery(q2);
	/*
	for (set<string>::iterator iter=res2.begin(); iter != res2.end(); iter++) {
		cout << "result: " << *iter << "!";
	}
	*/
	CPPUNIT_ASSERT(res2.size() == 1);

	// Test 1 same unfixed syn between 2 clauses
	// Select a s.t. Modifies(a,v1) pattern a(v2,_)
	ModifiesClause* m3 = new ModifiesClause();
	m3->setFirstArg("a");
	m3->setFirstArgFixed(false);
	m3->setFirstArgType(ARG_STATEMENT);
	m3->setSecondArg("v1");
	m3->setSecondArgFixed(false);
	m3->setSecondArgType(ARG_VARIABLE);

	PatternAssgClause* p3 = new PatternAssgClause("a");
	p3->setVar("v2");
	p3->setVarFixed(false);
	p3->setExpression("_");

	StringPair pr3 = *new StringPair();
	pr3.setFirst("a");
	pr3.setSecond(ARG_VARIABLE);

	Query q3 = *new Query();
	q3.addSelectSynonym(pr3);
	q3.addClause(m3);
	q3.addClause(p3);

	set<string> res3 = e.evaluateQuery(q3);
	
	CPPUNIT_ASSERT(res3.size() == 5);

	// Test 2 same unfixed syn between 2 clauses
	// Select a s.t. Modifies(a,v) pattern a(v,_)
	ModifiesClause* m4 = new ModifiesClause();
	m4->setFirstArg("a");
	m4->setFirstArgFixed(false);
	m4->setFirstArgType(ARG_STATEMENT);
	m4->setSecondArg("v");
	m4->setSecondArgFixed(false);
	m4->setSecondArgType(ARG_VARIABLE);

	PatternAssgClause* p4 = new PatternAssgClause("a");
	p4->setVar("v");
	p4->setVarFixed(false);
	p4->setExpression("_");

	StringPair pr4 = *new StringPair();
	pr4.setFirst("a");
	pr4.setSecond(ARG_STATEMENT);

	Query q4 = *new Query();
	q4.addSelectSynonym(pr4);
	q4.addClause(m4);
	q4.addClause(p4);

	set<string> res4 = e.evaluateQuery(q4);
	
	CPPUNIT_ASSERT(res4.size() == 5);

	// Test 2 same unfixed syn between 2 clauses
	// Select v s.t. Follows*(a1,a2) pattern a2(v,_)
	FollowsStarClause* f1 = new FollowsStarClause();
	f1->setFirstArg("a1");
	f1->setFirstArgFixed(false);
	f1->setFirstArgType(ARG_STATEMENT);
	f1->setSecondArg("a2");
	f1->setSecondArgFixed(false);
	f1->setSecondArgType(ARG_STATEMENT);
	CPPUNIT_ASSERT(f1->isValid());

	PatternAssgClause* p5 = new PatternAssgClause("a2");
	p5->setVar("v");
	p5->setVarFixed(false);
	p5->setExpression("_");
	CPPUNIT_ASSERT(p5->isValid());

	StringPair pr5 = *new StringPair();
	pr5.setFirst("v");
	pr5.setSecond(ARG_VARIABLE);

	Query q5 = *new Query();
	q5.addSelectSynonym(pr5);
	q5.addClause(f1);
	q5.addClause(p5);

	set<string> res5 = e.evaluateQuery(q5);
	
	CPPUNIT_ASSERT(res5.size() == 2);

	// Test 2 same unfixed syn between 2 clauses
	// Select v s.t. Follows*(a1,a2) pattern a2(v,_)
	FollowsStarClause* f2 = new FollowsStarClause();
	f2->setFirstArg("a1");
	f2->setFirstArgFixed(false);
	f2->setFirstArgType(ARG_STATEMENT);
	f2->setSecondArg("a2");
	f2->setSecondArgFixed(false);
	f2->setSecondArgType(ARG_STATEMENT);
	CPPUNIT_ASSERT(f1->isValid());

	PatternAssgClause* p6 = new PatternAssgClause("a2");
	p6->setVar("v");
	p6->setVarFixed(false);
	p6->setExpression("_");
	CPPUNIT_ASSERT(p6->isValid());

	StringPair pr6 = *new StringPair();
	pr6.setFirst("c");
	pr6.setSecond(ARG_CONSTANT);

	Query q6 = *new Query();
	q6.addSelectSynonym(pr6);
	q6.addClause(f2);
	q6.addClause(p6);

	set<string> res6 = e.evaluateQuery(q6);
	// To be checked
	//BOOST_FOREACH(auto p, res6) {
	//	cout << p << endl;
	//}
	CPPUNIT_ASSERT(res6.size() == 5);
}
void queryDriver(string query, list<string> &result, PKB *pkb){
	//// cout<<"Begin parse query"<<endl;
	pkb->printParentTable();
	pkb->printModifiesTable();
	pkb->printModifiesProcTable();

	/*cout<<"test here"<<endl;
	cout<<"getChildren 15"<<endl;
	set<STMTNUM> temp = pkb->getChildren(15);
	for(set<STMTNUM>::iterator it = temp.begin();it!=temp.end();it++){
		cout<<*it<<endl;
	}
	cout<<"getParent 63"<<endl;
	cout<<pkb->getParent(63)<<endl;*/



	QueryParser qp;
	QueryEvaluator qe = QueryEvaluator::QueryEvaluator(pkb);

	bool isValid = true;
	Query parsedQuery = qp.queryParse(query,isValid);

	if(!isValid){
		//// cout << "Query Invalid" << endl;
		return;
	}

	//// cout<<"End parse query"<<endl;
	

	//// cout<<"Begin evaluate query"<<endl;

	vector<Relationship> newRelations;
	unordered_map<string, int> synIndexMap;
	unordered_map<int, vector<Pair>> clauseAnswers = qe.evaluateQuery(parsedQuery, &newRelations);

	//// cout<<"End evaluate query"<<endl;

	//// cout <<"Begin projecting results"<< endl;
	vector<vector<int>> tupleTable = createTupleTable(clauseAnswers, newRelations, &synIndexMap );

	vector<string> selectedSyn = parsedQuery.getSelectedSyn();
	unordered_map<string, TypeTable::SynType> synTable = parsedQuery.getSynTable();
	set<string> ansSet;
	ansSet.insert("");

	if(synTable.find(selectedSyn.at(0))->second == TypeTable::BOOLEAN) {
		if(tupleTable.size()!=0)
			result.push_back("true");
		else
			result.push_back("false");

		return;
	}

	//// cout << "Begin handling unprocessed selected synonyms" << endl;
	for(int i=0; i<int(selectedSyn.size()); i++) {
		//// cout << "Checking for the following syn: " << selectedSyn.at(i) << endl;
		if(synIndexMap.count(selectedSyn.at(i)) == 0) {
			//// cout << selectedSyn.at(i) << " has not been processed" << endl;
			unordered_map<string, TypeTable::SynType>::iterator it = synTable.find(selectedSyn.at(i));

			vector<vector<int>> newTable;
			set<int> allOfType;

			if(it->second == TypeTable::VARIABLE) {
				allOfType = pkb->getAllVarIndex();
			}
			else if(it->second == TypeTable::CONSTANT) {
				set<int> allConstIndex = pkb->getAllConstIndex();
				ConstTable* constTable = pkb->getConstTable();
				for(set<int>::iterator it=allConstIndex.begin(); it!=allConstIndex.end(); it++) {
					allOfType.insert(atoi(constTable->getConst(*it).c_str()));
				}
			}
			else if(it->second == TypeTable::PROCEDURE) {
				allOfType = pkb->getAllProcIndexes();
			}
			else if(it->second == TypeTable::STMTLST) {
				allOfType = pkb->getAllStmtList();
			}
			else {
				allOfType = pkb->getAllStmts(it->second);
			}

			for(vector<vector<int>>::iterator it1=tupleTable.begin(); it1!=tupleTable.end(); it1++) {
				for(set<int>::iterator it2=allOfType.begin(); it2!=allOfType.end(); it2++) {
					vector<int> newTuple;
					newTuple.insert(newTuple.begin(), it1->begin(), it1->end());
					newTuple.push_back(*it2);
					newTable.push_back(newTuple);
				}				
			}

			synIndexMap.insert(make_pair(selectedSyn.at(i), synIndexMap.size()));
			tupleTable = newTable;
		}
		else {
			//// cout << "Syn has already been processed." << endl;
		;}
	}
	//// cout << "End handling unprocessed selected synonyms" << endl;

	if(tupleTable.size()==0)
		return;

	//// cout << "Begin creating tuple of answers" << endl;
	for(int i=0; i<int(tupleTable.size()); i++) {
		//// cout << "Creating tuple of answer " << i << endl;
		string ans = "";
		for(int j=0; j<int(selectedSyn.size()); j++) {
			//// cout << "Adding \"" << selectedSyn.at(j) << " \"to tuple." << endl;
			unordered_map<string, TypeTable::SynType>::iterator it = synTable.find(selectedSyn.at(j));
			int index = synIndexMap.at(selectedSyn.at(j));
			//// cout << selectedSyn.at(j) << " has index " << index << endl;

			int tempAns = tupleTable.at(i).at(index);

			if(it->second == TypeTable::VARIABLE) {
				VarTable* varTable = pkb->getVarTable();
				ans = ans + varTable->getVarName(tempAns) + " ";
				//// cout << "Adding " << varTable->getVarName(tempAns) << " to tuple" << endl;
			}
			/*else if(it->second == TypeTable::CONSTANT) {
				ConstTable* constTable = pkb->getConstTable();
				ans = ans + constTable->getConst(tempAns) + " ";
				//// cout << "Adding " << constTable->getConst(tempAns) << " to tuple" << endl;
			}*/
			else if(it->second == TypeTable::PROCEDURE && !parsedQuery.getSelectedSynIsCallProcedure().at(j)) {
				ProcTable* procTable = pkb->getProcTable();
				ans = ans + procTable->getProcName(tempAns) + " ";
				//// cout << "Adding " << procTable->getProcName(tempAns) << " to tuple" << endl;
			}
			else {
				ans = ans + to_string(static_cast<long long>(tempAns)) + " ";
				//// cout << "Adding " << to_string(static_cast<long long>(tempAns)) << " to tuple" << endl;
			}
			//// cout << endl;
		}
		ans = ans.substr(0, ans.length()-1);
		//// cout << "Final Tuple: " << ans << endl;
		//// cout << endl;
		//// cout << endl;
		if(ansSet.find(ans) == ansSet.end()) {
			result.push_back(ans);
			ansSet.insert(ans);
		}
	}
	//// cout << "End creating tuple of answers" << endl;

	//// cout <<"End projecting results"<< endl;
	
}