- •Общее
- •О языке
- •Встроенные функции
- •Операции композиции
- •Типы данных
- •Описание программы
- •Процесс выполнения функциональной программы
- •Вызов программы
- •Полный пример программы
- •Интерпретатор и компилятор языка FPTL
- •Кластерный интерпретатор
- •Как достигается автоматический поиск переносимых ФП?
- •Как мы находим мемоизуемые ФП?
- •Как мы поддерживаем любое кол-во машин в кластере и процессоров на машине?
- •Массивы в языке FPTL
- •Компилятор программ языка FPTL
- •Характеристики компилятора
- •Тесты компилятора
- •Вычисление интеграла с заданной точностью
- •Тест рекурсии из комплекта тестов с сайта http://shootout.alioth.debian.org/gp4/benchmark.php?test=recursive&lang=all
- •Вычисление значения N-ого числа Фибоначчи на типе данных Nat
- •Разделение строки на лексемы
- •Приложение – тексты тестовых программ
- •Вычиcление интеграла с заданной точностью – Java
- •Вычиcление интеграла с заданной точностью – FPTL
- •Тест рекурсии - Java
- •Тест рекурсии – FPTL
- •Вычисление значения N-ого числа Фибоначчи на типе данных Nat – Java
- •Вычисление значения N-ого числа Фибоначчи на типе данных Nat – FPTL
- •Разделение строки на лексемы – Java
- •Разделение строки на лексемы – FPTL
Вычисление значения N-ого числа Фибоначчи на типе данных Nat
Вычисление числа 26-го числа Фибоначчи на типе чисел Nat, для которого определены функции nul (аналог нуля) и succ (следующее число). Так, например, число 2 в этом типе чисел выглядит как nul.succ.succ. Программа сначала переводит свой аргумент из обычных чисел в тип Nat, затем вычисляет указанное число Фибоначчи, используя арифметику над типом Nat, а затем переводит полученный результат из типа Nat обратно в обычные числа.
Компилируемый код: 0.25 сек
Интерпретируемый код: 3.969 сек (мемоизовалась функция F)
Разделение строки на лексемы
Не так давно популярный на rsdn тест по повторяемому в цикле один миллион раз разделению строки "123 345 asdf 23453 asdfas" на лексемы пробелами, и суммированию колва получившихся лексем.
Компилируемый код: 2.968 сек
Интерпретируемый код:7.08 сек (для 100 000 итераций. Для миллиона итераций интерпретатор уходит в своп и дождаться результата не представляется возможным).
Приложение – тексты тестовых программ
Вычиcление интеграла с заданной точностью – Java
package fptl.decompiler.Generated;
import ComputingBlock.InternalForm.Data.*; import java.util.*;
public class Test implements Runnable
{
public void run()
{
System.out.println("Compiled:" + integ(0.0, 1.0, 9.99999993922529E-9));
}
private double integ(double arg0, double arg1, double arg2)
{
double var9 = (arg0 + arg1) / (double)2; double var18 = (arg0 + arg1) / (double)2;
if (Math.abs((((((var9 - arg0) * ((var9 * var9) + (arg0 * arg0))) / (double)2) + (((arg1 - var18) * ((arg1 * arg1) + (var18 * var18))) / (double)2)) -
(((arg1 - arg0) * ((arg1 * arg1) + (arg0 * arg0))) / (double)2))) < arg2)
{
return ((arg1 - arg0) * ((arg1 * arg1) + (arg0 * arg0))) / (double)2;
}
else
{
return integ(arg0, (arg0 + arg1) / (double)2, arg2 / (double)2) + integ((arg0 + arg1) / (double)2, arg1, arg2 / (double)2);
}
}
}
Вычиcление интеграла с заданной точностью – FPTL
Functional Program integ
Scheme integ
{
@= ((((I(1,3)*MID).TRP * (MID*I(2,3)).TRP).plus * (I(1,3)*I(2,3)).TRP).minus.abs * I(3,3)).lt ->
(I(1,3)*I(2,3)).TRP,
(((I(1,3)*MID*(I(3,3)*<2>).div).@ * (MID*I(2,3)*(I(3,3)*<2>).div).@).plus);
MID = ((I(1,3)*I(2,3)).plus*<2>).div;
TRP = (((I(2,2)*I(1,2)).minus*(I(2,2).F*I(1,2).F).plus).mult*<2>).div; F = (id*id).mult;
}
Application
%integ(0.0, 10.0, 0.00000001)
Тест рекурсии - Java
package fptl.decompiler.Generated;
import ComputingBlock.InternalForm.Data.*; import java.util.*;
public class Test implements Runnable
{
public void run()
{
System.out.println("Compiled:" + gentoo());
}
private ParamClass0 gentoo()
{
return new ParamClass0(ACK(3, 11), FIBD(38.0), TAK(30, 20, 10), FIB(3), TAKD(3.0, 2.0, 1.0));
}
private int ACK(int arg0, int arg1)
{
while (!(arg0 == 0))
{
if (arg1 == 0)
{
int argTemp0 = arg0 - 1; int argTemp1 = 1;
arg0 = argTemp0; arg1 = argTemp1;
}
else
{
int argTemp0 = arg0 - 1;
int argTemp1 = ACK(arg0, arg1 - 1); arg0 = argTemp0;
arg1 = argTemp1;
}
}
return arg1 + 1;
}
private double FIBD(double arg0)
{
return FIBD_TAILREC(arg0, 1.0);
}
private double FIBD_TAILREC(double arg0, double arg1)
{
while (true)
{
if (arg0 < 2.0) break;
double argTemp0 = arg0 - 2.0;
double argTemp1 = arg1 + FIBD(arg0 - 1.0); arg0 = argTemp0;
arg1 = argTemp1;
}
return arg1;
}
private int TAK(int arg0, int arg1, int arg2)
{
while (!(arg1 >= arg0))
{
int argTemp0 = TAK(arg0 - 1, arg1, arg2); int argTemp1 = TAK(arg1 - 1, arg2, arg0); int argTemp2 = TAK(arg2 - 1, arg0, arg1); arg0 = argTemp0;
arg1 = argTemp1; arg2 = argTemp2;
}
return arg2;
}
private int FIB(int arg0)
{
return FIB_TAILREC(arg0, 1);
}
private int FIB_TAILREC(int arg0, int arg1)
{
while (true)
{
if (arg0 < 2) break;
int argTemp0 = arg0 - 2;
int argTemp1 = arg1 + FIB(arg0 - 1); arg0 = argTemp0;
arg1 = argTemp1;
}
return arg1;
}
private double TAKD(double arg0, double arg1, double arg2)
{
while (!(arg1 >= arg0))
{
double argTemp0 = TAKD(arg0 - 1.0, arg1, arg2); double argTemp1 = TAKD(arg1 - 1.0, arg2, arg0); double argTemp2 = TAKD(arg2 - 1.0, arg0, arg1); arg0 = argTemp0;
arg1 = argTemp1; arg2 = argTemp2;
}
return arg2;
}
}
class ParamClass0
{
public int field0; public double field1; public int field2; public int field3; public double field4;
public ParamClass0(int lparam0, double lparam1, int lparam2, int lparam3, double lparam4)
{
field0 = lparam0; field1 = lparam1; field2 = lparam2; field3 = lparam3; field4 = lparam4;
}
public String toString()
{
return "(" + field0 + " * " + field1 + " * " + field2 + " * " + field3 + " * " + field4 + ")";
}
}
Тест рекурсии – FPTL
Functional Program gentoo
Scheme gentoo
{
@= ((<3>*<11>).ACK * <38.0>.FIBD * (<30>*<20>*<10>).TAK * <3>.FIB * (<3.0>*<2.0>*<1.0>).TAKD);
ACK = (I(1,2)*<0>).eq -> (I(2,2)*<1>).plus,
(
(I(2,2)*<0>).eq -> (I(1,2).DEC*<1>).ACK,
(
(I(1,2).DEC * (I(1,2)*I(2,2).DEC).ACK).ACK
)
);
DEC = (id*<1>).minus;
DECD = (id*<1.0>).minus;
FIB = (id*<2>).lt -> <1>,
(
((id*<2>).minus.FIB * id.DEC.FIB).plus
);
FIBD = (id*<2.0>).lt -> <1.0>,
(
((id*<2.0>).minus.FIBD * id.DECD.FIBD).plus
);
TAK = (I(2,3)*I(1,3)).ge -> I(3,3),
(
((I(1,3).DEC*I(2,3)*I(3,3)).TAK *
(I(2,3).DEC*I(3,3)*I(1,3)).TAK * (I(3,3).DEC*I(1,3)*I(2,3)).TAK).TAK
);