-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fairer enumerations? #14
Comments
@jwaldmann I'm sorry for the delay in replying.
You are right. That is usually what happens to tuple values within a tier. As you may have noticed, LeanCheck tries to be fair between tiers, but not within them. The idea is that values on the same tier have the same "priority" when tested, none is more important than others. One way to make it so that tests are always fair could be to use size, instead of the number of tests as a parameter to On LeanCheck, I choose to use just the number of tests for two reasons:
The drawback is that LeanCheck may end up being "unfair" to the last tier being tested. Which is what you've just shown on your example. One way to still keep it simpler but loosing fine grained control of runtime, is to define holds as follows:
That way, it will be fair to the last tier being tested -- which is where the unfairness may rise.
Explicitly it is not. Implicitly, somewhat yes. It will be lexicographic only when the underlying enumeration is also lexicographic. I find that property interesting.
In this specific case
This always bugged me a bit, but I never actually went down and tried to solve fairness withing tiers. This reminds me of an earlier unreleased version of LeanCheck I had which did not have the concept of tiers, it was just lists. But enumerations turned out to be very unfair. I think this is quite a hard problem, aggravated by the fact that fairness may be a bit subjective.
I think you are right. As we start to have more complex structures, the effect of the way we combine tiers will have in the enumerations becomes harder to predict intuitively. |
On fairness between tiers and inside tiers: I think in practice most of the time is spent in the "last" tier Anyway, I came up with this "objective" specification: when enumerating values of one tier of a fixed shape (e.g., tuples), for each set of components (indices), the projection of the enumeration to that subset of components should approximate the limit distribution as fast as possible. (It's still inexact - need to explain E.g., 3-tuples of N,
the projection to first component is
For any short prefix of the enumeration, then the projection to the first component will have very uneven distribution. There must be a theorem that says that one could do better. E.g., we can (hypothetically) enumerate the tier completely (or represent it in some other way, e.g., via BDDs) and then take a random permutation (equivalently, draw elements one after another, randomly). |
on fairness - see https://github.com/jwaldmann/fair-enum |
@jwaldmann Interesting... I'll do a careful read soon and I'll be back to this thread with my thoughts. @JonasDuregard already mentioned this in the other thread: FEAT may be more suitable for "shuffling" tiers of values as the enumeration is more efficient and permits efficient sampling of arbitrary values. The following example extracts the 10^10000th (gazillionth?) values on the enumeration of lists of booleans in less than a second:
... and since LeanCheck wasn't designed for sampling like that, it'll run out of memory before you can say gazillionth, haha! Besides FEAT it may also be insteresting to take a look on:
|
currently, leancheck enumerates lexicographically (within each tier):
That means the frequency of changes in the first component is much lower than in the last
(first is moving slowly, last one is busy).
This lexicographic property is not part of the published API? But some tests depend on it.
My expectation (for the API) would be "enumerates each tier in some (unspecified) order",
and I think I prefer a style of enumeration where these changes are distributed more evenly.
I have a version (see recent commits in my fork https://github.com/jwaldmann/leancheck) that gives
There's a nice paper waiting to be written here: what's the "most even" enumeration
(I'm sure there's previous work on codes), and can we obtained it via a nice program?
I think the concept only makes sense if the things to be enumerated have a fixed shape.
So it's not applicable to lists or trees, so overall effect (on my typical leancheck usage)
will probably be small.
The text was updated successfully, but these errors were encountered: