Section ClosedPredicates.
Variables S : {pred A}.
Definition divalg_closed := [/\ 1 \in S, linear_closed S & divr_2closed S].
(* Evaluation of a reified formula *)
Fixpoint holds (e : seq R) (f : formula R) {struct f} : Prop :=
match f with
| Bool b => b
| (t1 == t2)%T => eval e t1 = eval e t2
| Unit t1 => eval e t1 \in unit
| (f1 /\ f2)%T => holds e f1 /\ holds e f2
| (f1 \/ f2)%T => holds e f1 \/ holds e f2
| (f1 ==> f2)%T => holds e f1 -> holds e f2
| (~ f1)%T => ~ holds e f1
| ('exists 'X_i, f1)%T => exists x, holds (set_nth 0 e i x) f1
| ('forall 'X_i, f1)%T => forall x, holds (set_nth 0 e i x) f1
end.
(* Boolean test selecting terms in the language of rings *)
Fixpoint rterm (t : term R) :=
match t with
| _^-1 => false
| t1 + t2 | t1 * t2 => rterm t1 && rterm t2
| - t1 | t1 *+ _ | t1 ^+ _ => rterm t1
| _ => true
end%T.
(* Boolean test selecting formulas in the theory of rings *)
Fixpoint rformula (f : formula R) :=
match f with
| Bool _ => true
| t1 == t2 => rterm t1 && rterm t2
| Unit t1 => false
| f1 /\ f2 | f1 \/ f2 | f1 ==> f2 => rformula f1 && rformula f2
| ~ f1 | ('exists 'X__, f1) | ('forall 'X__, f1) => rformula f1
end%T.
(* Upper bound of the names used in a term *)
Fixpoint ub_var (t : term R) :=
match t with
| 'X_i => i.+1
| t1 + t2 | t1 * t2 => maxn (ub_var t1) (ub_var t2)
| - t1 | t1 *+ _ | t1 ^+ _ | t1^-1 => ub_var t1
| _ => 0%N
end%T.
(* Replaces inverses in the term t by fresh variables, accumulating the *)
(* substitution. *)
Fixpoint to_rterm (t : term R) (r : seq (term R)) (n : nat) {struct t} :=
match t with
| t1^-1 =>
let: (t1', r1) := to_rterm t1 r n in
('X_(n + size r1), rcons r1 t1')
| t1 + t2 =>
let: (t1', r1) := to_rterm t1 r n in
let: (t2', r2) := to_rterm t2 r1 n in
(t1' + t2', r2)
| - t1 =>
let: (t1', r1) := to_rterm t1 r n in
(- t1', r1)
| t1 *+ m =>
let: (t1', r1) := to_rterm t1 r n in
(t1' *+ m, r1)
| t1 * t2 =>
let: (t1', r1) := to_rterm t1 r n in
let: (t2', r2) := to_rterm t2 r1 n in
(Mul t1' t2', r2)
| t1 ^+ m =>
let: (t1', r1) := to_rterm t1 r n in
(t1' ^+ m, r1)
| _ => (t, r)
end%T.

Lemma to_rterm_id t r n : rterm t -> to_rterm t r n = (t, r).