Current section
Files
Jump to
Current section
Files
src/silos/developmental_silo/lc_developmental_events.erl
%%%-------------------------------------------------------------------
%%% @doc Behavioral event constructors for Developmental Silo.
%%%
%%% Events related to ontogeny, critical periods, and plasticity.
%%% Developmental Silo operates at timescale Ï„=40.
%%%
%%% @end
%%%-------------------------------------------------------------------
-module(lc_developmental_events).
-include("lc_developmental_events.hrl").
%% Event constructors
-export([
critical_period_opened/1,
critical_period_closed/1,
plasticity_changed/1,
developmental_stage_reached/1,
metamorphosis_triggered/1,
canalization_increased/1,
heterochrony_detected/1,
developmental_milestone/1
]).
%% Utility exports
-export([
make_meta/1,
make_meta/2,
event_to_map/1
]).
%%% ============================================================================
%%% Metadata Construction
%%% ============================================================================
-spec make_meta(Emitter :: atom()) -> #lc_event_meta{}.
make_meta(Emitter) ->
make_meta(Emitter, #{}).
-spec make_meta(Emitter :: atom(), Opts :: map()) -> #lc_event_meta{}.
make_meta(Emitter, Opts) ->
#lc_event_meta{
event_id = maps:get(event_id, Opts, generate_id()),
correlation_id = maps:get(correlation_id, Opts, undefined),
causation_id = maps:get(causation_id, Opts, undefined),
timestamp = maps:get(timestamp, Opts, erlang:system_time(microsecond)),
version = maps:get(version, Opts, ?LC_EVENT_VERSION),
emitter = Emitter
}.
%%% ============================================================================
%%% Critical Period Event Constructors
%%% ============================================================================
-spec critical_period_opened(map()) -> #critical_period_opened{}.
critical_period_opened(Data) ->
#critical_period_opened{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
period_type = maps:get(period_type, Data, cognitive),
plasticity_boost = maps:get(plasticity_boost, Data),
expected_duration_generations = maps:get(expected_duration_generations, Data)
}.
-spec critical_period_closed(map()) -> #critical_period_closed{}.
critical_period_closed(Data) ->
#critical_period_closed{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
period_type = maps:get(period_type, Data, cognitive),
actual_duration_generations = maps:get(actual_duration_generations, Data),
learning_achieved = maps:get(learning_achieved, Data, 0.0)
}.
%%% ============================================================================
%%% Plasticity Event Constructors
%%% ============================================================================
-spec plasticity_changed(map()) -> #plasticity_changed{}.
plasticity_changed(Data) ->
#plasticity_changed{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
plasticity_before = maps:get(plasticity_before, Data),
plasticity_after = maps:get(plasticity_after, Data),
change_cause = maps:get(change_cause, Data, age)
}.
%%% ============================================================================
%%% Developmental Stage Event Constructors
%%% ============================================================================
-spec developmental_stage_reached(map()) -> #developmental_stage_reached{}.
developmental_stage_reached(Data) ->
#developmental_stage_reached{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
stage_before = maps:get(stage_before, Data),
stage_after = maps:get(stage_after, Data),
age_generations = maps:get(age_generations, Data),
fitness_at_transition = maps:get(fitness_at_transition, Data)
}.
-spec metamorphosis_triggered(map()) -> #metamorphosis_triggered{}.
metamorphosis_triggered(Data) ->
#metamorphosis_triggered{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
stage_before = maps:get(stage_before, Data),
stage_after = maps:get(stage_after, Data),
structural_changes = maps:get(structural_changes, Data, #{neurons_added => 0, connections_rewired => 0}),
fitness_before = maps:get(fitness_before, Data)
}.
%%% ============================================================================
%%% Canalization Event Constructors
%%% ============================================================================
-spec canalization_increased(map()) -> #canalization_increased{}.
canalization_increased(Data) ->
#canalization_increased{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
canalization_before = maps:get(canalization_before, Data),
canalization_after = maps:get(canalization_after, Data),
perturbation_resistance = maps:get(perturbation_resistance, Data)
}.
-spec heterochrony_detected(map()) -> #heterochrony_detected{}.
heterochrony_detected(Data) ->
#heterochrony_detected{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
timing_deviation = maps:get(timing_deviation, Data),
affected_traits = maps:get(affected_traits, Data, []),
fitness_impact = maps:get(fitness_impact, Data, 0.0)
}.
-spec developmental_milestone(map()) -> #developmental_milestone{}.
developmental_milestone(Data) ->
#developmental_milestone{
meta = make_meta(maps:get(emitter, Data, developmental_silo), Data),
individual_id = maps:get(individual_id, Data),
milestone_type = maps:get(milestone_type, Data),
age_generations = maps:get(age_generations, Data),
performance_level = maps:get(performance_level, Data)
}.
%%% ============================================================================
%%% Utility Functions
%%% ============================================================================
-spec event_to_map(developmental_event()) -> map().
event_to_map(Event) when is_tuple(Event) ->
[RecordName | Fields] = tuple_to_list(Event),
FieldNames = record_fields(RecordName),
MetaMap = meta_to_map(hd(Fields)),
DataMap = maps:from_list(lists:zip(tl(FieldNames), tl(Fields))),
maps:merge(#{event_type => RecordName, meta => MetaMap}, DataMap).
%%% ============================================================================
%%% Internal Functions
%%% ============================================================================
generate_id() ->
Bytes = crypto:strong_rand_bytes(16),
binary:encode_hex(Bytes).
meta_to_map(#lc_event_meta{} = Meta) ->
#{
event_id => Meta#lc_event_meta.event_id,
correlation_id => Meta#lc_event_meta.correlation_id,
causation_id => Meta#lc_event_meta.causation_id,
timestamp => Meta#lc_event_meta.timestamp,
version => Meta#lc_event_meta.version,
emitter => Meta#lc_event_meta.emitter
}.
record_fields(critical_period_opened) -> [meta, individual_id, period_type, plasticity_boost, expected_duration_generations];
record_fields(critical_period_closed) -> [meta, individual_id, period_type, actual_duration_generations, learning_achieved];
record_fields(plasticity_changed) -> [meta, individual_id, plasticity_before, plasticity_after, change_cause];
record_fields(developmental_stage_reached) -> [meta, individual_id, stage_before, stage_after, age_generations, fitness_at_transition];
record_fields(metamorphosis_triggered) -> [meta, individual_id, stage_before, stage_after, structural_changes, fitness_before];
record_fields(canalization_increased) -> [meta, individual_id, canalization_before, canalization_after, perturbation_resistance];
record_fields(heterochrony_detected) -> [meta, individual_id, timing_deviation, affected_traits, fitness_impact];
record_fields(developmental_milestone) -> [meta, individual_id, milestone_type, age_generations, performance_level].