Skip to content

Instantly share code, notes, and snippets.

@AlgorithmsAreCool
Created February 22, 2023 20:02
Show Gist options
  • Save AlgorithmsAreCool/31530f7d63fc17461c1d5dd77a35b504 to your computer and use it in GitHub Desktop.
Save AlgorithmsAreCool/31530f7d63fc17461c1d5dd77a35b504 to your computer and use it in GitHub Desktop.
Testing CsCheck's coverage of constrained search spaces
// See https://aka.ms/new-console-template for more information
using CsCheck;
Console.WriteLine("Hello, World!");
TestIteratedDirectIntegerSpaceCoverage();
void TestEnumeratedSpaceCoverage()
{
const int iterations = 1000;
const int spaceCardinality = 16;
int totalCoverageCount = 0;
int coverageSum = 0;
var pointGenerator = Gen.Select(
Gen.Bool, Gen.Bool, Gen.Bool, Gen.Bool,
(a, b, c, d) => new PointInSpace(a, b, c, d)
);
for (int i = 0; i < iterations; i++)
{
pointGenerator.Enumerable.SampleOne(pointEnumerable =>
{
var dis = pointEnumerable.Take(spaceCardinality).Distinct();
var count = dis.Count();
//Console.WriteLine(count);
coverageSum += count;
if (count == spaceCardinality)
totalCoverageCount++;
});
}
Console.WriteLine($"Covered the entire search space in ({totalCoverageCount}) {(decimal)totalCoverageCount / iterations:P2} of cases");
Console.WriteLine($"Covered an average of {(decimal)coverageSum / (iterations * spaceCardinality):P2} cases");
}
void TestIteratedSpaceCoverage()
{
const int iterations = 1000;
const int spaceCardinality = 16;
int totalCoverageCount = 0;
int coverageSum = 0;
var pointGenerator = Gen.Select(
Gen.Bool, Gen.Bool, Gen.Bool, Gen.Bool,
(a, b, c, d) => new PointInSpace(a, b, c, d)
);
for (int i = 0; i < iterations; i++)
{
var uniquePoints = new HashSet<PointInSpace>();
pointGenerator.Sample(
point =>{
uniquePoints.Add(point);
},
iter: spaceCardinality,
threads: 1
);
coverageSum += uniquePoints.Count;
if (uniquePoints.Count == spaceCardinality)
totalCoverageCount++;
}
Console.WriteLine($"Covered the entire search space in ({totalCoverageCount}) {(decimal)totalCoverageCount / iterations:P2} of cases");
Console.WriteLine($"Covered an average of {(decimal)coverageSum / (iterations * spaceCardinality):P2} cases");
}
void TestIteratedIntegerSpaceCoverage()
{
const int iterations = 10000000;
const int spaceCardinality = 16;
int totalCoverageCount = 0;
int coverageSum = 0;
var pointGenerator = Gen.Select(
Gen.Int,
i => new PointInSpace(
(i & 1) == 0,
(i & 2) == 0,
(i & 4) == 0,
(i & 8) == 0)
);
for (int i = 0; i < iterations; i++)
{
var uniquePoints = new HashSet<PointInSpace>();
pointGenerator.Sample(
point =>
{
uniquePoints.Add(point);
},
iter: spaceCardinality,
threads: 1
);
coverageSum += uniquePoints.Count;
if (uniquePoints.Count == spaceCardinality)
totalCoverageCount++;
}
Console.WriteLine($"Covered the entire search space in ({totalCoverageCount}) {(decimal)totalCoverageCount / iterations:P8} of cases");
Console.WriteLine($"Covered an average of {(decimal)coverageSum / (iterations * spaceCardinality):P8} cases");
}
void TestIteratedDirectIntegerSpaceCoverage()
{
const int iterations = 10000000;
const int spaceCardinality = 16;
int totalCoverageCount = 0;
int coverageSum = 0;
var intGen = Gen.Int[0, spaceCardinality];
for (int i = 0; i < iterations; i++)
{
var uniquePoints = new HashSet<int>();
intGen.Sample(
point => {
uniquePoints.Add(point);
},
iter: spaceCardinality,
threads: 1
);
coverageSum += uniquePoints.Count;
if (uniquePoints.Count == spaceCardinality)
totalCoverageCount++;
}
Console.WriteLine($"Covered the entire search space in ({totalCoverageCount}) {(decimal)totalCoverageCount / iterations:P8} of cases");
Console.WriteLine($"Covered an average of {(decimal)coverageSum / (iterations * spaceCardinality):P8} cases");
}
public record PointInSpace(bool A, bool B, bool C, bool D);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment