Require Export Coq.Lists.List.
Require Vector.
Definition codeLength : nat -> nat :=
evalStrongRec 0
(fun n Hrecs : nat =>
switchPR n (S (codeNth (n - S (cPairPi2 (pred n))) Hrecs)) 0).

(* Specifications: *)
Lemma codeLengthCorrect :
forall l : list nat, codeLength (codeList l) = length l.
Lemma codeLengthIsPR : isPR 1 codeLength.
Definition codeApp : nat -> nat -> nat :=
evalStrongRec 1
(fun n Hrecs p1 : nat =>
switchPR n
(S
(cPair (cPairPi1 (pred n))
(codeNth (n - S (cPairPi2 (pred n))) Hrecs))) p1).
Lemma codeAppCorrect :
forall l1 l2 : list nat,
codeApp (codeList l1) (codeList l2) = codeList (l1 ++ l2).
Lemma codeAppIsPR : isPR 2 codeApp.
Definition codeListRemove (a l : nat) : nat :=
evalStrongRec 1
(fun n Hrecs p1 : nat =>
switchPR n
(switchPR (charFunction 2 beq_nat (cPairPi1 (pred n)) p1)
(codeNth (n - S (cPairPi2 (pred n))) Hrecs)
(S
(cPair (cPairPi1 (pred n))
(codeNth (n - S (cPairPi2 (pred n))) Hrecs))))
(codeList nil)) l a.
Lemma codeListRemoveCorrect :
forall (a : nat) (l : list nat),
codeListRemove a (codeList l) = codeList (list_remove nat eq_nat_dec a l).
Lemma codeListRemoveIsPR : isPR 2 codeListRemove.
Definition codeIn (a l : nat) : nat :=
evalStrongRec 1
(fun n Hrecs p1 : nat =>
switchPR n
(switchPR (charFunction 2 beq_nat (cPairPi1 (pred n)) p1) 1
(codeNth (n - S (cPairPi2 (pred n))) Hrecs)) 0) l a.
Lemma codeInCorrect :
forall (a : nat) (l : list nat),
codeIn a (codeList l) =
match In_dec eq_nat_dec a l with
| left _ => 1
| right _ => 0
end.
Lemma codeInIsPR : isPR 2 codeIn.
Definition codeNoDup : nat -> nat :=
evalStrongRec 0
(fun l recs : nat =>
switchPR l
(switchPR
(codeIn (cPairPi1 (pred l))
(codeNth (l - S (cPairPi2 (pred l))) recs))
(codeNth (l - S (cPairPi2 (pred l))) recs)
(S
(cPair (cPairPi1 (pred l))
(codeNth (l - S (cPairPi2 (pred l))) recs)))) 0).
Lemma codeNoDupCorrect :
forall l : list nat,
codeNoDup (codeList l) = codeList (no_dup _ eq_nat_dec l).
Lemma codeNoDupIsPR : isPR 1 codeNoDup.