"Усы, лапы и хвост" - вот и все автоматы, т.е. "if"-ы, "case"-ы, "switch"-и. Эта та же Р-схема или Дракон-диаграмма, но в табличной форме.

Вся таблица делится на три вертикальных части:

* слева - аргументы функции;
* далее тело ф-ции;
* последний столбец - результат ф-ции;

Аргументы и результат могут отсутствовать. В секции входных аргументов каждый столбец отражает всю информацию об одном аргументе. Вверху, как заголовок -- дуга, где предикат сопоставляется с определением аргумента, и может быть связанное действие:
Вложение:
arg_header.PNG [ 2.11 КБ | Просмотров: 18402 ]

что может означать:
## Код:
```
procedure set_damage(var attacks: List[Attacks]; const surprise: Bool; const defense: Int);
begin
...
end
```

Ниже в столбце могут быть (необязательно) указаны все возможные значения аргумента. В этом случае далее в теле функции все действия будут указаны именно в контексте этого значения:
Вложение:
arg_val.PNG [ 3.08 КБ | Просмотров: 18402 ]

В секции для тела функции каждый столбец выражает только одно действие. Формируется конвейер операций из столбцов, слева направо. В заголовке столбца -- дуга, где предикат отражает смысл действия, к примеру, задаёт имя переменной. Ниже в ячейках могут быть указаны действия (под дугами), предикаты (над дугами). Предикат отражает результат того, что указано выше в ячейках - или действия, или заголовка столбца. И предикат, и действие сопоставляются всегда с тем, что указано выше и слева в таблице:
Вложение:
pred_act.PNG [ 7.62 КБ | Просмотров: 18402 ]

Здесь выражено, что переменная "attack" может иметь два значения: "Magic" и "Melee", затем переменная "power" в соответствие с этими значениями может принимать два варианта значения: "5" и "4". Таким образом, столбец всегда отражает только одно действие, но вариантов может быть много. И если глянуть влево рисунка, то обращаем внимание, что вся эта пляска из-за того, что первый аргумент ф-ции "attacks" является не пустым списком. Всё это в результате может быть транслировано так:
## Код:
```
procedure set_damage(var attacks: List[Attacks]; const surprise: Bool; const defense: Int);
begin
    if attacks.NotEmpty then
    begin
        attack := attacks.GetHeader();
        atks := attacks.GetTail();

        if attack = Magic then
            power := 5
        else
        if attacks = Melee then
            power := 4;
        ...
    end;
    ...
end
```

И если посмотреть исходный сборник примеров вокруг ф-ции "damage", то там "power" есть не переменная, а вызов функции. И в таблице таким образом показано тело этой функции, как два варианта её реализации. И тамошняя схемтаблица есть сводная, одновременно отражающая два варианта реализации ф-ции "damage".

Дуга действия может быть продлена до конца таблицы - до результата ф-ции. В то же время, чтобы не лепить длинных палок, например, для аргумента ф-ции м.б. указана дуга, что означает продвижение ещё до конвейера, т.е. немедленный выход из функции (при этом в таблице в соответствующей строке нет никаких действий):
Вложение:
arg_exit.PNG [ 9.62 КБ | Просмотров: 18402 ]

Транслируем:
## Код:
```
procedure set_damage(var attacks: List[Attacks]; const surprise: Bool; const defense: Int);
begin
    if attacks.NotEmpty then
    begin
        attack := attacks.GetHeader();
        atks := attacks.GetTail();
        ...
    end
    else exit;
end
```

Действия могут быть связанными, выражая функциональные отношения:
Вложение:
act_link.PNG [ 11.23 КБ | Просмотров: 18402 ]

Здесь "effectiveness" вычисляется как умножение "power" на значение из предыдущего шага, которое, в свою очередь, зависит от аргумента ф-ции "surprise":
## Код:
```
procedure set_damage(var attacks: List[Attacks]; const surprise: Bool; const defense: Int);
begin
    if attacks.NotEmpty then
    begin
        attack := attacks.GetHeader();
        atks := attacks.GetTail();

        if attack = Magic then
            power := 5
        else
        if attacks = Melee then
            power := 4;
        
        if surprise then
            tmp := 3
        else
            tmp := 2;

        effectiveness := power * tmp;

        ...
    end
    else exit;
end
```

Причём действие для "effectiveness" указано во второй строке таблицы, как действие под дугой заголовка столбца. В этом случае нет потребности сопоставлять с чем либо слева, т.е. вся вторая строка в таблице -- для безусловных действий.

И действия, и предикаты могут иметь несколько вариантов. Правила обработки предикатов такие же, как и в Р-схемах - сверху вниз, т.е. так выражается последовательность для "if"-ов. Действия могут сопоставляться только с предикатами слева (в заголовке ничего нет), могут формировать цепочки операций. Масштаб рассмотрения действий и связей -- произвольный:
Вложение:
act_var.PNG [ 11.36 КБ | Просмотров: 18402 ]

Циклы выражаются через спецдугу. Если дуга никак не подписана -- переход на начало ф-ции. Рекомендуется по возможности быть функционально однородным, и циклы формировать через рекурсивные вызовы (к тому же, меньше вопросов как организовывать "while"-ы с "repeat"-ами). В исходном примере рядом с таблицей был текстовый код, который, фактически, есть набор функций, где имеется и рекурсия. Точно также можно отобразить одновременно весь набор таблиц-функций и исследовать процесс (алгоритм).
Для наглядности можно нужный столбец, как в теле ф-ции, так и в аргументах (или даже все столбцы-аргументы), "накрыть" спец-дугой:
Вложение:
recurs.PNG [ 9.24 КБ | Просмотров: 18402 ]

Обратная дуга -- против конвейера, отражает вылеты из функции. Семантика м.б. разная. Например, для аргументов ф-ции:
## Код:
```
arg1: int | arg2     !! var1
    <-----------|--------->!!--------->   ...
      < 0       | string   !!
                |          !!
    ...
```

Транслируем:
## Код:
```
function some_func(arg1: int; arg2: string): any_type;
begin
    if arg1 < 0 then
        raise Exception ("arg1 < 0");
    ...
end;
```

Или "assert" для конкретного значения аргумента:
## Код:
```
arg1      | arg2     !! var1
    ----------->|--------->!!--------->   ...
      int       | string   !!
                |          !!
    ...
      1         |          !!  ... 
    ...         |          !!

      -1        |          !!  ... 
    <-----------|          !!
                |          !!
    ...
```

Эквивалентно:
## Код:
```
function some_func(arg1: int; arg2: string): any_type;
begin
    case arg1 of
        1 :   ...;

        ...

        -1 : raise Exception ("arg1 = -1");
    ...
    end;

    ...
end;
```

Точно также могут быть заданы условия для любого столбца (в заголовке) -- и для действий, и для результата ф-ции. Внутри столбца-операции проверочные условия могут быть заданы как предикаты без связанных действий:
## Код:
```
| var1    |
    |-------->|
    |   ....  |
    |         |
    |   < 0   |
    |<--------|
    |         |
    |   ...   |
```

## Код:
```
function some_func(arg1: int; arg2: string): any_type;
begin
    ...
    if var1 < 0 then
        raise Exception ("var1 < 0");    
    ...
end;
```

Если указать действие прямо под предикатом:
## Код:
```
| var1    |
    |-------->|
    |   ....  |
    |         |
    |   < 0   |
    |<--------|
    |  Беда!  |
    |         |
    |   ...   |
```

## Код:
```
function some_func(arg1: int; arg2: string): any_type;
begin
    ...
    if var1 < 0 then
        raise Exception ("Беда!");    
    ...
end;
```

В таблице могут быть столбцы вида "try - except/finally" с соответствующей обработкой.

В исходном примере применялась семантика "сигналы и продолжение" (рядом был поясняющий код):
Вложение:
signal.PNG [ 9.16 КБ | Просмотров: 18402 ]

Если не сработают "if"-ы: "_ <= 0" и "_ >= 1", то будет "отправлен" сигнал "InvalidVal(_)" (вместе со значением вычислений). Если где-то сверху в стеке вызовов ф-ций нет обработчика сигнала или сигнал не обработан -- вылет, иначе -- предикаты ниже и последующие действия отражают анализ полученных указаний и их применение.