445 lines
17 KiB
Markdown
445 lines
17 KiB
Markdown
# Tripartite Synapse — Pseudocode v10
|
||
|
||
> Companion document: `tripartite_synapse_v10_biology.md` explains the biological
|
||
> meaning of every variable and behavior. This document is the logic only.
|
||
|
||
---
|
||
|
||
## Conventions
|
||
|
||
```
|
||
SCOPE = { DAY, NIGHT }
|
||
CONTEXT = { AP, NOT_AP, bAP, NOT_bAP, CONTINUOUS }
|
||
COMPONENTS = { PRE, POST, DEND, SOMA, AXON, ASTRO }
|
||
|
||
DAY variables
|
||
budget fast resource (energy + consumables), consumed by behavior
|
||
fast_trace local record, decays in ms–s, biases next behavior
|
||
possible_tag accumulates from fast_trace, decays in s–min
|
||
endurance_need accumulates on interrupted local success, decays in s–min
|
||
|
||
DAY→NIGHT bridge
|
||
tag decays in hours; POST: CANDIDATE → STABLE
|
||
|
||
NIGHT variables
|
||
energy assembly ATP, NOT recoverable
|
||
material structural proteins, RECOVERABLE after decay
|
||
structure strength ceiling — READ in DAY, WRITTEN in NIGHT
|
||
budget_ceiling endurance ceiling — READ in DAY, WRITTEN in NIGHT
|
||
|
||
LOCALITY RULE
|
||
every evaluation uses only local state + signals that have arrived.
|
||
no component reads another compartment's internal state.
|
||
```
|
||
|
||
---
|
||
|
||
## Saturating form (used wherever a graded signal drives output)
|
||
|
||
```
|
||
sat(x, K) = x / (K + x)
|
||
```
|
||
|
||
---
|
||
|
||
## Fixed parameters
|
||
|
||
```
|
||
K_release K_AMPA K_Dserine
|
||
Mg_eject Ca_STP Ca_TAG
|
||
elig dop_thr tag_thr tag_expiry
|
||
traj_thr endur_thr
|
||
spillover inactivation overload
|
||
homeostatic_ceiling decay_rate capacity_decay_rate recycle
|
||
|
||
dopamine NE ACh // organism broadcast (external)
|
||
glucose // vascular ceiling (external)
|
||
geometry // dendritic topology (external)
|
||
```
|
||
|
||
---
|
||
---
|
||
# DAY
|
||
|
||
Execution contexts (AP, bAP, CONTINUOUS): run behavior, spend budget, deposit traces.
|
||
Replenishment contexts (NOT_AP, NOT_bAP): competitive refill, ship downstream, decay traces, set tags.
|
||
|
||
---
|
||
|
||
## Pool-filling primitives
|
||
|
||
Two shapes share the core "rise toward a ceiling, bounded by the gap, paying budget":
|
||
|
||
```
|
||
// PRIVATE: fill own pool from own reserve toward own ceiling, at a rate cap
|
||
fill(pool, ceiling, rate_cap, cost, budget):
|
||
amount = min(rate_cap, ceiling - pool)·Δt // bounded by rate AND gap
|
||
pool += amount
|
||
budget -= amount·cost
|
||
|
||
// CONTESTED: fill toward ceiling by a rationed share of a shared supply S
|
||
refill(component c from supply S):
|
||
demand = c.budget_ceiling - c.budget // claim = gap to ceiling
|
||
total = Σ demand over components on S
|
||
factor = min(1, S / (total + ε))
|
||
c.budget += demand × factor // never exceeds ceiling
|
||
S -= demand × factor
|
||
```
|
||
|
||
Choose by source: a pool drawn from a **private reserve** uses `fill`; a pool drawn from a
|
||
**contested shared supply** uses `refill`. The distinction is biologically real — RRP comes
|
||
from the bouton's private reserve pool, while operational budget comes from astrocytic lactate
|
||
that neighbours compete for.
|
||
|
||
---
|
||
|
||
## PRE
|
||
|
||
```
|
||
DAY | AP:
|
||
if pre_budget < release_cost:
|
||
suppress(NT_flux)
|
||
if pre_fast_trace > traj_thr: // LOCAL success: I released strongly
|
||
pre_endurance_need += pre_fast_trace × (1 + retrograde_local)
|
||
exit
|
||
pre_fast_trace += spike_Ca(input_freq); pre_fast_trace *= decay(100ms)
|
||
drive = sat(pre_fast_trace, K_release)
|
||
if RRP > 0:
|
||
NT_flux = RRP × drive
|
||
glutamate += NT_flux·Δt; RRP -= NT_flux·Δt; pre_budget -= NT_flux·fusion_cost
|
||
fill(RRP, pre_structure.slot_ceiling, pre_structure.refill_ceiling, vatpase_cost, pre_budget)
|
||
if glutamate > spillover: drive *= brake // output brake (not a fill)
|
||
|
||
DAY | NOT_AP:
|
||
pre_fast_trace *= decay(100ms); pre_endurance_need *= decay(min)
|
||
refill(pre from astro_lactate[syn] + axon_ship_pre) // contested: lactate + shipment
|
||
fill(RRP, pre_structure.slot_ceiling, pre_structure.refill_ceiling, vatpase_cost, pre_budget)
|
||
if pre_fast_trace > elig: pre_possible_tag += pre_fast_trace
|
||
pre_possible_tag *= decay(s); dopamine *= decay(ms)
|
||
if dopamine > dop_thr and pre_possible_tag > tag_thr:
|
||
pre_tag += dopamine × pre_possible_tag
|
||
pre_tag *= decay(hr)
|
||
```
|
||
|
||
---
|
||
|
||
## POST
|
||
|
||
```
|
||
DAY | NOT_bAP:
|
||
refill(post from astro_lactate[syn] + dend_ship_post)
|
||
|
||
// SOURCE 1 — AMPA: current + small Ca + begins Mg ejection
|
||
a = sat(glutamate, K_AMPA)
|
||
AMPA_current = a × AMPA_surface; Vm += AMPA_current
|
||
post_fast_trace += AMPA_Ca·AMPA_current; post_budget -= AMPA_cost
|
||
|
||
// SOURCE 2 — NMDA: large Ca if local coincidence
|
||
if Vm > Mg_eject and astro_Dserine > thr and glutamate > 0:
|
||
post_fast_trace += NMDA_Ca(glutamate)·rise_speed(); post_budget -= NMDA_cost
|
||
|
||
post_fast_trace *= decay(ms)
|
||
|
||
// CASE 1 — short-term potentiation: fill slots from private reserve (no dopamine)
|
||
// NOT generic fill(): rate is Ca-driven, and the else-branch is the STD consequence
|
||
if post_fast_trace > Ca_STP:
|
||
AMPA_surface = min(AMPA_surface + Ca_insert(post_fast_trace),
|
||
post_structure.slot_ceiling) // private: spine endosomal reserve
|
||
post_budget -= traffic_cost
|
||
else:
|
||
AMPA_surface = max(AMPA_surface - drift·Δt, baseline) // STD = consequence
|
||
|
||
// interrupted success (LOCAL: my Ca was climbing toward a tag)
|
||
if post_budget < req_cost and post_fast_trace > traj_thr and post_fast_trace_rising:
|
||
post_endurance_need += post_fast_trace
|
||
|
||
// CASE 2 — tagging CANDIDATE
|
||
if post_fast_trace > Ca_TAG: post_possible_tag += post_fast_trace
|
||
post_possible_tag *= decay(min); post_endurance_need *= decay(min)
|
||
post_budget -= pka_cost
|
||
dopamine *= decay(ms)
|
||
if dopamine > dop_thr and post_possible_tag > tag_thr:
|
||
post_tag += dopamine × post_possible_tag // STABLE
|
||
post_tag *= decay(hr)
|
||
|
||
DAY | bAP:
|
||
// SOURCE 3 — bAP: depolarization + Ca, amplifies existing signal
|
||
Vm += bAP_depol × dend_structure.bAP_fidelity; post_budget -= bAP_cost
|
||
if post_possible_tag > Ca_TAG: post_fast_trace += bAP_Ca_boost()
|
||
```
|
||
|
||
---
|
||
|
||
## DEND
|
||
|
||
```
|
||
DAY | bAP:
|
||
bAP_local, reached = propagate(SOMA.fired, dend_structure.bAP_fidelity,
|
||
dend_budget, geometry)
|
||
dend_budget -= prop_cost × reached
|
||
// interrupted success (LOCAL: my branch was strongly active)
|
||
if reached < full and dend_fast_trace > traj_thr:
|
||
dend_endurance_need += dend_fast_trace
|
||
dend_fast_trace += bAP_Ca(bAP_local) + spine_spillover(); dend_fast_trace *= decay(300ms)
|
||
dend_budget -= branch_Ca_cost
|
||
branch_Vm = integrate(POST.Vm, spines); dend_budget -= integrate_cost
|
||
|
||
DAY | NOT_bAP:
|
||
dend_fast_trace *= decay(300ms); dend_endurance_need *= decay(min)
|
||
refill(dend from astro_lactate[branch] + soma_ship_dend)
|
||
ship(dend_budget → post_budget, gap_to(post))
|
||
if dend_fast_trace > elig: dend_possible_tag += dend_fast_trace
|
||
dend_possible_tag *= decay(s); dopamine *= decay(ms)
|
||
if dopamine > dop_thr and dend_possible_tag > tag_thr:
|
||
dend_tag += dopamine × dend_possible_tag
|
||
dend_tag *= decay(hr)
|
||
if dend_tag > tag_expiry and dend_budget > translate_cost:
|
||
dend_budget -= translate_cost
|
||
commit_threshold *= 1/(1 + ACh·gain)
|
||
```
|
||
|
||
---
|
||
|
||
## SOMA
|
||
|
||
```
|
||
DAY | AP:
|
||
threshold = soma_structure.baseline / (1) // baseline strength
|
||
× (1 + soma_adaptation)
|
||
× neuromod(NE, ACh)
|
||
can_fire = soma_Na_inactivation < inactivation
|
||
if branch_Vm > threshold and can_fire:
|
||
if soma_budget < ap_cost:
|
||
// interrupted success (LOCAL: nuclear Ca climbing toward CREB)
|
||
if soma_fast_trace > traj_thr and soma_fast_trace_rising:
|
||
soma_endurance_need += soma_fast_trace
|
||
exit
|
||
fired = True; soma_budget -= ap_cost
|
||
soma_Na_inactivation += ap_amp // → refractory (emergent)
|
||
soma_adaptation += ap_contrib // → threshold rise
|
||
soma_fast_trace += nuclear_Ca() // → plasticity
|
||
soma_budget -= nuclear_cost
|
||
if soma_fast_trace > elig: soma_possible_tag += soma_fast_trace
|
||
soma_possible_tag *= decay(s); dopamine *= decay(ms)
|
||
if dopamine > dop_thr and soma_possible_tag > tag_thr:
|
||
soma_tag += dopamine × soma_possible_tag
|
||
soma_tag *= decay(hr); soma_budget -= creb_cost
|
||
|
||
DAY | NOT_AP:
|
||
// bottom-up alignment: suprathreshold input during refractory (LOCAL)
|
||
if branch_Vm > threshold and soma_Na_inactivation > inactivation:
|
||
soma_refractory_alignment += (branch_Vm - threshold) × soma_Na_inactivation
|
||
recovery = base_recovery × (1 + soma_refractory_alignment)
|
||
soma_Na_inactivation *= decay(τ_Na / recovery)
|
||
soma_adaptation *= decay(τ_adapt)
|
||
soma_fast_trace *= decay(τ_nuclear)
|
||
soma_refractory_alignment *= decay(τ_align) // self-limiting
|
||
soma_endurance_need *= decay(min)
|
||
fill(soma_budget, soma_budget_ceiling, mito_output, 0, soma_budget) // private: own mitochondria, no external cost
|
||
branch_Vm = integrate(DEND.branch_Vm, branches)
|
||
ship(soma_budget → dend_budget, gap_to(dend))
|
||
ship(soma_budget → axon_budget, gap_to(axon))
|
||
```
|
||
|
||
---
|
||
|
||
## AXON
|
||
|
||
```
|
||
DAY | AP:
|
||
reliability = axon_structure.propagation × (1 - fail(axon_fast_trace))
|
||
if axon_budget < prop_cost:
|
||
reliability *= budget_factor
|
||
// interrupted success (LOCAL: I was propagating a strong train)
|
||
if axon_fast_trace > traj_thr:
|
||
axon_endurance_need += axon_fast_trace
|
||
delivered = fired × reliability; axon_budget -= prop_cost × delivered
|
||
axon_fast_trace += delivered; axon_fast_trace *= decay(s)
|
||
|
||
DAY | NOT_AP:
|
||
axon_fast_trace *= decay(s); axon_endurance_need *= decay(min)
|
||
refill(axon from soma_ship_axon + astro_lactate[shaft])
|
||
ship(axon_budget → pre_budget, gap_to(pre))
|
||
if axon_fast_trace > elig: axon_possible_tag += axon_fast_trace
|
||
axon_possible_tag *= decay(s); dopamine *= decay(ms)
|
||
if dopamine > dop_thr and axon_possible_tag > tag_thr:
|
||
axon_tag += dopamine × axon_possible_tag
|
||
axon_tag *= decay(hr)
|
||
```
|
||
|
||
---
|
||
|
||
## ASTRO
|
||
|
||
```
|
||
DAY | CONTINUOUS:
|
||
astro_central_budget += glycolysis(glucose)·Δt // root, capped by glucose
|
||
|
||
// demand-weighted lactate allocation across territory
|
||
for each astrosynapse i:
|
||
demand[i] = clearance_load[i] × astro_structure[i].delivery_eff
|
||
factor = min(1, astro_central_budget / (Σ demand · lactate_cost + ε))
|
||
for each i:
|
||
astro_lactate[i] = demand[i] × factor
|
||
astro_central_budget -= astro_lactate[i] × lactate_cost
|
||
|
||
// per-astrosynapse fast operation (synapse i)
|
||
glutamate[i] -= astro_structure[i].EAAT × glutamate[i]·Δt
|
||
astro_central_budget -= clearance × EAAT_cost
|
||
astro_Dserine[i] += astro_structure[i].Dserine_tonic·Δt
|
||
|
||
if glutamate[i] > spillover:
|
||
astro_fast_trace[i] += mGluR_Ca(); astro_fast_trace[i] *= decay(s)
|
||
want = sat(astro_fast_trace[i], K_Dserine) × Ds_max
|
||
got = min(want, astro_central_budget × Ds_frac)
|
||
// interrupted success (LOCAL: I was under high demand)
|
||
if got < want and astro_fast_trace[i] > traj_thr:
|
||
astro_endurance_need[i] += (want - got)
|
||
astro_Dserine[i] += got; astro_central_budget -= got × Ds_cost
|
||
drive_pre[i] *= brake // same signal, PRE brake
|
||
if astro_fast_trace[i] > elig: astro_possible_tag[i] += astro_fast_trace[i]
|
||
astro_possible_tag[i] *= decay(s); dopamine *= decay(ms)
|
||
if dopamine > dop_thr and astro_possible_tag[i] > tag_thr:
|
||
astro_tag[i] += dopamine × astro_possible_tag[i]
|
||
astro_tag[i] *= decay(hr)
|
||
astro_endurance_need[i] *= decay(min)
|
||
if astro_fast_trace[i] > overload: trigger(lockdown)
|
||
```
|
||
|
||
---
|
||
|
||
## Special — Shockwave Lockdown
|
||
|
||
```
|
||
DAY or NIGHT | OVERLOAD:
|
||
Vm = HYPERPOLARIZED; AMPA_surface = mass_internalize() → post reserve
|
||
axon_fast_trace += overdrive(); astro_central_budget -= emergency_cost
|
||
```
|
||
|
||
---
|
||
---
|
||
# NIGHT
|
||
|
||
Build ceilings (structure = strength, budget_ceiling = endurance) from DAY evidence.
|
||
Two economies (energy: astrocyte→astrosynapse ; material: soma→spine/bouton) compete.
|
||
Unmaintained ceilings decay; recovered material funds the rest.
|
||
|
||
---
|
||
|
||
## Step 1 — Replenish and distribute
|
||
|
||
```
|
||
NIGHT | 1:
|
||
// energy economy (astrocyte central → astrosynapses, tag-weighted)
|
||
astro_central_budget += overnight_glycolysis(glucose)·Δt
|
||
astro_central_energy += overnight_astro_energy()·Δt
|
||
astro_central_material += astro_cellbody_synth()·Δt
|
||
W = Σ astro_tag[i] over astro_tag[i] > tag_expiry
|
||
for each i with astro_tag[i] > tag_expiry:
|
||
w = astro_tag[i]/W
|
||
astro_energy[i] += astro_central_energy × w
|
||
astro_material[i] += astro_central_material × w
|
||
|
||
// material economy (soma → branch/axon → spine/bouton)
|
||
soma_budget += overnight_mito()·Δt
|
||
soma_energy += overnight_soma_energy()·Δt
|
||
soma_material += CREB_synth(soma_tag)·Δt // bottleneck
|
||
|
||
dend_material += soma_material × f_dend; axon_material += soma_material × f_axon
|
||
soma_material -= (f_dend + f_axon)·soma_material
|
||
post_material += dend_material × f_spine; dend_material -= f_spine·dend_material
|
||
pre_material += axon_material × f_bouton; axon_material -= f_bouton·axon_material
|
||
|
||
{pre,post,dend,axon}_energy += soma_energy × f_energy[·]
|
||
{pre,post,dend,axon}_budget += astro_lactate_reserve × f[·]·Δt
|
||
```
|
||
|
||
## Step 2 — Strength commits (raise structure)
|
||
|
||
```
|
||
NIGHT | 2:
|
||
coherence = (pre_tag, post_tag, astro_tag all > tag_expiry) ? bonus : 1
|
||
|
||
for each component c with c_tag > tag_expiry:
|
||
Δ = min(slot_cost, c_material, c_energy × f)
|
||
c_structure += Δ × (coherence if c in {pre,post,astro} else 1)
|
||
c_material -= Δ; c_energy -= Δ × assembly_cost
|
||
if Δ < slot_cost: queue(c_strength_deficit → next NIGHT)
|
||
// astro_structure self-reinforcing: higher → future LTP easier
|
||
```
|
||
|
||
## Step 2b — Endurance commits (raise budget_ceiling)
|
||
|
||
```
|
||
NIGHT | 2b:
|
||
// driven by endurance_need (interrupted local success), NO dopamine
|
||
// competes with step 2 for the SAME material + energy
|
||
for each component c with c_endurance_need > endur_thr:
|
||
Δ = min(cap_cost, c_material × f_cap, c_energy × f_cap)
|
||
c_budget_ceiling += Δ
|
||
c_material -= Δ; c_energy -= Δ × biogenesis_cost
|
||
if Δ < cap_cost: queue(c_endurance_deficit → next NIGHT)
|
||
```
|
||
|
||
## Step 3 — Passive decay (both ceilings, by neglect)
|
||
|
||
```
|
||
NIGHT | 3:
|
||
remaining = total_material - consumed_by_commits
|
||
maint = remaining × maint_frac / synapse_count
|
||
|
||
for each synapse:
|
||
{pre,post,dend,astro}_structure -= decay_rate·Δt
|
||
{pre,post,dend,astro}_budget_ceiling -= capacity_decay_rate·Δt
|
||
if maint ≥ maint_cost:
|
||
structure += full_maint; budget_ceiling += full_cap_maint
|
||
else:
|
||
structure += maint × frac; budget_ceiling += maint × cap_frac
|
||
// both drift down — depotentiation / endurance-loss by neglect
|
||
|
||
for each synapse with net_change < 0:
|
||
rec = |net_change| × recycle
|
||
{pre,post,astro}_material += rec × frac // material recovered, energy not
|
||
```
|
||
|
||
## Step 4 — Homeostatic scaling
|
||
|
||
```
|
||
NIGHT | 4:
|
||
if soma_tag > homeostatic_ceiling:
|
||
s = homeostatic_ceiling / soma_tag
|
||
for each synapse:
|
||
post_structure.slot_ceiling *= s; pre_structure.slot_ceiling *= s
|
||
soma_material += Σ reduction × recycle
|
||
```
|
||
|
||
## Step 5 — Clear traces
|
||
|
||
```
|
||
NIGHT | 5:
|
||
all fast_trace = 0; all possible_tag = 0; all endurance_need = 0
|
||
soma_Na_inactivation = soma_adaptation = soma_refractory_alignment = 0
|
||
for each tag: if tag < tag_expiry: tag = 0 // else carry forward
|
||
// structure and budget_ceiling PERSIST
|
||
```
|
||
|
||
---
|
||
|
||
## One-view summary
|
||
|
||
```
|
||
DAY behavior runs within structure (strength) and budget_ceiling (endurance),
|
||
both filled by competition; consumes budget; deposits fast_trace.
|
||
fast_trace + non-local coincidence → tag (strength evidence)
|
||
depletion + interrupted LOCAL success → endurance_need (endurance evidence)
|
||
traces decay in NOT/CONTINUOUS contexts.
|
||
|
||
NIGHT tag → raise structure
|
||
endurance_need → raise budget_ceiling
|
||
both draw the SAME material + energy → strength and endurance compete
|
||
unmaintained ceilings decay → freed material funds the rest.
|
||
|
||
LOCALITY every evaluation uses only local state + arrived signals.
|
||
cross-compartment influence travels only as signals that become local.
|
||
```
|