Ltac SimplFreeVar :=
  repeat
   match goal with
   | H1:(?X1 = ?X2),H2:(?X1 <> ?X2) |- _ =>
       elim H2; apply H1
   | H1:(?X1 = ?X2),H2:(?X2 <> ?X1) |- _ =>
       elim H2; symmetry  in |- *; apply H1
   | H1:(?X1 <> ?X1) |- _ =>
       elim H1; reflexivity
   | H:(In ?X3 (freeVarFormula ?X9 (existH ?X1 ?X2))) |- _ =>
       assert (In X3 (list_remove nat eq_nat_dec X1 (freeVarFormula X9 X2)));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (fol.existH ?X9 ?X1 ?X2))) |- _ =>
       assert (In X3 (list_remove nat eq_nat_dec X1 (freeVarFormula X9 X2)));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (forallH ?X1 ?X2))) |- _ =>
       assert (In X3 (list_remove nat eq_nat_dec X1 (freeVarFormula X9 X2)));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (fol.forallH ?X9 ?X1 ?X2))) |- _ =>
       assert (In X3 (list_remove nat eq_nat_dec X1 (freeVarFormula X9 X2)));
        [ apply H | clear H ]
   | H:(In ?X3 (list_remove nat eq_nat_dec ?X1 (freeVarFormula ?X9 ?X2))) |-
   _ =>
       assert (In X3 (freeVarFormula X9 X2));
        [ eapply In_list_remove1; apply H
        | assert (X3 <> X1); [ eapply In_list_remove2; apply H | clear H ] ]
   | H:(In ?X3 (freeVarFormula ?X9 (andH ?X1 ?X2))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1 ++ freeVarFormula X9 X2));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (fol.andH ?X9 ?X1 ?X2))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1 ++ freeVarFormula X9 X2));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (orH ?X1 ?X2))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1 ++ freeVarFormula X9 X2));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (fol.orH ?X9 ?X1 ?X2))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1 ++ freeVarFormula X9 X2));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (impH ?X1 ?X2))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1 ++ freeVarFormula X9 X2));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (fol.impH ?X9 ?X1 ?X2))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1 ++ freeVarFormula X9 X2));
        [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (notH ?X1))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1)); [ apply H | clear H ]
   | H:(In ?X3 (freeVarFormula ?X9 (fol.notH ?X9 ?X1))) |- _ =>
       assert (In X3 (freeVarFormula X9 X1)); [ apply H | clear H ]
   | H:(In _ (_ ++ _)) |- _ =>
       induction (in_app_or _ _ _ H); clear H
   | H:(In _ (freeVarFormula ?X9 (substituteFormula ?X9 ?X1 ?X2 ?X3))) |- _
   =>
       induction (freeVarSubFormula3 _ _ _ _ _ H); clear H
   | H:(In _ (freeVarFormula ?X9 (LT ?X1 ?X2))) |- _ =>
       rewrite freeVarLT in H
   | H:(In _ (freeVarTerm ?X9 (LNT.natToTerm _))) |- _ =>
       elim (LNT.closedNatToTerm _ _ H)
   | H:(In _ (freeVarTerm ?X9 (natToTerm _))) |- _ =>
       elim (closedNatToTerm _ _ H)
   | H:(In _ (freeVarTerm ?X9 Zero)) |- _ =>
       elim H
   | H:(In _ (freeVarTerm ?X9 (Succ _))) |- _ =>
       rewrite freeVarSucc in H
   | H:(In _ (freeVarTerm ?X9 (var _))) |- _ =>
       simpl in H; decompose sum H; clear H
   | H:(In _ (freeVarTerm ?X9 (LNT.var _))) |- _ =>
       simpl in H; decompose sum H; clear H
   | H:(In _ (freeVarTerm ?X9 (fol.var ?X9 _))) |- _ =>
       simpl in H; decompose sum H; clear H
   end.Definition codeSysPrf : Formula :=
  let nv := newVar (2 :: 1 :: 0 :: v0 :: nil) in
  existH nv
    (andH
       (substituteFormula LNN
          (substituteFormula LNN
             (primRecFormula 2
                (proj1_sig
                   (checkPrfIsPR L codeF codeR codeArityF codeArityR
                      codeArityFIsPR codeArityRIsPR))) 0 
             (Succ (var nv))) 2 (var 0))
       (forallH (S nv)
          (impH (LT (var (S nv)) (var nv))
             (orH
                (substituteFormula LNN
                   (substituteFormula LNN
                      (substituteFormula LNN
                         (primRecFormula 2 (proj1_sig codeInIsPR)) 2
                         (var (S nv))) 1 (var nv)) 0 Zero)
                (substituteFormula LNN fU v0 (var (S nv))))))).

(* Specifications: *)
Lemma codeSysPrfCorrect1 : forall (f : fol.Formula L) (A : list (fol.Formula L)) (p : Prf L A f), (forall g : fol.Formula L, In g A -> mem _ U g) -> SysPrf T (substituteFormula LNN (substituteFormula LNN codeSysPrf 0 (natToTerm (codeFormula L codeF codeR f))) 1 (natToTerm (codePrf L codeF codeR A f p))).
Lemma codeSysPrfCorrect2 : forall (f : fol.Formula L) (A : fol.Formulas L), (exists g : fol.Formula L, In g A /\ ~ mem _ U g) -> forall p : Prf L A f, SysPrf T (notH (substituteFormula LNN (substituteFormula LNN codeSysPrf 0 (natToTerm (codeFormula L codeF codeR f))) 1 (natToTerm (codePrf L codeF codeR A f p)))).
Lemma codeSysPrfCorrect3 : forall (f : fol.Formula L) (n : nat), (forall (A : list (fol.Formula L)) (p : Prf L A f), n <> codePrf L codeF codeR A f p) -> SysPrf T (notH (substituteFormula LNN (substituteFormula LNN codeSysPrf 0 (natToTerm (codeFormula L codeF codeR f))) 1 (natToTerm n))).
Lemma freeVarCodeSysPrf : forall v : nat, In v (freeVarFormula LNN codeSysPrf) -> v <= 1.