Skip to content

Sorting primitives #1032

@weaversa

Description

@weaversa

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.

/** Swap `i`th and `j`th entries of sequence `a` via `@@`/`updates` */
swap:
    {n, a, w}
    Integral w =>
    [n]a -> w -> w -> [n]a
swap seq i j = updates seq [i,j] (seq @@ [j,i])

/**
 * "Partition" a sequence `seq` by a filtering predicate `f` such
 * that the output `seq'` has all the items satisfying `f`, followed
 * by all items not satisfying `f`
 */
partition: {n, a} (fin n) => (a -> Bit) -> [n]a -> [n]a
partition f seq = take (last out).0
  where
    out = ([(seq, 0, 0)] : [1]([n]a, [max 1 (width n)], [max 1 (width n)]))
        # [ if f (w' @ i) then (w', i', j)
             | j <= i    then (w', i, i')
             | f (w' @ j)  then (swap w' i j, i', j')
            else (w', i, j')
            where
                i' = i + 1
                j' = j + 1
          | (w', i, j) <- out
          | _ <- tail [0 .. n : [width n]] ]

/**
 * A recursive version of partition
 */
partition':
    {n, a} fin n =>
    (a -> Bit) -> [n]a -> [n]a
partition' f w =
    if `n == (0: [width n]) then w
    | ~ (f (w @ 0)) then partition' f (take`{max 1 n - 1} (w <<< 1)) # (take`{min 1 n} [w @ 0])
    else (take`{min 1 n} [w @ 0]) # partition' f (drop`{min 1 n} w)
Main> let S = [1,2,3,4,5,6,0,0,7,0,0,0]
Main> partition' (\x -> x != 0) S
Showing a specific instance of polymorphic result:
  * Using 'Integer' for 1st type argument of '<interactive>::S'
[1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0]
Main> partition (\x -> x != 0) S
Showing a specific instance of polymorphic result:
  * Using 'Integer' for 1st type argument of '<interactive>::S'
[1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0]

And now that I look at it, I think all the [width ...] could be made into Integer instead. Though, maybe it's best to stick with bitvectors when possible...

Metadata

Metadata

Assignees

No one assigned

    Labels

    algorithms in CryptolRequires writing Cryptol code, rather than modifying the implementation's source code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions