#[derive(Clone, Debug)]
pub struct HomeostaticVariable {
pub value: f32,
pub target: f32,
pub tolerance: f32,
}
pub trait HomeostaticProvider {
fn homeostatic_variables(&self) -> &[HomeostaticVariable];
}
#[derive(Clone, Debug)]
pub struct Observation {
pub data: Vec<f32>,
}
impl Observation {
pub fn new(data: Vec<f32>) -> Self {
Self { data }
}
pub fn dim(&self) -> usize {
self.data.len()
}
}
#[derive(Clone, Debug)]
pub enum Action {
Discrete(usize),
Continuous(Vec<f32>),
}
impl Action {
pub fn to_one_hot(&self, num_actions: usize) -> Vec<f32> {
match *self {
Action::Discrete(i) => {
let mut v = vec![0.0; num_actions];
v[i] = 1.0;
v
}
Action::Continuous(ref v) => v.clone(),
}
}
pub fn dim(&self, num_actions: usize) -> usize {
match *self {
Action::Discrete(_) => num_actions,
Action::Continuous(ref v) => v.len(),
}
}
}
pub struct StepResult {
pub observation: Observation,
pub homeostatic: Vec<HomeostaticVariable>,
}
#[derive(Clone, Copy, Debug)]
pub enum ActionKind {
Discrete { n: usize },
Continuous { dim: usize, scale: f32 },
}
impl ActionKind {
pub fn dim(&self) -> usize {
match *self {
ActionKind::Discrete { n } => n,
ActionKind::Continuous { dim, .. } => dim,
}
}
}
pub trait Environment: HomeostaticProvider {
fn observation_dim(&self) -> usize;
fn num_actions(&self) -> usize;
fn observe(&self) -> Observation;
fn step(&mut self, action: &Action) -> StepResult;
fn reset(&mut self);
}