Алгоритмика плетения резинок. Глава 5

Мир Когнито
начало http://www.proza.ru/2015/07/31/1688
назад http://www.proza.ru/2015/08/03/20

Применив метод изображения резинок упрощенно, в виде (прямоугольной) скобки, концами вниз (А, если она за данной резинкой, то изображать её прерывисто (причём с обеих сторон), в отношении текущей резинки.) я, кажется, начинаю двигаться к решению задачи формальной записи структур из резинок.
А, если к этому добавить еще и нумерацию (а, точнее, индексацию. Т.к. 2 измерения имеют место.) резинок как по строкам (сверху вниз), так и по столбцам (слева направо)) А также идею отображения отношения (между резинками) «над» (или под), то решение вырисовывается до конца. Например, для структуры на рис.7 мы получаем такое тело цикла (отображения структуры):
1.р(1,1) над р(1,3)
2.р(1,1) над р(1,2)
В сумме 1-2 так: р(1,1) над р(1,[3,2])
3.р(2,1) над р(1,2)
4.р(2,1) над р(2,2)
В сумме 3-4 так: р(2,1) над р([1,2],2)
В сумме 1-4 так:  [р(1,1) над р(1,[3,2]), р(2,1) над р([1,2],2)]
А еще более кратко так:
[р(1, [2,1]) над р(1,[3,2]), р(2,1) над р([1,2],2)]
(то есть цикл в цикле. И 1-ыйцикл – перед перечислением операций (в которых – дано перечисление параметров в 1-ом цикле))
(Здесь 1-ый индекс резиники – это номер её позиции в слое, а 2-ой индекс – номер слоя резинки)
Как же оно будет выглядеть в общем? Чтобы вставить его в цикл.
Чтобы понять это, рассмотрим продолжение:
5.р(1,3) над р(1,5)
6.р(1,3) над р(1,4)
Шаги 5-6 кратко так: р(1,3) над р(1, [5,4])
7.р(2,3) над р(1,4)
8.р(2,3) над р(2,4)
Шаги 7-8 кратко так: р(2,3) над р([1,2],4)
Шаги 5-8 кратко так: 
[р( [1,2],3) над р(1,[5,4]), р(2,3) над р([1,2],4)]
В результате проект обобщения тел цикла таков:
[р( [1,2],3) над р({1},[5,4]), р(2,3) над р([1,2],{4})]
(где конструкция {1} или {4} означает выделение диапозона вариций другого параметра при заданном значении этого параметра (соответственно номера строки или столбца))

Какова же формальная запись структуры на рис.6? Вот она:
1.р(1,1) над {р(1,2),р(1,3)}
(в этой записи уже свернуто две записи:
р(1,1) над р(1,2)
р(1,1) над р(1,3)
)
2.р(2,1) над {р(1,2),р(2,3)}
3.р(1,2) над {р(1,3),р(2,3)}
4.р(1,3) над {р(1,4),р(1,5)}
5.р(2,3) над {р(1,4),р(2,5)}
6.р(1,4) над {р(1,5),р(2,5)}
Учитывая сходство шагов 1 и 2, запишем их вместе так:
1.р([1,2],1) над {р(1,2),р([1,2],3)}
Тогда шаги 1-3 вместе запишутся так:
1.р([[1,2],1],[1,2]) над {р(1,[[2*2],3]),р([[1,2],2],3)}
(здесь конструкция [[1,2],1],[1,2] означает, что при значении 1 индекса уровня резинки (2-ой индекс) задействуется последовательность [1,2] вариации значений позиции резинке на уровне (1-ый индекс), а при значении 2 индекса уровня резинки задействуется значение 1 позиции резинке на уровне.)
Тогда по аналогии шаги 4-6 запишутся вместе так:
2.р([[1,2],1],[3,4]) над {р(1,[[2*4],5]),р([[1,2],2],3)}

В итоге получаем следующую запись:
1.р([[1,2],1],[1,2]) над {р(1,[[2*2],3]),р([[1,2],2],3)}
2.р([[1,2],1],[3,4]) над {р(1,[[2*4],5]),р([[1,2],2],3)}
Чтобы записать цикл любой длины, нужно в записях 1 и 2 выделить элемент, который будет счётчиком цикла. Понятно, что это номер уровня резинки. Обозначим его «и». После чего становится ясно, как выглядит левая часть записи тела цикла:
р([[1,2],1],и)
(что означает, что при пробегании «и» ряда значений 1..дл (где дл –длина изделия) значение 1-ого индекса периодически пробегает  ряд вариации [1,2])
Но как выглядит правая часть записи тела цикла? Ведь здесь тоже надо выделить элементы, связаные с «и». Каковы же они? Внимательная проработка самой первой, 6-шаговой, записи алгоритма даёт ответ на этот вопрос. А именно, это опять-таки 2-ые индексы резинок.(в которых и указаны (на самом деле) выражения от и) Отсюда ясно, что правая часть записи тела цикла выглядит так:
{р(1,[[2*(и+1)],и+2]),р([[1,2],2],[[2*(и+2)],и+1])}
(в данной записи и+1 означает, что резинка цепляется за следующий слой, а и+2 – за послеследующий. Интерпретация конструкций вида [[1,2],1],[1,2] разъяснена выше)
Следовательно, тело цикла в целом запишется так:
р([[1,2],1],и) над {р(1,[[2*(и+1)],и+2]),р([[1,2],2],[[2*(и+2)],и+1])}
(отсюда, в частности, следует, что приведённую выше запись цикла для структуры на рис.7 необходимо скорректировать. Но этим займёмся попозже. Чтобы у заинтересванного читателя была возможность сделать это самостоятельно.)
А сам цикл, стало быть, так:
Повт(р([[1,2],1],и) над
Но как же из формальной записи структуры получить формальную запись алгоритма? Попытаемся ответить на этот вопрос для структуры 6, тем более, что алгоритм для её создания приведен в главе 4. Повторим для наглядности его здесь:

1.повт([повт(н(ст(и),в([по,пр],),ст(и+1)),и=1+2..3),
(конструкция в([по,пр],)  означает, что при к=1 надевание резинки на следующий столбик происходит сначала с предварительным поворотом по часовой стрелке на 180 град (при и=1), а потом – против часовой стрелки на тот же угол (при и=3), при дальнейших значениях к поворот не делается)
н(ст2,ст3),
повт(м(п(п),ст(и),л,ст(и)),и=2..3),
повт(н(ст(и),ст(и+1)),и=1+2..3),
повт(м(п(п),ст(и),л,ст(и)),и=1..4)],
к=1..дл)
2.м(п(),ст1,ст2)
3.м(п(),ст4,ст3)
4.ц(з(1),п(),ст2)
5.ц(з(2),п(),ст3)
6.ц(з(1),у1)
7.ц(з(2),у2)
8.повт(с(п(),ст(и)),и=2..3)
9.конец
Сравнение этих 2-х описаний приводит к мысли, что, возможно, трудность перевода описания структуры в описание алгоритма её создания (А1-) коренится в том, что в описании структуры и – это номер уровня резинки, а в описании алгоритма и – это номер позиции столбика в ряду столбиков. Как же разрешить эту коллизию смыслов? Но, тем не менее, найти связующее звено между этими 2-мя описаниями.
А вот оно, связующее звено: номер позиции столбика в ряду (в описании алгоритма (А2-)) соответствует номеру позиции резинки на уровне (в описании структуры). А вот номер уровня (в описании структуры)  - соответствует (как правило) значению счётчика цикла на данном его проходе (в описании алгоритма) Значит, эти величины в обоих описаниях должны обозначаться одинаково.

Отсюда принимаем решения:
к – это номер прохода цикла (соответственно номер образуемого уровня)
и – это номер резинки на уровне. (а значит, и номер столбика в ряду на станке)
Но в том-то всё и дело, что резинка на уровне (изделия) получается из 2-х столбиков на станке (и то после того, как её снимут с обоих столбиков)
Как же разрешить эту коллизию?
Пока не знаю.
Ну, разве что обратив внимание на связи резинки с другими резинками. Ибо, если в основе структуры лежит базовый элемент 2 за 1, то этих связей всегда 2 (а не одна, как при базовом элементе 1 за 1)
Да, точно: резинка (исходная) превращается в резинку-элемент структуры, только если оба её конца – связали (-сцепили) с другими резинками.(или с застёжками – это тоже важный элемент структуры)) После чего её можно снимать с приспособления – не развяжется. Но что отсюда следует?
Что после этого – пропадает связь исходных позиций резинки с позицией её в структуре.

А что если исследовать соответствие описаний структуры и алгоритма сборки простейшей цепочки? Да, это хорошая идея.
Итак, описание структуры:
1.р1 над р2
2.р2 над р3
3.р3 над р4
И т.д.
А коротко так:
Повт(р(и) над р(и+1),и=1..дл-1)

Описание алгоритма сборки (на станке):
1.повт(н(р1,ст(и,1),ст(и+1,1)),и=1..дл-1)
2.н(р1,ст(дл,1),в(пр),ст(дл,1))
3.повт(м(п(п),ст(и,1),под(),ст(и-1,1)),и=дл..2)
4.ц(з,п(1-2),ст(дл,1))
5.повт(с(п(),ст(и,1)),и=дл-1..2)
6.ц(з,п(),ст(1,1))
7.с(п(),ст(1,1))
8.конец
Нас интересует здесь сборочная часть:
1.повт(н(р1,ст(и,1),ст(и+1,1)),и=1..дл-1)
2.н(р1,ст(дл,1),в(пр),ст(дл,1))
3.повт(м(п(п),ст(и,1),под(),ст(и-1,1)),и=дл..2)
Однако и её только сопоставить с описанием структуры кажется проблематичным, и в 1-ую очередь потому что, надевание резинок идёт в одно направлении, а провязывание (соединение) в другом. Из-за этого алгоритм усложняется. Нет ли (для этого же изделия) алгоритма попроще?

Возьмём описание алгоритма сборки (на рогатке):
1.н(р1,ст1,в(пр),ст2)
2.повт([н(р1,ст1,ст2), м(п(п),ст[1,2],между(1,2))],и=1..дл)
3.повт([ц(з,п(),ст(и),с(п(),ст(и))],и=1,2)
4.ц(з,у0)
5.конец

2-ое описание явно проще, поэтому возьмём его для начала. Вот его сборочная часть:
1.н(р1,ст1,в(пр),ст2)
2.повт([н(р1,ст1,ст2), м(п(п),ст[1,2],между(1,2))],и=1..дл)
(причём н(р1,ст1,в(пр),ст2) – это подготовительный шаг (создание узла0), так что собственно сборка – это
повт([н(р1,ст1,ст2), м(п(п),ст[1,2],между(1,2))],и=1..дл))
Сопоставим это с описанием структуры:
Повт(р(и) над р(и+1),и=1..дл-1)

Интересно, что такое (компактное) описание отвлекает нас от главного: что изделие состоит из конечного количества резинок.(и собирается слой за слоем) А в пределе оно состоит из одной резинки:
1.р1,
Вот и всё описание структуры. Ан нет, не всё! Ибо, чтобы изделие было законченным, с обоих сторон сложенной вдвое резинки должны быть установлены кольца-застежки (зн и зк).(Хотя (реальные) застежки, конечно, делаются так, что объединяют в себе 2 кольца-замыкателя. Но такие застёжки сделаны так потому, что предназначены для создания цилиндрической формы изделия. А если нам этого не нужно?)
Поэтому описание структуры (простейшего изделия) всё-таки таково:
1.зн над р1
2.р1 над зк
Если же изделие состоит из 2-х резинок, то описание его структуры таково:
1.зн над р1
2.р1 над р2
3.р2 над зк
Есть и ещё одна деталь, связанная с описанием структуры, которая до сих пор от нас ускользала. Но, если структуру изобразить графически, то эта деталь немедленно выходит из тени: у всякой резинки есть 2 конца, которыми она находится над другой резинкой или кольцом-застёжкой.(и каждое это над (для каждого конца резинки) – соответствует одному шагу провязывания) Поэтому предыдущие 2 описания правильно запишутся так:
1.зн над р1
2.р1 над 2*зк
Для цепочки из 2-х резинок:
1.зн над р1
2.р1 над 2*р2
3.р2 над 2*зк

Когда мы описываем структуру, на каждом слое которой находятся хотя бы 2 резинки, то мы не можем игнорировать, конечно, эту (вышеупомянутую) деталь (за исключением последнего утверждения):
0.зн над р1
1.р1 над {р2,р3}
2.р2 над {р3,р4}
3.р3 над {р4,зк}
4.р4 над 2*зк
Но зато мы игнорируем здесь еще одну деталь. А именно то, что 2 конца резинки – это, вообще-то, разные концы: один левый, другой правый. И какой из них находится над чем-то – весьма важная с точки зрения описания алгоритма деталь.
Поэтому более корректное описание последней структуры  (слева направо для каждой резинки) таково:
0.зн над р1
1.р1 над {р3,р2}
2.р2 над {р3,р4}
3.р3 над {зк,р4 }
4.р4 над 2*зк

А, с точки зрения замечания о том, что единицей описания структуры является одно утверждение над, это описание более корректно отобразить так:
0.зн над р1
1.р1 над р3
2.р1 над р2
3.р2 над р3
4.р2 над р4
5.р3 над зк
6.р3 над р4
7.р4 над зк
8.р4 над зк
То же самое, впрочем, относится и к шагу 0, т.к. и на нём зн зацепляется за 2 (нити) резинки (так как каждая резинка (в структуре) сложена вдвое)  Единственное отличие, конечно, этой ситуации от всех остальных ситуаций зацепления – что здесь зацепление происходит за середину (которых у сложенной вдвое резинки одна, в отличие от концов), а не за конец резинки.

Всё это здорово, но алгоритм проще восстановить по самой простой структуре, а именно по такой:
1.зн над р1
2.р1 над зк
3.р1 над зк
Соответствующий ей алгоритм таков:
1.н(р,ст1,в(по),ст2) (готовится реализация утверждения 1.зн над р1 описания структуры)
2.ц(зн,у0) (узел0 – это перекрестие 2 нитей резинки1, образовавшееся между столбиками) (реализуется утверждение 1.зн над р1 описания структуры)
3.м(п(),ст1,ст2) (готовится реализация утверждений 2.р1 над зк, 3.р1 над зк описания структуры)
4.ц(зк,п(),ст2) (реализуются утверждения 2.р1 над зк, 3.р1 над зк описания структуры.
Как выяснется здесь, и в описании алгоритма мы записываем реализацию этих утверждений описания структуры. Хотя реально выполняется 2 шага:
4.ц(зк,п(2),ст2)
4а.ц(зк,п(1),ст2))
5.с(п(),ст2) (изделие отделяется от приспособления)
6.конец

Итак, предварительный вывод: описание алгоритма состоит из шагов, реализующих конкретное утверждение , а также предваряющих их шагов, подготовливающих выполнение основного шага. Последний шаг (или последовательность шагов) – это отделение изделия от приспособления.

Напишем теперь алгоритм сборки для чуть более сложной структуры:
1.зн над р1
2.р1 над р2
3.р1 над р2
4.р2 над зк
5.р2 над зк
Соответствующий ей алгоритм таков:
1.н(р1,ст1,в(по),ст2) (готовится реализация утверждения 1.зн над р1 описания структуры.
Кстати, здесь применил новинку в описании алгоритма: при обзначении резинки указал не цвет её, а уникальный идентификатор. Понятно, что так легче приводить в соответствие описанию структуры описание алгоритма)
2.ц(зн,у0(р1)) (узел0 – это перекрестие 2 нитей резинки1, образовавшееся между столбиками) (реализуется утверждение 1.зн над р1 описания структуры. Отсюда, кстати, вывод: зн не просто можно, а нужно (т.к. удобнее и точнее) зацеплять за узел0 (представляющий из себя также перекрестие 2-х нитей резинок) сразу, как он был создан)
3.н(р2,ст1,ст2) (готовится реализация утверждений 2.р1 над р2, 3.р2 над р2 описания структуры)
4.м(п(2),ст1,между(ст1,ст2)) (реализуется утверждение 2.р1 над р2)
5.м(п(2),ст2,между(ст1,ст2)) (реализуется утверждение 3.р2 над р2)
6.м(п(1),ст1,ст2) (готовится реализация утверждений 4.р2 над зк, 5.р2 над зк)
7.ц(зк,п(2),ст2) (реализуется утверждение 4.р2 над зк)
8.ц(зк,п(1),ст2) (реализуется утверждение 5.р2 над зк)
9.с(п(),ст2) (изделие отделяется от приспособления)
10.конец

Таким образом, вышеприведённый предварительный вывод подтверждён, а поэтому найден ключевой момент к построению описания алгоритма по описанию структуры изделия. (А1-) К этому добавлю еще то, что подготовка к реализации утверждения о структуре заключается в установке на приспособление элементов изделия (как правило, участвующих в готовящемся к реализации утверждении о структуре. Как минимум, установка таких элементов на приспособления должна произойти раньше реализации данного утверждения о структуре.)