Example #1
0
File: prover.c Project: ombt/ombt
// resolve two clauses, if possible.
int
resolveClauses(Array<OrderedSet<Clause> > &clausesArray, 
	Clause &cl1, Clause &cl2, int &clausesAdded, unsigned int currentDepth)
{
	// clear this flag
	clausesAdded = 0;

	// check if any of the clauses are empty
	if (cl1.isEmpty() || cl2.isEmpty())
	{
		return(VALID);
	}

	// check if clauses can be resolved
	if (!cl1.getSOS() && cl2.getSOS())
	{
		// one clause must be in the set-of-support
		return(NOMATCH);
	}
	if ((cl1.getType() == Clause::Negative && 
	     cl2.getType() == Clause::Negative) ||
	    (cl1.getType() == Clause::Positive && 
	     cl2.getType() == Clause::Positive))
	{
		// two positive clauses or two negative clauses
		// can not be resolved.
		return(NOMATCH);
	}

	// attempt to resolve two clauses. use A-ordering resolution,
	// try to resolve maximal literals.
	//
	Literal maxlit1;
	if (cl1.getMaximalLiteral(maxlit1) != OK)
	{
		return(NOTOK);
	}
	Literal maxlit2;
	if (cl2.getMaximalLiteral(maxlit2) != OK)
	{
		return(NOTOK);
	}
	if (maxlit1 != ~maxlit2)
	{
		return(NOMATCH);
	}

	// factor clauses
	if (factor(maxlit1, cl1) == NOTOK)
	{
		return(NOTOK);
	}
	if (factor(maxlit2, cl2) == NOTOK)
	{
		return(NOTOK);
	}

	// attempt to unify the clauses
	Substitutions subs;
	if (unify(maxlit1, ~maxlit2, subs) != OK)
	{
		return(NOMATCH);
	}

	// can resolve, remove literals from clauses
	Clause newcl1(cl1);
	if (newcl1.remove(maxlit1, 1) != OK)
	{
		return(NOTOK);
	}
	if (subs.applyTo(newcl1) != OK)
	{
		return(NOTOK);
	}
	Clause newcl2(cl2);
	if (newcl2.remove(maxlit2, 1) != OK)
	{
		return(NOTOK);
	}
	if (subs.applyTo(newcl2) != OK)
	{
		return(NOTOK);
	}

	// store new clause and update flag
	Clause newcl = newcl1+newcl2;
	if (newcl.renameVariables() != OK)
	{
		return(NOTOK);
	}
	newcl.setDepth(currentDepth+1);
	newcl.setNumber(nextClause++);
	if (clausesArray[currentDepth+1].insert(newcl) != OK)
	{
		return(NOTOK);
	}
	clausesAdded = 1;

	// indicate the clauses that were resolved
	dumpnewclause(cl1, cl2, newcl);

	// check if we found an empty clause
	if (newcl.isEmpty())
	{
		return(VALID);
	}
	else
	{
		return(OK);
	}
}
Example #2
0
File: clause.cpp Project: ombt/ombt
// rename variables in clause
int
Clause::renameVariables()
{
	Clause newcl;
	Map<String, String> nvs;

	// rename variables in positive clause
	BinaryTree_AVL_Iterator_InOrder<Literal> pclIter(positiveClause);
	for ( ; !pclIter.done(); pclIter++)
	{
		Literal literal(pclIter());
		if (literal.renameVariables(nvs) != OK)
		{
			ERROR("renameVariables failed.", errno);
			return(NOTOK);
		}
		if (newcl.insert(literal) != OK)
		{
			ERROR("insert failed.", errno);
			return(NOTOK);
		}
	}

	// rename variables in negative clause
	BinaryTree_AVL_Iterator_InOrder<Literal> nclIter(negativeClause);
	for ( ; !nclIter.done(); nclIter++)
	{
		Literal literal(nclIter());
		if (literal.renameVariables(nvs) != OK)
		{
			ERROR("renameVariables failed.", errno);
			return(NOTOK);
		}
		if (newcl.insert(literal) != OK)
		{
			ERROR("insert failed.", errno);
			return(NOTOK);
		}
	}

	// rename variables in answers clause
	ListIterator<Literal> ansIter(answers);
	for ( ; !ansIter.done(); ansIter++)
	{
		Literal literal(ansIter());
		if (literal.renameVariables(nvs) != OK)
		{
			ERROR("renameVariables failed.", errno);
			return(NOTOK);
		}
		if (newcl.insertAnswer(literal) != OK)
		{
			ERROR("insert failed.", errno);
			return(NOTOK);
		}
	}

#if 0
	// update table of renamed variables
	if (updateVariableNames(nvs) != OK)
		return(NOTOK);
#endif

	// overwrite existing clauses
	newcl.setDepth(getDepth());
	newcl.setNumber(getNumber());
	newcl.setConclusion(getConclusion());
	newcl.setQuery(getQuery());
	newcl.setSOS(getSOS());
	*this = newcl;

	// all done
	return(OK);
}
Example #3
0
File: prover.c Project: ombt/ombt
// resolve two clauses, if possible.
int
resolveClauses(Array<BinaryTree_AVL<Clause> > &clausesArray, 
	Clause &cl1, Clause &cl2, int &clausesAdded, unsigned int currentDepth)
{
	// check if any of the clauses are empty
	statistics[ResolutionsAttempted] += 1;
	totalstatistics[TotalResolutionsAttempted] += 1;
	if (cl1.isEmpty() || cl2.isEmpty())
	{
		return(VALID);
	}

	// check if clauses can be resolved
	if (!cl1.getSOS() && !cl2.getSOS())
	{
		// one clause must be in the set-of-support
		return(NOMATCH);
	}
	if ((cl1.getType() == Clause::Negative && 
	     cl2.getType() == Clause::Negative) ||
	    (cl1.getType() == Clause::Positive && 
	     cl2.getType() == Clause::Positive))
	{
		// two positive clauses or two negative clauses
		// can not be resolved.
		return(NOMATCH);
	}

	// attempt to resolve two clauses. use A-ordering resolution,
	// try to resolve maximal literals.
	//
	Literal maxlit1;
	if (cl1.getMaximalLiteral(maxlit1) != OK)
	{
		ERROR("getMaximalLiteral failed.", errno);
		return(NOTOK);
	}
	Literal maxlit2;
	if (cl2.getMaximalLiteral(maxlit2) != OK)
	{
		ERROR("getMaximalLiteral failed.", errno);
		return(NOTOK);
	}
	if ((cl1.getTotalMembers() > maxliterals) ||
	    (cl2.getTotalMembers() > maxliterals))
	{
		statistics[MaximumLiteralsClausesRejected] += 1;
		totalstatistics[TotalMaximumLiteralsClausesRejected] += 1;
		return(NOMATCH);
	}
	if (maxlit1.unify_ne(~maxlit2))
	{
		return(NOMATCH);
	}

	// factor clauses
	Substitutions subs;
	if (factor(maxlit1, cl1, subs) == NOTOK)
	{
		ERROR("factor failed.", errno);
		return(NOTOK);
	}
	if (factor(maxlit2, cl2, subs) == NOTOK)
	{
		ERROR("factor failed.", errno);
		return(NOTOK);
	}

	// attempt to unify the clauses
	subs.clear();
	int status = unify(maxlit1, ~maxlit2, subs);
	switch (status)
	{
	case OK:
		if (verbose)
		{
			cout << endl;
			Literal ml1(maxlit1);
			cout << "max literal 1 (before subs): " << ml1 << endl;
			subs.applyTo(ml1);
			cout << "max literal 1 (after subs): " << ml1 << endl;
			Literal ml2(maxlit2);
			cout << "max literal 2 (before subs): " << ml2 << endl;
			subs.applyTo(ml2);
			cout << "max literal 2 (after subs): " << ml2 << endl;
			MustBeTrue(equal(ml1, ~ml2));
		}
		break;
	case NOMATCH:
		return(NOMATCH);
	default:
		ERROR("unify failed.", errno);
		return(status);
	}

	// can resolve, remove literals from clauses
	Clause newcl1(cl1);
	if (newcl1.remove(maxlit1) != OK)
	{
		ERROR("remove failed.", errno);
		return(NOTOK);
	}
	if (subs.applyTo(newcl1) != OK)
	{
		ERROR("applyTo failed.", errno);
		return(NOTOK);
	}
	Clause newcl2(cl2);
	if (newcl2.remove(maxlit2) != OK)
	{
		ERROR("remove failed.", errno);
		return(NOTOK);
	}
	if (subs.applyTo(newcl2) != OK)
	{
		ERROR("applyTo failed.", errno);
		return(NOTOK);
	}

	// store new clause and update flag
	Clause newcl = newcl1+newcl2;
	if (newcl.renameVariables() != OK)
	{
		ERROR("renameVariables failed.", errno);
		return(NOTOK);
	}
	newcl.setDepth(currentDepth+1);
	newcl.setNumber(nextClause++);
	if (clausesArray[currentDepth+1].insert(newcl) != OK)
	{
		ERROR("insert failed.", errno);
		return(NOTOK);
	}
	clausesAdded = 1;

	// indicate the clauses that were resolved
	statistics[ClausesGenerated] += 1;
	totalstatistics[TotalClausesGenerated] += 1;
	dumpnewclause(cl1, cl2, newcl);

	// check if we found an empty clause
	if (newcl.isEmpty())
	{
		return(VALID);
	}
	else
	{
		return(OK);
	}
}