End TrivialLift.
Module Hesselink.
Section ReductionHesselink.
Variable Sigma' : Type.
Variable P : pcp Sigma'.
Inductive Sigma := embed (s : Sigma') | Start | hash.
Definition embed_string (s : list Sigma') := map embed s.
Notation "#" := hash.
Definition f : pcp Sigma' -> cfg Sigma :=
fun P =>
(Start, (Start, [Start]) ::
(flat_map
(fun x => [ (Start, embed_string (fst x) ++ [Start] ++ embed_string (rev (snd x)));
(Start, embed_string (fst x) ++ [#] ++ embed_string (rev (snd x)))])
P)).

(* Specifications: *)
Lemma in_rules x A :
(x, A) el rules (f P) -> x = Start /\ (A = [Start] \/ (exists x M, (M = Start \/ M = #) /\ x el P /\ A = embed_string (fst x) ++ [M] ++ embed_string (rev (snd x)))).
Lemma terminal_f x :
~ Start el x <->
terminal (f P) x.