Некоторые сложности обрануживаются в ленивых языках:
fib = 1:1:(zipWith (+) fib (tail fib))
Здесь fib присутствует и в левой и в правой части, то есть мы получаем полноценное уравнение, решением которого будет бесконечная последовательность чисел Фибоначчи. Так как на бесконечных последовательностях естественным образом определяется топология, Haskell может решить это уравнение методом протых итераций (через оператор неподвижной точки).
Еще дальше по пути уравнений пошел Prolog. Каждый предикат определяет уравнение на множествах, хоть и записывается без знака равенства. Решаются такие уравнения почти перебором и возможность использовать в них арифметику сильно ограничена.
Но есть язык, в котором уравнения являются важнейшей частью — это Modelica.
model Point Real x,y; equation end Point; model Line parameter Real len; Point p1,p2; equation len = (p1.x-p2.x)^2 + (p1.y-p2.y)^2; end Line;
Здесь отрезок определяется как координаты концов и длинна, при этом длина и координаты связаны очевидным уравнением.
(К сожалению, source такого языка не знает, а вставить раскрашенный pygment-ом html не получается.)
Естественно, уравнения могут быть объединены в систему:
model Hand Point ph,pl; parameter Real l1,h1,l2,h2; Line ll1(len = l1),lh1(len = h1),ll2(len = l2),lh2(len = h2); Real arcl,arch; Point p; equation ll1.p1 = pl; lh1.p1 = ph; ll1.p2.x = pl.x + l1 * arcl; lh1.p2.x = ph.x + h1 * arch; ll1.p2 = ll2.p1; lh1.p2 = lh2.p1; p = ll2.p2; p = lh2.p2; end Hand;
Здесь описывается манипулятор, состоящий из четырех соединенных шарнирами реек управляемый двумя сервоприводами.
Как следует из названия, Modelica преднозначена для моделирования сложных, гетерогенных систем. Ее реализации есть у знаменитого Вольфрама, производителя САПР (не путать и «чертежными программами») CATIA. Есть также и свободные реализации, такие как OpenModelica.
Так как моделируемые объекты редко описываются алгебраическими уравнениями, Modelica умеет решать и обыкновенные дифференциальные уравнения. К сожалению, уравнения в частных произвожных она пока не осилила, но обычно можно разбить систему на онечные элементы и породить обыкновенные дифуры в цикле.
В качестве примера приведу модель очень сложной гибридной электромеханической системы — Гауссгана:
model Gauss extends Modelica.Electrical.Analog.Interfaces.OnePort; Real x (start = -1); Real sp (start = 0); Real co; Real pw (start = 0); Real ke; Real se; Real pe; equation der(pw) = i*v; ke = sp^2/2; se = i^2/2; pe = pw - ke - se; co = (if abs(x) > 0.2 then (abs(x)*(x^(-5))/3.0) else (x/((0.2^5)*3.0))); der(sp) = -co * i; der(x) = sp; der(i) = v + (co * sp); end Gauss; model Main Modelica.Electrical.Analog.Basic.Ground g; Modelica.Electrical.Analog.Sources.ConstantVoltage ps; Modelica.Electrical.Analog.Basic.Resistor rps; Gauss gun; equation connect(ps.p, g.p); connect(ps.p, gun.p); connect(ps.n, rps.p); connect(rps.n, gun.n); end Main;
Здесь x — координата снаряда, v — напряжение, i — ток. Для отладки вычисляется полная энергия pe — ее график будет горизонтальной прямой.
Кроме текстового представления программы, в Modelica стандартизовано и графическое (хотя лично я предпочитаю работать с текстом). Для повторного использования кода применяется знакомое многим по ООП наследование. Есть обширные библиотеки по этектротехнике, теплотехнике, механике и, даже, биохимии.
Разработчики «Моделик» не расчитывают охватить все одной системой — большенство реализаций допускает комоделирование с помощью Functional Mock-up Interface. При желании этот же интерфейс можно задействовать для взаимодействия с внешним миром, но это пока открытая область.
ссылка на оригинал статьи http://habrahabr.ru/post/202596/
Добавить комментарий