internal void Refine(TPredicate other) { if (!StackHelper.TryEnsureSufficientExecutionStack()) { StackHelper.CallOnEmptyStack(Refine, other); return; } if (_left is null && _right is null) { // If this is a leaf node create left and/or right children for the new predicate TPredicate thisAndOther = _solver.And(_pred, other); if (_solver.IsSatisfiable(thisAndOther)) { // The predicates overlap, now check if this is contained in other TPredicate thisMinusOther = _solver.And(_pred, _solver.Not(other)); if (_solver.IsSatisfiable(thisMinusOther)) { // This is not contained in other, both children are needed _left = new PartitionTree(_solver, thisAndOther, null, null); // The right child corresponds to a conjunction with a negation, which matches thisMinusOther _right = new PartitionTree(_solver, thisMinusOther, null, null); } else // [[this]] subset of [[other]] { // Other implies this, so populate the left child with this _left = new PartitionTree(_solver, _pred, null, null); } } else // [[this]] subset of [[not(other)]] { // negation of other implies this, so populate the right child with this _right = new PartitionTree(_solver, _pred, null, null); //other must be false } }