Example #1
0
// factor the literals in a clause. the current implementation
// attempts to unify only two terms. 
//
int
factor(Literal &fl, Clause &cl, Substitutions &flsubs)
{
	// clear substitutions
	flsubs.clear();

	// scan clause for possible literals to unify
	List<Literal> flset;
	ClauseIterator clIter(cl);
	for ( ; !clIter.done() && clIter().lt(fl); clIter++)
	{
		// do nothing
	}
	for ( ; !clIter.done() && clIter().eq(fl); clIter++)
	{
		MustBeTrue(flset.insertAtEnd(clIter()) == OK);
	}

	// check if there is more than one literal in the set
	if (flset.getCount() < 2)
	{
		return(NOMATCH);
	}

	// try to find a factor
	int factorfound = 0;
	Substitutions subs;
	ListIterator<Literal> flsetIter(flset);
	for ( ; !flsetIter.done() && !factorfound; flsetIter++)
	{
		// we found the key literal
		if (fl == flsetIter())
		{
			// skip key literal
			continue;
		}

		// try to unify
		subs.clear();
		if (unify(fl, flsetIter(), subs) == OK)
		{
			// literals unified
			factorfound++;
			break;
		}
	}
	if (!factorfound)
	{
		return(NOMATCH);
	}

	// key literal should be in the clause
	Literal tmp_fl(fl);
	if (cl.retrieve(tmp_fl) != OK)
	{
		// key literal was NOT found. not possible.
		ERROR("key literal was not found.", errno);
		return(NOTOK);
	}

	// remove factor literal
	if (verbose)
	{
		cout << endl;
		cout << "clause before factoring ... " << cl << endl;
	}
	Literal fl2(flsetIter());
	if (cl.remove(fl2) != OK)
	{
		// factor literal was NOT found.
		ERROR("unable to remove factor key literal.", errno);
		return(NOTOK);
	}

	// apply substitutions to entire clause
	if (subs.applyTo(cl) != OK)
	{
		ERROR("applyTo failed.", errno);
		return(NOTOK);
	}
	if (verbose)
	{
		cout << "factored literal ... " << fl2 << endl;
		cout << "clause after factoring ... " << cl << endl;
	}

	// return substitutions
	flsubs = subs;

	// all done
	return(OK);
}