let backtrack (candidates: candidates) : unit =
  (* remove closing lookahead candidate. *)
  begin
    match candidates.cd_preselected with
      | None -> ()
      | Some (candidate, _, _) ->
         if Context_unifier.is_raw_context_unifier_invalid candidate.ca_raw_context_unifier then
           candidates.cd_preselected <- None
         else
          failwith "Selection_assert.backrack: preselected"
  end;

  (* the lookahead within the bound is exhaustively processed before the next split or close,
     so it can just be dropped. *)

  candidates.cd_lookahead <- Selection_lookahead.create Const.max_assert_lookahead;
  (* the lookahead without the bound may still be useful. *)
  Selection_lookahead.backtrack candidates.cd_lookahead_exceeding;

  (* remove the easy to remove retracted valid candidates,
     remove the others later on when they are retracted from the queue. *)

  retract_valid_min candidates;
  retract_valid_max candidates;

  backtrack_forgotten candidates;
  backtrack_exceeding candidates;

  (* remove unprocessed candidates *)
  clear_unprocessed candidates