Esempio n. 1
0
void CommutativeRExpTest::testStar()
{
	// 0* = 1
	CPPUNIT_ASSERT( CommutativeRExp::null().star() == CommutativeRExp::one() );

	CPPUNIT_ASSERT( a->star() == CommutativeRExp(CommutativeRExp::Star, std::shared_ptr<CommutativeRExp>(new CommutativeRExp(*a))));
}
// star the whole RExp
CommutativeRExp CommutativeRExp::star() const
{
	if(this->type == Star)
		return *this; // absorb the star
	else if (this->type == Empty)
		return one(); // {}* = ε
	else
		return CommutativeRExp(Star, std::shared_ptr<CommutativeRExp>(new CommutativeRExp(*this))); // star the element
}
Esempio n. 3
0
void CommutativeRExpTest::testStar()
{
	// 0* = 1
	CPPUNIT_ASSERT( CommutativeRExp::null().star() == CommutativeRExp::one() );

	CPPUNIT_ASSERT( a->star() == CommutativeRExp(CommutativeRExp::Star, std::shared_ptr<CommutativeRExp>(new CommutativeRExp(*a))));

  // a.b^* != a.(a+b)^*
  CPPUNIT_ASSERT( (*a) * (*b).star() !=  (*a) * ((*a) + (*b)).star());

}
// try to find a case of xx^* and convert it to x^+
void CommutativeRExp::optimize_starplus()
{
	// we have to be careful, we will modify the set_copy!
	// loop over all elements in the set and find the stared elements
	std::shared_ptr<std::multiset<CommutativeRExp>> set_copy(new std::multiset<CommutativeRExp>());
	*set_copy = *this->setm;
	bool changed = false;
	for(auto it = this->setm->begin(); it != this->setm->end(); ++it)
	{
		if(it->type == Star) // we found a stared element
		{
			// distinguish on the nested type
			switch(it->rexp->type)
			{
				case Element:  // easy, just try to find this element on the outer set, fall through case
				case Addition: // addition behaves like an element in the original multiplication set
				{
					auto elem = set_copy->find(*it->rexp);
					if(elem != set_copy->end())
					{
						// create x^+
						auto plus_elem = CommutativeRExp(Plus, it->rexp);
						// delete both x and x^*
						set_copy->erase(*elem);
						set_copy->erase(*it);
						// then insert x^+
						set_copy->insert(plus_elem);
						changed = true;
					}
					break;
				}
				case Multiplication: // more tricky case, because the inner stared elements are distributed in the original multiplication set
				{
					bool found_all_elements = true;
					// for every element in the starred multiplication
					for(auto it2 = it->rexp->setm->begin(); it2 != it->rexp->setm->end(); ++it2)
					{
						auto elem = set_copy->find(*it2);
						if(elem == set_copy->end())
						{
							found_all_elements = false;
							break;
						}
					}
					if(found_all_elements)
					{
						// create x^+
						auto plus_elem = CommutativeRExp(Plus, it->rexp);
						// delete both x and x^*
						for(auto it2 = it->rexp->setm->begin(); it2 != it->rexp->setm->end(); ++it2)
							set_copy->erase(*it2);
						set_copy->erase(*it);
						// then insert x^+
						set_copy->insert(plus_elem);
						changed = true;
					}
					break;
				}
				case Star:  // should not happen, fall through
				case Plus:  // no idea, what to do, fall through
				case Empty: // should not happen
					assert(false); // we should have been optimizing this, debug more!
					break;
			}
		}

	}
	if(changed)
		this->setm = set_copy;
}