csys: basically working: process numerical values with adding to state value and checking threshold

This commit is contained in:
Helmut Merz 2026-05-19 16:05:05 +02:00
parent acda4f301f
commit 8eb05caaae
3 changed files with 32 additions and 17 deletions

View file

@ -82,15 +82,13 @@ defmodule Scopes.CSys do
# helpers
def compose(ops) do
fn msg ->
Enum.reduce(ops, msg,
fn op, val ->
case val do
nil -> nil
val -> op.(val)
end
end
)
fn msg -> Enum.reduce(ops, msg, &bind/2) end
end
defp bind(op, val) do
case val do
nil -> nil
val -> op.(val)
end
end
end

View file

@ -1,5 +1,6 @@
defmodule Scopes.CSys.Program do
alias Scopes.CSys
require Logger
alias Scopes.CSys
alias Scopes.Shape
defmodule State do
@ -59,7 +60,7 @@ 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, :data | _rest] -> process_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)
@ -71,6 +72,22 @@ defmodule Scopes.CSys.Program do
# message handlers // proc steps
def process_data(msg, scope) do
data = Shape.data(msg)
state = CSys.state(scope)
value_n = state.value + data.value
Logger.info([data: data.value, state: state.value, threshold: state.threshold])
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}
CSys.update(put_elem(scope, 0, state_n))
else
state_n = %{state | value: value_n}
CSys.update(put_elem(scope, 0, state_n))
end
end
def set(msg, scope) do
data = Shape.data(msg)
state = CSys.state(scope)

View file

@ -27,22 +27,22 @@ defmodule Scopes.CSysTest do
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],
CSys.send_message(zero, [:csys, :create, :pred],
%{op: CSys.compose([CSys.data_only(), 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(one, 1)
assert receive_data().value in [-1, 1]
assert receive_data().value in [-1, 1]
#assert receive_data().value in [-1, 1]
CSys.send_message(two, [:csys, :create, :pred])
three = receive_data([:csys, :created]).new
CSys.send_message(three, [:csys, :connect], %{target: zero})
Process.sleep(2)
CSys.send_value(three, 3)
assert 3 = receive_data().value
assert 3 = receive_data().value
assert receive_data().value in [2, 3]
assert receive_data().value in [2, 3]
Process.sleep(50)
refute_received msg, "unhandled message(s): #{inspect(msg)}"
end