(* ** PCP reduces to BPCP *)
(* natural numbers n to bitstrings of the form 1^n *)
Definition to_bitstring (n : nat) : string bool := Nat.iter n (cons true) [].
(* strings of natural numbers to bitstrings, [ n1, ... n2 ] |-> 1^n1 0 ... 1^n2 0 *)
Fixpoint f_s (x : string nat) : string bool :=
match x with
| nil => nil
| a :: x => to_bitstring a ++ [false] ++ f_s x
end.
(* extension to cards and stacks *)
Definition f_c '(x,y) := (f_s x, f_s y).
Definition f (P : stack nat) : stack bool :=
map f_c P.
(* interpretation of a bitstring as list of natural numbers *)
Fixpoint g_s' (x : string bool) (n : nat) : string nat :=
match x with
| nil => nil
| true :: x' => g_s' x' (S n)
| false :: x' => n :: g_s' x' 0
end.
Definition g_s x := g_s' x 0.
(* extension to cards and stacks *)
Definition g_c '(x,y) := (g_s x, g_s y).
Definition g (P : stack bool) : stack nat :=
map g_c P.
(* Invariants *)

Theorem reduction : PCP ⪯ PCPb.