(** A library of Bellantoni-Cook functions on bitstrings without numerical interpretation *)
(** * Swapping of two arguments  - arities: (2, 0) *)
Definition inv_e (e : BC) : BC :=
comp 2 0 e (proj 2 0 1 :: proj 2 0 0 :: nil) nil.
(** * Conversion from arities (1, 1) to (2, 0) *)
Definition from_11_to_20 (e : BC) : BC :=
comp 2 0 e (proj 2 0 0 :: nil) (proj 2 0 1 :: nil).
(** * Concatenation of bitstrings  - arities: (1, 1) *)
Definition app_e : BC :=
rec (proj 0 1 0)
(comp 1 2 (succ false) nil ((proj 1 2 1) :: nil))
(comp 1 2 (succ true) nil ((proj 1 2 1) :: nil)).
(** * constant function *)
Program Fixpoint constant (v:bs) : { e : BC | arities e = ok_arities 0 0 /\ sem e nil nil = v } :=
match v with
| nil => BC.zero
| b :: v' => BC.comp 0 0 (BC.succ b) nil [constant v']
end.
Next Obligation.
simpl.
tauto.
Qed.
Next Obligation.
simpl.
intros bs_to_BC v b v' Hv.
subst v.
destruct (bs_to_BC v') as [e [H1 H2] ].
simpl.
rewrite H1, H2.
tauto.
Defined.
(** * Recursion on the length of a bitstring, i.e., ignoring the value 0 or 1 of bits *)
Definition rec2 g h := rec g h h.

Lemma rec2_simpl g h i z l1 l2 :
sem (rec2 g h) ((i :: z) :: l1) l2 = sem h (z :: l1) (sem_rec (sem g) (sem h) (sem h) z l1 l2 :: l2).