public Rule?TryCreateRule(ReadOnlySpan <Rule> existingRules)
        {
            var seedsIndices = _seedSelector.FindSeedsIndices(existingRules);

            if (seedsIndices.IsEmpty)
            {
                return(null);
            }

            var seedIndex = Random.Choice(seedsIndices);
            var seed      = _dataset.GetInstanceData(seedIndex);

            var boxes = _boxConverter.FromRules(existingRules);

            if (_runExpensiveSanityChecks)
            {
                for (int i = 0; i < boxes.Length; i++)
                {
                    var box = boxes[i];
                    if (box.Contains(seed))
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            var dimensionExpansionOrder = NaturalRange.CreateShuffled(
                inclusiveStart: 0,
                exclusiveEnd: _dataset.FeatureCount);

            var secureRectangle = _boxCreator.TryCreateLargestNonIntersectingRectangle(
                seedIndex: seedIndex,
                existingHyperRectangles: boxes,
                dimensionExpansionOrder: dimensionExpansionOrder);

            if (secureRectangle is null)
            {
                return(null);
            }

            if (_runExpensiveSanityChecks)
            {
                for (int i = 0; i < boxes.Length; i++)
                {
                    var box = boxes[i];
                    if (_rectangleIntersector.IntersectsInAllDimension(secureRectangle, box))
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            var secureRectangleCoverage = _coverageComputer.ComputeCoverage(secureRectangle);
            var coveredInstancesIndices = secureRectangleCoverage.IndicesOfCoveredInstances.ToArray();

            if (coveredInstancesIndices.Length == 0)
            {
                return(null);
            }

            var coveredInstancesDistancesToSeed = _dataset.ComputeDistances(
                targetInstanceIndex: seedIndex,
                otherInstancesIndices: coveredInstancesIndices);

            Array.Sort(
                keys: coveredInstancesDistancesToSeed,
                items: coveredInstancesIndices);

            var instancesToCover  = Math.Min(_targetNumberOfInstancesToCover, coveredInstancesIndices.Length);
            var relevantInstances = coveredInstancesIndices
                                    .AsSpan()
                                    .Slice(start: 0, length: instancesToCover);

            var ruleAntecedent = _antecedentCreator.CreateAntecedent(
                seedIndex: seedIndex,
                nearestInstancesIndices: relevantInstances);

            if (ruleAntecedent is null)
            {
                return(null);
            }

            var ruleConsequent = _consequentCreator.CreateConsequent(relevantInstances);

            return(new Rule(
                       antecedent: ruleAntecedent,
                       consequent: ruleConsequent));
        }