pub struct CausalEffectPropagationProcess<Value, State, Context, Error, Log> { /* private fields */ }Expand description
The fundamental unit of causal computation in DeepCausality.
CausalEffectPropagationProcess encapsulates the state of a computation moving through a causal
graph. It unifies value propagation, state management, context awareness, error handling, and
comprehensive logging into a single, monadic structure.
§Concepts
- Outcome: The value/control-XOR-error channel —
Result<CausalEffect<Value>, Error>, theExcept E (Free CausalCommand (Maybe T))encoding. On the success side a process carries aCausalEffect<Value>— a value,None, or a control command (RelayTo); on the failure side it carries an error, never both: the W-invariant (error present ⇒ no value) holds by construction, not by discipline. - State: Persistent data that evolves as the process moves through the graph (Markovian state).
- Context: Read-only configuration or environment data available to all steps.
- Error: A failure state that short-circuits further computation but preserves logs.
- Logs: An append-only history of every step, essential for auditability and explainability.
§Rationale
In complex causal reasoning, it is not enough to just know the final result. We must know how that result was reached, what invalid states were encountered, and what context was active. This struct implements the Monad pattern to handle these concerns automatically, allowing users to focus on the domain logic (“Business Logic”) rather than plumbing (error checking, logging).
Because value and error live in ONE channel, the three monad laws (left identity, right
identity, associativity) hold unconditionally — including on errored carriers — and the
error short-circuit is a left zero (bind(raise e, f) = raise e, f never runs). This is
precondition P2 of the Causal Algebra program
(openspec/notes/archive/causal-algebra/Formalization.md §2), machine-checked in
lean/DeepCausalityFormal/Core/CausalMonad.lean.
All fields are private; construct via new (total — every representable state
is valid) or the named constructors, decompose via into_parts, and read
via the getters in getters.rs.
Implementations§
Source§impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>where
Log: LogAddEntry,
impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>where
Log: LogAddEntry,
Sourcepub fn clear_context(self) -> Self
pub fn clear_context(self) -> Self
Clear the carried context to None — the absence-setting counterpart to
alternate_context, whose codomain is Some(_)
only. Resolves the gap where a context set mid-chain could never be removed again.
Symmetric contract with alternate_context: a no-op on an errored carrier (an alternation
cannot repair a broken chain), value/state preserved, and one !!ContextCleared!! audit
entry appended on success so the substitution is recorded.
Source§impl<Value: Debug, Error: Debug, Log: Debug + Display + LogSize> CausalEffectPropagationProcess<Value, (), (), Error, Log>
impl<Value: Debug, Error: Debug, Log: Debug + Display + LogSize> CausalEffectPropagationProcess<Value, (), (), Error, Log>
Sourcepub fn explain(&self) -> String
pub fn explain(&self) -> String
Generates a human-readable explanation of the causal computation’s history.
This method iterates over the accumulated logs, providing a comprehensive history of the computation, including the final value and any errors.
§Returns
A String containing the formatted explanation.
Source§impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Sourcepub const fn outcome(&self) -> &Result<CausalEffect<Value>, Error>
pub const fn outcome(&self) -> &Result<CausalEffect<Value>, Error>
The effect-XOR-error channel: a CausalEffect (value or command), or the error that ended
the computation.
Sourcepub fn value(&self) -> Option<&Value>
pub fn value(&self) -> Option<&Value>
The carried scalar, if the process holds a value effect.
This is the everyday accessor: it lends Some(&v) only when the process carries an ordinary
value, and None for an errored process, a None effect, or a command effect. Reach for
value_cloned / into_value for the value by
value, and effect / command_target to discriminate.
Sourcepub fn value_cloned(&self) -> Option<Value>where
Value: Clone,
pub fn value_cloned(&self) -> Option<Value>where
Value: Clone,
The carried scalar cloned out, if the process holds a value effect.
The borrowing, owned-result counterpart to value; the non-consuming
counterpart to into_value.
Sourcepub fn effect(&self) -> Option<&CausalEffect<Value>>
pub fn effect(&self) -> Option<&CausalEffect<Value>>
The carried CausalEffect (value or command), or None if the process holds an error.
Yields the whole effect so callers can discriminate value / none / command (via
CausalEffect::is_command etc.). Most callers want the plain scalar instead: use
value. An errored process has no effect to lend — effect and error are one
channel (the W-invariant, by construction).
Sourcepub fn command_target(&self) -> Option<usize>
pub fn command_target(&self) -> Option<usize>
The target causaloid index if this process carries a RelayTo command effect, else None.
pub const fn state(&self) -> &State
pub const fn context(&self) -> &Option<Context>
Sourcepub fn error(&self) -> Option<&Error>
pub fn error(&self) -> Option<&Error>
The error that ended the computation, or None if the process carries a value.
pub const fn logs(&self) -> &Log
Source§impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Source§impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Sourcepub const fn new(
outcome: Result<CausalEffect<Value>, Error>,
state: State,
context: Option<Context>,
logs: Log,
) -> Self
pub const fn new( outcome: Result<CausalEffect<Value>, Error>, state: State, context: Option<Context>, logs: Log, ) -> Self
Total constructor over the single-channel representation.
With value-XOR-error encoded as one Result, every combination of arguments is a
valid process — there is nothing to validate and no way to construct the formerly
representable invalid state (value AND error).
Sourcepub fn into_parts(
self,
) -> (Result<CausalEffect<Value>, Error>, State, Option<Context>, Log)
pub fn into_parts( self, ) -> (Result<CausalEffect<Value>, Error>, State, Option<Context>, Log)
Decomposes the process into its channels: (outcome, state, context, logs).
The inverse of new; the by-value counterpart to the getters.
Sourcepub fn into_value(self) -> Option<Value>
pub fn into_value(self) -> Option<Value>
Consumes the process and returns the carried scalar, if any.
This is the terminal “give me the result value” accessor: it yields Some(v) only when
the process carries a value effect, and None for an errored process, a None effect, or a
command. It is the by-value counterpart to value, and mirrors
CausalEffect::into_value. Use it at the end of a chain
when you want the plain value out for display or comparison rather than a reference.
Source§impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Sourcepub fn bind<F, NewValue>(
self,
f: F,
) -> CausalEffectPropagationProcess<NewValue, State, Context, Error, Log>where
F: FnOnce(CausalEffect<Value>, State, Option<Context>) -> CausalEffectPropagationProcess<NewValue, State, Context, Error, Log>,
pub fn bind<F, NewValue>(
self,
f: F,
) -> CausalEffectPropagationProcess<NewValue, State, Context, Error, Log>where
F: FnOnce(CausalEffect<Value>, State, Option<Context>) -> CausalEffectPropagationProcess<NewValue, State, Context, Error, Log>,
Chains a stateful, context-aware computation.
This is the primary method for building Markovian process chains, as the
function f receives the value, state, and context from the previous step.
Error short-circuits as a left zero: on an errored process, f is NOT invoked and the
process is returned reassembled verbatim (error, state, context, and logs preserved),
which is what makes right identity bind(m, pure) = m hold unconditionally.
Source§impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Sourcepub fn with_state(
effect: CausalEffectPropagationProcess<Value, (), (), Error, Log>,
initial_state: State,
initial_context: Option<Context>,
) -> Self
pub fn with_state( effect: CausalEffectPropagationProcess<Value, (), (), Error, Log>, initial_state: State, initial_context: Option<Context>, ) -> Self
Lifts a stateless effect into a stateful process by providing an initial state and context.
This is the primary entry point for starting a stateful computation chain from a simple, pre-existing effect.
§Arguments
effect: The statelessPropagatingEffect(where State and Context are()).initial_state: The starting state for the new process.initial_context: The optional starting context for the new process.
§Returns
A new CausalEffectPropagationProcess ready for stateful operations.
Source§impl<Value, State, Context> CausalEffectPropagationProcess<Value, State, Context, CausalityError, EffectLog>
impl<Value, State, Context> CausalEffectPropagationProcess<Value, State, Context, CausalityError, EffectLog>
Sourcepub fn from_error(err: CausalityError) -> Self
pub fn from_error(err: CausalityError) -> Self
Creates a new process that explicitly contains an error. The state is set to default.
Sourcepub fn none() -> Self
pub fn none() -> Self
Creates a new process carrying the None effect (absence of evidence), default state, no error.
Sourcepub fn fmap<NewValue, F>(
self,
f: F,
) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, EffectLog>where
F: FnOnce(Value) -> NewValue,
pub fn fmap<NewValue, F>(
self,
f: F,
) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, EffectLog>where
F: FnOnce(Value) -> NewValue,
Maps the carried value with f, preserving state, context, and logs.
The fluent Functor operation on the carrier. It is total: it delegates to the total
CausalEffect::map, so a value maps its leaf (Some(v) → Some(f(v))), a None passes
through, and a command is preserved — its sub-program’s value leaf is mapped through the
RelayTo tree, so the command survives with its target intact. It never panics and never
manufactures an error; an errored carrier short-circuits (f not invoked, error + logs
preserved).
This is the functor, not the monad: bind is a value-level Kleisli step whose
continuation needs a value, so — unlike fmap — it cannot run under a command and the
reasoning engine folds commands (via CausalEffect::fold) before bind sees them. Hence
fmap f and bind(pure ∘ f) coincide on the value fragment but diverge on a command (fmap
preserves it; bind defers it).
Sourcepub fn from_effect(effect: CausalEffect<Value>) -> Self
pub fn from_effect(effect: CausalEffect<Value>) -> Self
Creates a new process from a given CausalEffect. The state is set to default.
pub fn from_value(value: Value) -> Self
Sourcepub fn from_effect_with_log(
effect: CausalEffect<Value>,
logs: EffectLog,
) -> Self
pub fn from_effect_with_log( effect: CausalEffect<Value>, logs: EffectLog, ) -> Self
Creates a new process from a given CausalEffect and EffectLog. State set to default.
pub fn from_value_with_log(value: Value, logs: EffectLog) -> Self
Sourcepub fn relay_to(target: usize, input: CausalEffect<Value>) -> Self
pub fn relay_to(target: usize, input: CausalEffect<Value>) -> Self
Creates a control-carrier process: a RelayTo(target, input) adaptive-reasoning jump.
Default state, no context, empty log.
Source§impl<Value, State, Context, Log> CausalEffectPropagationProcess<Value, State, Context, CausalityError, Log>
impl<Value, State, Context, Log> CausalEffectPropagationProcess<Value, State, Context, CausalityError, Log>
Sourcepub fn bind_or_error<F, NewValue>(
self,
f: F,
err_msg: &str,
) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, Log>where
F: FnOnce(Value, State, Option<Context>) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, Log>,
pub fn bind_or_error<F, NewValue>(
self,
f: F,
err_msg: &str,
) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, Log>where
F: FnOnce(Value, State, Option<Context>) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, Log>,
Chains a computation while automatically unwrapping the inner value effect.
If the effect is None, this method short-circuits with a CausalityError
containing the provided err_msg. This simplifies the common pattern of:
bind -> match effect_value { Some(v) => f(v), None => Error }
On an errored process, the continuation is NOT invoked (left zero).
Trait Implementations§
Source§impl<Value, State, Context, Error, Log> AlternatableContext<Context> for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> AlternatableContext<Context> for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Source§fn alternate_context(self, new_context: Context) -> Self
fn alternate_context(self, new_context: Context) -> Self
new_context, preserving the rest
of the chain.Source§impl<Value, State, Context, Error, Log> AlternatableState<State> for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> AlternatableState<State> for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Source§fn alternate_state(self, new_state: State) -> Self
fn alternate_state(self, new_state: State) -> Self
new_state, preserving the rest of
the chain.Source§impl<Value, State, Context, Error, Log> AlternatableValue<Value> for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value, State, Context, Error, Log> AlternatableValue<Value> for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Source§fn alternate_value(self, new_value: Value) -> Self
fn alternate_value(self, new_value: Value) -> Self
new_value, preserving the rest of
the chain.Source§impl<Value, State, Context> CausalMonad for CausalEffectPropagationProcess<Value, State, Context, CausalityError, EffectLog>where
State: Default,
impl<Value, State, Context> CausalMonad for CausalEffectPropagationProcess<Value, State, Context, CausalityError, EffectLog>where
State: Default,
Source§fn pure(value: Value) -> Self
fn pure(value: Value) -> Self
Source§fn bind<NewValue, F>(
self,
f: F,
) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, EffectLog>where
F: FnOnce(CausalEffect<Value>, State, Option<Context>) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, EffectLog>,
fn bind<NewValue, F>(
self,
f: F,
) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, EffectLog>where
F: FnOnce(CausalEffect<Value>, State, Option<Context>) -> CausalEffectPropagationProcess<NewValue, State, Context, CausalityError, EffectLog>,
Source§impl<Value: Clone, State: Clone, Context: Clone, Error: Clone, Log: Clone> Clone for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
impl<Value: Clone, State: Clone, Context: Clone, Error: Clone, Log: Clone> Clone for CausalEffectPropagationProcess<Value, State, Context, Error, Log>
Source§fn clone(
&self,
) -> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
fn clone( &self, ) -> CausalEffectPropagationProcess<Value, State, Context, Error, Log>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more