internal void Refine(ISolver <TSet> solver, TSet other) { if (!StackHelper.TryEnsureSufficientExecutionStack()) { StackHelper.CallOnEmptyStack(Refine, solver, other); return; } TSet thisAndOther = solver.And(_set, other); if (!solver.IsEmpty(thisAndOther)) { // The sets overlap, now check if this is contained in other TSet thisMinusOther = solver.And(_set, solver.Not(other)); if (!solver.IsEmpty(thisMinusOther)) { // This is not contained in other, minterms may need to be split if (_left is null) { Debug.Assert(_right is null); _left = new PartitionTree(thisAndOther); _right = new PartitionTree(thisMinusOther); } else { Debug.Assert(_right is not null); _left.Refine(solver, other); _right.Refine(solver, other); } } } }
internal void Refine(IBooleanAlgebra <TPredicate> solver, TPredicate other) { if (!StackHelper.TryEnsureSufficientExecutionStack()) { StackHelper.CallOnEmptyStack(Refine, solver, other); return; } 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, minterms may need to be split if (_left is null) { Debug.Assert(_right is null); _left = new PartitionTree(thisAndOther); _right = new PartitionTree(thisMinusOther); } else { Debug.Assert(_right is not null); _left.Refine(solver, other); _right.Refine(solver, other); } } } }
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 } }