Core Framework Module Guide
Infrastructure layer for Symbion reproducible experiments
This guide details how to use the Core framework module (symbion/core) of the Symbion library, which provides the core abstractions and tools needed for building reproducible scientific experiments.
Table of Contents
1. Module Overview
1.1 Design Philosophy
The Core module is the infrastructure layer of the Symbion library, following these design principles:
- Reproducibility First: All experiments can be fully reproduced via seeds and configurations
- Type Safety: Complete TypeScript type definitions
- Modular Design: Each sub-module is independent and composable
- Standardized Logging: Structured logs in JSONL/CSV format
- Standard RL Compatible: Seamless integration with Python Reinforcement Learning ecosystem
1.2 Core Submodules
| Submodule | Function | Main Usage |
|---|---|---|
| Space | Space Definition | Define structure of observations and actions |
| Objective | Metric System | Combine multiple optimization objectives |
| Constraint | Constraint System | Define and evaluate hard/soft constraints |
| Runner | Experiment Runner | Execute complete experiment loop |
| Logging | Logging System | Record experiment data |
2. Space - Space Definition
The Space module provides standard RL-compatible observation space and action space definitions.
DiscreteSpace
Represents a finite set of discrete options [0, n).
import { discrete } from 'symbion/core'; // MCS Selection: 0-28 Total 29 options const mcsSpace = discrete(29, ['MCS-0', 'MCS-1', ..., 'MCS-28']); // Direction Selection const directionSpace = discrete(4, ['North', 'East', 'South', 'West']);
BoxSpace - Continuous Space
Represents an n-dimensional continuous space, with bounds for each dimension.
import { box } from 'symbion/core'; // 3D Position Space const positionSpace = box( [3], // Shape: 3D vector [0, 0, 30], // Low: x, y, z min values [1000, 1000, 150] // High: x, y, z max values ); // Normalized Observation Space const normalizedObs = box( [12], // 12D observation vector -1, // Lower bound -1 for all dimensions 1, // Upper bound 1 for all dimensions 'float32' // Data type );
DictSpace
Named dictionary of spaces, used for structured inputs or outputs.
import { dict, box, discrete } from 'symbion/core'; const inputSpace = dict({ // Motion State position: box([3], 0, 1000), velocity: box([3], -20, 20), // Communication State mcsIndex: discrete(29), txPower: box([1], 0, 23), });
Space Operations
Sampling
import { sample, createRng } from 'symbion/core'; const space = box([3], 0, 1000); const rng = createRng(42); // Use seed for reproducibility const value = sample(space, rng.random.bind(rng)); console.log('Sample:', value);
Flattening & Unflattening
import { flatten, unflatten, dict, box } from 'symbion/core'; const space = dict({ position: box([3], 0, 1000) }); const value = { position: [100, 200, 50] }; const flattened = flatten(space, value); // [100, 200, 50] const restored = unflatten(space, flattened);
3. Objective - Metric System
Objective module provides metric definition, composition, and tracking functions for multi-objective optimization.
Simplified Metric Creation
import { simpleMetric } from 'symbion/core'; // Maximize reward const reward = simpleMetric('reward', (s) => s.reward, 'maximize'); // Minimize energy const energy = simpleMetric('energy', (s) => s.energy, 'minimize');
Metric Composition
import { combineMetricsWithTracking, simpleMetric } from 'symbion/core'; const metrics = [ simpleMetric('throughput', (s) => s.throughput, 'maximize'), simpleMetric('energy', (s) => s.energy, 'minimize'), ]; // Create composite evaluator (Weighted Sum) const composite = combineMetricsWithTracking(metrics, 'weighted_sum'); const result = composite.evaluate({ throughput: 100, energy: 50 }); console.log('Total Score:', result.total); console.log('Breakdown:', result.breakdown);
4. Constraint - Constraint System
Constraint module provides constraint definition and evaluation, distinguishing between hard constraints (must satisfy) and soft constraints (violation incurs penalty).
Creating Constraints
import { leConstraint, geConstraint } from 'symbion/core'; // Max Speed Constraint: speed ≤ 20 (Hard) const maxSpeed = leConstraint( 'max_speed', (state) => state.speed, 20, 'hard' ); // Min SINR Constraint: sinrDb ≥ 0 (Soft) const minSinr = geConstraint( 'min_sinr', (state) => state.sinrDb, 0, 'soft', { penaltyWeight: 10 } );
Constraint Evaluation
import { evaluateConstraints } from 'symbion/core'; const constraints = [maxSpeed, minSinr]; const state = { speed: 18, sinrDb: -3 }; const report = evaluateConstraints(constraints, state); console.log('Feasible (Hard constraints met?):', report.feasible); console.log('Total Penalty (Soft violations):', report.totalPenalty); console.log('Violations:', report.violations);
5. Runner - Experiment Runner
Runner module provides a unified experiment execution framework, integrating environment, policy, metrics, and constraints.
Runner Configuration
import { Runner, createTaskConfig, ConsoleLogger } from 'symbion/core'; const config = { // Task Config taskConfig: createTaskConfig({ taskName: 'uav-sim', seed: 42 }), // Environment and Policy environment: myEnvironment, policy: myPolicy, // Run Parameters maxStepsPerEpisode: 500, totalEpisodes: 100, // Logging loggers: [new ConsoleLogger('info')] }; const runner = new Runner(config);
Running Experiments
// Run complete experiment const result = await runner.run(); console.log(`Total Episodes: ${result.totalEpisodes}`); console.log(`Avg Metric: ${result.avgEpisodeMetric.toFixed(2)}`); console.log(`Success Rate: ${(result.successRate * 100).toFixed(1)}%`);
6. Logging - Logging System
Logging module provides structured logging, supporting step-level, episode-level, and report-level logs.
ConsoleLogger
import { ConsoleLogger } from 'symbion/core'; const logger = new ConsoleLogger('info'); // 'debug' | 'info' | 'warn' | 'error' // Log a step logger.logStep({ task: 'uav-sim', seed: 42, episode: 1, step: 10, observation: [...], action: [...], reward: 1.0 });