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

Lemma subFormulaMinimize :
forall (A B : Formula) (v x z : nat) (s : Term),
~ In x (freeVarTerm LNN s) ->
~ In v (freeVarTerm LNN s) ->
x <> z ->
v <> z ->
SysPrf NN
(iffH (substituteFormula LNN (minimize A B v x) z s)
(minimize (substituteFormula LNN A z s) (substituteFormula LNN B z s) v
x)).