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
                    }
                }