proposition: Lemma char_at_matches_is_char_no_ex offset len str P (Hlen : offset + len <= length str) : (Nat.eqb len 1 && char_at_matches offset str P)%bool = true <-> match get offset str with | Some ch => (P ch /\ substring offset len str ~= [ch])%string_like | None => False end.
proof: Proof. destruct (get offset str) as [ch|] eqn:Heq. { split; intro H. { apply Bool.andb_true_iff in H. destruct H as [H0 H1]. apply Nat.eqb_eq in H0; subst. erewrite char_at_matches_correct in H1 by eassumption. split; try assumption. rewrite get_drop in Heq. generalize dependent (drop offset str); clear Hlen offset str; intro str. intro H. apply get_0; assumption. } { destruct H as [H0 H1]. erewrite char_at_matches_correct by eassumption. apply Bool.andb_true_iff; split; [ | eassumption ]. apply length_singleton in H1. rewrite substring_length, <- Nat.sub_min_distr_r, Nat.add_sub in H1. apply Nat.eqb_eq. revert H1. apply Nat.min_case_strong; intros; omega. } } { split; [ intro H | intros [] ]. rewrite get_drop in Heq. apply no_first_char_empty in Heq. rewrite drop_length in Heq. apply Bool.andb_true_iff in H. destruct H as [H0 H1]. apply Nat.eqb_eq in H0; subst. omega. } Qed.
imports: Fiat.Common.Coq__8_4__8_5__Compat Coq.ZArith.ZArith Fiat.Common Fiat.Common.List.Operations Fiat.Common.List.ListFacts Fiat.Common.Le Fiat.Common.Tactics.SetoidSubst Fiat.Common.Tactics.IsClosed Fiat.Parsers.StringLike.Core Fiat.Common.UIP