use rand::Rng;
use rand::seq::SliceRandom;
use crate::rules::Rule;
use crate::schedule::Schedule;
use crate::substrates::graph::rules::RewriteRule;
use crate::substrates::graph::state::BinaryGraphState;
#[derive(Debug, Clone, Default)]
pub struct AllVerticesSchedule;
impl AllVerticesSchedule {
pub fn new() -> Self {
Self
}
}
impl Schedule<BinaryGraphState, RewriteRule> for AllVerticesSchedule {
fn name(&self) -> &str {
"all_vertices"
}
fn timing(&self) -> &str {
"asynchronous"
}
fn selection(&self) -> &str {
"exhaustive"
}
fn step(
&self,
state: &BinaryGraphState,
rules: &[RewriteRule],
rng: &mut dyn Rng,
) -> BinaryGraphState {
let mut current = state.clone();
let n = state.n_vertices();
let mut vertices: Vec<usize> = (0..n).collect();
vertices.shuffle(rng);
for &vertex in &vertices {
let mut rule_indices: Vec<usize> = (0..rules.len()).collect();
rule_indices.shuffle(rng);
for &ri in &rule_indices {
if let Some(info) = rules[ri].matches(¤t, vertex) {
current = rules[ri].apply(¤t, &info, rng);
break; }
}
}
current
}
}
pub static DEFAULT_SCHEDULE: AllVerticesSchedule = AllVerticesSchedule;
#[cfg(test)]
mod tests {
use super::*;
use crate::state::State;
use crate::substrates::graph::rules::create_structured_rules;
use ndarray::{arr1, arr2};
use rand::SeedableRng;
use rand::rngs::StdRng;
fn make_test_state() -> BinaryGraphState {
let adj = arr2(&[[0, 1, 0], [1, 0, 1], [0, 0, 0]]);
let labels = arr1(&[1, 0, 1]);
BinaryGraphState::new(3, adj.view(), labels.view()).unwrap()
}
#[test]
fn test_all_vertices_schedule_applies_rules() {
let state = make_test_state();
let rules = create_structured_rules();
let schedule = AllVerticesSchedule::new();
let mut rng = StdRng::seed_from_u64(42);
let new_state = schedule.step(&state, &rules, &mut rng);
assert_eq!(new_state.n_vertices(), 3);
for i in 0..3 {
assert!(new_state.label(i) <= 1);
}
}
#[test]
fn test_schedule_is_deterministic_given_seed() {
let state = make_test_state();
let rules = create_structured_rules();
let schedule = AllVerticesSchedule::new();
let mut rng1 = StdRng::seed_from_u64(42);
let mut rng2 = StdRng::seed_from_u64(42);
let result1 = schedule.step(&state, &rules, &mut rng1);
let result2 = schedule.step(&state, &rules, &mut rng2);
assert_eq!(result1.canonical_encoding(), result2.canonical_encoding());
}
}