/** * Computes the lowerbound from bottom-up; it will also set a suitable initial value for each * sig's upperbound. Precondition: sig is not a builtin sig */ private TupleSet computeLowerBound(List<Tuple> atoms, final PrimSig sig) throws Err { int n = sc.sig2scope(sig); TupleSet lower = factory.noneOf(1); for (PrimSig c : sig.children()) lower.addAll(computeLowerBound(atoms, c)); TupleSet upper = lower.clone(); boolean isExact = sc.isExact(sig); if (isExact || sig.isTopLevel()) for (n = n - upper.size(); n > 0; n--) { Tuple atom = atoms.remove(atoms.size() - 1); // If MUST<SCOPE and s is exact, then add fresh atoms to both LOWERBOUND and UPPERBOUND. // If MUST<SCOPE and s is inexact but toplevel, then add fresh atoms to the UPPERBOUND. if (isExact) lower.add(atom); upper.add(atom); } lb.put(sig, lower); ub.put(sig, upper); return lower; }