/*****************************************************************************/
/*!
*\file assumptions.cpp
*\brief Implementation of class Assumptions
*
* Author: Clark Barrett
*
* Created: Thu Jan 5 06:25:52 2006
*
*
*
* License to use, copy, modify, sell and/or distribute this software
* and its documentation for any purpose is hereby granted without
* royalty, subject to the terms and conditions defined in the \ref
* LICENSE file provided with this distribution.
*
*
*
*/
/*****************************************************************************/
#include
#include "assumptions.h"
using namespace std;
using namespace CVC3;
Assumptions Assumptions::s_empty;
const Theorem& Assumptions::findTheorem(const Expr& e) const {
static Theorem null;
// TRACE_MSG("assumptions", "findTheorem");
const Theorem& t = find(e);
if (!t.isNull()) return t;
// recurse
const vector::const_iterator aend = d_vector.end();
for (vector::const_iterator iter2 = d_vector.begin();
iter2 != aend; ++iter2) {
if (iter2->isRefl() || !iter2->isFlagged()) {
if (compare(*iter2, e) == 0) return *iter2;
if (!iter2->isAssump()) {
const Theorem& t = iter2->getAssumptionsRef().findTheorem(e);
if (!t.isNull()) return t;
}
if (!iter2->isRefl()) iter2->setFlag();
}
}
return null; // not found
}
bool Assumptions::findExpr(const Assumptions& a,
const Expr& e, vector& gamma) {
bool found = false;
const Assumptions::iterator aend = a.end();
Assumptions::iterator iter = a.begin();
for (; iter != aend; ++iter) {
if (iter->isRefl()) continue;
if (iter->isFlagged()) {
if (iter->getCachedValue()) found = true;
}
else {
if ((iter->getExpr() == e) ||
(!iter->isAssump() &&
findExpr(iter->getAssumptionsRef(), e, gamma))) {
found = true;
iter->setCachedValue(true);
}
else iter->setCachedValue(false);
iter->setFlag();
}
}
if (found) {
for (iter = a.begin(); iter != aend; ++iter) {
if (iter->isRefl()) continue;
if (!iter->getCachedValue()) gamma.push_back(*iter);
}
}
return found;
}
bool Assumptions::findExprs(const Assumptions& a, const vector& es,
vector& gamma) {
bool found = false;
const vector::const_iterator esbegin = es.begin();
const vector::const_iterator esend = es.end();
const Assumptions::iterator aend = a.end();
Assumptions::iterator iter = a.begin();
for (; iter != aend; ++iter) {
if (iter->isRefl()) continue;
else if (iter->isFlagged()) {
if (iter->getCachedValue()) found = true;
}
else {
// switch to binary search below? (sort es first)
if ((::find(esbegin, esend, iter->getExpr()) != esend) ||
(!iter->isAssump() &&
findExprs(iter->getAssumptionsRef(), es, gamma))) {
found = true;
iter->setCachedValue(true);
}
else iter->setCachedValue(false);
iter->setFlag();
}
}
if (found) {
for (iter = a.begin(); iter != aend; ++iter) {
if (iter->isRefl()) continue;
if (!iter->getCachedValue()) gamma.push_back(*iter);
}
}
return found;
}
Assumptions::Assumptions(const vector& v) {
if (v.empty()) return;
d_vector.reserve(v.size());
const vector::const_iterator iend = v.end();
vector::const_iterator i = v.begin();
for (;i != iend; ++i) {
if ((!i->getAssumptionsRef().empty())) {
d_vector.push_back(*i);
}
}
if (d_vector.size() <= 1) return;
sort(d_vector.begin(), d_vector.end());
vector::iterator newend =
unique(d_vector.begin(), d_vector.end(), Theorem::TheoremEq);
d_vector.resize(newend - d_vector.begin());
}
Assumptions::Assumptions(const Theorem& t1, const Theorem& t2)
{
if (!t1.getAssumptionsRef().empty()) {
if (!t2.getAssumptionsRef().empty()) {
switch(compare(t1, t2)) {
case -1: // t1 < t2:
d_vector.push_back(t1);
d_vector.push_back(t2);
break;
case 0: // t1 == t2:
d_vector.push_back(t1);
break;
case 1: // t1 > t2:
d_vector.push_back(t2);
d_vector.push_back(t1);
break;
}
} else d_vector.push_back(t1);
} else if (!t2.getAssumptionsRef().empty()) {
d_vector.push_back(t2);
}
}
void Assumptions::add(const Theorem& t)
{
if (t.getAssumptionsRef().empty()) return;
vector::iterator iter, iend = d_vector.end();
iter = lower_bound(d_vector.begin(), iend, t);
if (iter != iend && compare(t, *iter) == 0) return;
d_vector.insert(iter, t);
}
void Assumptions::add(const std::vector& thms)
{
if (thms.size() == 0) return;
IF_DEBUG(
vector::const_iterator iend = thms.end();
for (vector::const_iterator i = thms.begin();
i != iend; ++i) {
if (i+1 == iend) break;
DebugAssert(compare(*i, *(i+1)) == -1, "Expected sorted");
}
)
vector v;
v.reserve(d_vector.size()+thms.size());
vector::const_iterator i = d_vector.begin();
vector::const_iterator j = thms.begin();
const vector::const_iterator v1end = d_vector.end();
const vector::const_iterator v2end = thms.end();
// merge
while (i != v1end && j != v2end) {
if (j->getAssumptionsRef().empty()) {
++j;
continue;
}
switch(compare(*i, *j)) {
case 0:
// copy only 1, drop down to next case
++j;
case -1: // <
v.push_back(*i);
++i;
break;
default: // >
v.push_back(*j);
++j;
};
}
// Push in the remaining elements
for(; i != v1end; ++i) v.push_back(*i);
for(; j != v2end; ++j) {
if (!j->getAssumptionsRef().empty())
v.push_back(*j);
}
d_vector.swap(v);
}
string Assumptions::toString() const {
ostringstream ss;
ss << (*this);
return ss.str();
}
void Assumptions::print() const
{
cout << toString() << endl;
}
const Theorem& Assumptions::operator[](const Expr& e) const {
if (!d_vector.empty()) {
d_vector.front().clearAllFlags();
}
return findTheorem(e);
}
const Theorem& Assumptions::find(const Expr& e) const {
static Theorem null;
// binary search
int lo = 0;
int hi = d_vector.size() - 1;
int loc;
while (lo <= hi) {
loc = (lo + hi) / 2;
switch (compare(d_vector[loc], e)) {
case 0: return d_vector[loc];
case -1: // t < e
lo = loc + 1;
break;
default: // t > e
hi = loc - 1;
};
}
return null;
}
////////////////////////////////////////////////////////////////////
// Assumptions friend methods
////////////////////////////////////////////////////////////////////
namespace CVC3 {
Assumptions operator-(const Assumptions& a, const Expr& e) {
if (a.begin() != a.end()) {
a.begin()->clearAllFlags();
vector gamma;
if (Assumptions::findExpr(a, e, gamma)) return Assumptions(gamma);
}
return a;
}
Assumptions operator-(const Assumptions& a, const vector& es) {
if (!es.empty() && a.begin() != a.end()) {
a.begin()->clearAllFlags();
vector gamma;
if (Assumptions::findExprs(a, es, gamma)) return Assumptions(gamma);
}
return a;
}
ostream& operator<<(ostream& os, const Assumptions &assump) {
vector::const_iterator i = assump.d_vector.begin();
const vector::const_iterator iend = assump.d_vector.end();
if(i != iend) { os << i->getExpr(); i++; }
for(; i != iend; i++) os << ",\n " << i->getExpr();
return os;
}
} // end of namespace CVC3