proposition: Lemma first_index_helper_first_index_error {A B} (f : A -> bool) (rect : option (nat * A) -> B) (ls : list A) (rec : nat * A -> nat * A) : first_index_helper f rect ls rec = rect (let idx := first_index_error f ls in let v := option_rect (fun _ => option A) (nth_error ls) None idx in option_map rec (option_rect (fun _ => option (nat * A)) (fun v' : A => option_map (fun idx' : nat => (idx', v')) idx) None v)).
proof: Proof. revert B rec rect; induction ls as [|x xs IHxs]; simpl; intros. { reflexivity. } { destruct (f x). { reflexivity. } { rewrite !IHxs. destruct (first_index_error f xs) as [idx|] eqn:Heq; simpl; [ | reflexivity ]. destruct (nth_error xs idx) eqn:Heq'; simpl; [ | reflexivity ]. rewrite Heq'; simpl. reflexivity. } } Qed.
imports: Fiat.Common.Coq__8_4__8_5__Compat Coq.ZArith.ZArith Coq.Lists.List Coq.Lists.SetoidList Coq.Bool.Bool Fiat.Common Fiat.Common.List.Operations Fiat.Common.Equality Fiat.Common.List.FlattenList Fiat.Common.LogicFacts