Skip to content

Commit

Permalink
repeat lemmas (#25)
Browse files Browse the repository at this point in the history
move lemmas from
[verified_go_stdlib](https://github.com/jcp19/verified_go_stdlib) to
`bytes`.

- the name of `LemmaRepeatCommutative` could be better, it is not
`Repeat` that is commutative but `++` (with the special arguments `b`
and `Repeat(b, n)`
- `verified_go_stdlib` has a lemma that ensures `Repeat(s, a)[: b *
len(s)] == Repeat(s, MinInt(a, b))`. Should we move this here as well?
It depends on a `MinInt` function that could be replaced by `math.Min`
  • Loading branch information
HSMF authored Dec 4, 2024
1 parent dd3225e commit d2321b9
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions bytes/repeat_lemmas.gobra
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package bytes

//+gobra

ghost
ensures Repeat(b, 1) == b
decreases
func LemmaRepeatOnce(b seq[byte]) {
assert Repeat(b, 1) == b ++ Repeat(b, 0)
}

ghost
requires n > 0
ensures Repeat(b, n) == Repeat(b, n-1) ++ b
decreases n
func lemmaRepeatFlip(b seq[byte], n int) {
if n == 1 {
assert Repeat(b, n-1) == seq[byte]{}
} else {
assert Repeat(b, n) == b ++ Repeat(b, n-1)
lemmaRepeatFlip(b, n-1)
assert Repeat(b, n-1) == Repeat(b, n-2) ++ b
}
}

ghost
requires n >= 0
ensures b ++ Repeat(b, n) == Repeat(b, n) ++ b
decreases
func LemmaRepeatCommutesWithConcat(b seq[byte], n int) {
assert b ++ Repeat(b, n) == Repeat(b, n+1)
lemmaRepeatFlip(b, n+1)
}

ghost
requires n >= 0
ensures Repeat(b, 2 * n) == Repeat(b, n) ++ Repeat(b, n)
decreases n
func LemmaRepeatDoubled(b seq[byte], n int) {
if n != 0 {
assert Repeat(b, n) == b ++ Repeat(b, n - 1)
assert Repeat(b, n) ++ Repeat(b, n) == b ++ Repeat(b, n - 1) ++ b ++ Repeat(b, n - 1)
// order of repeating doesn't matter because it's always the same element that is repeated
assert b ++ Repeat(b, n - 1) ++ b ++ Repeat(b, n - 1) == b ++ (Repeat(b, n - 1) ++ b) ++ Repeat(b, n - 1)
LemmaRepeatCommutesWithConcat(b, n - 1)
assert b ++ (Repeat(b, n - 1) ++ b) ++ Repeat(b, n - 1) == b ++ (b ++ Repeat(b, n - 1)) ++ Repeat(b, n - 1)
assert b ++ Repeat(b, n - 1) ++ b ++ Repeat(b, n - 1) == b ++ b ++ Repeat(b, n - 1) ++ Repeat(b, n - 1)
LemmaRepeatDoubled(b, n - 1)
assert Repeat(b, n - 1) ++ Repeat(b, n - 1) == Repeat(b, 2 * (n - 1))
assert Repeat(b, 2 * n - 1) == b ++ Repeat(b, n - 1) ++ Repeat(b, n - 1)
assert Repeat(b, 2 * n) == b ++ b ++ Repeat(b, n - 1) ++ Repeat(b, n - 1)
} else {
assert Repeat(b, 2 * 0) == Repeat(b, 0) ++ Repeat(b, 0)
}
}


ghost
requires n >= 0
ensures len(Repeat(s, n)) == len(s) * n
decreases n
func LemmaRepeatLength(s seq[byte], n int) {
switch {
case n == 0:
assert len(Repeat(s, n)) == 0
default:
assert Repeat(s, n) == s ++ Repeat(s, n-1)
LemmaRepeatLength(s, n-1)
}
}

0 comments on commit d2321b9

Please sign in to comment.