Section BOUND.
Context {TX TG ID : Type}.
Variable tag_of_var : positive -> positive -> option bool -> TG.
Definition bound_vars  (fr : positive)
(v : Vars.t) : @GFormula (Formula Z) TX TG ID :=
Vars.fold (fun k acc =>
let y := (xO (fr + k)) in
let z := (xI (fr + k)) in
Cj
(Cj (A (mk_eq_pos k y z) (tag_of_var fr k None))
(Cj (A (bound_var y) (tag_of_var fr k (Some false)))
(A (bound_var z) (tag_of_var fr k (Some true)))))
acc) v TT.
Definition bound_problem  (F : @GFormula (Formula Z) TX TG ID) : GFormula :=
let v := vars_of_bformula F in
I (bound_vars (Pos.succ (Vars.max_element v)) v) None F.
Definition bound_problem_fr (fr : positive) (F : @GFormula (Formula Z) TX TG ID) : GFormula :=
let v := vars_of_bformula F in
I (bound_vars fr v) None F.
End BOUND.
Fixpoint ZChecker (l:list (NFormula Z)) (pf : ZArithProof)  {struct pf} : bool :=
match pf with
| DoneProof => false
| RatProof w pf =>
match eval_Psatz l w  with
| None => false
| Some f =>
if Zunsat f then true
else ZChecker (f::l) pf
end
| CutProof w pf =>
match eval_Psatz l w with
| None => false
| Some f =>
match genCuttingPlane f with
| None => true
| Some cp => ZChecker (nformula_of_cutting_plane cp::l) pf
end
end
(*    | SplitProof e pf1 pf2 => match ZChecker ((e,NonStrict)::l) pf1 , ZChecker (( *)
| EnumProof w1 w2 pf =>
match eval_Psatz l w1 , eval_Psatz l w2 with
|  Some f1 , Some f2 =>
match genCuttingPlane f1 , genCuttingPlane f2 with
|Some (e1,z1,op1) , Some (e2,z2,op2) =>
if (valid_cut_sign op1 && valid_cut_sign op2 && is_pol_Z0 (padd e1 e2))
then
(fix label (pfs:list ZArithProof) :=
fun lb ub =>
match pfs with
| nil => if Z.gtb lb ub then true else false
| pf::rsr => andb (ZChecker  ((psub e1 (Pc lb), Equal) :: l) pf) (label rsr (Z.add lb 1%Z) ub)
end)   pf (Z.opp z1)  z2
else false
|   _    ,   _   => true
end
|   _   ,  _ => false
end
end.
Fixpoint bdepth (pf : ZArithProof) : nat :=
match pf with
| DoneProof  => O
| RatProof _ p =>  S (bdepth p)
| CutProof _  p =>   S  (bdepth p)
| EnumProof _ _ l => S (List.fold_right (fun pf x => Max.max (bdepth pf) x)   O l)
end.
Definition ZTautoChecker  (f : BFormula (Formula Z)) (w: list ZArithProof): bool :=
@tauto_checker (Formula Z) (NFormula Z) unit Zunsat Zdeduce normalise negate  ZArithProof (fun cl => ZChecker (List.map fst cl)) f w.

Lemma ZTautoChecker_sound : forall f w, ZTautoChecker f w = true -> forall env, eval_f (fun x => x) (Zeval_formula env)  f.