(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
Require Extraction.
Inductive letter : Set :=
| A : letter
| B : letter.
Definition word := list letter.
Inductive emb : word -> word -> Prop :=
| emb0 : forall ys : word, emb nil ys
| emb1 :
forall (xs ys : list letter) (y : letter),
emb xs ys -> emb xs (y :: ys)
| emb2 :
forall (xs ys : list letter) (x : letter),
emb xs ys -> emb (x :: xs) (x :: ys).
Inductive L (v : word) : list word -> Prop :=
| L0 : forall (w : word) (ws : list word), emb w v -> L v (w :: ws)
| L1 : forall (w : word) (ws : list word), L v ws -> L v (w :: ws).
Inductive good : list word -> Prop :=
| good0 : forall (ws : list word) (w : word), L w ws -> good (w :: ws)
| good1 : forall (ws : list word) (w : word), good ws -> good (w :: ws).
Inductive R (a : letter) : list word -> list word -> Prop :=
| R0 : R a nil nil
| R1 :
forall (vs ws : list word) (w : word),
R a vs ws -> R a (w :: vs) ((a :: w) :: ws).
Inductive T (a : letter) : list word -> list word -> Prop :=
| T0 :
forall (b : letter) (w : word) (ws zs : list word),
a <> b -> R b ws zs -> T a (w :: zs) ((a :: w) :: zs)
| T1 :
forall (w : word) (ws zs : list word),
T a ws zs -> T a (w :: ws) ((a :: w) :: zs)
| T2 :
forall (b : letter) (w : word) (ws zs : list word),
a <> b -> T a ws zs -> T a ws ((b :: w) :: zs).
Inductive bar : list word -> Set :=
| bar1 : forall ws : list word, good ws -> bar ws
| bar2 : forall ws : list word, (forall w : word, bar (w :: ws)) -> bar ws.
Hint Constructors emb.
Hint Constructors L.
Hint Constructors good.
Hint Constructors R.
Hint Constructors T.
Hint Constructors bar.
Hint Extern 5 (?X1 <> ?X2) => intro; discriminate.
auto.
Defined.
Hint Resolve prop1.
simple induction 1; auto.
Defined.
Hint Resolve lemma1.
simple induction 1.
inversion 1.
inversion 3; auto.
Defined.
Hint Resolve lemma2'.
simple induction 1; auto.
inversion 3; eauto.
Defined.
Hint Resolve lemma2.
simple induction 1; auto; inversion 3; auto.
Qed.
Hint Resolve lemma3'.
simple induction 1; auto; inversion 3; eauto.
Defined.
Hint Resolve lemma3.

Theorem lemma4 :
forall (ws zs : list word) (a : letter), R a ws zs -> ws <> nil -> T a ws zs.