intros.
induction e;trivial;simpl interp_AF_to_F at 2.
simpl;case (natle n n0);case (natle n0 n1);case (natle n n1);simpl;Geometry.
simpl;case (natle n n0);simpl;symmetry;Geometry.
rewrite <- IHe1;rewrite <- IHe2;simpl uniformize_areas at 1;destruct (uniformize_areas e1);destruct (uniformize_areas e2);trivial;ring.
rewrite <- IHe1;rewrite <- IHe2;simpl uniformize_areas at 1;destruct (uniformize_areas e1);destruct (uniformize_areas e2);trivial;ring.
rewrite <- IHe;simpl uniformize_areas at 1;destruct (uniformize_areas e);trivial;ring.
rewrite <- IHe;simpl uniformize_areas at 1;destruct (uniformize_areas e);trivial;ring.
Qed.
Ltac generalize_all :=
repeat match goal with
H:_ |- _ => revert H
end.
Ltac uniformize_term exp lvar :=
let trm := interp_A lvar exp in
let trm2 :=constr:(interp_AF_to_F lvar (uniformize_areas trm)) in
(replace exp with trm2;[idtac|rewrite uniformize_areas_correct;trivial]).
(* This is a metaification to collect the list of all points *)
Inductive formula : Type :=
| f_imp : formula -> formula -> formula (* binary constructor *)
| f_const : Prop -> formula (* contructor for constants *).
Inductive formula2 : Type :=
| f_imp2 : formula2 -> formula2 -> formula2 (* binary constructor *)
| f_neq : AF -> AF -> formula2
| f_eq : AF -> AF -> formula2.
Fixpoint uniformize_areas_formula2 (e:formula2) {struct e} : formula2 :=
match e with
| f_imp2 e1 e2 =>
let s1 := (uniformize_areas_formula2 e1) in
let s2 := (uniformize_areas_formula2 e2) in
f_imp2 s1 s2
| f_neq e1 e2 =>
let s1 := (uniformize_areas e1) in
let s2 := (uniformize_areas e2) in
f_neq s1 s2
| f_eq e1 e2 =>
let s1 := (uniformize_areas e1) in
let s2 := (uniformize_areas e2) in
f_eq s1 s2
end.
Fixpoint interp_formula2_to_prop (lvar:list (prodT AVars nat)) (e:formula2) {struct e} : Prop :=
match e with
| f_imp2 e1 e2 =>
let s1 := interp_formula2_to_prop lvar e1 in
let s2 := interp_formula2_to_prop lvar e2 in
s1 -> s2
| f_neq e1 e2 =>
let s1 := interp_AF_to_F lvar e1 in
let s2 := interp_AF_to_F lvar e2 in
s1 <> s2
| f_eq e1 e2 =>
let s1 := interp_AF_to_F lvar e1 in
let s2 := interp_AF_to_F lvar e2 in
s1 = s2
end.

(* Specifications: *)
Lemma uniformize_areas_formula2_correct_gen :
forall (e:formula2) (lvar:list (prodT AVars nat)),
interp_formula2_to_prop lvar (uniformize_areas_formula2 e) <->
interp_formula2_to_prop lvar e.
Lemma uniformize_areas_formula2_correct :
forall (e:formula2) (lvar:list (prodT AVars nat)),
interp_formula2_to_prop lvar (uniformize_areas_formula2 e) ->
interp_formula2_to_prop lvar e.