diff --git a/lib/csys/program.ex b/lib/csys/program.ex index 18c4aca..90f958b 100644 --- a/lib/csys/program.ex +++ b/lib/csys/program.ex @@ -3,11 +3,16 @@ defmodule Scopes.CSys.Program do alias Scopes.Shape defmodule State do - defstruct [:value, :stage, :prog] + defstruct [:value, :threshold, :stage, :prog] end - def prepare(prog, value \\ []) do - state = %State{value: value, stage: :initial, prog: prog} + def prepare(prog, args) do + state = %State{ + value: args[:value], + threshold: args[:threshold], + stage: :initial, + prog: prog + } {state, get_proc(state)} end @@ -37,8 +42,8 @@ defmodule Scopes.CSys.Program do {stages, transitions} end - def prepare_basic(value \\ []) do - prepare(basic_prog(), value) + def prepare_basic(args \\ [value: 0, threshold: 0]) do + prepare(basic_prog(), args) end # basic processors @@ -53,11 +58,12 @@ defmodule Scopes.CSys.Program do def basic(msg, scope) do case Shape.head(msg) do + [:csys, :set | _rest] -> set(msg, scope) + #[:csys, :data | rest] -> process_data(rest, Shape.data(msg), scope) [:csys, :connect | _rest] -> CSys.connect(msg, scope) [:csys, :create, :succ | _rest] -> create_succ(msg, scope) [:csys, :create, :pred | _rest] -> create_pred(msg, scope) #[:csys, :next | _rest] -> next(scope, meta) - #[:csys, :data | rest] -> process_data(rest, Shape.data(msg), scope) #[:csys, action | rest] -> transition(action, scope) _ -> CSys.forward(msg, scope) || CSys.notify(msg, scope) end @@ -65,6 +71,15 @@ defmodule Scopes.CSys.Program do # message handlers // proc steps + def set(msg, scope) do + data = Shape.data(msg) + state = CSys.state(scope) + value = data[:value] || state.value + threshold = data[:threshold] || state.threshold + state_n = %{state | value: value, threshold: threshold} + CSys.update(put_elem(scope, 0, state_n)) + end + def create_succ(msg, scope) do new = CSys.create(msg, restart(scope)) data = Shape.data(msg) @@ -77,6 +92,15 @@ defmodule Scopes.CSys.Program do CSys.send_message(new, [:csys, :connect], Map.put(data, :target, self())) end +# synapse operations + + def negate() do + fn msg -> + value = Shape.data(msg)[:value] || 0 + Shape.create(Shape.head(msg), data: %{Shape.data(msg) | value: -value}) + end + end + # helper functions def restart({state, _proc, syns, env}) do diff --git a/test/csys_test.exs b/test/csys_test.exs index ef80b44..8c1eac6 100644 --- a/test/csys_test.exs +++ b/test/csys_test.exs @@ -24,22 +24,25 @@ defmodule Scopes.CSysTest do test "minimal-neural-net" do _env = Environ.setup(Program.prepare_basic()) zero = receive_data([:csys, :created]).new - CSys.send_value(zero, "Hello Zero!") - assert "Hello Zero!" = receive_data().value - CSys.send_message(zero, [:csys, :create, :pred], %{op: neg_only()}) - new1 = receive_data([:csys, :created]).new - CSys.send_message(new1, [:csys, :create, :succ], %{op: CSys.data_only()}) - new2 = 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: Program.negate()}) + one = receive_data([:csys, :created]).new + CSys.send_message(one, [:csys, :create, :succ], %{op: CSys.data_only()}) + two = receive_data([:csys, :created]).new Process.sleep(1) - CSys.send_value(new1, "Hello New1!") - assert "Hello New1!" = receive_data().value - CSys.send_message(new2, [:csys, :create, :pred]) - new3 = receive_data([:csys, :created]).new - CSys.send_message(new3, [:csys, :connect], %{target: zero}) + CSys.send_value(one, 1) + #assert 1 = receive_data().value + assert Enum.member?([-1, 1], receive_data().value) + assert Enum.member?([-1, 1], receive_data().value) + CSys.send_message(two, [:csys, :create, :pred]) + three = receive_data([:csys, :created]).new + CSys.send_message(three, [:csys, :connect], %{target: zero}) Process.sleep(1) - CSys.send_value(new3, "Hello New3!") - assert "Hello New3!" = receive_data().value - assert "Hello New3!" = receive_data().value + CSys.send_value(three, 3) + assert 3 = receive_data().value + assert 3 = receive_data().value Process.sleep(50) refute_received msg, "unhandled message(s): #{inspect(msg)}" end