let rec purify (s : t_subst) : term -> (term * t_subst) = function
  | Atm(_) 
  | Var(_) as e -> (e,s)
  | Uplet(l)        -> ( match norm_Uplet purify s l with
                        | ([t],ss) -> (t, ss)
                        | (ll, ss) -> (Uplet ll,ss)        )
  | Xor(l)        -> ( match norm_Xor purify s l with
                        | ([], ss) -> (Atm 0, ss)
                        | ([t],ss) -> (t, ss)
                        | (ll, ss) -> (Xor ll, ss)        )
  | Exp(t,l)    -> norm_Exp purify s t l
  | PCrypt(m,k) -> 
      let (mm,s1) = new_var_if_not_std (purify s m)
      in let (kk,s2) = new_var_if_not_std (purify s1 k)
      in (PCrypt(mm,kk), s2)
  | SCrypt(m,k) -> 
      let (mm,s1) = new_var_if_not_std (purify s m)
      in let (kk,s2) = new_var_if_not_std (purify s1 k)
      in (SCrypt(mm,kk), s2)
  | PInv(t)        -> 
      ( match purify s t with
          | (Var n as t, ss) -> 
              (match valeur n ss with
                 | PInv(t)  -> (t, ss)
                 | Atm(0)
                 | Xor(_)   -> (PInv t, ss) 
                 | t        -> (PInv t, ss) )
          | (Atm(0) as t, ss)
          | (Xor(_) as t, ss) -> 
              let (nv,ns) = add_newvalue ss t
              in (PInv nv, ns)
          | (PInv t, ss)               -> (t, ss)
          | (t, ss)                       -> (PInv t, ss)        )