Beispiel #1
0
void Constraints::substIntoEquates(ConstraintMap& in) {
	// Substitute the fixed types into the equates. This may generate more
	// fixed types
	ConstraintMap extra;
	ConstraintMap cur = in;
	while (cur.size()) {
		extra.clear();
		ConstraintMap::iterator kk;
		for (kk = cur.begin(); kk != cur.end(); kk++) {
			Exp* lhs = kk->first;
			std::map<Exp*, LocationSet, lessExpStar>::iterator it = equates.find(lhs);
			if (it != equates.end()) {
				// Possibly new constraints that
				// typeof(elements in it->second) == val
				Exp* val = kk->second;
				LocationSet& ls = it->second;
				LocationSet::iterator ll;
				for (ll = ls.begin(); ll != ls.end(); ll++) {
					ConstraintMap::iterator ff;
					ff = fixed.find(*ll);
					if (ff != fixed.end()) {
						if (!unify(val, ff->second, extra)) {
							if (VERBOSE || DEBUG_TA)
								LOG << "Constraint failure: " << *ll << " constrained to be " <<
									((TypeVal*)val)->getType()->getCtype() << " and " <<
									((TypeVal*)ff->second)->getType()->getCtype() << "\n";
							return;
						}
					} else
						extra[*ll] = val;	// A new constant constraint
				}
				if (((TypeVal*)val)->getType()->isComplete()) {
					// We have a complete type equal to one or more variables
					// Remove the equate, and generate more fixed
					// e.g. Ta = Tb,Tc and Ta = K => Tb=K, Tc=K
					for (ll = ls.begin(); ll != ls.end(); ll++) {
						Exp* newFixed = new Binary(opEquals,
							*ll,		// e.g. Tb
							val);		// e.g. K
							extra.insert(newFixed);
					}
					equates.erase(it);
				}
			}
		}
		fixed.makeUnion(extra);
		cur = extra;	// Take care of any "ripple effect"
	}					// Repeat until no ripples
}
Beispiel #2
0
// Constraints up to but not including iterator it have been unified.
// The current solution is soln
// The set of all solutions is in solns
bool Constraints::doSolve(std::list<Exp*>::iterator it, ConstraintMap& soln, std::list<ConstraintMap>& solns) {
LOG << "Begin doSolve at level " << ++level << "\n";
LOG << "Soln now: " << soln.prints() << "\n";
	if (it == disjunctions.end()) {
		// We have gotten to the end with no unification failures
		// Copy the current set of constraints as a solution
		//if (soln.size() == 0)
			// Awkward. There is a trivial solution, but we have no constraints
			// So make a constraint of always-true
			//soln.insert(new Terminal(opTrue));
		// Copy the fixed constraints
		soln.makeUnion(fixed);
		solns.push_back(soln);
LOG << "Exiting doSolve at level " << level-- << " returning true\n";
		return true;
	}

	Exp* dj = *it;
	// Iterate through each disjunction d of dj
	Exp* rem1 = dj;		  // Remainder
	bool anyUnified = false;
	Exp* d;
	while ((d = nextDisjunct(rem1)) != NULL) {
LOG << " $$ d is " << d << ", rem1 is " << ((rem1==0)?"NULL":rem1->prints()) << " $$\n";
		// Match disjunct d against the fixed types; it could be compatible,
		// compatible and generate an additional constraint, or be
		// incompatible
		ConstraintMap extra;	  // Just for this disjunct
		Exp* c;
		Exp* rem2 = d;
		bool unified = true;
		while ((c = nextConjunct(rem2)) != NULL) {
LOG << "   $$ c is " << c << ", rem2 is " << ((rem2==0)?"NULL":rem2->prints()) << " $$\n";
			if (c->isFalse()) {
				unified = false;
				break;
			}
			assert(c->isEquality());
			Exp* lhs = ((Binary*)c)->getSubExp1();
			Exp* rhs = ((Binary*)c)->getSubExp2();
			extra.insert(lhs, rhs);
			ConstraintMap::iterator kk;
			kk = fixed.find(lhs);
			if (kk != fixed.end()) {
				unified &= unify(rhs, kk->second, extra);
LOG << "Unified now " << unified << "; extra now " << extra.prints() << "\n";
				if (!unified) break;
			}
		}
		if (unified)
			// True if any disjuncts had all the conjuncts satisfied
			anyUnified = true;
		if (!unified) continue;
		// Use this disjunct
		// We can't just difference out extra if this fails; it may remove
		// elements from soln that should not be removed
		// So need a copy of the old set in oldSoln
		ConstraintMap oldSoln = soln;
		soln.makeUnion(extra);
		doSolve(++it, soln, solns);
		// Revert to the previous soln (whether doSolve returned true or not)
		// If this recursion did any good, it will have gotten to the end and
		// added the resultant soln to solns
		soln = oldSoln;
LOG << "After doSolve returned: soln back to: " << soln.prints() << "\n";
		// Back to the current disjunction
		it--;
		// Continue for more disjuncts this disjunction
	}
	// We have run out of disjuncts. Return true if any disjuncts had no
	// unification failures
LOG << "Exiting doSolve at level " << level-- << " returning " << anyUnified << "\n";
	return anyUnified;
}