Module Argument.
Definition bullet := var 0.
(* encodes symbol true *)
Definition b2 := (arr bullet bullet).
(* encodes symbol false *)
Definition b3 := arr bullet (arr bullet bullet).
Fixpoint append_word (s: formula) (v: list bool) :=
match v with
| [] => s
| a :: v =>
if a then
append_word (arr b2 s) v else
append_word (arr b3 s) v
end.
Definition encode_word (v: list bool) := append_word bullet v.
Definition encode_pair (s t: formula) := arr b3 (arr s (arr t b3)).
Notation "⟨ s , t ⟩" := (encode_pair s t).
Notation "⟦ v ⟧" := (encode_word v).
Notation "s → t" := (arr s t) (at level 50).
(* environment encoding the instance ((v, w), P) of BMPCP *)
Definition Γ v w P :=
(encode_pair (var 1) (var 1)) ::
(arr (encode_pair (encode_word v) (encode_word w)) a_b_a) ::
map (fun '(v, w) => arr (encode_pair (append_word (var 2) v) (append_word (var 3) w)) (encode_pair (var 2) (var 3))) ((v, w) :: P).
(* derivability of an instance of a → b → a *)
Definition adequate v w P n :=
exists p q, der (Γ v w P) n (arr p (arr q p)).
(* derivability of (v ++ v₁ ++...++ vₙ, w ++ w₁ ++...++ wₙ) *)
Definition solving (v w: list bool) P n :=
exists A,
(incl A ((v, w) :: P)) /\
exists ζ, der (Γ v w P) n
(substitute ζ (encode_pair
(encode_word (v ++ tau1 A))
(encode_word (w ++ tau2 A)))).

Lemma solving_step {v w P n} : solving v w P (S n) -> adequate v w P n \/ solving v w P n \/ MPCPb ((v, w), P).