Материал отражает концепции и идеи, что бы хотелось видеть в современной среде разработки, как автоматизировать и ускорить получение результата, и что можно предложить для существенного улучшения диалога с ЭВМ. Иллюстрируются подходы, включая большие языковые модели. Методы программирования, выраженные в языках и структурирования проектов неизменны практически вот уже на протяжении более полувека без существенных изменений, поэтому, по мере работы с ИИ, в буквальном смысле на рубеже 25 и 26 годов возникла необходимость переосмысления предыдущего опыта и адаптация возможного решения для нового инструмента, ставшим неотъемлемой новой базой для разработки программ автоматизации и обработки данных. Быть может, читателем столь длинного промпт-рассказа станет квадриллионная модель, которая порадует меня такой системой.

"Слоган"

Время хороших, очень хороших и выдающихся языков программирования прошло. Настало время плохих сред проектирования.

Основные ограничения

Для взаимодействия с человеком (включая диалог машина-машина) должны быть сформированы удобные инструменты, однако, они попадают под следующие физические ограничения.

  • Частота «атомарного» вычислителя на основе КМОП в современных процессорах порядка 3-5 ГГц (начиная с ~2002-4гг - насыщение), f_T=g/(2πC) (ёмкость транзистора), f_T \sim 1/L_g^2 (ширина затвора), r \propto  1/(V-V_{th})^2 (сопротивление канала, Random Dopant Fluctuation, когда под затвором всего несколько атомов примесей), включая аналогичные ограничения для ЭСЛ (эмиттерно-связанная логика, токовое переключение, сотни МГц уже в 80-е годы), GaAs, КНИ и др. Иными словами, алгоритмы вида y_0=a \cdot y_{-1}+b\cdot y_{-2}+c\cdot y_{-3}+\ldots, соответствующие БИХ-фильтру, которые не могут быть распараллелены и зависят от результатов предыдущих вычислений, могут выполняться за такт именно с этой предельной скоростью. Решение: пока не ясно, нанопроводники GAAFET, SiGe, Hi-k, гетеропереходы, AIII-BV, SQUID и прочие сверхпроводниковые-криогенные (классическая, не кубитная логика) методы.

  • Скорость обмена данными между ядрами, процессорами, ОЗУ/GPU, определяемая эффективной скоростью сигналаv с учётом диэлектрической проницаемости материала v=c/\sqrt{\varepsilon}, где c - скорость света в вакууме, для текстолита \varepsilon=4 скорость примерно в 2 раза ниже. Если от процессора до памяти порядка 10 см, это соответствует предельной частоте 1.5 ГГц, что ограничивает выборку данных в виде разбросанных элементов списка, в основном это текст, применение регулярных выражений. Решение: увеличение разрядности шины (1024 и более), использование HBM, кремниевых интерпозеров, располагая память как можно ближе к процессору. Аналогично пункту выше, на частотах свыше 10 ГГц длина волны менее 3 см - ограничение скорости передачи данных между ядрами процессора, цепи из сосредоточенных превращаются в распределённые. Сделать слоёный модуль в высоту - теплопроводность кремния, сгорит при плотности свыше ~50 Вт/см² (современное тепловыделение), объёмная плотность тепла будет чрезвычайно большой, подходит лишь для flash. Решение: сверхтекучий гелий, условно бесконечная теплоёмкость и теплопроводность, нулевая вязкость но гигантские потери. Чтобы отвести 3 Вт от жидкого гелия требуется свыше 1 кВт внешней мощности, чем ниже температура - тем мощнее (см. уравнение Карно).

  • Скорость обусловленная аппаратурой хранилища, например, НЖМД при перемещении от цилиндра к цилиндру порядка десятков мс, обусловленное быстродействием механизма Voice Coil, чтение фрагментированных файлов от сектора к сектору того же порядка, обусловленное скоростью вращения, аналогично для SSD при практически одновременном чтении/записи, за пределами сегментов до десятков мкс или любого другого накопителя с блочной организацией.

  • Скорость, обусловленная сетевым взаимодействием, определяющая удельную общую плотность вычислений на единицу объёма серверной, например, ПФлопс/кубометр, один из главнейших и ключевых показателей для полного цикла обучения ИИ-моделей. Ограничение - в чистом виде скорость света c: 1 метр = 300 МГц. Решение: компактизация шин, изготовление сверхшироких шин под конкретный датацентр и предельный теплоотвод (трансформаторное масло, фазовый переход).

Архитектурные ограничения и особенности:

  • Пропускная способность DRAM-памяти (включая HBM) и уровней кэша на случайном доступе порядка 10 ГБ/с: стирает разницу между RISC-CISC из-за практически одинакового контроллера памяти на ветвистых задачах if-else-call, списки указатель на указатель, регулярные выражения, т.е. не DSP, не \sum x_{n-i} - алгоритмы (КИХ-фильтр).

  • Ширина шины данных/инструкций в основном 64 бит на параллельной выборке: использование микрокода и конвейера, виток развития к VLIW как SIMD-расширения (включая DSP), предсказание переходов, спекулятивное исполнение, небольшой недостаток Meltdown/Spectre

  • Время отклика процессора на прерывания и периферии, сервисные функции, работа с памятью: использование DMA, дополнительные независимые ядра выполнения критических функций ОС, как можно более аппаратное выделение динамической памяти, устранение сегментации, сборка мусора, JIT-расширения для виртуальных машин.

  • Скорость распространения информации по переключающим и логическим цепочкам, элементам состояния: использование многоядерных вычислителей с разветвлёнными шинами, ПЛИС, комбинационная логика спецвычислений малой разрядности, оптимизация секвенциальной логики и конечных автоматов, частичная реконфигурация ПЛИС во время работы под задачу.

Исходя из вышесказанного можно сделать для пользователя простой, образный вывод. При вводе данных с клавиатуры приятно когда отклик почти мгновенный, менее 50 мс, при ведении мышью обработка летит за ней до 200 мс, при перерисовке тяжёлых графических окон со множеством объектов до 500 мс, прямой запрос к рабочей среде до 1 с, отложенный до 5 с, аналитический-обзорный, отладка, отчёты, визуализация местных данных, ответ на промпты порядка 10 с.

Тесты производительности памяти

Первый тест основан на произвольном доступе с использованием односвязного списка, "разрушающим" кэш процессора и показывает производительность, связанную с запаздыванием между модулем памяти и вычислителем. Метод основан на последовательном обходе элементов этого списка из сильно разбросанных случайным образом тысяч и миллионов указателей, шаг которых в основном превышает размер кеша процессора. В этом случае блочное считывание последовательных фрагментов практически бесполезно, так как следующий элемент может находиться уже в другом блоке.

Односвязный список без данных, состоящий из массива указателей, случайным образом расположенных и указывающих на следующий элемент внутри этого массива
Односвязный список без данных, состоящий из массива указателей, случайным образом расположенных и указывающих на следующий элемент внутри этого массива

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

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

/* Date: 2 sep 2025
 * Description: Тест памяти с неупорядоченным и упорядоченным доступом
 * Result: @i3-7020U 8G RAM Linux 6.8.0-79-generic
 * Количество элементов Num: 4M 4M 2M 2M 1M
 * Время формирования массива: 18.937546 с  14.197654 с 7.984623 с 6.656924 с 1.228238 с
 * Время путешествия по списку: 0.036960 с  0.033441  с 0.026459 с 0.017605 с 0.015280 с
 * Время путешествия по массиву: 0.017713 с 0.017406  с 0.008949 с 0.008602 с 0.004504 с
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Путешествие по массиву в 2 мегауказателей (64 бит)
#define  Num  1000000
void *ArrayUkaz[Num];
clock_t start, end;
double cpu_time_used;

void main(void) {
	srand(time(NULL));
	int rndNum = 0;
	void **pptr = ArrayUkaz, **pptr_ = ArrayUkaz; //текущий и предыдущий указатель в массиве
	void **pptrBase = pptr; //указатель на первый элемент
	start = clock();
	printf("%x \n", (unsigned int) ArrayUkaz);
	for (int i = 0; i <= (Num + 1); i++) {
		//получаем ячейку для нового
		rndNum = (rand() % Num); // число от 0 до Num-1
		int Perek = rndNum % 2; //переключатель, елсли 1 - движемся вправо, 0 - влево по массиву
		int j = rndNum;
		pptr = &ArrayUkaz[rndNum]; //текущий указатель
		int idxl = 0, idxr = Num - 1; // начальные условия для индексов
		int fll = 0, flr = 0;
		if (*pptr != NULL) { //ячейка занята
			if (Perek == 0) { //влево пока не найдём свободную ячейку или до начала
				fll = 0;
				if (--j <= idxl) {
					fll = 1; //помечаем флаг полного заполнения слева
				} else {
					for (; ArrayUkaz[j] != NULL; j--) {
						if (j <= idxl) {
							fll = 1; //помечаем флаг полного заполнения слева
							break;
						}
					}
				}
				if (fll == 0) { //свободная ячейка
					pptr = ArrayUkaz + j; //сохраняем адрес текущей ячейки
				} else {
					//движемся в другую сторону, вправо
					j = rndNum;
					for (; ArrayUkaz[j] != NULL; j++) {
						if (j >= idxr) {
							flr = 1; //помечаем флаг полного заполнения справа
							break;
						}
					}
				}
				if (fll != 0 && flr != 0) { //готово, массив заполнен
					pptr;
					break;
				}
			} else { //движемся вправо пока не найдём свобоную ячейку или до конца
				flr = 0;
				if (++j >= (idxr + 1)) {
					flr = 1; // помечаем флаг заполнения справа
				} else {
					for (; ArrayUkaz[j] != NULL; j++) {
						if (j >= idxr) {
							flr = 1; // помечаем флаг заполнения справа
							break;
						}
					}
				}
				if (flr == 0) { //свободная ячейка
					pptr = ArrayUkaz + j; //сохраняем адрес текущей ячейки
				} else {
					j = rndNum;
					//движемся в другую сторону
					for (; ArrayUkaz[j] != NULL; j--) {
						if (j <= idxl) {
							fll = 1; //помечаем флаг полного заполнения слева
							break;
						}
					}
					if (fll == 0) { //свободная ячейка
						pptr = ArrayUkaz + j; //сохраняем адрес текущей ячейки
					}

				}
				if (fll != 0 && flr != 0) { //готово, массив заполнен
					pptr;
					break;
				}
			}
		}
		//printf("%d %d %d %x %d  %x\n", rndNum, j, ((unsigned int) pptr - (unsigned int)ArrayUkaz)/8, (unsigned int) pptr,((unsigned int) pptr_ - (unsigned int)ArrayUkaz)/8, (unsigned int)pptr_);
		*pptr = pptr_; //пишем предыдущий в текущий
		pptr_ = pptr;	//предыдущий становится текущим

	}
	end = clock();
	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
	printf("Время формирования массива: %f с\n", cpu_time_used);
	//printf("\n");
	start = clock();
	void **NextPtr = NULL;
	pptr = pptr_;
	for (int i = 0; i <= Num; i++) {
		//Путешествие по односвязному списку
		NextPtr = *pptr;
		pptr = NextPtr;
		//printf("%d %x \n", ((unsigned int) NextPtr - (unsigned int)ArrayUkaz)/8 ,  (unsigned int) NextPtr);
	}

	end = clock();
	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
	printf("Время путешествия по списку: %f с\n", cpu_time_used);

	start = clock();
	for (int i = 0; i < (Num - 1); i++) {
		//Путешествие по массиву последовательных элементов
		volatile void **a = NULL;
		ArrayUkaz[i] = a;
		volatile void **b = ArrayUkaz[i];
		ArrayUkaz[i+1] = b;
	}
	end = clock();
	cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
	printf("Время путешествия по массиву: %f с\n", cpu_time_used);
}

Экскурс

Что такое язык программирования? Упрощённо - формальное описание процесса обработки данных. Причём, не обязательно для вычислительной машины, тем более, электронной. Результат работы программы можно посчитать вручную на калькуляторе, а сам код записать в виде предложения на разговорном языке или, теперь уже, промпта. Также, вычисления можно проводить с использованием, например, пневматических интеграторов. В крайнем случае программа содержит только данные, включая нулевой длины, и ничего не делает.

Автоматизация абстракции
Автоматизация абстракции

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

Первая виртуальная машина по управлению дисплеем и АЦПУ (алфавитноцифровое печатающее устройство). До сих пор LF (Line Feed, перевод строки) 0xA and CR LF (Carriage Return возврат каретки + LF) 0xD является камнем преткновения между Linux и Windows.
Первая виртуальная машина по управлению дисплеем и АЦПУ (алфавитноцифровое печатающее устройство). До сих пор LF (Line Feed, перевод строки) 0xA and CR LF (Carriage Return возврат каретки + LF) 0xD является камнем преткновения между Linux и Windows.

Первые 32 символа - управляющая последовательность для работы с телетайпом и первыми алфавитно-текстовыми контроллерами для ЧБ-мониторов, которые поддерживали эту кодировку непосредственно для вывода на экран того что есть в видеопамяти. Это уже потом возникло то, что можно прочитать из файла по int 21h и записать на экран по int 10h. Так и появился первый редактор чего бы то ни было и в том числе кода. С появлением графических оболочек основа мало изменилась с точки зрения представления. Однако, благодаря Unicode становится возможным расширить это до текст-графического интерфейса. Целочисленная сетка для координат предпочтительнее так как обладает однозначным замыканием полигонов, линейным динамическим диапазоном (у плавающей запятой - экспоненциальный), введения бита ограничения, проверки чётности, вида сетки (абсолютная, относительная, знаковая или беззнаковая), пригодностью для обучения ИИ за счёт токенизации координат для "чертёжного мышления".

Возможность расширения кодировки как основа для полноценного текст-графического интерфейса пользователя, включая виртуальную машину (байткод) и даже оконные функции
Возможность расширения кодировки как основа для полноценного текст-графического интерфейса пользователя, включая виртуальную машину (байткод) и даже оконные функции
Любителям минимализма посвящается

Несмотря на то что современная консоль, включая bash, command.com, Volkov Commander в 64 килобайта, Norton Unilites, и другие шедевры с int 10h, Turbo Vision и Ncurses не менялась практически 30 лет, возможно было сделать текст-графическую на основе "векторных" дисплеев на следующем примере.

Схема видеокарты, рисующей линии, на основе памяти и интеграторов, в качестве ОЗУ со свойствами кольцевого буфера целесообразно применить элементы памяти на основе линий задержки, магнитострикционных или ртутных
Схема видеокарты, рисующей линии, на основе памяти и интеграторов, в качестве ОЗУ со свойствами кольцевого буфера целесообразно применить элементы памяти на основе линий задержки, магнитострикционных или ртутных

Интегратором на операционных усилителях можно вполне рисовать линии на экране, имея ОЗУ, простейший ЦАП на резисторах и осциллограф со входами XY и выводом управления яркостью

Пример простейшей модели интегратора со сбросом с заданием начальных условий (в Scilab)
Пример простейшей модели интегратора со сбросом с заданием начальных условий (в Scilab)

С дугами и окружностями немного сложнее, но выход есть - это генератор ортогонального сигнала с соответствующими блоками умножения и сложения. Синхронизировав таймер с выходом генератора можно вырезать кусочки кривых. Умножение можно выполнить на сумматоре, логарифмическом и антилогарифмическом усилителе, зная, что \text{ln}(a\cdot b)=\text{ln}(a)+\text{ln}(b) и \text{e}^{(\text{ln}(a\cdot b))}=a\cdot b. Ортогональный сигнал формируется с использованием производной и понижающего коэффициента:
{d/ dt}(A\cdot \text {sin}(\omega\cdot t)) = A\cdot \omega\cdot \text{cos}(\omega\cdot t), таким образом необходимо результат поделить на коэффициент \omega, являющийся круговой частотой. Параметрическая формула для эллипса с заданным углом поворота довольно проста
x(t)=a\cdot \text {cos}(ψ)\cdot \text {cos}(t)-b\cdot \text {sin}(ψ)\cdot \text {sin}(t)
y(t)=b\cdot \text {cos}(ψ)\cdot \text {sin}(t)+a\cdot \text {sin}(ψ)\cdot \text {cos}(t)

Модель формирования дуги эллипса из ортогонального сигнала
Модель формирования дуги эллипса из ортогонального сигнала
Слева - параметрический график x-y, справа - от времени t
Слева - параметрический график x-y, справа - от времени t

Аналогично можно с использованием интеграторов и источника ступенчатого сигнала рисовать кривые Безье с заданными начальными условиями. Первый интеграл - прямая, второй - парабола, третий - она же, кубическая.
Таким образом, можно сформировать текст-графический интерфейс с использованием микросхем памяти, таймеров, операционных усилителей и динамических элементов с использованием ёмкости, включая гираторы. Также возможна обратная растеризация с использованием АЦП, в этом случае такая видеокарта была бы гибридной, аналого-цифровой.

Таким образом, можно реализовать встроенный оконный интерфейс непосредственно в сам редактор, достаточно лаконичный, содержащий области прокрутки, поля, изменение размеров, послойное отображение, обработку событий и не привносящий лишней информационной и визуальной нагрузки, наоборот, являющийся частью семантики общей картины.

Основные проблемы

Папки-файлы

Типовая структура процесса проектирования представлена на рисунке 1.

Рис. 1. Основной путь и обратные связи при проектировании ПО
Рис. 1. Основной путь и обратные связи при проектировании ПО

Основой всего является также её величество Файловая система. File/folder not found. Fatal error: cannot open... Кому не знакомы данные сообщения, отнимающие часы и даже дни, вынуждающие сёрфить по форумам а иногда и писать письма разработчикам. Причиной такого поведения является отступление от языка предметной области и использование файловой системы для структурирования проекта, в то время как она предназначена в большей мере для простого хранения именованных данных. Расширение у файла, определяющее содержание, появилось исторически довольно давно, но это стало обыденностью ввиду широкого распространения для всех ОС. 0xCAFEBABE, MZ, JFIF, PK, %PDF, Rar! - то же самое расширение, только... попавшее внутрь файла в виде магической фразы или ID, и однозначно его идентифицирующее но уже для целевой утилиты. Типовая структура файловой системы для управления проектом представлена на рис. 2. Файловая система является прямым деревом с очень слабыми обратными связями, причём характер этих связей должен поддерживаться согласно правил именования файлов, их содержимого, правил расширений, образцов заполнения структуры. Особо "приятное" явление - когда имя файла/директории несёт некоторую семантику, например, номер версии, имеет приставку имени разработчика или суффикс 1,2,3,qwerty, которые проникают в make, становятся абсолютными, и, вишенка на торте - это системные переменные PATH, попадающие в проект. Поэтому, в данной концепции производится отказ от файловой системы/переменных окружения/реестра/внешних настроек как от метода структурирования проекта, инкапсулируя их в отдельные свойства системы, из которых уже генерируются необходимые конструкции и настройки. Таким образом, файловая система и иные элементы, связанные с операционной системой становятся уже более низким уровнем и служат лишь для хранения и преобразования данных, не принимая непосредственного участия в процессе проектирования на языке предметной области. Также, в качестве хранилища рассматриваются базы данных и облачные службы, включая объектное взаимодействие по API, ассоциативное хранение информации, микро-скрипты и, быть может, подгружаемые веса генерирующих нейросетей. В качестве источника/приёмника используется любой шлюз, начиная от диска /mnt, C:, http/ftp, TCP/IP и заканчивая UART к микроконтроллеру, возможен также вариант.

Рис. 2. Типовое структурирование проекта с использованием файловой системы
Рис. 2. Типовое структурирование проекта с использованием файловой системы

Как было уже сказано ранее, разработчики ОС постарались оптимизировать фрагментацию при использовании НЖМД (минимизировав перемещение механикой по цилиндрам и разброс по секторам), разрабатывали специальные алгоритмы для этого, хотя, как оказалось, пришли к использованию файловой системы в файловой системе. Достаточно добавить расширение .zip к любому xlsx, odt, и прочим офисным файлам и тут же он станет файлами и папками при распаковке. То есть архиватор внутри себя сам создаёт файловую систему а далее пакет после разархивации пользуется ей как виртуальной локальной копией. То есть достаточно к совокупности файлов и папок добавить внешнюю стороннюю объединяющую сущность (вне файловой системы ОС) и получается документ. Но возможно также объединять другие документы такими же документами-контейнерами, а также извлекать из них отдельно рисунки, текст, нумерацию и др, прикладывать сгенерированные документы для печати или выходной результат, таким образом, объединяющая сущность уже устанавливает соответствие, и дерево превращается в клубок, о чём речь пойдёт далее.

Процесс формирования исполняемого модуля

Файловая система также привносит разбиение между этапами построения и преобразования данных из текста в двоичный формат исполняемых модулей. Среда разработки фактически представляет также собой файл, в котором определены настройки и этапы построения, даже если это IDE, имеется нечто вроде make, cmake и др. во внутреннем представлении. Но основой является то что представлено на рис. 3.

Рис. 3. Дублируемые элементы средой разработки и основными элементами формирования объектных и исполняемых модулей
Рис. 3. Дублируемые элементы средой разработки и основными элементами формирования объектных и исполняемых модулей

Разделение на этапы построения соответствуют конвейеру преобразования исходного кода в исполняемые модули, каждый из этапов объединяется в большие группы - редактор текста, компиляцию и редактор связей, что принято как основные этапы, хотя можно даже сделать отдельный лексер-парсер, препроцессор, кодогенератор, компоновщик в модули, компоновщик модулей в исполняемый объект, загрузчик исполняемого объекта, как это было на заре первых высокоуровневых программ.
Как видно из рисунка, существует множество дублируемых сущностей. Так, в современной среде проектирования (IDE) имеется встроенный механизм формирования упрощённого абстрактного синтаксического дерева (AST) и содержит предварительно откомпилированный фрагмент кода для подсветки синтаксиса, ошибок, парных скобок и др. То есть уже на этом уровне непрерывно выполняется работа непосредственно самого компилятора в виде лексического и синтаксического анализа. Дублируется лексер, парсер, создаваемые таблицы символов, раскрытие макросов и другие элементы программы. Рефакторинг кода также производится исходя из разбиения на комментарии, непосредственно код. Профайлинг аналогичен рефакторингу по результатам тестов и замеров производительности отдельных компонент в части замены кода на более оптимальный. Причём, рефакторинг должен уметь отличать имя объекта от имени класса/структуры, область видимости, анализируя полный контекст, особенно что касается typedef на C.

Редактор на основе АСД (AST)

Общая структура предлагаемого решения представлена на рис. 4. В основном IDE использует файловую систему как промежуточный механизм обмена данными и их хранения в виде именованных записей с заданными атрибутами, которые и формируют структуру проекта. Частично она содержит элементы отладки, их визуализацию а также свой встроенный проводник, позволяющий осуществить навигацию по файлам-папкам в проекте, извлекая и визуализируя из них содержание уже на предметной области, характерной для заданного языка программирования. Исходный код частично касается среды проектирования благодаря интеграции встроенного лексера-парсера для подсветки, автозаполнения и рефакторинга. Остальные элементы являются слабо связанные и представляют в большей мере фоновый вызов утилит, при этом IDE лишь обеспечивает согласование путей и кодогенерацию вспомогательных элементов (make и др.).

Рис. 4. Среда разработки на основе файловой системы и АСД. В АСД используется язык предметной области - контролируется изменение самих функций, классов, данных, тестов, локальных и глобальных версий, при этом отсутствует файловая система как концепция основы для проекта
Рис. 4. Среда разработки на основе файловой системы и АСД. В АСД используется язык предметной области - контролируется изменение самих функций, классов, данных, тестов, локальных и глобальных версий, при этом отсутствует файловая система как концепция основы для проекта

Как уже было отмечено краеугольным камнем любой среды проектирования является хранилище и текстовый редактор. К сожалению, если любая среда эти сущности не поддерживает "как принято" для ввода и структурирования данных, она становится единственным механизмом, обеспечивающим взаимодействие с пользователем. Так, в основном визуальные среды вроде Matlab+Simulink, LabView, UML Rational Rose (-), Визуальный Дракон, являются комбайнами, которые неотделимы от самого графического или текст-графического языка. Поэтому, необходимо максимально приблизить спецификацию к некоему универсальному текст-графическому интерфейсу, лаконичному как командная строка но при этом функциональному и способному к масштабированию до графического представления и обратно.

Среда на основе АСД (см. рис. 4) касается всех элементов проекта, которые соответствуют языка предметной области, связанной с разработкой программ и не выделяет существенно отдельно какие-либо из них.

На рис. 5 представлена основная начальная концепция среды на основе АСД.

Рис. 5. Концепция среды проектирования на основе АСД
Рис. 5. Концепция среды проектирования на основе АСД

Концепция представления в виде AST применялась довольно давно и широко, включая активные текстовые редакторы, и первые среды с WYSIWYG. Внутри файла применялись управляющие структуры, различные обрамления текста и др., широко известные примеры - комментарии содержащие тэги для Doxygen, md-файлы, man-ы, разумеется, HTML и др. языки разметки.

Рис. 6 - примеры активных текстовых редакторов
Рис. 6 - примеры активных текстовых редакторов

Первый редактор, это, конечно же, тот самый, проверка синтаксиса на лету и всё это в паре десятков кБ УФПЗУ - ZX-Spectrum. 2 - Simulink изменяет поведение линии при поднесении к портам выхода и входа (соответствие), 3 - проверка синтаксиса в PyCharm, 4 - поля класса в Visual Studio, 5 - IDE Xerox Alto (1970-е!). Хотя это не является в полной именно активным текстовым редактором или таким, syntax free editor, но это поведение характерно именно для разработки ПО.

Для проверки предлагаемой концепции для реализации использовалась базовая платформа на основе Python (2025), далее она была реализована на языке С полностью с привлечением промпт-инжиниринга. Вообще говоря, язык С может переживать второе рождение благодаря существенной кодовой базе для обучения ИИ а также как высокоуровневый ассемблер. При этом, всё ради чего сделаны компилируемые С++, Rust, Pascal-Delphi, Go, C# и др. практически теряют своё преимущество благодаря управлению памятью со стороны ИИ и поддержки "контроля" кода агентами. ООП также уходит на второй план благодаря автоматизации состояния, поведения и идентичности объекта с динамической типизацией на уровне спецификации. При этом, „Си — инструмент, острый, как бритва: с его помощью можно создать и элегантную программу, и кровавое месиво“ — Б. Керниган. Также, лаконичность его грамматики наряду с Python/Basic позволяет более эффективно работать с контекстным окном. Структурная схема представлена на рис. 7. Платформа производит кодогенерацию на основе АСД в код на языке С (включая расширения, OpenMP, ассемблерные вставки, OpenCL/CUDA и др), который содержит определения, необходимые для обратной интеграции в среду Python или С. В коде содержатся комментарии, позволяющие осуществить взаимосвязь с узлами и ветвями АСД по идентификаторам, тем самым, делая возможным отладку. АСД реализовано в виде объектов на С. В качестве движка - OpenGL, включая GLUT.

Рис. 7. Механизм реализации редактора АСД
Рис. 7. Механизм реализации редактора АСД

Особенностью реализации изначально является многопроцессорный (multiprocessing) обработчик запросов пользователя, обхода АСД, взаимодействия с другими сервисами, кодогенератор на основе заданных шаблонов C-файлов (с именем, похожим на хеш и упрощающим работу), вызов внешнего средства gcc, формирование объектных файлов во временных папках (включая файл в памяти). В настоящее время проект полностью портирован на чистый С (версия ISO/IEC 9899:2024, включающая дополнения по битовым полям), с потокобезопасными очередями и многопроцессорной поддержкой, весь код генерируется промптами и удерживается в контекстном окне вспомогательными python/bash скриптами. Python также помогает формировать вспомогательные элементы - текстуры, шрифты и C-файлы с данными, выносимые за контекстное окно и проверяемые проверкой кодогенератора.
Наиболее интересной реализацией являлась бы непосредственная генерация на уровне мета-языка уровня GENERIC/GIMPLE, или даже LLVM, который является промежуточным представлением для любого языка начиная от Fortran до C++ и OpenACC. Однако, это может создать некоторые проблемы с отладкой, так как GDB ассоциирует точки остановки именно с номерами строк исходного языка. Поэтому, производится кодогенерация на С, где в классических /**/ комментариях имеются атрибуты, отображающие заданные узлы, ветви части АСД на С-строки, далее командами GDB возможно проводить уже высокоуровневую отладку, следуя по визуализации с "точками остановки на блок-схеме", при этом, сохраняя эффективность компилятора вместо интерпретатора (виртуальной машины обработки АСД), причём, часть дерева может быть компилируемой, часть - интерпретируемой (ещё более удобная отладка с изменениями налету, формированием файла в памяти (ramdrive) .so/.dll и его заргузкой). Вплоть до того, что осуществить отладку до промпта, ассоциировав слова с соответствующим ID комментария. Например, циклически пройти слева направо и справа налево массив "А роза упала на лапу Азора".

=>=

Программа представляется в виде текстовых, графических элементов, как показано на рис. 8. Принципиальным моментом является то, что это фактически язык программирования с синтаксисом, определяемым пользователем. В этом случае отпадает необходимость отслеживания необходимых синтаксических конструкций. Фактически, документация всегда имеется под рукой, ассоциированная с той или иной командой.

Рис. 8. Формы представления одной и той же программы заданной в виде АСД
Рис. 8. Формы представления одной и той же программы заданной в виде АСД

Как видно из рис. 8, для АСД имеется множество вариантов для визуализации пользователю. И это является ключевой особенностью этой среды, что то что видно на экране это не есть какой-либо разбитый по строкам файл исходного кода а результат интерпретации части АСД. Таким образом, данная среда в виде текст-графического интерфейса имеет много схожего с браузером, который визуализирует разметку (HTML+CCS) с её поведением (JS+HTTPS), и может быть интегрирован в самые разнообразные интерфейсы, сохраняя лаконичность командной строки и возможности WYSIWYG. Недостатком является то, что обычный текстовый редактор уже невозможно использовать, разве что АСД сохраняется в виде человекочитаемого формата (HRF) в виде JSON-XML, но это опять возврат к истокам. Важной особенностью отсутствия привязки к синтаксису является задание переменных в любом виде, хоть с пробелами, привнести смысл расположением или цветом (чёрное - int, красное - float) и др, включая настраиваемое динамическое поведение при визуализации, мерцание, подчёркивание, несколько курсоров, подсветка и др.

Далее представлены примеры визуализации одной и той же программы. На рис. 9 представлено представление одного и того же алгоритма с синтаксисом, определяемым пользователем или иным другим стилем по умолчанию. Следует отметить что семантика индексации может быть настраиваемой, a[i], a(i+1) или даже нижний индекс a_{i}.

Рис. 9. Варианты визуализации одного и того же дерева
Рис. 9. Варианты визуализации одного и того же дерева

Пользователь может выбирать что ему нравится, включая элементарные атрибуты цвет, шрифт, соответствующие, например, переменной, числу, типу числа (целое, вещественное), его разрядности, классу, функции, шаблону, regexp-у, сигналу и др. Для операторов предусматриваются отдельные графические элементы, включая окна или линии-ограничители области действия оператора. Можно использовать как скобки, так и табуляции, задавать следование слева направо или справа налево для удобства в отдельных языках. Равно как вместо индексации в скобках использовать индексы внизу переменной. Предлагается также использовать HDL-элементы (языки описания аппаратуры) в наравне с семантикой классических языков, так, сигналом может быть переменная, изменение сигнала - условное выражение хранящее n-1-е состояние, дельта-задержка и другие эффекты "два сигнала на один вход" - гонка данных, включая возможное обнаружение ошибок "чтение-модификация-запись" уже на этапе моделирования и компиляции, при наличии прерываний и иных асинхронных процессов. Например, в далёком теперь уже 1991 году "indentation is Python's way of grouping statements. Python does not (yet!) provide an intelligent input line editing facility, so you have to type a tab or space(s) for each indented line. In practice you will prepare more complicated input for Python with a text editor; most text editors have an auto-indent facility" уже имелись скорее всего те самые штрихи, которые позволили бы создать интерактивный активный текстовый редактор для первого Python, но, мощность тех компьютеров, оставляла желать лучшего, даже для Turbo Vision, хотя тогда появились уже первые 386е с фантастическим цветными 16 бит 640 на 480 на 13 дюймовом мониторе и паре мегабайт ОЗУ.

На рис. 10 представлена возможная реализация механизма комментариев. Каждый узел имеет собственные координаты и координаты комментария, выраженные в символах, возможно его расположение относительно данного объекта, при этом, в полной мере используется двумерная область, позволяя размещать комментарии не мешающие восприятию кода. Сам комментарий также имеет атрибуты в виде дополнительных ссылок и иных объектов, например, вызов внешнего файла, содержащего данные, руководство и др. Тем самым, имеется принципиальный подход - код и комментарии разделены, то есть изменение комментария не есть изменение кода, также, пробелы, табуляции и переносы строки не являются основанием именно для git-овки структуры алгоритма. Изменение алгоритма - это непосредственная модификация АСД. Это даёт весомое преимущество для раздельного контроля версий данных, алгоритмов, комментариев, документации и иных элементов программы инвариантно к синтаксическим и оформительским изменениям. Ещё раз следует отметить, что редактированию подвергается невидимая структура АСД слева на рис. 10, справа - то как она отображается по внутренним правилам IDE и опциям пользователя. Таким образом, отображение свободно от синтаксиса и является настраиваемым под любые визуальные предпочтения.

Рис. 10. Помимо непосредственно операнда, каждый узел снабжён множеством дополнительных атрибутов, интерпретируемых как комментарии, координаты их микро-окошек, определяемых пользователем, ссылки и др.
Рис. 10. Помимо непосредственно операнда, каждый узел снабжён множеством дополнительных атрибутов, интерпретируемых как комментарии, координаты их микро-окошек, определяемых пользователем, ссылки и др.

На рис. 11 представлен метод построения вспомогательных комментариев, необходимых для формирования документации, фактически это комментарии, имеющие атрибут обхода при генерации документа по коду. Они также имеют свой слой и могут быть интегрированы с основными, быть отображаемыми, частично скрытыми, имеют возможность включать в список содержимое основных комментариев. Данные компоненты генерируют документацию в заданном формате, удобнее всего с использованием готовых шаблонов, например, для LaTeX. Комментарий имеет теги, позволяющие ссылаться на имена переменных, узлы АСД в виде операторов.

Рис. 11. Вспомогательные комментарии для генерации документации
Рис. 11. Вспомогательные комментарии для генерации документации

Также, предполагается возможность задавать обратные связи между кодом и документацией, особенно если в ней указаны переменные, наименования регистров, периферии и др. Пример представлен на рис. 12. Также возможна обратная нотация, например, отдельным полем из документации в код. При таком подходе можно избежать ошибок в сопутствующих руководствах связанных с заменой в комментариях, пропуском номера, суффикса или приставки переменной. Обычно используются инструменты, которые не предоставляют такую обратную связь, например, Doxygen и другие генераторы документации по коду, для которых нужна специальная нотация в комментариях. Важно отметить что комментарий хранится отдельно от кода и это не затрагивает процесс компиляции. Комментарий, если он не изменяет код, не является триггером для перекомпиляции фрагмента или всех элементов. Также ведётся отдельный журнал изменения комментариев и их версий (возможна отдельная версия от версии кода или композитная). Этот же атрибут может быть использован для ассоциации с промптом или формирования промпта по коду (!) а также для использования в RAG.

Рис .12. Объединение кода и комментариев, фрагментов документации, по которым формируется общий документ
Рис .12. Объединение кода и комментариев, фрагментов документации, по которым формируется общий документ

При использовании имён переменных, особенно для отладки, возникает необходимость их обработать и, например, вывести на экран (консоль или фрейм), отправить по сети и др. Аналогично с именами классов, функций. Они начинают играть роль объектов которые можно импортировать, экспортировать, встраивать в виде каких-либо элементов. Таким образом, можно легко интегрировать в строку имена переменных, при этом, отсутствует необходимость синхронизировать строки с этими именами. Пример интеграции имени переменных в строку для вывода представлен на рис. 13. Таким образом, имя переменной может быть даже с пробелами, содержать эмодзи-смайлы, зависеть от атрибутов, в узле АСД это завершённая utf-8 строка. Отображение может скрывать длинные переменные, а также... использовать переменные в качестве промпта! int Известно_что_если_хорошенько_задокументировать_переменную_то_ИИ_по_ней_сделает_код = 0;

Рис. 13. Внедрение имён функций, переменных в произвольный текст
Рис. 13. Внедрение имён функций, переменных в произвольный текст

Защита кода, атрибуты авторов, а также метки времени от доверенных центров позволяют реализовать более гибкий контроль, многопользовательскую разработку. Фрагменты кода и данных содержат атрибуты, которые позволяют произвести контроль аутентичности, шифрования, упростить делопроизводство, подписывать "разработал, проверил, отладка, тестирование, документация, нормоконтроль, утвердил, сдано в архив, дискета упакована и опечатана". Также, данный подписанный, хешированный код удобен тем, что может быть использован для контроля непосредственно bootloader-ом, например, сверяя контрольные суммы при загрузки кода и данных из ПЗУ в ОЗУ, причём такие операции можно назначить не только для выходных двоичных данных, но и для обхода АСД с целью контроля его целостности или иной другой информации. Пример крипто-этикеток и контрольных сумм приведён на рис. 14

Рис. 14. Защита пользовательского кода, подлинность, метки времени
Рис. 14. Защита пользовательского кода, подлинность, метки времени
Гипотетическая pull-push реклама в исходном коде
//GPIO
	GPIO_InitTypeDef GpDt;        /*Git 4 Free             */
	GPIO_DeInit(GPIOA);           /*Осциллографы           */
	GPIO_DeInit(GPIOB);           /*Мультиметры            */
  	GPIO_DeInit(GPIOC);           /*Паяльные станции       */         
                                  /*-To remove ad 2$/month-*/
	GpDt.GPIO_Mode = GPIO_Mode_Out_PP;
	GpDt.GPIO_Speed = GPIO_Speed_50MHz;      /*Анализаторы спектра*/
	GpDt.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; ///Спец Предложение///

Потенциально бесплатные сервисы при pull могут встраивать банеры в исходный код локального репозитория в виде комментариев, при этом, при работе с веб-мастером или пропиретарной оболочкой удалённого репозитория такого нет, или, наоборот при push в удалённом репозитории с использованием веб-просмотрщика появляются объявления. Реклама отключается оплатой преимум доступа. В этом случае предлагаемая система может "отфильтровывать" не подписанный код, что позволяет избежать встраивания каких-либо элементов провайдером или хостером. При этом, можно разрешить рекламу, если система предоставляет от этого какие-то бонусы за просмотры, например, мегатокены ИИ за 5 секунд человеческого внимания.

import numpy as np ###учебники по математике, ЕГЭ ###      
import cv2 ###видеокамеры, глазки, сигнализация, звоните###
import random
from multiprocessing import Process, Queue
from multiprocessing.shared_memory import SharedMemory
###Многопроцессорные стойки для Ваших самых смелых идей     ###
###Nvidia, AMD, Intel, ARM, 1ТБ в подарок                   ###
###GitFree v 1.1 Cloud. Премиум-тариф 200р/месяц без рекламы###
import serial                            ##RS-485 всегда в наличии##
from datetime import datetime
import socket                            #+Роутеры, свитчи, не б/у+#
import os                                
import RPi.GPIO as GPIO                  ###Raspberry, Orange      ###
from gpiozero import CPUTemperature      ###и многое другое        ### 
import time                              ###заказывайте 24/7       ###
from enum import Enum                    ###широкий выбор          ###
import copy                              ###гарантия               ### 
from subprocess import check_call

Также, можно унифицировать байткод АСД до уровня, пригодного для построения полноценного браузера. Среда разработки в этом случае вполне может с использованием дополнений поддерживать стили, анимацию, так как исходный код для этого фактически реализуется теми же средствами. В этом случае нет необходимости отдельных сущностей HTML/CSS/JS, фактически, представляющих единую виртуальную машину WebASM/WebGL и др., которые могут быть интегрированы в общий формат, более того, существенно упрощается взаимодействие между данными фронтенда и бэкэнда (см. далее рис. 22). Неразрывность модели АСД позволяет "склеить" фронтенд и бекенд без избыточного разнообразия фреймворков по описанию данных, протоколам и др. Пример АСД, который содержит стили представлен на рис. 15. Скрипты по экспорту также реализуются средствами системы и позволяют осуществить релиз указанной части дерева, данных в необходимом формате для документации или отображения на экране, особенно это касается формул и специальных символов, не относящихся к Unicode, которые могут быть представлены как в виде растра так и векторно. Присутствуют элементарные таймеры, фоновый цикл и асинхронный запрос-ответ.

Рис. 15. Стили и поведение при отображении или экспорте данных
Рис. 15. Стили и поведение при отображении или экспорте данных

Предлагается трёхмерное представление кода, помимо двумерного. В двумерном варианте можно расположить следующие блоки непосредственно рядом с предыдущими, семантически можно использовать стрелки, одинаковый цвет, градиент цвета, характеризующий последовательность. В "трёхмерном" варианте, вернее 2.5D, используются маркеры "ныряния" и "выныривания" на следующий слой, при необходимости, можно задействовать альфа-канал для предпросмотра. В этом случае код приобретает слоистую структуру, это может быть удобно для циклов и условий с большой степенью вложенности а также для длинных функций. На рис. 16 представлен эскиз возможной реализации данного метода. Он напоминает следование по подсистемам в Matlab, по иерархическим листам в KiCAD/Altium, а для двумерного расположения кода - печатную плату с перетаскиванием проводников и компонент. Важно отметить, что визуализация не влияет на базовые элементы АСД а дополняет их, тем самым, упрощается обратная совместимость, включая работу старых версий с данными из более поздних и реализация минимального технологического долга.

Рис. 16. Двумерное и "трёхмерное" (слоистое) представление кода
Рис. 16. Двумерное и "трёхмерное" (слоистое) представление кода

=>=

В качестве базы можно выделить следующую концепцию в виде дескрипторов данных или имён-идентификаторов (перменные), пространств имён, определителя последовательности данных и их поведения (класс), функций (включая безымянные), область видимости, процесс. Пространство имён является контейнером для классов, функций и других пространств, аналогично функции могут содержать классы, пространства, область видимости ( эквивалент " int a;{int a;}" на С без оператора до фигурных скобок) и так далее. Функция - более частный случай области видимости, которая создаёт локальные переменные, область видимости отличается тем что может быть процедурой без затенения отдельных внешних переменных. Процесс - независимо формируемые переменные, данные и функции, полностью изолированы от внешнего окружения, процесс может быть как абстрактным (определение), виртуальным (эмуляция), так и физическим.

=>=

Пример объявления переменных представлен на рис. 17 и 18. В пределах блока пространства имён область видимости переменных распространяется "снизу вверх и сверху вниз" согласно настройкам, то есть нет необходимости использовать прототипы, а если такое необходимо существует их экспорт в виде атрибутов. Дополнительно можно использовать генерацию прототипов (например, для документации или экспорта/копирования) и сортировку имён в порядке использования или координат. В этом случае имеется отличие от Mathcad, где важно относительное расположение элементов, для разрешения взаимных зависимостей используется метка последовательности, создающая упорядоченное множество объектов. АСД содержит атрибут переменной, определяющий её тип, поведение и идентичность (расположение в памяти, статическая, динамическая) и др. Каждый символ может быть заменён шаблоном или алгебраической подстановкой. При объявлении шаблона используется поле символической подстановки (которое применяется также для функций, классов) и таблица замены символов. Блок определений переменных по умолчанию содержит аргументы, принимающие типы данных template<type>, включая массивы типов (полезных для прототипирования пакетов UART).Таким образом, можно конструировать любые данные, которые могут быть составляющими класса, функции, пространства имён и кодогенератора. На рис. 17 представлен дескриптор данных для описания переменных, встроенный калькулятор, включая символический процессор, регулярные выражения, на рис. 18 - установщик двоичных данных и инициализатор битовых полей, многомерных структур а также выравнивания в памяти, расположение в фиксированной ячейке. Вводится концепция пустого не именованного поля, которое будет определено позже как отдельный класс, что позволяет легко найти то, что ещё предстоит сделать. Обычно это размещается в комментарий с пометкой "TBD", "Reserved", "Доделать", "!!!" и др. Особенно важна промпт-заглушка для таких данных. Также предоставляются инструменты для работы с двоичными числами, разбиение на тетрады и др., включая инициализаторы с использованием масок, двоичных И-ИЛИ-НЕ, каждое поле является вычислимым и по умолчанию содержит объект-формулу (как вспомогательное АСД). Интегральные типы данных являются встроенными, помимо этого, дополнительно имеются элементы теории множеств, Булевой алгебры, работа с NaN, \pm \infty, числ EPS, комплексные, арифметика с Q-форматом, насыщаемая и др. Возможна интеграция движка системы символьных вычислений (CAS) Maxima для работы с формулами. Предоставляется работа с атрибутами эквивалентными #pragma align или pack для работы со структурами struct и объединениями union, они являются частью узлов АСД для переменных по которым генерируются уже необходимые директивы компилятора.

Рис. 17. Дескриптор данных. Задаётся группа значений в виде таблицы, шаблоны - по умолчанию, вычисляемые выражения благодаря интеграции Maxima, конструктор регулярных выражений
Рис. 17. Дескриптор данных. Задаётся группа значений в виде таблицы, шаблоны - по умолчанию, вычисляемые выражения благодаря интеграции Maxima, конструктор регулярных выражений
Рис. 18. Дескрипторы битовых полей, представления числа в удобном двоичном формате, двумерные и многомерные данные, указание расположения в виде дескриптора объектов или в качестве свойства к объекту, эквивалент #pragma align/pack
Рис. 18. Дескрипторы битовых полей, представления числа в удобном двоичном формате, двумерные и многомерные данные, указание расположения в виде дескриптора объектов или в качестве свойства к объекту, эквивалент #pragma align/pack

Следующая концепция это альяс переменных, то есть перегрузка объявления и/или определения (ad-hoc полиморфизм не только для функций но и для переменных и других сущностей). В дальнейшем вводится вариативность и версионность. Альяс отличается тем, что имеет возможные варианты применения и назначения. Это несколько напоминает union на С, который объединяет несколько структур и других типов данных с одним и тем же базовым адресом. Отличием является возможность непосредственного доступа к полям, в этом случае сокращается цепочка имён и улучшается восприятие а также независимость объявлений. Пример альяса представлен на рис. 19. Варианты использования - основное объявление, для формирования сериализированных данных, для отладки и визуализации, также, возможны отдельные структуры для корректного экспорта в JSON, XML с проверкой граничных значений, типов данных, непосредственно из сессии отладки или как отдельная функция. Тем самым, каждый объект, включая интегральные типы данных может иметь альяс с дескриптором, имеющим функции импорта-экспорта данных и использовать их для форматного, графического вывода как printf так и для начальных значений. Группировка лямбда-классом позволяет сразу же высвечивать отдельно все опции по команде "." доступа к полю, что удобно для согласованных данных даже если у них различные имена. Лямбда класс - не именованный класс-контейнер, распределённый, не обязательно последовательное расположение элементов, и вбирающий в себя элементы из других классов, также его можно сделать именованным но это свойство произвольного выбора элементов из других классов и расположения их в нужном порядке он сохранит. Упрощённо - класс на основе выбранных элементов из других классов, если в другом классе элемент удалён он автоматически удаляется в лямбда-классе, более подробно - см. рис. 23.

Рис. 19. Альясы описаний данных.
Рис. 19. Альясы описаний данных.

При определении данных в функциях используется в основном строгое соответствие между именем объекта и его использованием, когда рефакторинг производится в заданной области видимости или для глобальных объектов. Изменение имени ведёт к автоматическому применению изменений, если не требуется использовать копирование-вставку в общем виде (символическую) и иные действия вне структуры АСД. В этом отношении действует концепция "черновик" или скетч кода, выражаемые в виде кусочков скелета действий или определений, обычно они вставляются в .txt вне проекта или файлы с расширением наподобие .c_, чтобы исключить наброски из сборки. Также может отдельно использоваться расширенный буфер обмена с сохранением (см. далее). Причём, рефакторинг осуществляется корректно и затрагивает только необходимые фрагменты кода, и, особенно, комментарии, строки, зависимые от имён в программе, как было указано ранее. Это существенно облегчает синхронизацию кода, документации, при этом, изменение в комментариях или объявлениях не приводит к перекомпиляции всего мира, не требует специальных языковых приёмов вроде абстрактных базовых классов, прекомпилированных заголовков и др. См. С. Мейерс 42 рекомендации... и 35 рекомендаций (2 книги) - о том как файловая система, паттерны программирования вместе с языком образуют единое целое, причём актуально спустя 20 лет. Пример представлен на рис. 20.

Рис. 20 - редактирование имён, применение изменений в АСД, статическое и динамическое управление объектами
Рис. 20 - редактирование имён, применение изменений в АСД, статическое и динамическое управление объектами

На рис 21 представлена важная особенность - это возможность микса строгой типизации
С/С++ и динамической как в Python. Следует отметить что эти языки приведены только в качестве примера, в АСД связка с привязкой к целевому синтаксису является универсальной и позволяет интегрировать любые. В этом случае переменная может содержать преимущественный тип данных, производится отлаживание с этим типом, проверку этого типа в контексте идентификации типов во время выполнения RTTI, генерацию исключений при несоответствии, безопасный и контролируемый static/dynamic cast. Следует отметить что в отличие от компилятора, который сам решает какие идентификаторы присваивать классам, в данной системе возможно прямое назначение, например, для таблиц виртуальных функций или цепочек swith-case. Это позволяет реализовать пакетную обработку с использованием typeid без отрыва от механизмов наследования. В этом случае может даже быть произведено локальное моделирование с целью восстановления следования и трансформации типа объекта по функциям, включая стек контроля за приводимыми типами. При необходимости - имплементация интерпретатора по месту, отвечающего за динамическое исполнение при невозможности кодогенерации со строгой типизацией. Тут же следует отметить, что ИИ непосредственно позволяет на выходе получить часть или целое АСД с наиболее компактными и семантически яркими токенами без задействования механизмов естественного языка, тем самым генерировать алгоритмы и структуры данных без применения и "знания" синтаксиса, что гораздо эффективнее при обучении ИНС, об этом далее.

21. Микс из языков строгой и динамической типизацией
21. Микс из языков строгой и динамической типизацией

Важно отметить, что на слабо типизированных и динамических языках имеются некоторые конструкции, позволяющие выявить тип данных и управлять им на этапе "компиляции", когда IDE или сам язык может дать предупреждение о согласовании данных. В этом случае применяются методы, позволяющие это подсказать. Например, PyCharm распознаёт проверку if isinstance(объект, класс): ... как указание на последующий класс, ставя точку появляется список полей, в основном эти проверки можно использовать как в рантайм так и с тегом-комментарием, закомментировав их для релиза чтобы увеличить быстродействие и избежать проверок. Аналогично можно указать явный тип без проверки в рантайм как объект:тип, или использовать комментарий # type: тип. Система на основе АСД может иметь динамические элементы с пометкой типа, с проверкой во время исполнения, а также тип, получаемый в ходе моделирования и отладки. В этом случае нет "потерянных" объектов и всегда можно обратиться к полю соответствующего класса, дав этому объекту соответствующую "этикетку". Класс-этикетка это концепция, позволяющая обращаться к объекту с динамическим полем или потенциально вводимым при строгой типизации и являющейся виртуальной программной компонентой. При использовании микса из классических языков возможна реализация связки между АСД и их элементами и указание на строгий, смешанный и динамический вариант. При этом, автоматически генерируются необходимые элементы, которые позволяют осуществлять приведение типов данных и их проверку. В крайнем случае проверка отсутствует и применяется моделирование. Для трансляции между динамическими и статическими типами применяются функции-трансляторы как концепция. Функции осуществляют сопоставление между переменной со строгим типом и с динамическим (включая интегральные динамические типы, например преобразования
char<->float). Они легко автоматически линкуются с необходимыми вставками средствами самой ID и локально компилируются. Стыковка с АСД осуществляется координатным методом как номер строки и позиция переменной чтобы не усложнять парсер IDE для текстовых вставок.

Концепция трансляции данных позволяет реализовать эффективные клиент-серверные архитектуры на различных платформах, где требуется согласование данных. При миксе язков, синхронизация имён переменных, их назначения - это отдельное направление. Пример представлен на рис. 22. Интегральные функции - это те, которые по умолчанию имеются как поле к интегральным типам данных, рассматриваемых как класс. Довольно удобно, например, для int a = 0xAE получить второй бит написав a.bit2, также можно преобразовать b=a.tofloat(), следует отметить что точка - это не синтаксис а инструкция для IDE, нажав которую, отношение класс-поле может отобразить так как удобно, цветом, пробелом и др. Есть универсальное представление, а есть такое, которое удобно в каждом конкретном случае. Следует отметить, что переменные, как в редакторе схем и выводов условно-графических обозначений, могут иметь атрибут вход-выход как на редакторе схем, что позволяет произвести статический тест согласования, атрибуты сигнала, "заземления" NULL, "питания" как константы, "передний фронт" в виде необходимости использования переменной в "if-else", "тактовый вход" для переменных-счётчиков.

Рис 22. Согласование типов данных в различных структурах
Рис 22. Согласование типов данных в различных структурах

Можно выделить такой класс классов, который являются некими аналогом гетерогенных компонент в САПР электроники. Когда одна микросхема разбивается на функциональные блоки, одинаковые или отличающиеся. В этом случае класс может быть разбит на отдельные единицы, расформированные по экрану, что существенно облегчает чтение больших структур, например, обеспечивающих описание периферийных регистров контроллеров. Это является некоторым аналогом выборочного наследования, когда производный класс выбирает только необходимые поля и методы из базового, при этом, существует символическая связь. В этом случае производный объект не может быть приведён к базовому, так как состоит из другой последовательности полей, однако, метод может быть применён один и тот же (по имени) и адресация к полям будет зависеть от класса. При обновлении полей базового класса изменятся соответственно поля производного. Связь осуществляется по идентификаторам полей, а также по ссылкам, определяемых отдельными "переменными", содержащими фактически относительный номер строки и столбца.

Рис. 23 Гетерогенные классы и производный класс с выборочными полями из базового
Рис. 23 Гетерогенные классы и производный класс с выборочными полями из базового

Специальное направление - начальные условия в заданной области видимости для переменных. Очень часто возникает необходимость задать начальные параметры, особенно если они получаются в ходе работы программы или тестирования, импортировать-экспортировать их, скопировать-вставить, преобразовать и др. Предлагается механизм согласования класса с возможными вариантами начальных условий, хранящихся рядом с ним. Пользователь может задавать даже массив начальных условий для различных версий, переключаемых в рамках одной переменной. Это позволяет избежать многочисленных копипастов и прочих лишних действий, необходимых для задания значений по месту, для самой программы, для тестирования, моделирования. Начальные условия можно выгрузить и загрузить, экспортировать-импортировать, применить расчёты для значений, назначить скрипт генерации. Также, некоторые значения можно обозначить как фиксированные, в этом случае возможна генерация программного кода, вызывающего исключение при доступе к неизменяемому полю, assertion или иной механизм. Также, для удобства, можно определить необходимое количество разрядов, отображаемых на экране для заданной переменной или в области видимости или в группе, чтобы оценить значение. Удобнее #define PI 3.14... а далее возможно раскрытие по требованию. Возможно задать принадлежность констант соответствующим областям видимости и перечислениям. Таким образом, группы констант (включая строковые и символические значения) являются универсальными инициализаторами для любых сущностей, начиная от имён функций/классов и заканчивая двоичными значениями.

Рис. 24. Задание начальных условий переменным класса
Рис. 24. Задание начальных условий переменным класса

Механизмы наследования реализуются с их внутренним описанием и компоновкой. Аналогично, для функций с рекурсией, где реализованы все механизмы контроля неявного стека. Производится управление размещением таблиц виртуальных функций (ВФ) в заданной области памяти, управление кучей и стеком во избежание переполнения особенно для небольших контроллеров, также это важно при многопоточном выполнении. Возможно явное указание функций-исключений для заданной глубины стека с его проверкой перед вызовом. Отдельное направление - замена вызовов функций по указателю на конструкции switch-case для небольших иерархий. Также, оптимизация для контроллеров у которых не существует команды
call &F(x)+idx функции по указателю (в частности, со смещением). В некоторых особых случаях можно реализовать как подпрограмму с применением переходов JMP/JC. Каждый класс имеет свой уникальный идентификатор, присваиваемый компилятором, который также (не обязательно) может являться индексом в таблице ВФ. Уровень доступа помимо общеизвестных public/private/protected может быть расширен пользовательским, для выбранной глубины иерархии или имени класса, наличию того или иного ключа. Пользователь также может управлять всеми этими идентификаторами. Первый компилятор С++ транслировал код на С. Пример представлен на рис. 25.

Рис. 25. Управление механизмами наследования, виртуальными и рекурсивными функциями
Рис. 25. Управление механизмами наследования, виртуальными и рекурсивными функциями

В качестве отдельного класса переменных следует отметить имена, которые используются для обозначения секций в map-файле, которые также можно описать с использованием дескриптора данных. В редакторе, особенно для микроконтроллеров, действия с map уже должны быть естественными и встроенными без выноса в отдельную сущность, включая варианты исполнения с различной памятью и периферией, режимами программирования и отладки с JTAG/Bootloader/RAM/Flash и др. Данный тип переменных представлен на рис. 26. Также вводятся упаковщики с расширенным поведением, где маппинг можно определять скриптом (см. далее назначение выводов процессора). Потенциально, возможен динамический маппинг во время исполнения, где специальный внешний загрузчик может загружать различные версии налету, например, в ПЛИС, объединяющей процессорные ядра и контроллер некоторой ОС. В этом случае возможно создание аппаратной ОС, где распределением задач занимается уже не центральный процессор общего назначения а специализированный контроллер. Таблица назначения отображает многомерные составные данные, матрица инцидетности - графы, в этом случае адреса могут быть произвольными и даже виртуальными (в разрядности условных единиц). Гипотетическое направление - это вероятный индекс, который приближённо указывает местоположение объекта, вычисление которого производится с плавающей запятой как результат работы нейросети (аналог хеш-функции).
В развитие идеи - центральный процессор уже не центральный, а управляемый GPU, который уже поумнел достаточно чтобы делать object picking, таскать формочки, растеризовать шрифты, далее реализуются callback-и для процессора, в этом случае изолированное ядро ОС, которое оркестрирует остальными ядрами общего назначения в ответ на действия пользователя как с дисплея так и по сети (удалённо), ставя им пулы задач с естественным прерыванием выполнения и виртуализируя оборудование, сводя на нет различные лаги и зависания.

Рис. 26. Дескрипторы расположения данных и объектов (эквивалент ld/cmd-файлов)
Рис. 26. Дескрипторы расположения данных и объектов (эквивалент ld/cmd-файлов)

Немаловажной концепцией является отслеживание переменных и их расположения в самой программе, как они используются, где встречаются и как задействованы. В этом случае АСД предоставляет гораздо более гибкие инструменты чем простое редактирование текста и поиск по нему, включая возможную навигацию по промптам и результатам генерации ИИ, включая обратную связь между ИИ и скорректированным вручную кодом. Для IDE характерно прямое программирование макросов средствами самой же среды, расширение функцией осуществляется непосредственно, также, имеется взаимодействие с репозиторием аддонов, куда можно размещать любые полезные сущности а также с "базой знаний", где можно размещать АСД для "большой мегаваттной" тренировки LLM на основе байткода в качестве датасетов.

На рис. 27 представлены возможности по работы с подставляемыми значениями переменных а также контроль переменных с использованием подставляемого макроса. Формируется непосредственно макрос внутри кода, поощряется повторное использование алгоритма. При этом алгоритм, представленный как часть АСД, в общем виде, может иметь произвольные данные. Иными словами, производится наследование алгоритма и его повторное использование инвариантно к входным данным. Показан пример присваивания, с семантикой определяемой пользователем. Можно использовать как := так и :, =, пробел, <- и многое другое. В данном случае пользователь может визуализировать, какие переменные у него ещё не использованы, например, каналы PWMC1,2,5. Это является удобным, в том числе для отслеживания того что инициализировано, использовано а что нет из периферии. При этом, в отличие, например, от CubeIDE и остальных идёт обратная связь от кода к визуальному представлению, включая анализ состояний при переключаемых режимах работы периферии, а не только жёстко заданных изначально. Фактически, инкапсулируется устройство и визуализируется с использованием графического интерфейса, например, подобное STMCube, Processor Expert/Codewarrior (NXP), MPLab Microchip и др. Причём, макрос может быть как виртуальный, проверяющий код но также содержащий элементы, входящие в исполняемую программу, например, для вывода программой состояния тех или иных не инициализированных портов.

Рис. 27.  Работа с переменными и код, проверяющий код
Рис. 27. Работа с переменными и код, проверяющий код

Конвертер значений, особенно для работы с битовыми полями является неотъемлемым инструментом для разработки и описания двоичных данных. Пример приведён на рис. 28. Осуществляется полноценный перевод со встроенным калькулятором, возможность анализировать тетрады, представление по IEEE 754, включая FP8/16, Q-формат для целочисленной арифметики (включая целое.дробь), коррекция арифметическим сдвигом "<<" при умножении, данные со знаком в прямом, дополнительном и обратном коде, код Грея, полиномы, выравнивание в памяти, упаковка в структуре, включая выбор различных вариантов в зависимости от версии (см. версионирование далее) и др.

Рис. 28. Работа с двоичными данными и форматами чисел
Рис. 28. Работа с двоичными данными и форматами чисел

Кроме параметрического рефакторинга с заменой имён, при использовании АСД можно использовать структурный, когда можно выделить отдельные группы ветвей, узлов и использовать их для создания новых элементов или шаблонов. В классических языках это приводит к копированию-вставке, изменению кода в большинстве мест, отслеживанию этих изменений вручную. Примером является, например, разбиение одного класса на несколько, объединение или разбиение функций, манипуляции со большой степенью вложенности циклов или условных операторов. Простой пример по изменению структуры класса представлен на рис. 29. Также возможно для удобства размещения присваивания в 2D, также, индексация Arr[i] заменяется на Arr_i, для упрощения визуального восприятия.

Рис. 29 Структурный рефакторинг - разбиение/слияние классов без CtrlCV
Рис. 29 Структурный рефакторинг - разбиение/слияние классов без CtrlCV
Рис. 30 - параметрическая замена и рефакторинг
Рис. 30 - параметрическая замена и рефакторинг

Параметрический рефакторинг представлен на рис. 30. Важна ассоциация между составными именами и их местом в АСД. Также, в роли ветвей могут выступать локальные модели, которые вычисляют параметры из окружения. Следует отметить, что для каждого оператора можно посмотреть перегрузку, даже для интегральных типов данных, включая возможную реализацию на ассемблере благодаря локальной компиляции. Ветвь АСД, как уже было сказано ранее транслируется на известную хорошо оптимизированную платформу, образуемую заданным языком программирования (в данном случае С) и библиотеками-платформой.

Составные типы данных, структуры, классы, массивы, списки, множества, оформляемые в виде таблиц, визуализируемые в виде необходимых графов в удобном виде а также, например, с применением gnuplot непосредственно как комментарий. Функции для построения графиков можно применить к соответствующим массивам. Аналогично визуализируются иерархии (классов, функций и т. д.), например, с graphviz. Растеризованный (или даже векторный SVG) вариант отображается на экране, информация для генерации формируется из узлов АСД и ветвей непосредственно. Пример последовательных и распределённых структур данных представлен на рис. 30. Особенно актуальна визуализация длинных строк, односвязных и двусвязных списков с указателями prev-next-null, массивов, предпросмотра данных, расположенных распределённо согласно результатам вычислений, деревьев и иных сложных структур. В этом случае имеется концепция load-debug-save, позволяя сохранять получаемые при отладке структуры во временные объекты, на диск, и использовать их в качестве начальных значений для следующих отладочных версий, без применения вездесущих вставок в код, отвечающих за временный ввод-вывод на одиночную консоль или графику. Пример задействующий визуализацию данных представлен на рис. 31. Данные, получаемые в ходе отладки могут быть непосредственно использованы в программе в качестве некоторых начальных условий и просто внешней информации, особенно это касается процессов обучения ИНС и моделирования.

Рис. 31. Массив, список, множество. Визуализация известных типов данных, манипуляции с изображением, звуком, текстовыми и табличными данными.
Рис. 31. Массив, список, множество. Визуализация известных типов данных, манипуляции с изображением, звуком, текстовыми и табличными данными.

Предполагаются действия над алгоритмами, данными с применением более унифицированного буфера обмена, содержащего стек непосредственных выборок, а также журналирование действий и преобразование типов данных, включая быстрое извлечение и написание скриптов по содержимому буфера обмена, включая импорт-экспорт и изменение данных налету, например, форматирование изображения, текста и др. Пример представлен на рис. 32. Также, возможно сохранения истории копирования-вставок при выходе из среды проектирования. Следует отметить что при копировании-вставки используются ассоциированные с кодом участки АСД, содержащие полные атрибуты, тем самым, копируются автоматически комментарии, ссылки на документацию, на другие фрагменты кода и др.

Рис. 32. Унифицированный буфер обмена с визуализаций, стеком и хранилище
Рис. 32. Унифицированный буфер обмена с визуализаций, стеком и хранилище

Класс как... объект или данные, описывающие хранение других данных, почти файл. В этом случае он является контейнером, который позволяет расширить возможности файловой системы до агрегации и наличия поведения, тем самым, формируя локальную структуру данных вида "клубок" нежели "дерево", характеризующее файловую систему. Фактически появляется новый вид "проводника", который позволяет объединять объекты, хранить выходные и входные объекты, прикреплять внешние ссылки и идентификаторы, сериализовать объекты, оптимизировать передачу данных на узкополосных каналах, интегрировать данные в чаты, электронную почту и др. Таким образом, IDE уже не поддерживает файловую систему в том виде в котором она обычно используется для структурирования проекта, она нужна лишь как один из методов хранения данных и ввода-вывода, причём в качестве "файловой" системы может выступать сеть, облако, WebAPI и др. В этом случае уровень работы с данными абстрагируется на более высоком уровне и представляет объектное хранилище, включая загрузку-выгрузку, содержащие непосредственно сущности предметной области (классы, методы, функции, комментарии, промпты, их версии и др), как обёртка над файловой системой, терминалом, git. В этом случае аргументы функции в терминале автоматически подсвечиваются так как реализованы и понимаемы самой IDE, кроме того, пайпы становятся уже объектными и с определённым поведением, минимизируя количество утилит обработки и временных данных.

Кодогенерация представлена на рис. 33. Макросы и настройки. Особенно для отладки. В предлагаемой среде макрос является фактически такой же частью программного кода и реализуется теми же инструкциями. Этим он мало отличается, например, от макросов Lisp или кода Python в части применения exec, и, разумеется всевозможные #define на С. Тем самым, позволяя создавать код, модифицирующий сам себя, включая самооптимизацию по быстродействию, памяти и др. Иными словами, производится генерация скелета АСД за счёт применения другого фрагмента АСД. Далее производится его наиболее удобная визуализация. Кодогенерация - неотъемлемая часть языка, и, возможно, будущих защищённых архитектур, позволяющих на лету запускать в песочницах произвольный самомодифицирующийся код. И, разумеется, результат работы ИИ. Также следует отметить в связи с этим архитектуру "видеокарта наоборот" которая выполняет функцию центрального процессора и оркестрирует самим ЦП на основе выбора объектов (object picking) и прочих вычислений связанных с действиями на экране и выбором сущностей, вызывая callback-и для кнопок и полигонов как было сказано ранее. Также операционная система уходит в отдельное защищённое ядро, которое даёт фрагменты памяти для исполнения другими ядрами для пользовательского кода, тем самым формируя полноценную "песочницу", лишённую Meltdown/Spectre относительно ОС и прочих прелестей соседнего выполнения. В этом случае Docker-изация уже выполняется на аппаратном уровне и виртуальные машины становятся всё более виртуальными, тем самым позволяя выполнять код, сгенерированный кодом или ИИ непосредственно и предназначающийся для тестирования и отладки одновременно с "продактом". Пример кодогенерации представлен на рис. 33. Основные генераторы - табличное, макрос, генерация по шаблону данных или графику (аналог stimulus/testbench для HDL-языков),

Рис. 33. Кодогенерация на основе данных
Рис. 33. Кодогенерация на основе данных

Специализированная кодогенерация. На рис. 34 представлена генерация на основе скетчей, эскизов алгоритмов. Гипотетическая конструкция, содержащая нечто такое, что определяет сущность его реализации с минимальной информацией необходимой для его восстановления. Так, промптом ИИ вполне возможно довложить туда недостающие ветви по месту. Пока что речь о данных не идёт, их просто нет в этом представлении. То есть это некий аналог сортировочной сети, имеющий определённую структуру. Таким образом, вводится помимо классического представления о наследовании классов наследование функций и алгоритмов. Алгоритм инвариантен к данным, каждый оператор является перегруженным и должен быть определён для заданных, в общем виде, совершенно разных классов. Операции идут с "истина, не истина (ложь)" с ветвлениями. Весьма гипотетически - операции с весами нейросетей, на основе которых (кластеры генерации алгоритмов) производится формирование скелета. Так, в данной работе используется 8 бит код для виртуальной машины, объединяющий данные и функции и содержащий важнейшие промпт-ориентированные сущности, включая отображение ("образное мышление") и семантику слов. То есть данные становятся функциями и наоборот буквально меняя старший разряд. 256 значений хватит всем. Тем самым, полное описание алгоритмов и данных на основе виртуальной машины из узлов АСД вполне укладывается в 8-ми битное обучение и реализацию ИНС.

Рис. 34 кодогенерация на основе структуры, наследования алгоритма на основе его "скелета"
Рис. 34 кодогенерация на основе структуры, наследования алгоритма на основе его "скелета"

Скриншот-пример описания виртуальной машины для АСТ, сделанные в редакторе Jave прототип кодов сделал ещё в 2019, первая попытка и идея такого редактора на основе winapi console (думал будет текстовый) 2007 год), просмотр - gedit. Следует отметить главное - что биты - это не в классическом понимании численные значения а в общем виде - перечисления. Тем самым, возможна токенизация виртуальной машины безотносительно к численными опкодам, считая только предыдущие и последующие элементы описания, собранные во множество элементов. Поначалу, конечно же, для упрощения работы с АСД код для встроенной ВМ будет иметь численный некий произвольно фиксированный опкод. Вполне вероятно что их идентификаторы можно улучшить согласно эмбеддингу для более надёжной идентификации векторов. То есть в первых микропроцессорах ассемблерные опкоды были удобны с точки зрения "разводки кристалла" для двоичных операций и подбирались почти вручную, в данном же случае опкод должен быть оптимален с точки зрения минимизации ошибок проптов при генерации АСД ИИ.

Опкоды виртуальной машины АСД 8 бит (фрагменты)

Виртуальная машина содержит: описание объектов, действий, ввода-вывода, графические примитивы, элементы HDL, многопоточности, логические функции, индексацию массива, множества и одно-, двусвязного списков, описание классов, хеширование, контрольная сумма, описание функций и областей видимости, атрибутов объектов.

Немаловажным является контроль выражений, операторов и в общем виде - кода. Иными словами код, проверяющий код. Например, с использованием АСД гораздо проще "видеть" не инициализированные переменные, отсутствие ветвей от malloc до free, всевозможные assertions легко включаемые вставкой в ветвь и др. Для каждой функции назначается контрольное выражение для статической и динамической проверки во время выполнения. Также, для перегруженных операторов может быть назначена дополнительная реализация, включающая регистры процессора и даже функционал описания на HDL-языках, выраженные в прямом, дополнительном и обратном коде. В одной версии + работает с прямым кодом, с другой микросхемой с обратным и др. Более того, assertion не только являются частью самой программы, но и описывают окружение как макросы, позволяя ИИ корректировать окружающий код на этапе его генерации. Допустим, идёт статическая проверка количества каналов АЦП, что оно соответствует части устройств 10 бит и части 12 бит и тому подобное, а также что где-то необходимо взять согласно векторной базе на основе данных datasheet-а старшую часть регистра или младшую. Пример контрольных выражений представлен на рис. 35.

Рис. 35. Контрольные значения
Рис. 35. Контрольные значения

Для более тщательного контроля значений можно использовать дополнительные атрибуты к любому отображаемому элементу дерева. Пример представлен на рис. 36. Пользователь может самостоятельно добавлять необходимые ему сущности.

Рис. 36. Идентификаторы, списки, свойства всех объектов в программе и программных объектов
Рис. 36. Идентификаторы, списки, свойства всех объектов в программе и программных объектов

Взаимосвязь между ассемблером, языком верхнего уровня и АСД представлена на рис. 37. АСД позволяет использовать прямую связь между кодогенератором и языком. Тем самым, например, в дизассемблере изменив sub на add можно увидеть как меняется оператор с - на +, также, изменив номер в переменной в стеке увидеть как меняется буква, добавляя команды на ассемблере производится локальная "декомпиляция наверх" и в коде появляются новые операторы или функции уже на верхнем уровне. В этом случае IDE, компилятор, линкёр образуют фактически единое целое и имеют все необходимые метаданные с любым уровнем абстракции. Более того, могут быть скромные попытки отладить по шагам промпт, подсвечивая отдельные слова или токены, имеющие, например, наибольшую вероятность соответствия с кодом (не путать с порядком реализации задачи и иной task management, to do list на основе промпта) который суть уже решение. IDE позволяет уже реализовать локальную микро-модель, которая к промпту подставляет необходимые дополнительные атрибуты для LLM с точки зрения обратного хода от кода к исходному вводу, что позволяет дополнительно использовать RAG на основе АСД, при этом, исследуется возможность как двоичного так и текстового представления. Потенциально LLM дообучать на расширении Unicode, ассоциируя "смайлики" или дополнительные зарезервированные символы с заданной кодогенерацией.

Рис. 37. Визуализация взаимодействия между ассемблером и ЯВУ
Рис. 37. Визуализация взаимодействия между ассемблером и ЯВУ

В случае использования АСТ нет особой разницы в описании алгоритма с точки зрения реализации на интерпретируемом или компилируемом языке, включая непосредственную кодогенерацию. Система разработки может сама предложить использовать интерпретируемые вставки. Также это касается регулярных выражений - для коротких и статических возможно использование компилируемых значений, для изменяемых, динамических, или длинных - подключать библиотеку-интерпретатор регулярных выражений. Это же касается и кода. Пользователь может отметить компилируемые и интерпретируемые участки а система может исходя из анализа данных сгенерировать необходимую реализацию. Разумеется, данная модификация будет известна пользователю, система расставляет атрибуты для дерева реализующего тот или иной подход. Пример интерпретируемых или компилируемых фрагментов представлен на рис. 38. Семантически данные участки кода могут быть выделены отдельными линиями, цветом, бэкграундом и др. Может также быть использован "скетч" кода, содержащий описание данных без указания имени, система сама назначит имя переменной. Важным является также то, что ИИ может использовать подобного рода инструменты (model generated tools) непосредственно для работы с данными, расширяя свои возможности по контекстному окну, например, давая отдельные команды для рефакторинга или синтеза описания данных-классов и что особенно важно для локальных и глобальных тестов.

38. Взаимодействие компилируемых и интерпретируемых единиц
38. Взаимодействие компилируемых и интерпретируемых единиц

На рис. 39 представлены дополнительные атрибуты, которые используются для промежуточного представления, будь то компилятор C/C++ или LLVM. Атрибутами являются настройки по конкретной реализации двоичного исполняемого кода на процессоре, GPU, ином вычислителе. Например, в данном случае оптимизация общая, или по быстроте исполнения, также может быть

Рис. 39. Атрибуты к элементам АСД управления компилятором
Рис. 39. Атрибуты к элементам АСД управления компилятором

На рис. 40 представлен механизм версионирования. Главным постулатом является код≠программа. Изменение комментария ≠ изменение программы. Это более общий случай ad-hoc полиморфизма, заключающегося в перегрузке имён функций. Помимо непосредственно имени функции есть её реализующий алгоритм, номер версии, дата создания, выбор варианта для компиляции, то есть выбор по дополнительным атрибутам по ходу заданных значений. Например, перегрузка версий означает, что выбирается наиболее свежая, при необходимости - указывается в коде заданное значение. В этом случае отпадает механизм git, так как отслеживается непосредственно изменение класса, функции, данных, комментариев и иных сущностей предметной области, в то время как классические инструменты более заточены на контроле изменений файла и текста. Там же контроль на основе UUID, таймстемпов, хешей и др. с нативной поддержкой многопользовательской среды. push-pull превращается в некий аналог чата нежели почтовую переписку.

Рис. 40. Механизмы версионирования
Рис. 40. Механизмы версионирования

На рис. 41 изображены механизмы тестирования. Они тесно связаны с версиями, при этом, современные инструменты их поддерживают весьма слабо, на языковом уровне это лишь макросы и прочие assertion которые нагромождают строки кода а также дополнительные файлы вроде test1, test2 которым иногда надо делать rm/del, создавая мешанину. В предлагаемом варианте тест - неотъемлемая часть кода, включая промпт-инжиниринг, где слово "протестируй" является триггером серии действий. На примере изображена визуализация теста, его параметры, входные и выходные данные, версию теста, тестируемые переменные, граничные условия, исходные данные, версии исходных данных и их источник. В процессе тестирования полученные результаты могут быть вновь легко повторно использованы для самой программы, как это обычно бывает. Различные генераторы шрифтов, текстур легко получают резульат в непосредственно объектном виде и используют тут же в коде минуя .dat .csv, буфер обмена и прочие tmp-сущности. Причём, доступ к этим данным открыт в IDE, их можно легко экспортировать, сериализировать в облако, спросить про них у ИИ, применить парсер и др. с полной визуализаций и утилит для визуализации данных, включая двусвязные списки, деревья как было сказано выше. Тест оборачивает локально функцию, область видимости и даже данные и их описание, например, можно статически проверить что класс содержит только ADC0...ADC7 вместо ...ADC15, можно проверить сколько статических переменных будет в стеке, сколько в инициализируемой памяти, сколько в куче.

Рис. 41. Тестирование, содержащее версии кода, данных, тестов
Рис. 41. Тестирование, содержащее версии кода, данных, тестов

На рис. 42 изображены настраиваемые механизмы наследования. Как было отмечено выше, они образуют таблицы виртуальных функций, для рекурсивных функций - управление стеком. Представлены формы реализации в виде массивов указателей на функции или цепочек switch-case, включая идентификаторы классов, которые можно использовать для сериализации, например, при передаче структурированных данных по UART, где можно сразу же сделать протокол для передачи данных и методов с наследованием.

Рис. 42 Механизмы ООП под контролем
Рис. 42 Механизмы ООП под контролем

На рис. 43 представлена взаимосвязь между АСД и генерируемым по АСД кодом для целевой платформы. С используется как удобный платформо-независимый ассемблер, включая его же расширение до CUDA/OpenMP/OpenCL и другие. Составляется таблица привязок по именным и двоичными дентификатором. Для разделения элементов АСД и компилятора используются классические комментарии с формируемым текстом. Следует отметить, что в этом случае убираются лишние пробелы, табуляции, свойственные для прочтения человеком и не имеющим значения для машинно-ориентированного формата.

Рис. 43. Пример вывода кода целевой платформы и его согласование с АСД
Рис. 43. Пример вывода кода целевой платформы и его согласование с АСД

На рис. 44 изображен механизм "обёртки" функций. Декораторы могут быть в том числе и для данных, формирующие предикаты. Обёртка визуализируется в прямом смысле как, например, внешняя оболочка и в основном используется для протоколов, стеков, тестов. Осуществляется полный контроль по передаче аргументов и синтаксические "зависания", пользователь использует правило - меняю в данном месте, меняется везде. Система сама отслеживает по АСД какие элементы связаны и редактирует по цепочке, минуя текстовый поиск-замену.

Рис. 44 - встраиваемый атрибут функции "обёртка"
Рис. 44 - встраиваемый атрибут функции "обёртка"

На рис. 45 изображено "наследование" функций. В этом случае функцию легко разбить на две и более мелких сущностей непосредственно с согласованием аргументов, возвращаемых значений а также параллельных вставок. Она может быть разбита по месту, визуально сокращая это действие, затем, функции могут быть объединены под пространством имён или иной группировкой, включая отправку в класс или статический/глобальный метод. Разбитие с использование АСД позволяет полностью проконтролировать поток данных и избежать влияние синтаксиса и ошибок с этим связанным. Фактически функция - это образование локальной области видимости {} со стеком с копированием или непосредственным обращением к внешним данным (аргументам).

Рис. 45. Редактирование функций - разбиение с использованием обхода АСД
Рис. 45. Редактирование функций - разбиение с использованием обхода АСД

На рис. 46 представлен расширенный функционал буфера обмена для работы прямо... в самом буфере обмена, их может быть несколько и они визуализируют также хорошо своё содержимое как и всё остальное. Фактически он неотделим от IDE и может быть использован как своя собственная область видимости содержащая скопированные и вставленные функции, переменные с той разницей что они все являются контекстно независимыми и локальными. Можно просматривать рисунки, данные, копировать часть алгоритма, текст. Скопировать в скопированное и др. Настраиваемый буфер обмена тем самым является многоуровневым и протоколируемым, можно задать отмену не только глобально но и по месту изменений. Отмена и возврат, буфер обмена сохраняемые и при восстановлении сессии можно точно также использовать Ctrl+Z для вчерашних изменений. Маска буфера обмена позволяет избирательно копировать код, текст, комментарии, рисунки и другие элементы на экране, включая быстрый скриншот фрагментов диалогов, фона, кода и его экспорт в буфер как png/jpg или plain text.

Рис. 46 - Функционал локального буфера обмена
Рис. 46 - Функционал локального буфера обмена

На рис. 47 показана концепция код анализирующий код. Где по месту реализуются макросы, которые позволяют проанализировать структуру кода согласно наличию или отсутствию элементов в виде полей, имён функций, двоичных значений, заранее заданных шаблонов, имён классов и принятых условных обозначений, любых других "захардкоженных" сущностей. В этом случае можно избежать магических значений, тщательно их задокументировать задав дополнительные в АСД атрибуты, не только заранее заданные по умолчанию в виде документации и комментария. Наподобие того как это делается в свойствах элементов САПР электроники - можно добавить к резистору поле допуска, наименование, поставщик, ТУ... и др. Можно также генерировать имена конкатенацией, для совсем ленивых - использовать локальное окружение алгоритма для генерации осмысленного имени переменной с помощью ИИ.

Рис. 47 - Кодогенерация для проверки, анализ кода с использованием кода
Рис. 47 - Кодогенерация для проверки, анализ кода с использованием кода

На рис. 48 представлены возможные гипотетические сервисы обеспечивающие комфорт и удобство не только для кода но и для вайбкодинга, включая звонок агенту ИИ, лайки под кодом, полностью многопользовательская среда для кода с визуализацией, аккаунты, удалённый доступ, отложенные изменения, планировщик заданий, диаграммы Ганта согласованные с "git" АСД, нормоконтроль, документооборот, тестирование, соответствие стандартам, регламентам, требованиям. Также, раздельная визуализация синтаксиса позволяет оптимизировать код для компьютера, планшета или телефона, убирая лишние скобки-запятые, ставя индексы для быстрого просмотра без потери смысла. Создаются условия для рейтинга кода, его просмотров, монетизации контента, возможность обмена качественного кода датасетов на токены для ИИ.

Рис. 48 Сетевые сервисы, взаимодействие, командная разработка
Рис. 48 Сетевые сервисы, взаимодействие, командная разработка

На рис. 49 представлена концепция точек останова. С использованием АСД она существенно расширяется, не привязана к синтаксису, может быть проставлена на начальное условие (i=0), условие выполнение (i<0), инструкцию после тела цикла (i++), например, то есть в двумерном пространстве кода. Благодаря жёсткой связке можно также это сделать для ассемблера и восходя до АСД визуализируя эффект конкретной инструкции на более высокоуровневые данные. В этом случае, благодаря описанию регистровой машины можно избежать отсутствия данных даже при -O3 (оптимизация) значений "optimized" спрятанных в регистрах или даже флагах или периферии. Точка остановки может быть как на инструкциях так и на данных, включая стоп по условию, а также на пайпах, сокетах, исключениях, состояний периферии, позволяя отладить протоколы или взаимодействие с ОС, назначая event, включая описание этого события небольшим скриптом (сборная точка отладки по нескольким событиям). Как для синхронных так и для асинхронных (многопоточных)

Рис. 49 Версии точек остановки, дополнительные атрибуты для отладки алгоритмов и данных
Рис. 49 Версии точек остановки, дополнительные атрибуты для отладки алгоритмов и данных

=>=

Далее рассматриваются концепции реализации АСД, которые могут быть использованы в связке с ИИ.
На рис. 50 представлена токенизация АСД. Осуществляется преобразование АСД в векторное представление, необходимое для обучения БЯМ. Осуществляется запись опкодов, их описания, комментариев, специальных маркеров-датасетов в качестве единой базы для последующего обучения, fine-tuning или RAG. В качестве примера - используются комментарии, также координаты расположения элементов кода, порядок выполнения в алгоритме, опкоды виртуальной машины АСД, текстовые элементы. В качестве ошибки - разница между матрицей, образуемой промптом, комментариями, и матрицей, состоящей из текстового вывода а также опкодов виртуальной машины и порядка. Это отличается от обычного текстового вывода LLM (БЯМ). Таким образом, для обучения необходим также двоичный ввод-вывод модели вместе с текстовым. Возможно также использование Unicode для унификации представления опкодов. Комплексный ввод-вывод позволяет существенно увеличить использование контекстного окна, например, для генерации алгоритмов, где в качестве выхода используется компактный формат виртуальной машины.

Рис. 50. Токенизация дерева
Рис. 50. Токенизация дерева

На рис. 51. представлена альтернатива, когда АСД не обучена двоичному выводу, однако, с использованием RAG можно в рамках заданного контекстного окна формировать необходимые элементы АСД на основе имеющегося хорошо известного языка, например, С. С использованием промпт-инъекций добавлять необходимые поля для восстановления АСД а также корректировать его целостность. Гипотетически, грамматика для вывода АСД может быть сведена к последовательности LISP-конструкций или шаблонных C-фраз, что может быть эффективным при непосредственной генерации АСД с использованием БЯМ.

Рис. 51. Использование широко известного языка программирования с БЯМ и АСД
Рис. 51. Использование широко известного языка программирования с БЯМ и АСД

На рис. 52 представлен возможный путь токенизации за счёт применения изменений. Изменения являются дополнением к опкодам и описывают полный diff изменения дерева, включая обратные инструкции вычитание-сложение, умножение-деление и др. Таким образом diff является обратимым на уровне инструкций и работает в обе стороны. В этом случае можно описать последовательность изменений и сделать на основе него обучающую выборку. Благодаря этому, можно создавать более "рассуждающую" модель кода, использовать математическую индукцию и создать для БЯМ элементы строгости для проверки вывода на основе внутренней модели переменных состояния этой виртуальной машины, которая, потенциально, может стать частью модели. Таким образом, виртуальная машина представляется сигнальной моделью в виде 8/16 битных операций с весами нейронов и функцией активации. Наиболее сложные модели - с элементами состояния, когда нейрон использует значение его предыдущее значение (непрерывно или дискретно).

Рис. 53 Отслеживание изменений как контекст
Рис. 53 Отслеживание изменений как контекст

На рис. 53 представлено полное взаимодействие между промптом, АСД и кодом, предлагаемое как первичное решение. Используются ембеддеры для опкодов виртуальной машины, текстов, позволяя тем самым оценить сходство алгоритма с текстом выраженного как АСД и наоборот. Возможно по-началу будут использованы обычные текстовые опкоды вместо двоичных. Для реализации обратной трансляции из кода в АСД используется Clang, включая возможности по рефакторингу С-кода, а также вывод GCC с параметрами
AST_DUMP_FLAG = -fdump-tree-original-raw или другими, отражающими GENERIC/GIMPLE, например, -fdump-tree-gimple и многие другие. В зависимости от задачи флаги могут комбинироваться чтобы улучшить парсер дерева для тех или иных целей.

Рис. 54 Взаимодействие между БЯМ и АСД с использованием промежуточной кодогенерации
Рис. 54 Взаимодействие между БЯМ и АСД с использованием промежуточной кодогенерации

На рис. 54 представлена возможная реализация дополнений к АСД, позволяющие реализовывать дополнения к неизвестному коду, при этом, структурно сохраняя основной. В этом случае важным является отсутствие ошибок или наличие "заглушек", позволяющих избежать некорректное поведения кода, обычно обозначаемого "TBD" - будет определён позднее. Таким образом, АСД позволяет гораздо более безопасно реализовать аддоны, перспективные участки кода, также сигнализировать о незавершённости или уходе кода "в пустоту". По аналогии с САПР электроники это ведущие в никуда печатные проводники, не присоединённые выводы, неправильный класс выводов, например, сигнальный-питание и др. Точно также и с кодом. По скану АСД можно создать документацию с применением "чанкования" текстовых ассоциированных данных и осуществить быстрый поиск промптами "где я не завершил код", "найти участки для дальнейшего развития".

Рис. 54. Разметка кода и неопределённый код, базы дополненной выборки
Рис. 54. Разметка кода и неопределённый код, базы дополненной выборки

На рис 55 представлен механизм подсказок и автодополнений к коду на основе БЯМ, включая базу знаний или эмбеддеры. В этом случае модель может подставить фрагмент АСД, снабдив его дополнительными комментариями. См. выше про комплексный вывод модели, помимо текста, двоичные значения для построения АСД соответствующего целевому алгоритму. В этом случае БЯМ позволяет сформировать большее количество кода чем просто в текстовом виде, включая краткие комментарии или шаблоны. Также, анализ АСД и кодогенерации уже непосредственно компилятором может отыскать ошибки, которые являются обратной связью для БЯМ, например, на уровне отсутствующих переменных, намеренных ошибок в генерированном коде для их обнаружения компилятором, также, включая цели построения датасетов для дообучения. Запросы осуществляются по MCP или иным каналам взаимодействия.

Рис. 55. Автодополнение на основе обратной связи и базы знаний БЯМ
Рис. 55. Автодополнение на основе обратной связи и базы знаний БЯМ

Рис. 56 - подсказки на системном уровне. Каждая из них имеет реализацию в АСД и представлена также в виде него.

Рис. 56. Опережая пользователя
Рис. 56. Опережая пользователя

Основные выводы.

Редактор на основе АСД:

  • код является результатом визуализацией абстрактного синтаксического дерева (АСД) программы по заданным правилам на экране, включая правила по взаимодействию с ним пользователя

  • код является свободным от синтаксиса, пользователь может задать дополнения к нему или изменить целиком

  • АСД внутренне представлено в виде узлов-опкодов операций и дескрипторов данных величиной 8 бит для возможного использования при обучению синтезу алгоритмов больших языковых моделей (БЯМ) или просто ИИ

  • редактирование АСД осуществляется путём взаимодействия с узлами и связями между ними, система разбита на уровни отклика по времени пользователю, позволяя работать с большими проектами

  • кодогенерация осуществляется с использованием мета-языка на основе С/Python, имеющего комментарии, имена переменных и иные инъекции, обеспечивающие обратную связь к системе и АСД

  • исследуется возможность непосредственной генерации АСД с использованием БЯМ, включая необходимые промпт-инъекции и базы данных дополненной выборки

  • исследуется токенизация АСД для дообучения или полного обучения БЯМ с целью синтеза данных и алгоритмов непосредственно из промпта в АСД и векторный вывод БЯМ (текстово-двоичный) с необходимыми атрибутами как дополнение к MCP

Комментарии (0)