Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(* -*- coding: utf-8 -*- *)
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Contributed by Laurent Théry (INRIA);
Adapted to Coq V8 by the Coq Development Team
Require Import Arith. Require Import Ascii. Require Import Bool. Require Import Coq.Strings.Byte.
Implementation of string as list of ascii characters
Inductive string : Set := | EmptyString : string | String : ascii -> string -> string. Declare Scope string_scope. Delimit Scope string_scope with string. Bind Scope string_scope with string. Local Open Scope string_scope. Register EmptyString as plugins.syntax.EmptyString. Register String as plugins.syntax.String.
Equality is decidable
forall s1 s2 : string, {s1 = s2} + {s1 <> s2}decide equality; apply ascii_dec. Defined. Local Open Scope lazy_bool_scope. Fixpoint eqb s1 s2 : bool := match s1, s2 with | EmptyString, EmptyString => true | String c1 s1', String c2 s2' => Ascii.eqb c1 c2 &&& eqb s1' s2' | _,_ => false end. Infix "=?" := eqb : string_scope.forall s1 s2 : string, {s1 = s2} + {s1 <> s2}s1, s2:stringreflect (s1 = s2) (s1 =? s2)s1, s2:stringreflect (s1 = s2) (s1 =? s2)s1:stringforall s2 : string, reflect (s1 = s2) (s1 =? s2)a:asciis1:stringIHs1:forall s0 : string, reflect (s1 = s0) (s1 =? s0)a0:asciis2:stringreflect (String a s1 = String a0 s2) ((a =? a0)%char &&& (s1 =? s2))case IHs1; [intros ->; now constructor | constructor; now intros [= ]]. Qed. Ltac t_eqb := repeat first [ congruence | progress subst | apply conj | match goal with | [ |- context[eqb ?x ?y] ] => destruct (eqb_spec x y) end | intro ].s1:stringIHs1:forall s0 : string, reflect (s1 = s0) (s1 =? s0)a0:asciis2:stringreflect (String a0 s1 = String a0 s2) (s1 =? s2)x:string(x =? x) = truet_eqb. Qed.x:string(x =? x) = truex, y:string(x =? y) = (y =? x)t_eqb. Qed.x, y:string(x =? y) = (y =? x)n, m:string(n =? m) = true <-> n = mt_eqb. Qed.n, m:string(n =? m) = true <-> n = mx, y:string(x =? y) = false <-> x <> yt_eqb. Qed.x, y:string(x =? y) = false <-> x <> yMorphisms.Proper (Morphisms.respectful eq (Morphisms.respectful eq eq)) eqbt_eqb. Qed.Morphisms.Proper (Morphisms.respectful eq (Morphisms.respectful eq eq)) eqb
Reserved Notation "x ++ y" (right associativity, at level 60). Fixpoint append (s1 s2 : string) : string := match s1 with | EmptyString => s2 | String c s1' => String c (s1' ++ s2) end where "s1 ++ s2" := (append s1 s2) : string_scope. (******************************)
Length
(******************************) Fixpoint length (s : string) : nat := match s with | EmptyString => 0 | String c s' => S (length s') end. (******************************)
Nth character of a string
(******************************) Fixpoint get (n : nat) (s : string) {struct s} : option ascii := match s with | EmptyString => None | String c s' => match n with | O => Some c | S n' => get n' s' end end.
Two lists that are identical through get are syntactically equal
forall s1 s2 : string, (forall n : nat, get n s1 = get n s2) <-> s1 = s2forall s1 s2 : string, (forall n : nat, get n s1 = get n s2) <-> s1 = s2s1:stringforall s2 : string, (forall n : nat, None = get n s2) <-> EmptyString = s2s1:stringforall (a : ascii) (s : string), (forall s2 : string, (forall n : nat, get n s = get n s2) <-> s = s2) -> forall s2 : string, (forall n : nat, match n with | 0 => Some a | S n' => get n' s end = get n s2) <-> String a s = s2s1, s2:stringa:asciis:string(forall n : nat, None = match n with | 0 => Some a | S n' => get n' s end) -> EmptyString = String a ss1, s2:stringa:asciis:stringEmptyString = String a s -> forall n : nat, None = match n with | 0 => Some a | S n' => get n' s ends1:stringforall (a : ascii) (s : string), (forall s2 : string, (forall n : nat, get n s = get n s2) <-> s = s2) -> forall s2 : string, (forall n : nat, match n with | 0 => Some a | S n' => get n' s end = get n s2) <-> String a s = s2s1, s2:stringa:asciis:stringEmptyString = String a s -> forall n : nat, None = match n with | 0 => Some a | S n' => get n' s ends1:stringforall (a : ascii) (s : string), (forall s2 : string, (forall n : nat, get n s = get n s2) <-> s = s2) -> forall s2 : string, (forall n : nat, match n with | 0 => Some a | S n' => get n' s end = get n s2) <-> String a s = s2s1:stringforall (a : ascii) (s : string), (forall s2 : string, (forall n : nat, get n s = get n s2) <-> s = s2) -> forall s2 : string, (forall n : nat, match n with | 0 => Some a | S n' => get n' s end = get n s2) <-> String a s = s2s1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:string(forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = None) -> String a s1' = EmptyStrings1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringString a s1' = EmptyString -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = Nones1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:string(forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s end) -> String a s1' = String a0 ss1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringString a s1' = EmptyString -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = Nones1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:string(forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s end) -> String a s1' = String a0 ss1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:string(forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s end) -> String a s1' = String a0 ss1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringH:forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s endH1:Some a = Some a0H2:a = a0String a0 s1' = String a0 ss1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringH:forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s endH1:Some a = Some a0H2:a = a0((forall n : nat, get n s1' = get n s) -> s1' = s) -> (s1' = s -> forall n : nat, get n s1' = get n s) -> String a0 s1' = String a0 ss1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringH:forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s endH1:Some a = Some a0H2:a = a0H0:(forall n : nat, get n s1' = get n s) -> s1' = sforall n : nat, get n s1' = get n ss1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringString a s1' = String a0 s -> forall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s ends1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringH1:a = a0H2:s1' = sforall n : nat, match n with | 0 => Some a | S n' => get n' s1' end = match n with | 0 => Some a0 | S n' => get n' s endrewrite H1; auto. Qed.s1:stringa:asciis1':stringRec:forall s0 : string, (forall n : nat, get n s1' = get n s0) <-> s1' = s0s2:stringa0:asciis:stringH1:a = a0H2:s1' = sforall n : nat, match n with | 0 => Some a | S n' => get n' s end = match n with | 0 => Some a0 | S n' => get n' s end
The first elements of s1 ++ s2 are the ones of s1
forall (s1 s2 : string) (n : nat), n < length s1 -> get n s1 = get n (s1 ++ s2)forall (s1 s2 : string) (n : nat), n < length s1 -> get n s1 = get n (s1 ++ s2)s1:stringforall (s2 : string) (n : nat), n < 0 -> None = get n s2s1:stringforall (a : ascii) (s : string), (forall (s2 : string) (n : nat), n < length s -> get n s = get n (s ++ s2)) -> forall (s2 : string) (n : nat), n < S (length s) -> match n with | 0 => Some a | S n' => get n' s end = match n with | 0 => Some a | S n' => get n' (s ++ s2) ends1:stringforall (a : ascii) (s : string), (forall (s2 : string) (n : nat), n < length s -> get n s = get n (s ++ s2)) -> forall (s2 : string) (n : nat), n < S (length s) -> match n with | 0 => Some a | S n' => get n' s end = match n with | 0 => Some a | S n' => get n' (s ++ s2) ends1:stringa:asciis1':stringRec:forall (s0 : string) (n0 : nat), n0 < length s1' -> get n0 s1' = get n0 (s1' ++ s0)s2:stringn:natforall n0 : nat, S n0 < S (length s1') -> get n0 s1' = get n0 (s1' ++ s2)apply lt_S_n; auto. Qed.s1:stringa:asciis1':stringRec:forall (s0 : string) (n1 : nat), n1 < length s1' -> get n1 s1' = get n1 (s1' ++ s0)s2:stringn, n0:natH:S n0 < S (length s1')n0 < length s1'
The last elements of s1 ++ s2 are the ones of s2
forall (s1 s2 : string) (n : nat), get n s2 = get (n + length s1) (s1 ++ s2)forall (s1 s2 : string) (n : nat), get n s2 = get (n + length s1) (s1 ++ s2)s1:stringforall (s2 : string) (n : nat), get n s2 = get (n + 0) s2s1:stringforall (a : ascii) (s : string), (forall (s2 : string) (n : nat), get n s2 = get (n + length s) (s ++ s2)) -> forall (s2 : string) (n : nat), get n s2 = match n + S (length s) with | 0 => Some a | S n' => get n' (s ++ s2) ends1:stringforall (a : ascii) (s : string), (forall (s2 : string) (n : nat), get n s2 = get (n + length s) (s ++ s2)) -> forall (s2 : string) (n : nat), get n s2 = match n + S (length s) with | 0 => Some a | S n' => get n' (s ++ s2) ends1:stringa:asciis1':stringRec:forall (s0 : string) (n0 : nat), get n0 s0 = get (n0 + length s1') (s1' ++ s0)s2:stringn:natget 0 s2 = get (length s1') (s1' ++ s2)s1:stringa:asciis1':stringRec:forall (s0 : string) (n0 : nat), get n0 s0 = get (n0 + length s1') (s1' ++ s0)s2:stringn:natforall n0 : nat, get (S n0) s2 = get (n0 + S (length s1')) (s1' ++ s2)s1:stringa:asciis1':stringRec:forall (s0 : string) (n0 : nat), get n0 s0 = get (n0 + length s1') (s1' ++ s0)s2:stringn:natforall n0 : nat, get (S n0) s2 = get (n0 + S (length s1')) (s1' ++ s2)rewrite <- Plus.plus_Snm_nSm; auto. Qed.s1:stringa:asciis1':stringRec:forall (s0 : string) (n1 : nat), get n1 s0 = get (n1 + length s1') (s1' ++ s0)s2:stringn, n0:natget (S n0) s2 = get (n0 + S (length s1')) (s1' ++ s2)
substring n m s returns the substring of s that starts
at position n and of length m;
if this does not make sense it returns ""
Fixpoint substring (n m : nat) (s : string) : string :=
match n, m, s with
| O, O, _ => EmptyString
| O, S m', EmptyString => s
| O, S m', String c s' => String c (substring 0 m' s')
| S n', _, EmptyString => s
| S n', _, String c s' => substring n' m s'
end.
The substring is included in the initial string
forall (s : string) (n m p : nat), p < m -> get p (substring n m s) = get (p + n) sforall (s : string) (n m p : nat), p < m -> get p (substring n m s) = get (p + n) ss:stringforall n m p : nat, p < m -> get p match n with | 0 => match m with | 0 | _ => EmptyString end | S _ => EmptyString end = Nones:stringforall (a : ascii) (s0 : string), (forall n m p : nat, p < m -> get p (substring n m s0) = get (p + n) s0) -> forall n m p : nat, p < m -> get p match n with | 0 => match m with | 0 => EmptyString | S m' => String a (substring 0 m' s0) end | S n' => substring n' m s0 end = match p + n with | 0 => Some a | S n' => get n' s0 ends:stringn:natforall m p : nat, p < m -> get p match m with | 0 | _ => EmptyString end = Nones:stringforall (a : ascii) (s0 : string), (forall n m p : nat, p < m -> get p (substring n m s0) = get (p + n) s0) -> forall n m p : nat, p < m -> get p match n with | 0 => match m with | 0 => EmptyString | S m' => String a (substring 0 m' s0) end | S n' => substring n' m s0 end = match p + n with | 0 => Some a | S n' => get n' s0 ends:stringforall (a : ascii) (s0 : string), (forall n m p : nat, p < m -> get p (substring n m s0) = get (p + n) s0) -> forall n m p : nat, p < m -> get p match n with | 0 => match m with | 0 => EmptyString | S m' => String a (substring 0 m' s0) end | S n' => substring n' m s0 end = match p + n with | 0 => Some a | S n' => get n' s0 ends:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall m p : nat, p < m -> get p match m with | 0 => EmptyString | S m' => String a (substring 0 m' s') end = match p + 0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall n0 m p : nat, p < m -> get p (substring n0 m s') = match p + S n0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m0 p : nat, p < m0 -> get p (substring n0 m0 s') = get (p + n0) s'n, m:natforall p : nat, p < 0 -> None = match p + 0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m0 p : nat, p < m0 -> get p (substring n0 m0 s') = get (p + n0) s'n, m:natforall n0 p : nat, p < S n0 -> match p with | 0 => Some a | S n' => get n' (substring 0 n0 s') end = match p + 0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall n0 m p : nat, p < m -> get p (substring n0 m s') = match p + S n0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m0 p : nat, p < m0 -> get p (substring n0 m0 s') = get (p + n0) s'n, m:natforall n0 p : nat, p < S n0 -> match p with | 0 => Some a | S n' => get n' (substring 0 n0 s') end = match p + 0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall n0 m p : nat, p < m -> get p (substring n0 m s') = match p + S n0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n0 m0 p0 : nat, p0 < m0 -> get p0 (substring n0 m0 s') = get (p0 + n0) s'n, m, m', p:natforall n0 : nat, S n0 < S m' -> get n0 (substring 0 m' s') = get (n0 + 0) s's:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall n0 m p : nat, p < m -> get p (substring n0 m s') = match p + S n0 with | 0 => Some a | S n' => get n' s' ends:stringa:asciis':stringRec:forall n1 m0 p0 : nat, p0 < m0 -> get p0 (substring n1 m0 s') = get (p0 + n1) s'n, m, m', p, n0:natH:S n0 < S m'n0 < m's:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall n0 m p : nat, p < m -> get p (substring n0 m s') = match p + S n0 with | 0 => Some a | S n' => get n' s' endintros n' m p H; rewrite <- Plus.plus_Snm_nSm; simpl; auto. Qed.s:stringa:asciis':stringRec:forall n0 m p : nat, p < m -> get p (substring n0 m s') = get (p + n0) s'n:natforall n0 m p : nat, p < m -> get p (substring n0 m s') = match p + S n0 with | 0 => Some a | S n' => get n' s' end
The substring has at most m elements
forall (s : string) (n m p : nat), m <= p -> get p (substring n m s) = Noneforall (s : string) (n m p : nat), m <= p -> get p (substring n m s) = Nones:stringforall n m p : nat, m <= p -> get p match n with | 0 => match m with | 0 | _ => EmptyString end | S _ => EmptyString end = Nones:stringforall (a : ascii) (s0 : string), (forall n m p : nat, m <= p -> get p (substring n m s0) = None) -> forall n m p : nat, m <= p -> get p match n with | 0 => match m with | 0 => EmptyString | S m' => String a (substring 0 m' s0) end | S n' => substring n' m s0 end = Nones:stringn:natforall m p : nat, m <= p -> get p match m with | 0 | _ => EmptyString end = Nones:stringforall (a : ascii) (s0 : string), (forall n m p : nat, m <= p -> get p (substring n m s0) = None) -> forall n m p : nat, m <= p -> get p match n with | 0 => match m with | 0 => EmptyString | S m' => String a (substring 0 m' s0) end | S n' => substring n' m s0 end = Nones:stringforall (a : ascii) (s0 : string), (forall n m p : nat, m <= p -> get p (substring n m s0) = None) -> forall n m p : nat, m <= p -> get p match n with | 0 => match m with | 0 => EmptyString | S m' => String a (substring 0 m' s0) end | S n' => substring n' m s0 end = Nones:stringa:asciis':stringRec:forall n0 m p : nat, m <= p -> get p (substring n0 m s') = Nonen:natforall m p : nat, m <= p -> get p match m with | 0 => EmptyString | S m' => String a (substring 0 m' s') end = Nones:stringa:asciis':stringRec:forall n0 m0 p : nat, m0 <= p -> get p (substring n0 m0 s') = Nonen, m:natforall n0 p : nat, S n0 <= p -> match p with | 0 => Some a | S n' => get n' (substring 0 n0 s') end = Nones:stringa:asciis':stringRec:forall n0 m0 p0 : nat, m0 <= p0 -> get p0 (substring n0 m0 s') = Nonen, m, m', p:natS m' <= 0 -> Some a = Nones:stringa:asciis':stringRec:forall n0 m0 p0 : nat, m0 <= p0 -> get p0 (substring n0 m0 s') = Nonen, m, m', p:natforall n0 : nat, S m' <= S n0 -> get n0 (substring 0 m' s') = Nones:stringa:asciis':stringRec:forall n0 m0 p0 : nat, m0 <= p0 -> get p0 (substring n0 m0 s') = Nonen, m, m', p:natforall n0 : nat, S m' <= S n0 -> get n0 (substring 0 m' s') = Noneapply Le.le_S_n; auto. Qed.s:stringa:asciis':stringRec:forall n1 m0 p0 : nat, m0 <= p0 -> get p0 (substring n1 m0 s') = Nonen, m, m', p, n0:natH:S m' <= S n0m' <= n0
concat sep sl concatenates the list of strings sl, inserting
the separator string sep between each.
Fixpoint concat (sep : string) (ls : list string) :=
match ls with
| nil => EmptyString
| cons x nil => x
| cons x xs => x ++ sep ++ concat sep xs
end.
Test if s1 is a prefix of s2
Fixpoint prefix (s1 s2 : string) {struct s2} : bool :=
match s1 with
| EmptyString => true
| String a s1' =>
match s2 with
| EmptyString => false
| String b s2' =>
match ascii_dec a b with
| left _ => prefix s1' s2'
| right _ => false
end
end
end.
If s1 is a prefix of s2, it is the substring of length
length s1 starting at position O of s2
forall s1 s2 : string, prefix s1 s2 = true <-> substring 0 (length s1) s2 = s1forall s1 s2 : string, prefix s1 s2 = true <-> substring 0 (length s1) s2 = s1s1:stringforall s2 : string, prefix EmptyString s2 = true <-> substring 0 0 s2 = EmptyStrings1:stringforall (a : ascii) (s : string), (forall s2 : string, prefix s s2 = true <-> substring 0 (length s) s2 = s) -> forall s2 : string, prefix (String a s) s2 = true <-> substring 0 (S (length s)) s2 = String a ss1:stringforall (a : ascii) (s : string), (forall s2 : string, prefix s s2 = true <-> substring 0 (length s) s2 = s) -> forall s2 : string, prefix (String a s) s2 = true <-> substring 0 (S (length s)) s2 = String a ss1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringfalse = true <-> EmptyString = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringforall (a0 : ascii) (s : string), ascii_dec a a0 &&& prefix s1' s = true <-> String a0 (substring 0 (length s1') s) = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringforall (a0 : ascii) (s : string), ascii_dec a a0 &&& prefix s1' s = true <-> String a0 (substring 0 (length s1') s) = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringa = b -> prefix s1' s2' = true <-> String b (substring 0 (length s1') s2') = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringa <> b -> false = true <-> String b (substring 0 (length s1') s2') = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringe:a = bH1:prefix s1' s2' = true -> substring 0 (length s1') s2' = s1'H2:substring 0 (length s1') s2' = s1' -> prefix s1' s2' = trueH3:prefix s1' s2' = trueString b (substring 0 (length s1') s2') = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringe:a = bH1:prefix s1' s2' = true -> substring 0 (length s1') s2' = s1'H2:substring 0 (length s1') s2' = s1' -> prefix s1' s2' = trueH3:String b (substring 0 (length s1') s2') = String a s1'prefix s1' s2' = trues1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringa <> b -> false = true <-> String b (substring 0 (length s1') s2') = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringe:a = bH1:prefix s1' s2' = true -> substring 0 (length s1') s2' = s1'H2:substring 0 (length s1') s2' = s1' -> prefix s1' s2' = trueH3:String b (substring 0 (length s1') s2') = String a s1'prefix s1' s2' = trues1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringa <> b -> false = true <-> String b (substring 0 (length s1') s2') = String a s1's1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringa <> b -> false = true <-> String b (substring 0 (length s1') s2') = String a s1'case n; injection H; auto. Qed.s1:stringa:asciis1':stringRec:forall s0 : string, prefix s1' s0 = true <-> substring 0 (length s1') s0 = s1's2:stringb:asciis2':stringn:a <> bH:String b (substring 0 (length s1') s2') = String a s1'false = true
Test if, starting at position n, s1 occurs in s2; if
so it returns the position
Fixpoint index (n : nat) (s1 s2 : string) : option nat := match s2, n with | EmptyString, O => match s1 with | EmptyString => Some O | String a s1' => None end | EmptyString, S n' => None | String b s2', O => if prefix s1 s2 then Some O else match index O s1 s2' with | Some n => Some (S n) | None => None end | String b s2', S n' => match index n' s1 s2' with | Some n => Some (S n) | None => None end end. (* Dirty trick to avoid locally that prefix reduces itself *) Opaque prefix.
If the result of index is Some m, s1 in s2 at position m
forall (n m : nat) (s1 s2 : string), index n s1 s2 = Some m -> substring m (length s1) s2 = s1forall (n m : nat) (s1 s2 : string), index n s1 s2 = Some m -> substring m (length s1) s2 = s1s2:stringforall (n m : nat) (s1 : string), match n with | 0 => match s1 with | EmptyString => Some 0 | String _ _ => None end | S _ => None end = Some m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end = s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> substring m (length s1) s = s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end = s1s2:stringn:natforall (m : nat) (s1 : string), match s1 with | EmptyString => Some 0 | String _ _ => None end = Some m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end = s1s2:stringn:natnat -> forall (m : nat) (s1 : string), None = Some m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end = s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> substring m (length s1) s = s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end = s1s2:stringn, m:nats1:stringSome 0 = Some m -> match m with | 0 | _ => EmptyString end = EmptyStrings2:stringn, m:nats1:stringforall (a : ascii) (s : string), None = Some m -> match m with | 0 | _ => EmptyString end = String a ss2:stringn:natnat -> forall (m : nat) (s1 : string), None = Some m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end = s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> substring m (length s1) s = s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end = s1s2:stringn, m:nats1:stringforall (a : ascii) (s : string), None = Some m -> match m with | 0 | _ => EmptyString end = String a ss2:stringn:natnat -> forall (m : nat) (s1 : string), None = Some m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end = s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> substring m (length s1) s = s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end = s1s2:stringn:natnat -> forall (m : nat) (s1 : string), None = Some m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end = s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> substring m (length s1) s = s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end = s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> substring m (length s1) s = s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringmatch n with | 0 => if prefix s1 (String b s2') then Some 0 else match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s2' with | Some n0 => Some (S n0) | None => None end end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:string(if prefix s1 (String b s2') then Some 0 else match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end) = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringtrue = true <-> substring 0 (length s1) (String b s2') = s1 -> Some 0 = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m : nat) (s0 : string), index n0 s0 s2' = Some m -> substring m (length s0) s2' = s0n:nats1:stringH0:true = true <-> substring 0 (length s1) (String b s2') = s1match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringfalse = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some 0 -> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> substring n0 (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> substring n0 (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringm':natforall n0 : nat, (Some n0 = Some m' -> substring m' (length s1) s2' = s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> Some (S n0) = Some (S m') -> substring m' (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringm':nat(None = Some m' -> substring m' (length s1) s2' = s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> substring m' (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringm':nat(None = Some m' -> substring m' (length s1) s2' = s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> substring m' (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringn':natmatch index n' s1 s2' with | Some n0 => Some (S n0) | None => None end = Some 0 -> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringn':natforall n0 : nat, match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> substring n0 (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringn':natforall n0 : nat, match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> substring n0 (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringn', m':natforall n0 : nat, (Some n0 = Some m' -> substring m' (length s1) s2' = s1) -> Some (S n0) = Some (S m') -> substring m' (length s1) s2' = s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringn', m':nat(None = Some m' -> substring m' (length s1) s2' = s1) -> None = Some (S m') -> substring m' (length s1) s2' = s1intros; discriminate. Qed.s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> substring m0 (length s0) s2' = s0n, m:nats1:stringn', m':nat(None = Some m' -> substring m' (length s1) s2' = s1) -> None = Some (S m') -> substring m' (length s1) s2' = s1
If the result of index is Some m,
s1 does not occur in s2 before m
forall (n m : nat) (s1 s2 : string), index n s1 s2 = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s2 <> s1forall (n m : nat) (s1 s2 : string), index n s1 s2 = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s2 <> s1s2:stringforall (n m : nat) (s1 : string), match n with | 0 => match s1 with | EmptyString => Some 0 | String _ _ => None end | S _ => None end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn:natforall (m : nat) (s1 : string), match s1 with | EmptyString => Some 0 | String _ _ => None end = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringn:natforall (n0 m : nat) (s1 : string), None = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn, m:nats1:stringSome 0 = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 | _ => EmptyString end <> EmptyStrings2:stringn, m:nats1:stringforall (a : ascii) (s : string), None = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 | _ => EmptyString end <> String a ss2:stringn:natforall (n0 m : nat) (s1 : string), None = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn:nats1:stringforall p : nat, 0 <= p -> p < 0 -> match p with | 0 | _ => EmptyString end <> EmptyStrings2:stringn, m:nats1:stringforall (a : ascii) (s : string), None = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 | _ => EmptyString end <> String a ss2:stringn:natforall (n0 m : nat) (s1 : string), None = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn, m:nats1:stringforall (a : ascii) (s : string), None = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 | _ => EmptyString end <> String a ss2:stringn:natforall (n0 m : nat) (s1 : string), None = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn:natforall (n0 m : nat) (s1 : string), None = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = Some m -> forall p : nat, n <= p -> p < m -> substring p (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringmatch n with | 0 => if prefix s1 (String b s2') then Some 0 else match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s2' with | Some n0 => Some (S n0) | None => None end end = Some m -> forall p : nat, n <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:string(if prefix s1 (String b s2') then Some 0 else match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end) = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringtrue = true <-> substring 0 (length s1) (String b s2') = s1 -> Some 0 = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m : nat) (s0 : string), index n0 s0 s2' = Some m -> forall p : nat, n0 <= p -> p < m -> substring p (length s0) s2' <> s0n:nats1:stringH0:true = true <-> substring 0 (length s1) (String b s2') = s1forall p : nat, 0 <= p -> p < 0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some m -> forall p : nat, 0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = Some 0 -> forall p : nat, 0 <= p -> p < 0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> forall p : nat, 0 <= p -> p < S n0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> forall p : nat, 0 <= p -> p < S n0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':natforall n0 : nat, (Some n0 = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> Some (S n0) = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p:nat0 <= 0 -> 0 < S m' -> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p:natforall n0 : nat, 0 <= S n0 -> S n0 < S m' -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p:natH2:0 <= 0H3:0 < S m'H4:match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1(false = true -> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1) -> (match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> false = true) -> Falses2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p:natforall n0 : nat, 0 <= S n0 -> S n0 < S m' -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p:natforall n0 : nat, 0 <= S n0 -> S n0 < S m' -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p, n0:natH2:0 <= S n0H3:S n0 < S m'Some x = Some m's2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p, n0:natH2:0 <= S n0H3:S n0 < S m'0 <= n0s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p, n0:natH2:0 <= S n0H3:S n0 < S m'n0 < m's2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p, n0:natH2:0 <= S n0H3:S n0 < S m'0 <= n0s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p, n0:natH2:0 <= S n0H3:S n0 < S m'n0 < m's2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringm', x:natH:Some x = Some m' -> forall p0 : nat, 0 <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1H1:Some (S x) = Some (S m')p, n0:natH2:0 <= S n0H3:S n0 < S m'n0 < m's2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringm':nat(None = Some m' -> forall p : nat, 0 <= p -> p < m' -> substring p (length s1) s2' <> s1) -> false = true <-> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end = s1 -> None = Some (S m') -> forall p : nat, 0 <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = Some m -> forall p : nat, S n0 <= p -> p < m -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn':natmatch index n' s1 s2' with | Some n0 => Some (S n0) | None => None end = Some 0 -> forall p : nat, S n' <= p -> p < 0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn':natforall n0 : nat, match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> forall p : nat, S n' <= p -> p < S n0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn':natforall n0 : nat, match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = Some (S n0) -> forall p : nat, S n' <= p -> p < S n0 -> match p with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':natforall n0 : nat, (Some n0 = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> Some (S n0) = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p:natS n' <= 0 -> 0 < S m' -> match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p:natforall n0 : nat, S n' <= S n0 -> S n0 < S m' -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p0 : nat, n0 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p:natforall n0 : nat, S n' <= S n0 -> S n0 < S m' -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p, n0:natH1:S n' <= S n0H2:S n0 < S m'Some x = Some m's2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p, n0:natH1:S n' <= S n0H2:S n0 < S m'n' <= n0s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p, n0:natH1:S n' <= S n0H2:S n0 < S m'n0 < m's2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p, n0:natH1:S n' <= S n0H2:S n0 < S m'n' <= n0s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p, n0:natH1:S n' <= S n0H2:S n0 < S m'n0 < m's2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = Some m0 -> forall p0 : nat, n1 <= p0 -> p0 < m0 -> substring p0 (length s0) s2' <> s0n, m:nats1:stringn', m', x:natH:Some x = Some m' -> forall p0 : nat, n' <= p0 -> p0 < m' -> substring p0 (length s1) s2' <> s1H0:Some (S x) = Some (S m')p, n0:natH1:S n' <= S n0H2:S n0 < S m'n0 < m's2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1intros; discriminate. Qed.s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = Some m0 -> forall p : nat, n0 <= p -> p < m0 -> substring p (length s0) s2' <> s0n, m:nats1:stringn', m':nat(None = Some m' -> forall p : nat, n' <= p -> p < m' -> substring p (length s1) s2' <> s1) -> None = Some (S m') -> forall p : nat, S n' <= p -> p < S m' -> match p with | 0 => match length s1 with | 0 => EmptyString | S m'0 => String b (substring 0 m'0 s2') end | S n'0 => substring n'0 (length s1) s2' end <> s1
If the result of index is None, s1 does not occur in s2
after n
forall (n m : nat) (s1 s2 : string), index n s1 s2 = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s2 <> s1forall (n m : nat) (s1 s2 : string), index n s1 s2 = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s2 <> s1s2:stringforall (n m : nat) (s1 : string), match n with | 0 => match s1 with | EmptyString => Some 0 | String _ _ => None end | S _ => None end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn:natforall (m : nat) (s1 : string), match s1 with | EmptyString => Some 0 | String _ _ => None end = None -> s1 <> EmptyString -> 0 <= m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringn:natforall (n0 m : nat) (s1 : string), None = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn, m:nats1:stringforall (a : ascii) (s : string), None = None -> String a s <> EmptyString -> 0 <= m -> match m with | 0 | _ => EmptyString end <> String a ss2:stringn:natforall (n0 m : nat) (s1 : string), None = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn:natforall (n0 m : nat) (s1 : string), None = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 | _ => EmptyString end | S _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringn, n', m:natforall s1 : string, None = None -> s1 <> EmptyString -> S n' <= 0 -> match length s1 with | 0 | _ => EmptyString end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringforall (a : ascii) (s : string), (forall (n m : nat) (s1 : string), index n s1 s = None -> s1 <> EmptyString -> n <= m -> substring m (length s1) s <> s1) -> forall (n m : nat) (s1 : string), match n with | 0 => if prefix s1 (String a s) then Some 0 else match index 0 s1 s with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String a (substring 0 m' s) end | S n' => substring n' (length s1) s end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringmatch n with | 0 => if prefix s1 (String b s2') then Some 0 else match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end | S n' => match index n' s1 s2' with | Some n0 => Some (S n0) | None => None end end = None -> s1 <> EmptyString -> n <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:string(if prefix s1 (String b s2') then Some 0 else match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end) = None -> s1 <> EmptyString -> 0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringtrue = true <-> substring 0 (length s1) (String b s2') = s1 -> Some 0 = None -> s1 <> EmptyString -> 0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = None -> s1 <> EmptyString -> 0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> substring 0 (length s1) (String b s2') = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = None -> s1 <> EmptyString -> 0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringfalse = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n0 => Some (S n0) | None => None end = None -> s1 <> EmptyString -> 0 <= 0 -> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> 0 <= S n0 -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall (a : ascii) (s : string), false = true <-> String b (substring 0 (length s) s2') = String a s -> match index 0 (String a s) s2' with | Some n0 => Some (S n0) | None => None end = None -> String a s <> EmptyString -> 0 <= 0 -> String b (substring 0 (length s) s2') <> String a ss2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> 0 <= S n0 -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringa:asciis:stringH:false = true <-> String b (substring 0 (length s) s2') = String a sH0:match index 0 (String a s) s2' with | Some n0 => Some (S n0) | None => None end = NoneH1:String a s <> EmptyStringH2:0 <= 0H3:String b (substring 0 (length s) s2') = String a s(false = true -> String b (substring 0 (length s) s2') = String a s) -> (String b (substring 0 (length s) s2') = String a s -> false = true) -> Falses2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> 0 <= S n0 -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, false = true <-> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end = s1 -> match index 0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> 0 <= S n0 -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall (a : ascii) (s : string) (n0 : nat), false = true <-> String b (substring 0 (length s) s2') = String a s -> match index 0 (String a s) s2' with | Some n1 => Some (S n1) | None => None end = None -> String a s <> EmptyString -> 0 <= S n0 -> substring n0 (S (length s)) s2' <> String a ss2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = None -> s0 <> EmptyString -> n1 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringa:asciis:stringn0:natH:false = true <-> String b (substring 0 (length s) s2') = String a sH0:match index 0 (String a s) s2' with | Some n1 => Some (S n1) | None => None end = NoneH1:String a s <> EmptyStringH2:0 <= S n0index 0 (String a s) s2' = Nones2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = None -> s0 <> EmptyString -> n1 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringa:asciis:stringn0:natH:false = true <-> String b (substring 0 (length s) s2') = String a sH0:match index 0 (String a s) s2' with | Some n1 => Some (S n1) | None => None end = NoneH1:String a s <> EmptyStringH2:0 <= S n00 <= n0s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = None -> s0 <> EmptyString -> n1 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringa:asciis:stringn0:natH:false = true <-> String b (substring 0 (length s) s2') = String a sH0:match index 0 (String a s) s2' with | Some n1 => Some (S n1) | None => None end = NoneH1:String a s <> EmptyStringH2:0 <= S n00 <= n0s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringforall n0 : nat, match index n0 s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n0 <= m -> match m with | 0 => match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end | S n' => substring n' (length s1) s2' end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringn':natmatch index n' s1 s2' with | Some n0 => Some (S n0) | None => None end = None -> s1 <> EmptyString -> S n' <= 0 -> match length s1 with | 0 => EmptyString | S m' => String b (substring 0 m' s2') end <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringn':natforall n0 : nat, match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n' <= S n0 -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n0 m0 : nat) (s0 : string), index n0 s0 s2' = None -> s0 <> EmptyString -> n0 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringn':natforall n0 : nat, match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = None -> s1 <> EmptyString -> S n' <= S n0 -> substring n0 (length s1) s2' <> s1s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = None -> s0 <> EmptyString -> n1 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringn', n0:natH:match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = NoneH0:s1 <> EmptyStringH1:S n' <= S n0index n' s1 s2' = Nones2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = None -> s0 <> EmptyString -> n1 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringn', n0:natH:match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = NoneH0:s1 <> EmptyStringH1:S n' <= S n0n' <= n0apply Le.le_S_n; auto. Qed. (* Back to normal for prefix *) Transparent prefix.s2:stringb:asciis2':stringRec:forall (n1 m0 : nat) (s0 : string), index n1 s0 s2' = None -> s0 <> EmptyString -> n1 <= m0 -> substring m0 (length s0) s2' <> s0n, m:nats1:stringn', n0:natH:match index n' s1 s2' with | Some n1 => Some (S n1) | None => None end = NoneH0:s1 <> EmptyStringH1:S n' <= S n0n' <= n0
If we are searching for the Empty string and the answer is no
this means that n is greater than the size of s
forall (n : nat) (s : string), index n EmptyString s = None -> length s < nforall (n : nat) (s : string), index n EmptyString s = None -> length s < ns:stringforall n : nat, match n with | 0 => Some 0 | S _ => None end = None -> 0 < ns:stringascii -> forall s0 : string, (forall n : nat, index n EmptyString s0 = None -> length s0 < n) -> forall n : nat, match n with | 0 => Some 0 | S n' => match index n' EmptyString s0 with | Some n0 => Some (S n0) | None => None end end = None -> S (length s0) < ns:stringn:natSome 0 = None -> 0 < 0s:stringn:natforall n0 : nat, None = None -> 0 < S n0s:stringascii -> forall s0 : string, (forall n : nat, index n EmptyString s0 = None -> length s0 < n) -> forall n : nat, match n with | 0 => Some 0 | S n' => match index n' EmptyString s0 with | Some n0 => Some (S n0) | None => None end end = None -> S (length s0) < ns:stringn:natforall n0 : nat, None = None -> 0 < S n0s:stringascii -> forall s0 : string, (forall n : nat, index n EmptyString s0 = None -> length s0 < n) -> forall n : nat, match n with | 0 => Some 0 | S n' => match index n' EmptyString s0 with | Some n0 => Some (S n0) | None => None end end = None -> S (length s0) < ns:stringascii -> forall s0 : string, (forall n : nat, index n EmptyString s0 = None -> length s0 < n) -> forall n : nat, match n with | 0 => Some 0 | S n' => match index n' EmptyString s0 with | Some n0 => Some (S n0) | None => None end end = None -> S (length s0) < ns:stringa:asciis':stringH:forall n0 : nat, index n0 EmptyString s' = None -> length s' < n0n:natSome 0 = None -> S (length s') < 0s:stringa:asciis':stringH:forall n0 : nat, index n0 EmptyString s' = None -> length s' < n0n:natforall n0 : nat, match index n0 EmptyString s' with | Some n1 => Some (S n1) | None => None end = None -> S (length s') < S n0s:stringa:asciis':stringH:forall n0 : nat, index n0 EmptyString s' = None -> length s' < n0n:natforall n0 : nat, match index n0 EmptyString s' with | Some n1 => Some (S n1) | None => None end = None -> S (length s') < S n0s:stringa:asciis':stringH:forall n0 : nat, index n0 EmptyString s' = None -> length s' < n0n, n':natforall n0 : nat, (Some n0 = None -> length s' < n') -> Some (S n0) = None -> S (length s') < S n's:stringa:asciis':stringH:forall n0 : nat, index n0 EmptyString s' = None -> length s' < n0n, n':nat(None = None -> length s' < n') -> None = None -> S (length s') < S n'intros H0 H1; apply Lt.lt_n_S; auto. Qed.s:stringa:asciis':stringH:forall n0 : nat, index n0 EmptyString s' = None -> length s' < n0n, n':nat(None = None -> length s' < n') -> None = None -> S (length s') < S n'
Same as index but with no optional type, we return 0 when it
does not occur
Definition findex n s1 s2 :=
match index n s1 s2 with
| Some n => n
| None => O
end.
Fixpoint string_of_list_ascii (s : list ascii) : string := match s with | nil => EmptyString | cons ch s => String ch (string_of_list_ascii s) end. Fixpoint list_ascii_of_string (s : string) : list ascii := match s with | EmptyString => nil | String ch s => cons ch (list_ascii_of_string s) end.s:stringstring_of_list_ascii (list_ascii_of_string s) = sinduction s as [|? ? IHs]; [ reflexivity | cbn; apply f_equal, IHs ]. Defined.s:stringstring_of_list_ascii (list_ascii_of_string s) = ss:list asciilist_ascii_of_string (string_of_list_ascii s) = sinduction s as [|? ? IHs]; [ reflexivity | cbn; apply f_equal, IHs ]. Defined. Definition string_of_list_byte (s : list byte) : string := string_of_list_ascii (List.map ascii_of_byte s). Definition list_byte_of_string (s : string) : list byte := List.map byte_of_ascii (list_ascii_of_string s).s:list asciilist_ascii_of_string (string_of_list_ascii s) = ss:stringstring_of_list_byte (list_byte_of_string s) = ss:stringstring_of_list_byte (list_byte_of_string s) = ss:stringstring_of_list_ascii (List.map ascii_of_byte (List.map byte_of_ascii (list_ascii_of_string s))) = sapply ascii_of_byte_of_ascii. Qed.s:stringa:asciiascii_of_byte (byte_of_ascii a) = (fun x : ascii => x) as:list bytelist_byte_of_string (string_of_list_byte s) = ss:list bytelist_byte_of_string (string_of_list_byte s) = ss:list byteList.map byte_of_ascii (list_ascii_of_string (string_of_list_ascii (List.map ascii_of_byte s))) = sapply byte_of_ascii_of_byte. Qed.s:list bytea:bytebyte_of_ascii (ascii_of_byte a) = (fun x : byte => x) a
The concrete syntax for strings in scope string_scope follows the
Coq convention for strings: all ascii characters of code less than
128 are literals to the exception of the character `double quote'
which must be doubled.
Strings that involve ascii characters of code >= 128 which are not
part of a valid utf8 sequence of characters are not representable
using the Coq string notation (use explicitly the String constructor
with the ascii codes of the characters).
Module Export StringSyntax. String Notation string string_of_list_byte list_byte_of_string : string_scope. End StringSyntax. Example HelloWorld := " ""Hello world!"" ".