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) )