Inductive is_prefix (A : Set) : list A -> (nat -> A) -> Prop :=
  | is_prefix_nil : forall f : nat -> A, is_prefix A nil f
  | is_prefix_cons :
      forall (f : nat -> A) (x : A) (xs : list A),
      x = f (length xs) -> is_prefix A xs f -> is_prefix A (x :: xs) f.Inductive is_prefix (A : Set) : list A -> (nat -> A) -> Prop :=
  | is_prefix_nil : forall f : nat -> A, is_prefix A nil f
  | is_prefix_cons :
      forall (f : nat -> A) (x : A) (xs : list A),
      x = f (length xs) -> is_prefix A xs f -> is_prefix A (x :: xs) f.Inductive is_prefix (A : Set) : list A -> (nat -> A) -> Prop :=
  | is_prefix_nil : forall f : nat -> A, is_prefix A nil f
  | is_prefix_cons :
      forall (f : nat -> A) (x : A) (xs : list A),
      x = f (length xs) -> is_prefix A xs f -> is_prefix A (x :: xs) f.

(* Specifications: *)
Theorem L_idx : forall (f : nat -> word) (w : word) (ws : list word), L w ws -> is_prefix word ws f -> {i : nat | emb (f i) w /\ i < length ws}.
Theorem good_idx : forall (f : nat -> word) (ws : list word), good ws -> is_prefix word ws f -> {i : nat & {j : nat | emb (f i) (f j) /\ i < j}}.
Theorem bar_idx : forall (f : nat -> word) (ws : list word), bar ws -> is_prefix word ws f -> {i : nat & {j : nat | emb (f i) (f j) /\ i < j}}.
Theorem higman_idx : forall f : nat -> word, {i : nat & {j : nat | emb (f i) (f j) /\ i < j}}.
Theorem good_prefix_lemma : forall (ws : list word) (f : nat -> word), bar ws -> is_prefix word ws f -> {vs : list word | is_prefix word vs f /\ good vs}.
Theorem good_prefix : forall f : nat -> word, {vs : list word | is_prefix word vs f /\ good vs}.