Fixpoint simplif (e:AF) {struct e} : AF :=
  match e with 
   | AFplus e1 e2 => 
   let s1 := (simplif e1) in 
   let s2 := (simplif e2) in 
   match s1 with 
     AF0 => s2
     |_ => match s2 with 
        AF0 => s1
        |_ =>  AFplus s1 s2
        end
     end
   | AFmult e1 e2 =>
    let s1 := (simplif e1) in 
    let s2 := (simplif e2) in 
    match s1 with 
      AF0 => AF0
      |AF1 => s2
      |_ => match s2 with 
        AF0 => AF0
        |AF1 => s1
        |_ =>  AFmult s1 s2
        end
    end
  | AFopp e =>    
    let s := (simplif e) in 
    match s with 
       AF0 => AF0
       | AFopp e1 => e1
       | _ => AFopp s
    end
  | AS e1 e2 e3 => if (nateq e1 e2) then AF0 else
  (if (nateq e1 e3) then AF0 else (if (nateq e2 e3) then AF0 else e))
  | AD e1 e2 => if (nateq e1 e2) then AF0 else e
  | _ => e
end.

(* Specifications: *)
Lemma simplif_correct : forall (e:AF) (lvar:list (prodT AVars nat)), interp_AF_to_F lvar (simplif e) = interp_AF_to_F lvar e.