Section PrimRecs_case.
Let cast (x : nat) (n : nat) (m : nat) (EQ : n = m) : PrimRecs x n -> PrimRecs x m :=
match EQ with
| eq_refl => fun xs => xs
end.
End PrimRecs_case.
Fixpoint runPrimRec {n : arity} (f : PrimRec n) {struct f} : naryFun n :=
match f with
| PR_succ => S
| PR_zero => O
| PR_proj n i => eval_proj (n := n) i
| PR_compose n m g h => eval_compose (n := n) (m := m) (runPrimRecs g) (runPrimRec h)
| PR_primRec n g h => eval_primRec (n := n) (runPrimRec g) (runPrimRec h)
end
with runPrimRecs {n : arity} {m : arity} (fs : PrimRecs n m) {struct fs} : Vector.t (naryFun n) m :=
match fs with
| PRs_nil n' => VNil
| PRs_cons n' m' f fs' => VCons m' (runPrimRec f) (runPrimRecs fs')
end.
Fixpoint PrimRecGraph_complete (n : arity) (f : PrimRec n) (xs : Vector.t nat n) (z : nat) (SPEC : PrimRecSpec n f xs z) {struct SPEC}
: PrimRecGraph f xs z
with PrimRecsGraph_complete (n : arity) (m : arity) (fs : PrimRecs n m) (xs : Vector.t nat n) (z : Vector.t nat m) (SPEC : PrimRecsSpec n m fs xs z) {struct SPEC}
: PrimRecsGraph fs xs z.
Fixpoint PrimRecSpec_sound (n : arity) (f : PrimRec n) (xs : Vector.t nat n) (z : nat) (SPEC : PrimRecSpec n f xs z) {struct SPEC}
: eval_vec xs (runPrimRec f) = z
with PrimRecsSpec_sound (n : arity) (m : arity) (fs : PrimRecs n m) (xs : Vector.t nat n) (z : Vector.t nat m) (SPEC : PrimRecsSpec n m fs xs z) {struct SPEC}
: V.map (eval_vec xs) (runPrimRecs fs) = z.
Fixpoint PrimRecSpec_complete (n : arity) (f : PrimRec n) {struct f}
: forall xs, PrimRecSpec n f xs (eval_vec xs (runPrimRec f))
with PrimRecsSpec_complete (n : arity) (m : arity) (fs : PrimRecs n m) {struct fs}
: forall xs, PrimRecsSpec n m fs xs (V.map (eval_vec xs) (runPrimRecs fs)).

Theorem PrimRecSpec_iff (n : arity) (f : PrimRec n) (xs : Vector.t nat n) (z : nat)
: PrimRecSpec n f xs z <-> eval_vec xs (runPrimRec f) = z.