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)))))))))).

Lemma freeVarPrimRecPiFormulaHelp1 :
forall (n : nat) (A B : Formula) (v : nat),
In v (freeVarFormula LNN (primRecPiFormulaHelp n A B)) ->
In v (freeVarFormula LNN A) \/
In v (freeVarFormula LNN B) \/ v = S (S n) \/ v = S n.