(** ** Traditional Definition *)
Definition symbol := nat.
Definition string X := list X.
Definition card X : Type := string X * string X.
Definition stack X := list (card X).
Definition SRS := stack nat.
Definition BSRS := stack bool.
Notation "x / y" := (x,y).
Fixpoint tau1 (X : Type) (A : stack X) : string X :=
match A with
| [] => []
| (x / y) :: A => x ++ tau1 A
end.
Fixpoint tau2 X (A : stack X) : string X :=
match A with
| [] => []
| (x / y) :: A => y ++ tau2 A
end.
Definition PCP P := exists A : SRS, A <<= P /\ A <> [] /\ tau1 A = tau2 A.
(** ** Inductive Definition *)
Inductive derivable (X : Type) (R : stack X) : string X -> string X -> Prop :=
|  der_sing x y : x/y el R -> derivable R x y
| der_cons x y u v : x/y el R -> derivable R u v -> derivable R (x ++ u) (y ++ v).

(* Specifications: *)
Lemma derivable_BPCP X (P : stack X) u v :
derivable P u v -> exists A, A <<= P /\ A <> nil /\ tau1 A = u /\ tau2 A = v.
Lemma BPCP_derivable X (P : stack X) u v : (exists A, A <<= P /\ A <> nil /\ tau1 A = u /\ tau2 A = v) -> derivable P u v.
Definition BPCP P := exists A : BSRS, A <<= P /\ A <> [] /\ tau1 A = tau2 A.