Definition L (G : cfg) x := rewt G [startsym G] x /\ terminal G x.
Definition PALIN (G : cfg) := exists x, L G x /\ x = List.rev x.
End CFGs.
(* spec    proof comments *)
(*  62      154      517 pcp_cfg.v *)
Section Reduction.
Variable P : SRS.
Definition Sigma := sym P.
Notation "#" := (fresh Sigma).
Definition Start := (fresh (# :: Sigma)).
Definition enc x := fst x ++ [#] ++ snd x ++ [#].
Definition G1 : cfg :=
(Start, (Start, [Start]) ::
(flat_map
(fun x => [ (Start, (fst x) ++ [Start] ++ enc x);
(Start, (fst x) ++ [#] ++ enc x)]) P)).
Definition G2  : cfg :=
(Start, (Start, [Start]) ::
(flat_map
(fun x => [ (Start, (snd x) ++ [Start] ++ enc x);
(Start, (snd x) ++ [#] ++ enc x)]) P)).
Definition inter_nonempty '(G1, G2) :=
exists x, @L G1 x /\ L G2 x.

(* Specifications: *)
Lemma in_rules1 x A :
(x, A) el rules G1 -> x = Start /\ (A = [Start] \/ (exists x M, (M = [Start] \/ M = [#]) /\ ({H : x el P | A = (fst x) ++ M ++ enc x}))).
Lemma terminal_G1 x :
~ Start el x <->
terminal G1 x.
Lemma in_rules2 x A :
(x, A) el rules G2 -> x = Start /\ (A = [Start] \/ (exists x M, (M = [Start] \/ M = [#]) /\ ({H : x el P | A = (snd x) ++ M ++ enc x}))).
Lemma terminal_G2 x :
~ Start el x <->
terminal G2 x.