From 998be76e347dd286ebc672c5a724b5e929761a55 Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Wed, 20 May 2026 08:02:03 +0200 Subject: [PATCH] csys: clean-up, use comprehensions instead of reduce; + synapse operation: multiply --- lib/csys/csys.ex | 19 ++++++++----------- lib/csys/program.ex | 18 +++++++++++------- test/csys_test.exs | 7 +------ 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/lib/csys/csys.ex b/lib/csys/csys.ex index d7f42f1..34d2b29 100644 --- a/lib/csys/csys.ex +++ b/lib/csys/csys.ex @@ -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 - nil -> nil - val -> op.(val) + fn msg -> + for op <- ops, reduce: msg do + nil -> nil + val -> op.(val) + end end end end diff --git a/lib/csys/program.ex b/lib/csys/program.ex index 493b8c7..a3591b3 100644 --- a/lib/csys/program.ex +++ b/lib/csys/program.ex @@ -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 diff --git a/test/csys_test.exs b/test/csys_test.exs index 4bbdee8..2340ffe 100644 --- a/test/csys_test.exs +++ b/test/csys_test.exs @@ -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