let restrict x s =
  try
    let (y, prf) = apply s x in              (* [prf |- x = y]. *)
      Trace.msg "v" "Restrict" x Term.pp;
      let  (y, _) = find s y in              (* now get canonical [y]. *)
      let find' =
        let newfind = Map.remove x s.find in (* remove [x |-> y]. *)
          try
            let invx = inv s x in            (* for all [z |-> x], set [z |-> y]. *)
              Set.fold
                (fun z -> Map.add z (y, None))
                invx
                newfind
          with
              Not_found -> newfind
      in
      let inv' =
        let newinv = Map.remove x s.inv in  
                (** remove the inverse of x. *)

          try 
            let invy = inv s y in           (* remove [x] from the inverse of [y]. *)
            let invy' = Set.remove x invy in
              if Set.is_empty invy' then 
                Map.remove y newinv
              else 
                Map.add y invy' newinv
          with
              Not_found -> newinv
      in
        {find = find'; inv = inv'; removable = Set.remove x s.removable}
  with
      Not_found -> s