Section Reduction.
Notation "# x" := (var_term x) (at level 2).
Definition t_f b x := Func (existT _ 1 (f b)) (Vector.cons x Vector.nil).
Definition t_e := Func (existT _ 0 e) Vector.nil.
Definition t_dum := Func (existT _ 0 dum) Vector.nil.
Definition f_P x y := Pred (existT _ 2 P) (Vector.cons x (Vector.cons y Vector.nil)).
Notation "x ≡ y" := (Pred (existT _ 2 equiv) (Vector.cons x (Vector.cons y Vector.nil))) (at level 20).
Notation "x ≢ y" := (¬ (x ≡ y)) (at level 20).
Notation "x ≺ y" := (Pred (existT _ 2 less) (Vector.cons x (Vector.cons y Vector.nil))) (at level 20).
Fixpoint tprep (x : list bool) (y : term) :=
match x with
| nil => y
| b::x => t_f b (tprep x y)
end.
Definition tenc (x : list bool) := tprep x t_e.
Definition ax_P := ∀ ∀ f_P #1 #0 --> (#1 ≢ t_dum) ∧ (#0 ≢ t_dum).
Definition ax_S1 := ∀ ¬ (#0 ≺ #0).
Definition ax_S2 := ∀ ∀ ∀ #2 ≺ #1 --> #1 ≺ #0 --> #2 ≺ #0.
Definition ax_HF1_true := ∀ t_f true #0 ≢ t_e.
Definition ax_HF1_false := ∀ t_f false #0 ≢ t_e.
Definition ax_HF2_true := ∀ ∀ t_f true #1 ≢ t_dum --> t_f true #1 ≡ t_f true #0 --> #1 ≡ #0.
Definition ax_HF2_false := ∀ ∀ t_f false #1 ≢ t_dum --> t_f false #1 ≡ t_f false #0 --> #1 ≡ #0.
Definition ax_HF2 := ∀ ∀ t_f true #1 ≡ t_f false #0 --> (t_f true #1 ≡ t_dum ∧ t_f false #0 ≡ t_dum).
Definition ax_HF3_true := ∀ t_f true #0 ≢ t_dum --> #0 ≢ t_dum.
Definition ax_HF3_false := ∀ t_f false #0 ≢ t_dum --> #0 ≢ t_dum.
Definition ax_HI' c :=
(#1 ≡ tenc (fst c) ∧ #0 ≡ tenc (snd c))
∨ (∃ ∃ #3 ≡ tprep (fst c) #1 ∧ #2 ≡ tprep (snd c) #0 ∧ f_P #1 #0
∧ ((#1 ≺ #3 ∧ #0 ≡ #2) ∨ (#0 ≺ #2 ∧ #1 ≡ #3) ∨ (#1 ≺ #3 ∧ #0 ≺ #2))).
Definition ax_HI (R : BSRS) := ∀ ∀ f_P #1 #0 --> list_or (map ax_HI' R).
Definition finsat_formula (R : BSRS) :=
ax_P ∧ ax_S1 ∧ ax_S2 ∧ ax_HF1_true ∧ ax_HF1_false ∧ ax_HF2_true ∧ ax_HF2_false
∧ ax_HF2 ∧ ax_HF3_true ∧ ax_HF3_false ∧ ax_HI R ∧ ∃ f_P #0 #0.
(* Verification of the reduction *)

Theorem finsat_reduction R :
dPCPb R <-> finsat (finsat_formula R).