//============================================================================= // Примеры, описанные в третьем разделе материалов по // функционально-параллельному программированию //============================================================================= //-------------------------------------------------------------------- // Функция, возвращающая произведение вектора на скаляр. // С подробными комментариями //.................................................................... // Примеры данных: // ((3,5.9,6,4),7) //.................................................................... // VecScalMult << funcdef Param // Формат аргумента: ((x1, x2, … xn), y), // где ((x1, x2, … xn)- числовой вектор, y - числовой скаляр { // Выделение из списка параметров первого элемента - // вектора и обозначение его идентификатором X X << Param:1; // Выделение из списка параметров второго элемента - // скаляра и обозначение его идентификатором y y << Param:2; // Определение длины вектора и обозначение полученного // значения идентификатором Len Len << X:|; // Формирование вектора длины Len путем дублирования скаляра // y Len раз и обозначение его идентификатором V V << (y,Len):dup; // Объединение двух векторов X и Y в двухстрочную матрицу ((X,V) // Транспонирование полученной матрицы // в список двухэлементных подсписков :# // Преобразование полученного списка в параллельный :[] // Параллельное выполнение операции умножения над всеми // парами, охват полученного параллельного списка круглыми //скобками и выход из функции в возвратом полученного списка :*)>>return } //-------------------------------------------------------------------- // Функция, возвращающая произведение вектора на скаляр. // Без комментариев. //.................................................................... // Примеры данных: // ((3,5.9,6,4),7) //.................................................................... // VecScalMultNoComment << funcdef Param // Формат аргумента: ((x1, x2, … xn), y), // где ((x1, x2, … xn)- числовой вектор, y - числовой скаляр { X << Param:1; y << Param:2; Len << X:|; V << (y,Len):dup; ((X,V):#:[]:*) >>return } //-------------------------------------------------------------------- // Функция, возвращающая произведение вектора на скаляр, // написанная с использованием минимального числа операторов //.................................................................... // Примеры данных: // ((3,5.9,6,4),7) //.................................................................... // VecScalMultBrief << funcdef Param // Формат аргумента: ((x1, x2, : xn), y), // где ((x1, x2, : xn)- числовой вектор, y - числовой скаляр { ((Param:1,(Param:2,Param:1:|):dup):#:[]:*) >>return } //-------------------------------------------------------------------- // Функция, параллельно находящая сумму, разность, // произведение и частное двух чисел - элементов // двухэлементного списка аргументов //.................................................................... // Примеры данных: // (3, 5) //.................................................................... // ParAddSubMultDiv << funcdef Param // Формат аргумента: (число, число), { // Осуществляем параллельное нахождение суммы, // разности, произведения и частного двух чисел // с возвращением списка результатов (Param:[+,-,*,/]) >>return } //-------------------------------------------------------------------- // Функция, возвращающая абсолютное значение аргумента //.................................................................... // Примеры данных: // 3 // -5 // 0 //.................................................................... // Abs << funcdef Param // Аргумент является числом { // Задержанное выражение, результат которого - // аргумент с изменённым знаком ({Param:-}, // Второй аргумент не нуждается в задержке, // поскольку не влечёт никаких вычислений Param): // Параллельное сравнение аргумента функции с нулём на // "меньше" и "больше либо равно" с последующим охватом // результата круглыми скобками [(Param,0):(<,=>) // Преобразование списка булевских скалярных величин в // список целочисленных констант, значения которых // соответствуют позициям булевских величин, имеющих // значение "истина". Поскольку условия "меньше" и "больше // либо равно" исключают друг друга, то результатом данной // операции будет целочисленная константа, имеющая // значение, равное 1 или 2, соответствующее первому или // второму элементу списка задержанных вычислений. // Применение этой константы к списку задержанных вычислений // повлечёт за собой выбор соответствующего элемента, но // раскрытия задержки не произойдёт, пока не будет предпринята // попытка интерпретации задержанного элемента :?] // Раскрытие задержки и завершение функции с возвратом // результата :. >>return }; //-------------------------------------------------------------------- // Функция, возвращающая абсолютное значение аргумента //.................................................................... // Примеры данных: // 3 // -5 // 0 //.................................................................... // Abs2 << funcdef Param // Аргумент является числом { ({Param:-}, Param):[(Param,0):(<,=>) :?]:. >>return } //-------------------------------------------------------------------- // Функция, возвращающая сумму элементов вектора //.................................................................... // Примеры данных: // (3, -5, 0, 6, 7) //.................................................................... // VecSum << funcdef Param // Формат аргумента: (x1, x2, … , xn) // где x1, x2, … , xn - числа { // Обозначим длину вектора идентификатором Len Len<]):?]^ ( // Первый элемент списка задержанных выражений: при длине // аргумента меньшей двух преобразуем одноэлементный список // в параллельный, что приводит к выделению его единственного // элемента {Param:[]}, // Аргумент имеет длину 2, поэтому просто суммируем // его элементы {Param:+}, // Третий элемент списка задержанных вычислений реализован // в виде блока, поскольку для удобочитаемости и наглядности // записи данного задержанного выражения были использованы // идентификаторы. { block { // Идентификатором OddVec обозначен список данных, // составленный из нечётных элементов аргумента OddVec << Param:[(1,Len,2):..]; // Идентификатором EvenVec обозначен список данных, // составленный из чётных элементов аргумента EvenVec << Param:[(2,Len,2):..]; // Оба списка объединяются в параллельный список над // которым выполняется функция суммирования элементов // списка, что приводит к параллельному рекурсивному // выполнению этой функции ([OddVec,EvenVec]: VecSum // Результаты параллельного выполнения двух // экземпляров функции VecSum суммируются ):+ // Осуществляется выдача результата из блока >>break } // конец блока } // конец задержанного списка ) } //-------------------------------------------------------------------- // Функция, возвращающая сумму элементов вектора //.................................................................... // Примеры данных: // (3, -5, 0, 6, 7) //.................................................................... // VecSum2 << funcdef Param // Формат аргумента: (x1, x2, … , xn) // где x1, x2, … , xn - числа { Len<]):?]^ ( {Param:[]}, {Param:+}, { block { OddVec << Param:[(1,Len,2):..]; EvenVec << Param:[(2,Len,2):..]; ([OddVec,EvenVec]: VecSum):+ >>break } // конец блока } // конец задержанного списка ) } //-------------------------------------------------------------------- // Функция, осуществляющая декомпозицию списка с последующим // вычислением функции, переданной в качестве второго параметра. //.................................................................... // Примеры данных: // ((3, -5, 0, 6, 7),+) //.................................................................... // BinTreeReduction << funcdef Param // Формат аргумента: (x1, x2, … , xn) // где x1, x2, … , xn - элементы обрабатываемого вектора // f - обрабатывающая функция { Len << Param:1:|; // длина списка-аргумента Func << Param:2; // Переданная функция return<< .^[((Len,2):[<,=,>]):?]^ ( {Param:1:[]}, // Первый элемент при длине меньшей двух {Param:1:Func}, // Свертка с использованием параметра-функции { // Блок, определяющий рекурсивные вычисления block { // нечетные элементы OddVec << Param:1:[(1,Len,2):..]; // четные элементы EvenVec << Param:1:[(2,Len,2):..]; // Рекурсивная параллельная декомпозиция со сверткой ([(OddVec,Func),(EvenVec,Func)]: BinTreeReduction):Func >>break} // конец блока } // конец третьего задержанного аргумента ) // конец всех альтернатив } //-------------------------------------------------------------------- // Выбор минимального значения для // двухэлементного числового вектора //.................................................................... // Примеры данных: // (3, -5) //.................................................................... // Min << funcdef Param // Формат аргумента: (число1, число2) { Param:[Param:(<=,>):?] >>return }; //-------------------------------------------------------------------- // Суммирование абсолютных значений // двухэлементного числового вектора //.................................................................... // Примеры данных: // (3, -5) //.................................................................... // AbsAdd << funcdef Param // Формат аргумента: (число1, число2) { [Param:1,Param:2]:(Abs):+ >>return }; //-------------------------------------------------------------------- // Функция, тестирующая различные варианты // параметров-функций в BinTreeReduction //.................................................................... // Примеры данных: // (3, -5, -1, 6, 7) //.................................................................... // BinTreeReductionTest << funcdef Param // Формат аргумента: (x1, x2, : , xn) // где x1, x2, : , xn - числа { ( (Param,+):BinTreeReduction, (Param,*):BinTreeReduction, (Param,Min):BinTreeReduction, (Param,AbsAdd):BinTreeReduction )>>return }