public IEnumerable <BigInteger> EnumerateExcludedValues(BigIntRange searchRange, bool reverse = false)
 {
     if (reverse)
     {
         //If reverse is true, reverse the order of the provided bounds. However, they are expected to be in
         //ascending order, so to make this true, multiply them by negative 1 (and reverse their directions,
         //as well as taking the negative of the search range's limits). Then, take the negative of the results,
         //to get the correct output, still in reverse order.
         return(RangeSet.EnumerateExcludedValues(
                    sortedBounds: _sortedSet.Reverse().Select(x => x.GetNegative()),
                    searchRange: searchRange.GetNegative()
                    ).Select(x => - x));
     }
     else
     {
         return(RangeSet.EnumerateExcludedValues(
                    sortedBounds: _sortedSet,
                    searchRange: searchRange
                    ));
     }
 }
        public static IEnumerable <BigInteger> IterateNonTrivialZeros(BigInteger maxZ, Action <ExpansionTerm> currentPathStartingPointPrinter = null)
        {
            var termOptions = new TermOptionsMatrix(maxZ);

            //	var sortedEliminatedRanges = new List<BigIntRange>();
            var eliminatedRanges = new RangeSet();

            BigInteger prevStartingPointEval = BigInteger.Zero;             //Starts lower than any evaluated starting point

            foreach (ExpansionTerm pathStartingPoint in EnumerateSortedTermOptions())
            {
                currentPathStartingPointPrinter?.Invoke(pathStartingPoint);
                //	Console.WriteLine("#25 current starting point: " + pathStartingPoint);

                //	//Debugging:
                //	eliminatedRanges.DebugBounds();
                //	foreach (var range in eliminatedRanges.IncludedRanges) {
                //		Console.WriteLine("#40: " + range.Start + " to " + range.End);
                //	}
                //	Console.WriteLine("#41: " + eliminatedRanges.Count);

                BigInteger startingPointEval = pathStartingPoint.Evaluate();

                if (startingPointEval > maxZ)
                {
                    //If gone past end of requested range, return all remaining stored values
                    //up to end of requested range, then stop enumerating.
                    var gaps = eliminatedRanges.EnumerateExcludedValues(
                        searchRange: BigIntRange.CreateStartEnd(
                            start: prevStartingPointEval + 1,
                            end: maxZ
                            )
                        );
                    foreach (BigInteger gap in gaps)
                    {
                        yield return(gap);
                    }
                    //	foreach (var range in eliminatedRanges.IncludedRanges) {
                    //		Console.WriteLine("#42: " + range.Start + " to " + range.End);
                    //	}
                    //	Console.WriteLine("#43: " + eliminatedRanges.Count);
                    yield break;
                }

                foreach (BigInteger summedPath in termOptions.EnumerateSummedExpansionPaths(pathStartingPoint, capToMaximum: true))
                {
                    //	Console.WriteLine("#44: " + summedPath + ", " + expansionPath.ToString(includeSpaces: false));

                    BigInteger newRangeMax = summedPath;
                    BigInteger newRangeMin = summedPath;

                    //	Console.WriteLine("#44.1: " + newRangeMin + ", " + newRangeMax);

                    //Exclude adjacent trivial zeros (multiples of 3) as well
                    if ((newRangeMax + 1) % 3 == 0)
                    {
                        newRangeMax += 1;
                    }
                    if ((newRangeMin - 1) % 3 == 0)
                    {
                        newRangeMin -= 1;
                    }

                    //	Console.WriteLine("#44.2: " + newRangeMin + ", " + newRangeMax);

                    //	Console.WriteLine("#45: " + eliminatedRanges.Count);
                    eliminatedRanges.AddRange(BigIntRange.CreateStartEnd(newRangeMin, newRangeMax));
                    //	Console.WriteLine("#46: " + eliminatedRanges.Count);
                }

                {
                    //	Console.WriteLine("#47: " + eliminatedRanges.Count);
                    var gaps = eliminatedRanges.EnumerateExcludedValues(
                        searchRange: BigIntRange.CreateStartEnd(
                            start: prevStartingPointEval + 1,
                            end: startingPointEval
                            )
                        );
                    foreach (BigInteger gap in gaps)
                    {
                        yield return(gap);
                    }
                    //	Console.WriteLine("#48");
                }

                prevStartingPointEval = startingPointEval;
            }
        }