Здравствуйте, Gaperton, Вы писали:
G>...
G>Подходы, пнимаешь... Я то делаю как?
G>G>-module( node ).
G>new() -> nil.
G>cycle( _ ) ->
G> out( c, in( a ) + in( b ) ),
G> nil.
G>
G>Вот это — двухвходовой сумматор. Модель событий с именоваными входами и выходами, с асинхронной посылкой и блокирующим получением, с множественной подпиской. Подписка на входы делается так
G>G>connect( Source, Out, Destination, In )
G>
G>где имена входов и выходов — атомы. Что, впрочем, не обязательно
.
G>...
Интересный подход. Что-то наподобие dataflow переменных получается. Так может имеет смысл взглянуть на язык где эти перемнные уже реализованы. Например Mozart\Oz. В CTM кстати есть пример подобного симулятора цифровых цепей. Собственно вот код оттуда:
fun {GateMaker F}
fun {$ Xs Ys}
fun {GateLoop Xs Ys}
case Xs#Ys of {X|Xr}#{Y|Yr} then {F X Y}|{GateLoop Xr Yr} end
end
in
thread {GateLoop Xs Ys} end
end
end
AndG = {GateMaker fun {$ X Y} X*Y end}
OrG = {GateMaker fun {$ X Y} X+Y-X*Y end}
XorG = {GateMaker fun {$ X Y} X+Y-2*X*Y end}
% Теперь можно описать схему состоящую из нескольких элементов. Например сумматор. Он имеет три входа и два выхода.
proc {FullAdder X Y Z ?C ?S}
K L M
in
K = {AndG X Y}
L = {AndG Y Z}
M = {AndG X Z}
C = {OrG K {OrG L M}
S = {XorG Z {XorG X Y}}
end
% Использование
declare
X=1|1|0|_
Y=0|1|0|_
Z=1|1|1|_
{FullAdder X Y Z C S}
{Browse inp(X Y Z)#sum(C S)}
Тут каждый элемент работает в своем изолированном потоке (логическом — аналог процессов в Erlang), а для обмена данными используются dataflow переменные. Т.е. когда вычисление натыкается на переменную которой еще не присвоено значение, поток временно приостанавливается, а когда переменная получает значение (в другом потоке, конечно) то вычисление автоматически возобновляется. Связи между элементами описываются вполне наглядно — просто одна и таже переменная в одном случае служит выходом, а в другом входом.
--
Mikl