Ltac simplif_term exp :=
  let lvar := build_numbered_var_list exp in 
  let trm := interp_A lvar exp in 
  let trm2 :=constr:(interp_AF_to_F lvar (simplif trm)) in 
 (replace exp with trm2 in *;[simpl|rewrite simplif_correct;trivial]).Ltac Rbasic_simpl := match goal with 
_:_ |- ?X1 = ?X2 => simplif_term X1;simplif_term X2;unfold interp_AP_to_Point;simpl
end.Fixpoint natle (n m:nat) {struct m} : bool :=
  match n, m with
  | O, O => true
  | O, Datatypes.S n' => true
  | Datatypes.S n', Datatypes.S m' => natle n' m'
  | _, _ => false
  end.Fixpoint uniformize_areas (e:AF) {struct e} : AF :=
match e with 
  | AFplus e1 e2 => 
    let s1 := (uniformize_areas e1) in 
    let s2 := (uniformize_areas e2) in 
    AFplus s1 s2
  | AFmult e1 e2 =>
    let s1 := (uniformize_areas e1) in 
    let s2 := (uniformize_areas e2) in 
    AFmult s1 s2
  | AFopp e1 =>
    let s1 := (uniformize_areas e1) in 
    AFopp s1
  | AFinv e1 =>
    let s1 := (uniformize_areas e1) in 
    AFinv s1
  | AS e1 e2 e3 => if (natle e1 e2) then 
                                 (if (natle e2 e3) then (AS e1 e2 e3) else 
                                            (if (natle e1 e3)  then  (AFopp (AS e1 e3 e2)) else (AS e3 e1 e2))) 
                               else (if (natle e2 e3) then 
						(if (natle e1 e3) then (AFopp (AS e2 e1 e3)) else (AS e2 e3 e1)) 
					else (AFopp (AS e3 e2 e1))) 
  | AD e1 e2 => if (natle e1 e2) then (AD e1 e2) else  (AFopp (AD e2 e1))
  | _ => e
end.

Lemma uniformize_areas_correct : forall (e:AF) (lvar:list (prodT AVars nat)), interp_AF_to_F lvar (uniformize_areas e) = interp_AF_to_F lvar e.