This PR verifies the `String.dropWhile` and `String.takeWhile`
functions.
It also includes a refactor of the `PatternModel` class so that the
`not_matches_empty` condition is moved into a separate typeclass
`StrictPatternModel`. This allows string patterns to implement
`LawfulForwardPatternModel` unconditionally, which means that more of
the general theory about patterns directly applies to string patterns
without having to do a case distinction for empty strings.
This PR also includes a study of the `PatternModel` machinery given to
slices `s` and `t` such that `s.copy = t.copy`. From these results, we
deduce statements like `s.copy.startsWith pat = s.startsWith pat` (which
is far from obvious!).
This PR implements verification infrastructure for backwards patterns
that is analogous to the existing infrastructure for forward patterns.
Based on this it adds verification for the `skipSuffix?`, `endsWith` and
`dropSuffix?` functions on strings.
To enable this, we add some supporting theory about `String.slice`
(that's a lowercase `s`) and `String.Pos.prev`.
This PR introduces the functions `String.Slice.skipPrefix?`,
`String.Slice.Pos.skip?`, `String.Slice.skipPrefixWhile`,
`String.Slice.Pos.skipWhile` and redefines `String.Slice.takeWhile` and
`String.Slice.dropWhile` to use these new functions.
This PR renames the function `ForwardPattern.dropPrefix?` to
`ForwardPattern.skipPrefix`?
This function `(s : String.Slice) -> Option s.Pos` is not to be confused
with `String.Slice.dropPrefix? : (s : String.Slice) -> Option
String.Slice`.
This PR takes a more principled approach in deriving `String` pattern
lemmas by reducing to simpler cases similar to how the instances are
defined.
This reduces duplication of complex arguments (at the expense of having
to state more simple lemmas; however these lemmas are useful to users as
well).
This PR relates `String.split` to `List.splitOn` and `List.splitOnP`,
provided that we are splitting by a character or character predicate.
Also included: some more lemmas about `List.splitOn`, and a refactor of
the generic `split` verification to get rid of the awkward `SlicesFrom`
constuct.
This PR verifies the `String.Slice.splitToSubslice` function by relating
it to a model implementation `Model.split` based on a
`ForwardPatternModel`.
The proof is generic, so it works for splitting by characters, strings
etc.
From this, we will be able to give user-facing API lemmas for
`String.split` and friends in future PRs.
We also move the verification of string patterns from
`String.Slice.Pattern` to `String.Slice.Pattern.Model` to achieve better
separation between code that users run in their programs and code that
only supports the theory.
This PR provides a `LawfulForwardPatternModel` instance for string
patterns, i.e., it proves correctness of the `dropPrefix?` and
`startsWith` functions for string patterns.
Note that this is "just" the correctness proof; there isn't a way to
actually use it yet. API lemmas will follow.