Module Argument.
(* inject configuration into nat *)
Definition embed : config -> nat := to_nat.
Definition unembed : nat -> config := of_nat.
Definition embedP {X: config} : (unembed (embed X) = X) := enumP.
(* step relation to semi-unification constraints *)
Definition SM_to_SUcs (M: ssm) : list constraint :=
map (fun '(x, y, a, b, d) =>
if d then ((a, embed ([], [], x)), (embed ([], [], y), b)) (* ax -> yb *)
else ((b, embed ([], [], y)), (embed ([], [], x), a)) (* xa -> by *)
) M.
(* n is 1 + bound - length X.2 *)
Fixpoint ζ (n: nat) (X: config) : term :=
match n with
| 0 => atom (embed (nf X))
| S n =>
match X with
| (A, B, x) =>
if narrow_dec (A, B, x) then arr (ζ n (A, B++[false], x)) (ζ n (A, B++[true], x))
else atom (embed (nf X))
end
end.
Definition ψ (a: bool) (n: nat) (i: nat): term :=
match unembed i with
| (A, B, x) => ζ (n - length B) (A++[a], B, x)
end.
End SM.
(* reduction completeness *)
Fixpoint term_depth_bound (t: term) : nat :=
match t with
| atom _ => 1
| arr s t => 1 + (term_depth_bound s) + (term_depth_bound t)
end.
Fixpoint depth_bound (φ: valuation) (xs: list state) : nat :=
match xs with
| [] => 1
| x :: xs => 1 + term_depth_bound (φ x) + depth_bound φ xs
end.

Lemma depth_boundP {φ: valuation} {x: state} {xs: list state} : In x xs -> term_depth_bound (φ x) <= depth_bound φ xs.