csys: clean-up, use comprehensions instead of reduce; + synapse operation: multiply

This commit is contained in:
Helmut Merz 2026-05-20 08:02:03 +02:00
parent b5f78355fe
commit 998be76e34
3 changed files with 20 additions and 24 deletions

View file

@ -29,7 +29,8 @@ defmodule Scopes.CSys do
end
def forward(msg, scope) do
Enum.reduce(syns(scope), false, fn s, _acc -> s.(msg); true end)
for s <- syns(scope), reduce: false, do: (_acc -> s.(msg))
#Enum.reduce(syns(scope), false, fn s, _acc -> s.(msg); true end)
end
def create(_msg, scope = {state, proc, _syns, env}) do
@ -40,15 +41,13 @@ defmodule Scopes.CSys do
def connect(msg, {state, proc, syns, env}) do
data = Shape.data(msg)
op = data[:op] || noop()
op = data[:op] || []
syn = synapse(data[:target], op, 0)
update({state, proc, [syn | syns], env})
end
# synapse operations
def noop(), do: fn msg -> msg end
def filter_head(pat) do
fn msg -> if List.starts_with?(Shape.head(msg), pat), do: msg end
end
@ -83,13 +82,11 @@ defmodule Scopes.CSys do
# helpers
def compose(ops) do
fn msg -> Enum.reduce(ops, msg, &bind/2) end
end
defp bind(op, val) do
case val do
fn msg ->
for op <- ops, reduce: msg do
nil -> nil
val -> op.(val)
end
end
end
end

View file

@ -4,13 +4,14 @@ alias Scopes.CSys
alias Scopes.Shape
defmodule State do
defstruct [:value, :threshold, :stage, :prog]
defstruct [:value, :threshold, :bias, :stage, :prog]
end
def prepare(prog, args) do
state = %State{
value: args[:value],
value: args[:bias],
threshold: args[:threshold],
bias: args[:bias],
stage: :initial,
prog: prog
}
@ -43,7 +44,7 @@ alias Scopes.CSys
{stages, transitions}
end
def prepare_basic(args \\ [value: 0, threshold: 0]) do
def prepare_basic(args \\ [threshold: 0, bias: 0]) do
prepare(basic_prog(), args)
end
@ -80,7 +81,7 @@ alias Scopes.CSys
if value_n >= state.threshold do
msg = Shape.create(Shape.head(msg), data: %{data | value: value_n})
CSys.forward(msg, scope) || CSys.notify(msg, scope)
state_n = %{state | value: 0}
state_n = %{state | value: state.bias}
CSys.update(put_elem(scope, 0, state_n))
else
state_n = %{state | value: value_n}
@ -93,7 +94,8 @@ alias Scopes.CSys
state = CSys.state(scope)
value = data[:value] || state.value
threshold = data[:threshold] || state.threshold
state_n = %{state | value: value, threshold: threshold}
bias = data[:bias] || state.bias
state_n = %{state | value: value, threshold: threshold, bias: bias}
CSys.update(put_elem(scope, 0, state_n))
end
@ -111,13 +113,15 @@ alias Scopes.CSys
# synapse operations
def negate() do
def multiply(n) do
fn msg ->
value = Shape.data(msg)[:value] || 0
Shape.create(Shape.head(msg), data: %{Shape.data(msg) | value: -value})
Shape.create(Shape.head(msg), data: %{Shape.data(msg) | value: n * value})
end
end
def negate(), do: multiply(-1)
# helper functions
def restart({state, _proc, syns, env}) do

View file

@ -16,17 +16,12 @@ defmodule Scopes.CSysTest do
Shape.data(receive_select(head))
end
def neg_only() do
fn msg -> if Shape.data(msg)[:value] < 0, do: msg end
end
describe "basic:" do
test "minimal-neural-net" do
_env = Environ.setup(Program.prepare_basic())
zero = receive_data([:csys, :created]).new
CSys.send_value(zero, 0)
assert 0 = receive_data().value
#CSys.send_message(zero, [:csys, :create, :pred], %{op: neg_only()})
CSys.send_message(zero, [:csys, :create, :pred],
%{op: [CSys.data_only(), Program.negate()]})
one = receive_data([:csys, :created]).new
@ -34,7 +29,7 @@ defmodule Scopes.CSysTest do
two = receive_data([:csys, :created]).new
Process.sleep(1)
CSys.send_value(one, 1)
assert receive_data().value in [-1, 1]
assert receive_data().value == 1
#assert receive_data().value in [-1, 1]
CSys.send_message(two, [:csys, :create, :pred])
three = receive_data([:csys, :created]).new