Широко известнасхема цикла «линейный поиск», которая имеет следующий вид:
## Код:
```
Взять_первую_ситуацию;
WHILE ~ситуации_закончились & ~искомое_найдено DO Взять_следующую_ситуацию END;
IF ~ситуации_закончились THEN (* Искомое найдено *) END
```

При работе над проектом Oberon Vision (аналог Turbo Vision — библиотеки для создания псевдографического интерфейса пользователя) оказалось, что элементы меню, окна и прочее удобно организовывать в двунаправленные кольца (то есть двунаправленные списки, в которых первый и последний элементы также взаимно связаны).
## Код:
```
TYPE Control* = POINTER TO ControlDesc;
  ControlDesc* = RECORD
    parent*: Control; (* Указатель на непосредственный родительский элемент *)
    children*: Control; (* Указатель на первый дочерний элемент *)
    prev*, next*: Control; (* Указатели на братские элементы для организации двунаправленного кольца *)
    caption*: ARRAY 256 OF CHAR
  END;
```

Одна из подзадач заключается в нахождении среди братских элементов (sibling elements), включая и сам элемент, элемента с определённым свойством. Например, необходимо найти элемент меню, у которого внутри строкового поля caption была бы определённая буква, перед которой стоит символ "&" (элемент "Save &As..." должен отреагировать на букву "A"). Это нужно для того, чтобы при нажатии на ту или иную клавишу, срабатывал соответствующий элемент меню.

У меня получился такой код:
## Код:
```
PROCEDURE MenuKeyDown*(c: Control; key: G.Key);
VAR p: Control; (* Поиск осуществляется среди братских элементов 'c', включая его самого. *)
  br: Control; (* Элемент-барьер *)
  found: BOOLEAN;
BEGIN
  ...
  p := c.prev;
  br := p;
  REPEAT
    p := p.next;
    found := MenuHotkey(p(Menu), CHR(key.sym))
  UNTIL found OR (p = br);
  IF found THEN
    p.do.click(p)
  END;
  ...
END MenuKeyDown;
```

Как видите, данный код не соответствует вышеупомянутой схеме линейного поиска. Как решить данную задачу более правильно?