-
Notifications
You must be signed in to change notification settings - Fork 126
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
Sorting primitives #1032
Comments
Perhaps a useful generalization of
An ordinary
When used with type If we implement the sorting functions using a sorting network, they would probably work reasonably well even on symbolic inputs. A sorting algorithm would be particularly nice to have in the standard library because it is a pretty tricky thing for users to implement themselves in Cryptol. |
Humm, yeah, a sorting primitive is an interesting idea. I think |
I like the idea of the |
If we provide a Unfortunately the most efficient generic sorting networks like bitonic mergesort are not generally stable, but you can add a bit of extra structure to make them stable (by pairing each value with its index and including that in the comparisons). Another alternative would be to use an insertion-sort-style sorting network, which only does compare-and-swap of adjacent values, and is therefore stable. The algorithm would be quite simple to specify too. However, it would have worse asymptotics (O(n^2) swaps compared to O(n log^2 n) for bitonic mergesort). |
Here's an insertion sort that I believe to be stable:
The implementation would be a bit nicer if we implemented #701. |
I guess the interesting question to answer is "which formulation produces better symbolic formulae?" I suspect a bitonic sort with comparisons incorporating the original position will be slightly better, as the comparisons on positions will all start concrete, and the generated mux trees over positions will only depend on the results of comparisons made earlier in the sorting network. |
Using the above definition of
Setting I could also prove that the first and last elements are the right way around:
Most properties about
So it seems that the insertion-sort-style sorting network is at least somewhat reasonable for symbolic stuff. The performance on concrete input is not so great though; sorting a list of 1000 integers takes about 8 or 9 seconds on my machine, and that grows quadratically with the length of the list. |
Here's another one that I thought Z3 did surprisingly well on:
|
I got this one to go through...
|
Here's a mergesort for kicks and giggles, along with some properties of sorts. Unfortunately, this version performs more poorly on most of the same properties as tried for the insertion sort earlier:
Here's a runthrough of some more explicit sort properties:
Specifying in Cryptol whether an arbitrary sort is stable (w.r.t. its comparator) has thus far eluded me... |
OK, this attachment defines stable sorts, orders, and some utility functions in distinct modules.
|
Should we add basically this implementation to the Prelude and later consider the question of making it a primitive? |
The original post asked it would be nice to have some primitives that give users the "feeling" of having variable length sequences. It is interesting to see if we can take that seriously. Here's a module for lists:
Given that, here's an insertion sort:
Or, with even more of a lispy feel, here' a merge sort
The merge sort is more efficient at longer lists.
And we can still prove properties for fixed-length inputs.
Perhaps this is more of the "feel" that @weaversa was looking for? |
Thanks @msaaltink! I like the list type using
Here's also a nice dictionary data structure (showed to me by @LeventErkok 11ish years ago):
|
If people might be interested, I've implemented djbsort (https://sorting.cr.yp.to/) for 32-bit signed integers in Cryptol (it's basically a sorting network). Just found this issue... This was relevant in the context of Classic McEliece, which uses djbsort (and permutation networks) in its key generation. |
I don't know how useful these would be (outside of transposition ciphers), but wanted to drop them here for comment anyway. I'm also thinking it would be nice to have some primitives that give users the "feeling" of having variable length sequences.
And now that I look at it, I think all the
[width ...]
could be made intoInteger
instead. Though, maybe it's best to stick with bitvectors when possible...The text was updated successfully, but these errors were encountered: