Section Primative_Recursive_Representable.
Let Representable := Representable NN.
Let RepresentableAlternate := RepresentableAlternate NN closedNN1.
Let RepresentableHelp := RepresentableHelp NN.
Let Representable_ext := Representable_ext NN.
Definition beta (a z : nat) : nat :=
snd
(proj1_sig
(modulo (coPrimeBeta z (cPairPi1 a)) (gtBeta z (cPairPi1 a))
(cPairPi2 a))).
Definition betaFormula : Formula :=
existH 3
(andH (LT (var 3) (Succ (var 2)))
(existH 4
(andH (LT (var 4) (Succ (var 2)))
(andH
(equal
(Plus
(Times (Plus (var 3) (var 4))
(Succ (Plus (var 3) (var 4))))
(Times (natToTerm 2) (var 3)))
(Times (natToTerm 2) (var 2)))
(andH (LT (var 0) (Succ (Times (var 3) (Succ (var 1)))))
(existH 5
(andH (LT (var 5) (Succ (var 4)))
(equal
(Plus (var 0)
(Times (var 5)
(Succ (Times (var 3) (Succ (var 1))))))
(var 4))))))))).
Fixpoint addExists (m n : nat) (f : Formula) {struct n} : Formula :=
match n with
| O => f
| S n' => existH (n' + m) (addExists m n' f)
end.
Fixpoint addForalls (m n : nat) (f : Formula) {struct n} : Formula :=
match n with
| O => f
| S n' => forallH (n' + m) (addForalls m n' f)
end.
Fixpoint FormulasToFormula (n w m : nat)
(vs : Vector.t (Formula * naryFunc n) m) {struct vs} : Formula :=
match vs with
| Vector.nil => equal (var 0) (var 0)
| Vector.cons v m' vs' =>
andH (substituteFormula LNN (fst v) 0 (var (S m' + w)))
(FormulasToFormula n w m' vs')
end.
Fixpoint FormulasToFuncs (n m : nat) (vs : Vector.t (Formula * naryFunc n) m)
{struct vs} : Vector.t (naryFunc n) m :=
match vs in (Vector.t _ m) return (Vector.t (naryFunc n) m) with
| Vector.nil => Vector.nil _
| Vector.cons v m' vs' => Vector.cons _ (snd v) m' (FormulasToFuncs n m' vs')
end.
Fixpoint RepresentablesHelp (n m : nat)
(vs : Vector.t (Formula * naryFunc n) m) {struct vs} : Prop :=
match vs with
| Vector.nil => True
| Vector.cons a m' vs' =>
RepresentableHelp _ (snd a) (fst a) /\ RepresentablesHelp n m' vs'
end.
Let succFormula : Formula := equal (var 0) (Succ (var 1)).
Remark succRepresentable : Representable 1 S succFormula.
Let zeroFormula : Formula := equal (var 0) Zero.
Remark zeroRepresentable : Representable 0 0 zeroFormula.
Let projFormula (m : nat) : Formula := equal (var 0) (var (S m)).
Remark projRepresentable :
forall (n m : nat) (pr : m < n),
Representable n (evalProjFunc n m pr) (projFormula m).
Let composeSigmaFormula (n w m : nat) (A : Vector.t (Formula * naryFunc n) m)
(B : Formula) : Formula :=
addExists (S w) m
(andH (FormulasToFormula n w m A)
(subAllFormula LNN B
(fun x : nat =>
match x with
| O => var 0
| S x' => var (S x' + w)
end))).
Remark composeSigmaRepresentable :
forall n w m : nat,
n <= w ->
forall (A : Vector.t (Formula * naryFunc n) m) (B : Formula) (g : naryFunc m),
RepresentablesHelp n m A ->
Vector.t_rect (Formula * naryFunc n) (fun _ _ => Prop) True
(fun (pair : Formula * naryFunc n) (m : nat) (v : Vector.t _ m) (rec : Prop) =>
(forall v : nat, In v (freeVarFormula LNN (fst pair)) -> v <= n) /\ rec)
m A ->
Representable m g B ->
Representable n (evalComposeFunc n m (FormulasToFuncs n m A) g)
(composeSigmaFormula n w m A B).
(* Local composePiFormula [n,w,m:nat][A:(vector Formula*(naryFunc n) m)][B:Formula] : Formula := (addForalls (S w) m (impH (FormulasToFormula n w m A) (subAllFormula LNN B [x:nat] (Cases x of O => (var O) | (S x')=>(var (plus (S x') w))end)))).  Remark composePiRepresentable : (n,w,m:nat)(le n w)->(A:(vector Formula*(naryFunc n) m)) (B:Formula)(g:(naryFunc m)) (RepresentablesHelp n m A)-> (vector_rect Formula*(naryFunc n) [_][_]Prop True [pair:(Formula*(naryFunc n))][m:nat][v:(vector ? m)][rec:Prop] ((v:nat)(In v (freeVarFormula LNN (Fst pair)))->(le v n))/\rec m A)-> (Representable m g B)-> (Representable n (evalComposeFunc n m (FormulasToFuncs n m A) g) (composePiFormula n w m A B)). *)
Remark boundedCheck :
forall P : nat -> Prop,
(forall x : nat, decidable (P x)) ->
forall c : nat,
(forall d : nat, d < c -> ~ P d) \/ (exists d : nat, d < c /\ P d).
Remark smallestExists :
forall P : nat -> Prop,
(forall x : nat, decidable (P x)) ->
forall c : nat,
P c -> exists a : nat, P a /\ (forall b : nat, b < a -> ~ P b).
Let minimize (A B : Formula) (v x : nat) : Formula :=
andH A
(forallH x
(impH (LT (var x) (var v)) (notH (substituteFormula LNN B v (var x))))).
Remark minimize1 :
forall (A B : Formula) (v x : nat),
v <> x ->
~ In x (freeVarFormula LNN B) ->
forall a : nat,
SysPrf NN (substituteFormula LNN A v (natToTerm a)) ->
SysPrf NN (substituteFormula LNN B v (natToTerm a)) ->
(forall b : nat,
b < a -> SysPrf NN (notH (substituteFormula LNN A v (natToTerm b)))) ->
(forall b : nat,
b < a -> SysPrf NN (notH (substituteFormula LNN B v (natToTerm b)))) ->
SysPrf NN (iffH (minimize A B v x) (equal (var v) (natToTerm a))).
Let primRecSigmaFormulaHelp (n : nat) (SigA SigB : Formula) : Formula :=
andH
(existH 0
(andH SigA
(substituteFormula LNN (substituteFormula LNN betaFormula 1 Zero) 2
(var (S (S n))))))
(forallH (S (S (S n)))
(impH (LT (var (S (S (S n)))) (var (S n)))
(existH 0
(existH (S n)
(andH
(substituteFormula LNN
(substituteFormula LNN
(substituteFormula LNN betaFormula 1
(var (S (S (S n))))) 2
(var (S (S n)))) 0 (var (S n)))
(andH
(substituteFormula LNN SigB (S (S n))
(var (S (S (S n)))))
(substituteFormula LNN
(substituteFormula LNN betaFormula 1
(Succ (var (S (S (S n)))))) 2
(var (S (S n)))))))))).
Let primRecPiFormulaHelp (n : nat) (SigA SigB : Formula) : Formula :=
andH
(forallH 0
(impH SigA
(substituteFormula LNN (substituteFormula LNN betaFormula 1 Zero) 2
(var (S (S n))))))
(forallH (S (S (S n)))
(impH (LT (var (S (S (S n)))) (var (S n)))
(forallH 0
(forallH (S n)
(impH
(substituteFormula LNN
(substituteFormula LNN
(substituteFormula LNN betaFormula 1
(var (S (S (S n))))) 2
(var (S (S n)))) 0 (var (S n)))
(impH
(substituteFormula LNN SigB (S (S n))
(var (S (S (S n)))))
(substituteFormula LNN
(substituteFormula LNN betaFormula 1
(Succ (var (S (S (S n)))))) 2
(var (S (S n)))))))))).
Let primRecSigmaFormula (n : nat) (SigA SigB : Formula) : Formula :=
existH (S (S n))
(andH
(minimize (primRecSigmaFormulaHelp n SigA SigB)
(primRecPiFormulaHelp n SigA SigB) (S (S n))
(S (S (S (S n)))))
(substituteFormula LNN
(substituteFormula LNN betaFormula 2 (var (S (S n)))) 1
(var (S n)))).
Remark notBoundedForall :
forall (P : nat -> Prop) (b : nat),
(forall x : nat, decidable (P x)) ->
~ (forall n : nat, n < b -> P n) -> exists n : nat, n < b /\ ~ P n.
Remark In_betaFormula_subst_1_2_0 :
forall (a b c : Term) (v : nat),
In v
(freeVarFormula LNN
(substituteFormula LNN
(substituteFormula LNN (substituteFormula LNN betaFormula 1 a) 2 b)
0 c)) ->
In v (freeVarTerm LNN a) \/
In v (freeVarTerm LNN b) \/ In v (freeVarTerm LNN c).
Remark In_betaFormula_subst_1_2 :
forall (a b : Term) (v : nat),
In v
(freeVarFormula LNN
(substituteFormula LNN (substituteFormula LNN betaFormula 1 a) 2 b)) ->
In v (freeVarTerm LNN a) \/
In v (freeVarTerm LNN b) \/ In v (freeVarTerm LNN (var 0)).
Remark In_betaFormula_subst_1 :
forall (a : Term) (v : nat),
In v (freeVarFormula LNN (substituteFormula LNN betaFormula 1 a)) ->
In v (freeVarTerm LNN a) \/
In v (freeVarTerm LNN (var 2)) \/ In v (freeVarTerm LNN (var 0)).
Remark In_betaFormula :
forall v : nat,
In v (freeVarFormula LNN betaFormula) ->
In v (freeVarTerm LNN (var 1)) \/
In v (freeVarTerm LNN (var 2)) \/ In v (freeVarTerm LNN (var 0)).
Remark In_betaFormula_subst_2 :
forall (a : Term) (v : nat),
In v (freeVarFormula LNN (substituteFormula LNN betaFormula 2 a)) ->
In v (freeVarTerm LNN a) \/
In v (freeVarTerm LNN (var 1)) \/ In v (freeVarTerm LNN (var 0)).
Remark In_betaFormula_subst_2_1 :
forall (a b : Term) (v : nat),
In v
(freeVarFormula LNN
(substituteFormula LNN (substituteFormula LNN betaFormula 2 a) 1 b)) ->
In v (freeVarTerm LNN a) \/
In v (freeVarTerm LNN b) \/ In v (freeVarTerm LNN (var 0)).
Ltac PRsolveFV A B n :=
unfold existH, forallH, not in |- *; intros;
repeat
match goal with
| H:(_ = _) |- _ => discriminate H
| H:(?X1 <> ?X1) |- _ => elim H; reflexivity
| H:(?X1 = S ?X1) |- _ => elim (n_Sn _ H)
| H:(S ?X1 = ?X1) |- _ =>
elim (n_Sn X1); symmetry  in |- *; apply H
| H:(?X1 = S (S ?X1)) |- _ => elim (n_SSn _ H)
| H:(S (S ?X1) = ?X1) |- _ =>
elim (n_SSn X1); symmetry  in |- *; apply H
| H:(?X1 = S (S (S ?X1))) |- _ =>
elim (n_SSSn _ H)
| H:(S (S (S ?X1)) = ?X1) |- _ =>
elim (n_SSSn X1); symmetry  in |- *; apply H
| H:(In ?X3
(freeVarFormula LNN
(substituteFormula LNN
(substituteFormula LNN
(substituteFormula LNN betaFormula 1 _) 2 _) 0 _))) |- _
=>
decompose sum (In_betaFormula_subst_1_2_0 _ _ _ _ H); clear H
| H:(In ?X3
(freeVarFormula LNN
(substituteFormula LNN (substituteFormula LNN betaFormula 1 _)
2 _))) |- _ =>
decompose sum (In_betaFormula_subst_1_2 _ _ _ H); clear H
| H:(In ?X3 (freeVarFormula LNN (substituteFormula LNN betaFormula 1 _)))
|- _ =>
decompose sum (In_betaFormula_subst_1 _ _ H); clear H
| H:(In ?X3 (freeVarFormula LNN betaFormula)) |- _ =>
decompose sum (In_betaFormula _ H); clear H
| H:(In ?X3
(freeVarFormula LNN
(substituteFormula LNN (substituteFormula LNN betaFormula 2 _)
1 _))) |- _ =>
decompose sum (In_betaFormula_subst_2_1 _ _ _ H); clear H
| H:(In ?X3 (freeVarFormula LNN (substituteFormula LNN betaFormula 2 _)))
|- _ =>
decompose sum (In_betaFormula_subst_2 _ _ H);
clear H
(* Match Context With *)
| H:(In ?X3 (freeVarFormula LNN (fol.existH LNN ?X1 ?X2))) |- _ =>
assert
(In X3 (list_remove nat eq_nat_dec X1 (freeVarFormula LNN X2)));
[ apply H | clear H ]
| H:(In ?X3 (freeVarFormula LNN (fol.forallH LNN ?X1 ?X2))) |- _ =>
assert
(In X3 (list_remove nat eq_nat_dec X1 (freeVarFormula LNN X2)));
[ apply H | clear H ]
|
(* . *)
H:(In ?X3 (list_remove nat eq_nat_dec ?X1 (freeVarFormula LNN ?X2))) |- _
=>
assert (In X3 (freeVarFormula LNN X2));
[ eapply In_list_remove1; apply H
| assert (X3 <> X1); [ eapply In_list_remove2; apply H | clear H ] ]
| H:(In ?X3 (freeVarFormula LNN (fol.andH LNN ?X1 ?X2))) |- _ =>
assert (In X3 (freeVarFormula LNN X1 ++ freeVarFormula LNN X2));
[ apply H | clear H ]
| H:(In ?X3 (freeVarFormula LNN (fol.impH LNN ?X1 ?X2))) |- _ =>
assert (In X3 (freeVarFormula LNN X1 ++ freeVarFormula LNN X2));
[ apply H | clear H ]
| H:(In ?X3 (freeVarFormula LNN (fol.notH LNN ?X1))) |- _ =>
assert (In X3 (freeVarFormula LNN X1)); [ apply H | clear H ]
| H:(In _ (freeVarFormula LNN (primRecPiFormulaHelp _ _ _))) |- _ =>
decompose sum (freeVarPrimRecPiFormulaHelp1 _ _ _ _ H); clear H
| J:(In ?X3 (freeVarFormula LNN A)),H:(forall v : nat,
In v (freeVarFormula LNN A) ->
v <= S n) |- _ =>
elim (le_not_lt X3 (S n));
[ apply H; apply J | clear J; repeat apply lt_n_Sn || apply lt_S ]
| H:(In ?X3 (freeVarFormula LNN B)),H0:(forall v : nat,
In v (freeVarFormula LNN B) ->
v <= S (S (S n))) |- _ =>
elim (le_not_lt X3 (S (S (S n))));
[ apply H0; apply H | clear H; repeat apply lt_n_Sn || apply lt_S ]
| H:(In _ (_ ++ _)) |- _ =>
induction (in_app_or _ _ _ H); clear H
| H:(In _ (freeVarFormula LNN (substituteFormula LNN ?X1 ?X2 ?X3))) |- _
=>
induction (freeVarSubFormula3 _ _ _ _ _ H); clear H
| H:(In _ (freeVarFormula LNN (LT ?X1 ?X2))) |- _ =>
rewrite freeVarLT in H
| H:(In _ (freeVarTerm LNN (natToTerm _))) |- _ =>
elim (closedNatToTerm _ _ H)
| H:(In _ (freeVarTerm LNN Zero)) |- _ =>
elim H
| H:(In _ (freeVarTerm LNN (Succ _))) |- _ =>
rewrite freeVarSucc in H
| H:(In _ (freeVarTerm LNN (var _))) |- _ =>
simpl in H; decompose sum H; clear H
| H:(In _ (freeVarTerm LNN (fol.var LNN _))) |- _ =>
simpl in H; decompose sum H; clear H
end.
Remark primRecSigmaRepresentable :
forall (n : nat) (A : Formula) (g : naryFunc n),
Representable n g A ->
forall (B : Formula) (h : naryFunc (S (S n))),
Representable (S (S n)) h B ->
Representable (S n) (evalPrimRecFunc n g h) (primRecSigmaFormula n A B).
Fixpoint primRecFormula (n : nat) (f : PrimRec n) {struct f} : Formula :=
match f with
| succFunc => succFormula
| zeroFunc => zeroFormula
| projFunc n m _ => projFormula m
| composeFunc n m g h =>
composeSigmaFormula n n m (primRecsFormula n m g) (primRecFormula m h)
| primRecFunc n g h =>
primRecSigmaFormula n (primRecFormula n g) (primRecFormula (S (S n)) h)
end
with primRecsFormula (n m : nat) (fs : PrimRecs n m) {struct fs} :
Vector.t (Formula * naryFunc n) m :=
match fs in (PrimRecs n m) return (Vector.t (Formula * naryFunc n) m) with
| PRnil n => Vector.nil _
| PRcons n m f fs' =>
Vector.cons (Formula * naryFunc n) (primRecFormula n f, evalPrimRec n f) m
(primRecsFormula n m fs')
end.

Lemma primRecRepresentable :
forall (n : nat) (f : naryFunc n) (p : isPR n f),
Representable n f (primRecFormula n (proj1_sig p)).