active-inference 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +96 -0
- package/dist/beliefs/discrete.belief.d.ts +99 -0
- package/dist/beliefs/discrete.belief.js +121 -0
- package/dist/factory.d.ts +168 -0
- package/dist/factory.js +52 -0
- package/dist/helpers/math.helpers.d.ts +143 -0
- package/dist/helpers/math.helpers.js +168 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/models/agent.model.d.ts +252 -0
- package/dist/models/agent.model.js +330 -0
- package/dist/models/belief.model.d.ts +132 -0
- package/dist/models/belief.model.js +104 -0
- package/dist/models/observation.model.d.ts +76 -0
- package/dist/models/observation.model.js +1 -0
- package/dist/models/transition.model.d.ts +67 -0
- package/dist/models/transition.model.js +1 -0
- package/dist/observation/discrete.observation.d.ts +134 -0
- package/dist/observation/discrete.observation.js +142 -0
- package/dist/transition/discrete.transition.d.ts +139 -0
- package/dist/transition/discrete.transition.js +158 -0
- package/package.json +40 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Belief, Distribution } from './belief.model';
|
|
2
|
+
/**
|
|
3
|
+
* State transition matrix (B matrix in Active Inference notation).
|
|
4
|
+
* Defines P(s'|s, a) - probability of transitioning to state s'
|
|
5
|
+
* given current state s and action a.
|
|
6
|
+
*
|
|
7
|
+
* Structure: action → current_state → next_state → probability
|
|
8
|
+
*
|
|
9
|
+
* @typeParam A - Union type of possible action names
|
|
10
|
+
* @typeParam S - Union type of possible state names
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const B: TransitionMatrix<'move' | 'stay', 'left' | 'right'> = {
|
|
15
|
+
* move: {
|
|
16
|
+
* left: { left: 0.1, right: 0.9 }, // move from left → mostly goes right
|
|
17
|
+
* right: { left: 0.9, right: 0.1 } // move from right → mostly goes left
|
|
18
|
+
* },
|
|
19
|
+
* stay: {
|
|
20
|
+
* left: { left: 1.0, right: 0.0 }, // stay at left
|
|
21
|
+
* right: { left: 0.0, right: 1.0 } // stay at right
|
|
22
|
+
* }
|
|
23
|
+
* };
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export type TransitionMatrix<A extends string = string, S extends string = string> = Record<A, Record<S, Distribution<S>>>;
|
|
27
|
+
/**
|
|
28
|
+
* Interface for state transition models.
|
|
29
|
+
*
|
|
30
|
+
* In Active Inference, the transition model (B) captures the agent's
|
|
31
|
+
* beliefs about how the world state changes in response to actions.
|
|
32
|
+
* It's a key component of the generative model used for planning.
|
|
33
|
+
*
|
|
34
|
+
* The transition model enables:
|
|
35
|
+
* - Predicting future states given current beliefs and actions
|
|
36
|
+
* - Evaluating action sequences (policies) by simulating outcomes
|
|
37
|
+
* - Computing Expected Free Energy for action selection
|
|
38
|
+
*
|
|
39
|
+
* @typeParam A - Union type of possible action names
|
|
40
|
+
* @typeParam S - Union type of possible state names
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* class MyTransition implements ITransitionModel<'up' | 'down', 'top' | 'bottom'> {
|
|
45
|
+
* get actions() { return ['up', 'down'] as const; }
|
|
46
|
+
* predict(belief, action) { // ... return predicted belief }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export interface ITransitionModel<A extends string = string, S extends string = string> {
|
|
51
|
+
/**
|
|
52
|
+
* List of all possible actions the agent can take.
|
|
53
|
+
*/
|
|
54
|
+
readonly actions: A[];
|
|
55
|
+
/**
|
|
56
|
+
* Predict the belief state after taking an action.
|
|
57
|
+
* Computes: P(s') = Σ_s P(s'|s, a) × P(s)
|
|
58
|
+
*
|
|
59
|
+
* This is belief propagation through the transition model,
|
|
60
|
+
* used during planning to simulate future states.
|
|
61
|
+
*
|
|
62
|
+
* @param belief - Current belief over states
|
|
63
|
+
* @param action - Action to simulate
|
|
64
|
+
* @returns Predicted belief after the action
|
|
65
|
+
*/
|
|
66
|
+
predict(belief: Belief<S>, action: A): Belief<S>;
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { Distribution } from '../models/belief.model';
|
|
2
|
+
import { IObservationModel, ObservationMatrix } from '../models/observation.model';
|
|
3
|
+
/**
|
|
4
|
+
* Discrete observation model implementing the A matrix in Active Inference.
|
|
5
|
+
*
|
|
6
|
+
* This class represents P(o|s) - the probability of receiving observation o
|
|
7
|
+
* given the hidden state s. It's a core component of the agent's generative
|
|
8
|
+
* model used for perception and planning.
|
|
9
|
+
*
|
|
10
|
+
* ## Matrix Structure
|
|
11
|
+
*
|
|
12
|
+
* The observation matrix is organized as: `observation → state → probability`
|
|
13
|
+
*
|
|
14
|
+
* For each observation, you specify the probability of that observation
|
|
15
|
+
* occurring given each possible hidden state. Each column (observation
|
|
16
|
+
* conditional on all states) defines a likelihood function.
|
|
17
|
+
*
|
|
18
|
+
* ## Usage in Active Inference
|
|
19
|
+
*
|
|
20
|
+
* The observation model enables:
|
|
21
|
+
* - **Perception**: Bayesian belief updates when observations are received
|
|
22
|
+
* - **Ambiguity computation**: Expected uncertainty about observations
|
|
23
|
+
* - **Policy evaluation**: Predicting what observations actions will cause
|
|
24
|
+
*
|
|
25
|
+
* ## Sensor Accuracy
|
|
26
|
+
*
|
|
27
|
+
* The observation matrix encodes sensor reliability:
|
|
28
|
+
* - Perfect sensor: P(o|s) = 1 for matching state, 0 otherwise
|
|
29
|
+
* - Noisy sensor: Some probability mass spreads to wrong observations
|
|
30
|
+
* - Ambiguous sensor: Multiple states produce similar observations
|
|
31
|
+
*
|
|
32
|
+
* @typeParam O - Union type of possible observation names
|
|
33
|
+
* @typeParam S - Union type of possible state names
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // 90% accurate sensor for detecting danger
|
|
38
|
+
* const observation = new DiscreteObservation({
|
|
39
|
+
* see_safe: { safe: 0.9, danger: 0.1 }, // see_safe mostly in safe state
|
|
40
|
+
* see_danger: { safe: 0.1, danger: 0.9 } // see_danger mostly in danger state
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* // Use for Bayesian update
|
|
44
|
+
* const likelihood = observation.getLikelihood('see_danger');
|
|
45
|
+
* const posterior = belief.update(likelihood);
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @see {@link IObservationModel} - Interface this class implements
|
|
49
|
+
* @see {@link ObservationMatrix} - Type definition for the matrix structure
|
|
50
|
+
*/
|
|
51
|
+
export declare class DiscreteObservation<O extends string = string, S extends string = string> implements IObservationModel<O, S> {
|
|
52
|
+
matrix: ObservationMatrix<O, S>;
|
|
53
|
+
/**
|
|
54
|
+
* Create a discrete observation model from an observation matrix.
|
|
55
|
+
*
|
|
56
|
+
* @param matrix - Observation matrix defining P(o|s) for all observation-state pairs.
|
|
57
|
+
* Structure: observation → state → probability
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const observation = new DiscreteObservation({
|
|
62
|
+
* bright: { light_on: 0.95, light_off: 0.05 },
|
|
63
|
+
* dim: { light_on: 0.05, light_off: 0.95 }
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
constructor(matrix: ObservationMatrix<O, S>);
|
|
68
|
+
/**
|
|
69
|
+
* List of all possible observations in this model.
|
|
70
|
+
*
|
|
71
|
+
* Observations are extracted from the keys of the observation matrix.
|
|
72
|
+
*
|
|
73
|
+
* @returns Array of observation names
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* observation.observations; // ['bright', 'dim']
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
get observations(): O[];
|
|
81
|
+
/**
|
|
82
|
+
* List of all possible hidden states in this model.
|
|
83
|
+
*
|
|
84
|
+
* States are extracted from the first observation's state mappings.
|
|
85
|
+
* Assumes all observations have the same state space.
|
|
86
|
+
*
|
|
87
|
+
* @returns Array of state names
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* observation.states; // ['light_on', 'light_off']
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
get states(): S[];
|
|
95
|
+
/**
|
|
96
|
+
* Get the likelihood function for a specific observation.
|
|
97
|
+
*
|
|
98
|
+
* Returns P(o|s) for all states - this is the key function for
|
|
99
|
+
* Bayesian belief updates during perception.
|
|
100
|
+
*
|
|
101
|
+
* When the agent receives an observation, it uses this likelihood
|
|
102
|
+
* to update its beliefs: P(s|o) ∝ P(o|s) × P(s)
|
|
103
|
+
*
|
|
104
|
+
* @param observation - The observation received
|
|
105
|
+
* @returns Distribution mapping each state to its likelihood
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const likelihood = observation.getLikelihood('see_reward');
|
|
110
|
+
* // { good_state: 0.8, bad_state: 0.1 }
|
|
111
|
+
*
|
|
112
|
+
* // Use for belief update
|
|
113
|
+
* const posterior = belief.update(likelihood);
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
getLikelihood(observation: O): Distribution<S>;
|
|
117
|
+
/**
|
|
118
|
+
* Get the probability of a specific observation given a state.
|
|
119
|
+
*
|
|
120
|
+
* Returns P(o|s) - the probability of observing o when the
|
|
121
|
+
* true hidden state is s.
|
|
122
|
+
*
|
|
123
|
+
* @param observation - The observation
|
|
124
|
+
* @param state - The hidden state
|
|
125
|
+
* @returns Probability between 0 and 1
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* observation.probability('see_safe', 'danger'); // 0.1 (unlikely)
|
|
130
|
+
* observation.probability('see_safe', 'safe'); // 0.9 (likely)
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
probability(observation: O, state: S): number;
|
|
134
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Discrete observation model implementing the A matrix in Active Inference.
|
|
3
|
+
*
|
|
4
|
+
* This class represents P(o|s) - the probability of receiving observation o
|
|
5
|
+
* given the hidden state s. It's a core component of the agent's generative
|
|
6
|
+
* model used for perception and planning.
|
|
7
|
+
*
|
|
8
|
+
* ## Matrix Structure
|
|
9
|
+
*
|
|
10
|
+
* The observation matrix is organized as: `observation → state → probability`
|
|
11
|
+
*
|
|
12
|
+
* For each observation, you specify the probability of that observation
|
|
13
|
+
* occurring given each possible hidden state. Each column (observation
|
|
14
|
+
* conditional on all states) defines a likelihood function.
|
|
15
|
+
*
|
|
16
|
+
* ## Usage in Active Inference
|
|
17
|
+
*
|
|
18
|
+
* The observation model enables:
|
|
19
|
+
* - **Perception**: Bayesian belief updates when observations are received
|
|
20
|
+
* - **Ambiguity computation**: Expected uncertainty about observations
|
|
21
|
+
* - **Policy evaluation**: Predicting what observations actions will cause
|
|
22
|
+
*
|
|
23
|
+
* ## Sensor Accuracy
|
|
24
|
+
*
|
|
25
|
+
* The observation matrix encodes sensor reliability:
|
|
26
|
+
* - Perfect sensor: P(o|s) = 1 for matching state, 0 otherwise
|
|
27
|
+
* - Noisy sensor: Some probability mass spreads to wrong observations
|
|
28
|
+
* - Ambiguous sensor: Multiple states produce similar observations
|
|
29
|
+
*
|
|
30
|
+
* @typeParam O - Union type of possible observation names
|
|
31
|
+
* @typeParam S - Union type of possible state names
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* // 90% accurate sensor for detecting danger
|
|
36
|
+
* const observation = new DiscreteObservation({
|
|
37
|
+
* see_safe: { safe: 0.9, danger: 0.1 }, // see_safe mostly in safe state
|
|
38
|
+
* see_danger: { safe: 0.1, danger: 0.9 } // see_danger mostly in danger state
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* // Use for Bayesian update
|
|
42
|
+
* const likelihood = observation.getLikelihood('see_danger');
|
|
43
|
+
* const posterior = belief.update(likelihood);
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @see {@link IObservationModel} - Interface this class implements
|
|
47
|
+
* @see {@link ObservationMatrix} - Type definition for the matrix structure
|
|
48
|
+
*/
|
|
49
|
+
export class DiscreteObservation {
|
|
50
|
+
/**
|
|
51
|
+
* Create a discrete observation model from an observation matrix.
|
|
52
|
+
*
|
|
53
|
+
* @param matrix - Observation matrix defining P(o|s) for all observation-state pairs.
|
|
54
|
+
* Structure: observation → state → probability
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const observation = new DiscreteObservation({
|
|
59
|
+
* bright: { light_on: 0.95, light_off: 0.05 },
|
|
60
|
+
* dim: { light_on: 0.05, light_off: 0.95 }
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
constructor(matrix) {
|
|
65
|
+
this.matrix = matrix;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* List of all possible observations in this model.
|
|
69
|
+
*
|
|
70
|
+
* Observations are extracted from the keys of the observation matrix.
|
|
71
|
+
*
|
|
72
|
+
* @returns Array of observation names
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* observation.observations; // ['bright', 'dim']
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
get observations() {
|
|
80
|
+
return Object.keys(this.matrix);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* List of all possible hidden states in this model.
|
|
84
|
+
*
|
|
85
|
+
* States are extracted from the first observation's state mappings.
|
|
86
|
+
* Assumes all observations have the same state space.
|
|
87
|
+
*
|
|
88
|
+
* @returns Array of state names
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* observation.states; // ['light_on', 'light_off']
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
get states() {
|
|
96
|
+
const firstObs = this.observations[0];
|
|
97
|
+
return Object.keys(this.matrix[firstObs] || {});
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get the likelihood function for a specific observation.
|
|
101
|
+
*
|
|
102
|
+
* Returns P(o|s) for all states - this is the key function for
|
|
103
|
+
* Bayesian belief updates during perception.
|
|
104
|
+
*
|
|
105
|
+
* When the agent receives an observation, it uses this likelihood
|
|
106
|
+
* to update its beliefs: P(s|o) ∝ P(o|s) × P(s)
|
|
107
|
+
*
|
|
108
|
+
* @param observation - The observation received
|
|
109
|
+
* @returns Distribution mapping each state to its likelihood
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const likelihood = observation.getLikelihood('see_reward');
|
|
114
|
+
* // { good_state: 0.8, bad_state: 0.1 }
|
|
115
|
+
*
|
|
116
|
+
* // Use for belief update
|
|
117
|
+
* const posterior = belief.update(likelihood);
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
getLikelihood(observation) {
|
|
121
|
+
return this.matrix[observation] ?? {};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get the probability of a specific observation given a state.
|
|
125
|
+
*
|
|
126
|
+
* Returns P(o|s) - the probability of observing o when the
|
|
127
|
+
* true hidden state is s.
|
|
128
|
+
*
|
|
129
|
+
* @param observation - The observation
|
|
130
|
+
* @param state - The hidden state
|
|
131
|
+
* @returns Probability between 0 and 1
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* observation.probability('see_safe', 'danger'); // 0.1 (unlikely)
|
|
136
|
+
* observation.probability('see_safe', 'safe'); // 0.9 (likely)
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
probability(observation, state) {
|
|
140
|
+
return this.matrix[observation]?.[state] ?? 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Distribution } from '../models/belief.model';
|
|
2
|
+
import type { Belief } from '../models/belief.model';
|
|
3
|
+
import { ITransitionModel, TransitionMatrix } from '../models/transition.model';
|
|
4
|
+
/**
|
|
5
|
+
* Discrete state transition model implementing the B matrix in Active Inference.
|
|
6
|
+
*
|
|
7
|
+
* This class represents P(s'|s, a) - the probability of transitioning to
|
|
8
|
+
* a new state s' given the current state s and action a. It's a core
|
|
9
|
+
* component of the agent's generative model used for planning.
|
|
10
|
+
*
|
|
11
|
+
* ## Matrix Structure
|
|
12
|
+
*
|
|
13
|
+
* The transition matrix is organized as: `action → current_state → next_state → probability`
|
|
14
|
+
*
|
|
15
|
+
* For each action, you specify how each current state transitions to next states.
|
|
16
|
+
* Each row (current state) should sum to 1.0 (valid probability distribution).
|
|
17
|
+
*
|
|
18
|
+
* ## Usage in Active Inference
|
|
19
|
+
*
|
|
20
|
+
* The transition model enables:
|
|
21
|
+
* - **Planning**: Simulating future states to evaluate action sequences
|
|
22
|
+
* - **Policy evaluation**: Computing Expected Free Energy over time horizons
|
|
23
|
+
* - **State prediction**: Propagating beliefs through time
|
|
24
|
+
*
|
|
25
|
+
* @typeParam A - Union type of possible action names
|
|
26
|
+
* @typeParam S - Union type of possible state names
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Light switch model: actions affect the light state
|
|
31
|
+
* const transition = new DiscreteTransition({
|
|
32
|
+
* turn_on: {
|
|
33
|
+
* dark: { dark: 0.1, light: 0.9 }, // turn_on in dark → 90% light
|
|
34
|
+
* light: { dark: 0.0, light: 1.0 } // turn_on in light → stays light
|
|
35
|
+
* },
|
|
36
|
+
* turn_off: {
|
|
37
|
+
* dark: { dark: 1.0, light: 0.0 }, // turn_off in dark → stays dark
|
|
38
|
+
* light: { dark: 0.9, light: 0.1 } // turn_off in light → 90% dark
|
|
39
|
+
* }
|
|
40
|
+
* });
|
|
41
|
+
*
|
|
42
|
+
* // Predict state after action
|
|
43
|
+
* const currentBelief = new DiscreteBelief({ dark: 1.0, light: 0.0 });
|
|
44
|
+
* const predicted = transition.predict(currentBelief, 'turn_on');
|
|
45
|
+
* // predicted: { dark: 0.1, light: 0.9 }
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* @see {@link ITransitionModel} - Interface this class implements
|
|
49
|
+
* @see {@link TransitionMatrix} - Type definition for the matrix structure
|
|
50
|
+
*/
|
|
51
|
+
export declare class DiscreteTransition<A extends string = string, S extends string = string> implements ITransitionModel<A, S> {
|
|
52
|
+
matrix: TransitionMatrix<A, S>;
|
|
53
|
+
/**
|
|
54
|
+
* Create a discrete transition model from a transition matrix.
|
|
55
|
+
*
|
|
56
|
+
* @param matrix - Transition matrix defining P(s'|s, a) for all state-action pairs.
|
|
57
|
+
* Structure: action → current_state → next_state → probability
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const transition = new DiscreteTransition({
|
|
62
|
+
* move_left: {
|
|
63
|
+
* left: { left: 1.0, right: 0.0 },
|
|
64
|
+
* right: { left: 0.8, right: 0.2 }
|
|
65
|
+
* },
|
|
66
|
+
* move_right: {
|
|
67
|
+
* left: { left: 0.2, right: 0.8 },
|
|
68
|
+
* right: { left: 0.0, right: 1.0 }
|
|
69
|
+
* }
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
constructor(matrix: TransitionMatrix<A, S>);
|
|
74
|
+
/**
|
|
75
|
+
* List of all possible actions in this model.
|
|
76
|
+
*
|
|
77
|
+
* Actions are extracted from the keys of the transition matrix.
|
|
78
|
+
*
|
|
79
|
+
* @returns Array of action names
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* transition.actions; // ['move_left', 'move_right', 'stay']
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
get actions(): A[];
|
|
87
|
+
/**
|
|
88
|
+
* List of all possible states in this model.
|
|
89
|
+
*
|
|
90
|
+
* States are extracted from the first action's state mappings.
|
|
91
|
+
* Assumes all actions have the same state space.
|
|
92
|
+
*
|
|
93
|
+
* @returns Array of state names
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* transition.states; // ['left', 'center', 'right']
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
get states(): S[];
|
|
101
|
+
/**
|
|
102
|
+
* Get the transition distribution for a specific state-action pair.
|
|
103
|
+
*
|
|
104
|
+
* Returns P(s'|s, a) - the probability distribution over next states
|
|
105
|
+
* given the current state and action.
|
|
106
|
+
*
|
|
107
|
+
* @param state - The current state
|
|
108
|
+
* @param action - The action being taken
|
|
109
|
+
* @returns Distribution over next states
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const dist = transition.getTransition('left', 'move_right');
|
|
114
|
+
* // { left: 0.2, right: 0.8 }
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
getTransition(state: S, action: A): Distribution<S>;
|
|
118
|
+
/**
|
|
119
|
+
* Predict the belief state after taking an action.
|
|
120
|
+
*
|
|
121
|
+
* Performs belief propagation through the transition model:
|
|
122
|
+
* P(s') = Σ_s P(s'|s, a) × P(s)
|
|
123
|
+
*
|
|
124
|
+
* This is the core function used during planning to simulate
|
|
125
|
+
* what the agent's beliefs would be after taking an action.
|
|
126
|
+
*
|
|
127
|
+
* @param belief - Current belief distribution over states
|
|
128
|
+
* @param action - Action to simulate
|
|
129
|
+
* @returns Predicted belief after the action
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const current = new DiscreteBelief({ left: 0.8, right: 0.2 });
|
|
134
|
+
* const predicted = transition.predict(current, 'move_right');
|
|
135
|
+
* // Belief shifts toward 'right' based on transition probabilities
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
predict(belief: Belief<S>, action: A): Belief<S>;
|
|
139
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { DiscreteBelief } from '../beliefs/discrete.belief';
|
|
2
|
+
/**
|
|
3
|
+
* Discrete state transition model implementing the B matrix in Active Inference.
|
|
4
|
+
*
|
|
5
|
+
* This class represents P(s'|s, a) - the probability of transitioning to
|
|
6
|
+
* a new state s' given the current state s and action a. It's a core
|
|
7
|
+
* component of the agent's generative model used for planning.
|
|
8
|
+
*
|
|
9
|
+
* ## Matrix Structure
|
|
10
|
+
*
|
|
11
|
+
* The transition matrix is organized as: `action → current_state → next_state → probability`
|
|
12
|
+
*
|
|
13
|
+
* For each action, you specify how each current state transitions to next states.
|
|
14
|
+
* Each row (current state) should sum to 1.0 (valid probability distribution).
|
|
15
|
+
*
|
|
16
|
+
* ## Usage in Active Inference
|
|
17
|
+
*
|
|
18
|
+
* The transition model enables:
|
|
19
|
+
* - **Planning**: Simulating future states to evaluate action sequences
|
|
20
|
+
* - **Policy evaluation**: Computing Expected Free Energy over time horizons
|
|
21
|
+
* - **State prediction**: Propagating beliefs through time
|
|
22
|
+
*
|
|
23
|
+
* @typeParam A - Union type of possible action names
|
|
24
|
+
* @typeParam S - Union type of possible state names
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* // Light switch model: actions affect the light state
|
|
29
|
+
* const transition = new DiscreteTransition({
|
|
30
|
+
* turn_on: {
|
|
31
|
+
* dark: { dark: 0.1, light: 0.9 }, // turn_on in dark → 90% light
|
|
32
|
+
* light: { dark: 0.0, light: 1.0 } // turn_on in light → stays light
|
|
33
|
+
* },
|
|
34
|
+
* turn_off: {
|
|
35
|
+
* dark: { dark: 1.0, light: 0.0 }, // turn_off in dark → stays dark
|
|
36
|
+
* light: { dark: 0.9, light: 0.1 } // turn_off in light → 90% dark
|
|
37
|
+
* }
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* // Predict state after action
|
|
41
|
+
* const currentBelief = new DiscreteBelief({ dark: 1.0, light: 0.0 });
|
|
42
|
+
* const predicted = transition.predict(currentBelief, 'turn_on');
|
|
43
|
+
* // predicted: { dark: 0.1, light: 0.9 }
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @see {@link ITransitionModel} - Interface this class implements
|
|
47
|
+
* @see {@link TransitionMatrix} - Type definition for the matrix structure
|
|
48
|
+
*/
|
|
49
|
+
export class DiscreteTransition {
|
|
50
|
+
/**
|
|
51
|
+
* Create a discrete transition model from a transition matrix.
|
|
52
|
+
*
|
|
53
|
+
* @param matrix - Transition matrix defining P(s'|s, a) for all state-action pairs.
|
|
54
|
+
* Structure: action → current_state → next_state → probability
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const transition = new DiscreteTransition({
|
|
59
|
+
* move_left: {
|
|
60
|
+
* left: { left: 1.0, right: 0.0 },
|
|
61
|
+
* right: { left: 0.8, right: 0.2 }
|
|
62
|
+
* },
|
|
63
|
+
* move_right: {
|
|
64
|
+
* left: { left: 0.2, right: 0.8 },
|
|
65
|
+
* right: { left: 0.0, right: 1.0 }
|
|
66
|
+
* }
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
constructor(matrix) {
|
|
71
|
+
this.matrix = matrix;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* List of all possible actions in this model.
|
|
75
|
+
*
|
|
76
|
+
* Actions are extracted from the keys of the transition matrix.
|
|
77
|
+
*
|
|
78
|
+
* @returns Array of action names
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* transition.actions; // ['move_left', 'move_right', 'stay']
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
get actions() {
|
|
86
|
+
return Object.keys(this.matrix);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* List of all possible states in this model.
|
|
90
|
+
*
|
|
91
|
+
* States are extracted from the first action's state mappings.
|
|
92
|
+
* Assumes all actions have the same state space.
|
|
93
|
+
*
|
|
94
|
+
* @returns Array of state names
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* transition.states; // ['left', 'center', 'right']
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
get states() {
|
|
102
|
+
const firstAction = this.actions[0];
|
|
103
|
+
return Object.keys(this.matrix[firstAction] || {});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the transition distribution for a specific state-action pair.
|
|
107
|
+
*
|
|
108
|
+
* Returns P(s'|s, a) - the probability distribution over next states
|
|
109
|
+
* given the current state and action.
|
|
110
|
+
*
|
|
111
|
+
* @param state - The current state
|
|
112
|
+
* @param action - The action being taken
|
|
113
|
+
* @returns Distribution over next states
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const dist = transition.getTransition('left', 'move_right');
|
|
118
|
+
* // { left: 0.2, right: 0.8 }
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
getTransition(state, action) {
|
|
122
|
+
return this.matrix[action]?.[state] ?? {};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Predict the belief state after taking an action.
|
|
126
|
+
*
|
|
127
|
+
* Performs belief propagation through the transition model:
|
|
128
|
+
* P(s') = Σ_s P(s'|s, a) × P(s)
|
|
129
|
+
*
|
|
130
|
+
* This is the core function used during planning to simulate
|
|
131
|
+
* what the agent's beliefs would be after taking an action.
|
|
132
|
+
*
|
|
133
|
+
* @param belief - Current belief distribution over states
|
|
134
|
+
* @param action - Action to simulate
|
|
135
|
+
* @returns Predicted belief after the action
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const current = new DiscreteBelief({ left: 0.8, right: 0.2 });
|
|
140
|
+
* const predicted = transition.predict(current, 'move_right');
|
|
141
|
+
* // Belief shifts toward 'right' based on transition probabilities
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
predict(belief, action) {
|
|
145
|
+
const newDist = {};
|
|
146
|
+
for (const state of this.states) {
|
|
147
|
+
newDist[state] = 0;
|
|
148
|
+
}
|
|
149
|
+
for (const currentState of belief.states) {
|
|
150
|
+
const transition = this.getTransition(currentState, action);
|
|
151
|
+
const currentProb = belief.probability(currentState);
|
|
152
|
+
for (const nextState of Object.keys(transition)) {
|
|
153
|
+
newDist[nextState] += transition[nextState] * currentProb;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return new DiscreteBelief(newDist);
|
|
157
|
+
}
|
|
158
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "active-inference",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Active Inference Framework implementation for JavaScript/TypeScript",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "vitest run",
|
|
12
|
+
"test:watch": "vitest",
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"active-inference",
|
|
18
|
+
"free-energy",
|
|
19
|
+
"bayesian",
|
|
20
|
+
"agent",
|
|
21
|
+
"friston",
|
|
22
|
+
"ai",
|
|
23
|
+
"machine-learning"
|
|
24
|
+
],
|
|
25
|
+
"author": "Igor Rybakov <codevanger@gmail.com>",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/codevanger/active-inference"
|
|
30
|
+
},
|
|
31
|
+
"bugs": {
|
|
32
|
+
"url": "https://github.com/codevanger/active-inference/issues"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/codevanger/active-inference#readme",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"prettier": "^3.8.1",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^3.2.4"
|
|
39
|
+
}
|
|
40
|
+
}
|