This commit is contained in:
parent
925b539223
commit
68ac4ca48f
@ -4,7 +4,7 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.9.0"
|
rand = "0.9.1"
|
||||||
paste = "1.0.15"
|
paste = "1.0.15"
|
||||||
rust_decimal = { version = "1.37", features = ["macros", "maths"] }
|
rust_decimal = { version = "1.37", features = ["macros", "maths"] }
|
||||||
rush_macro = { path = "rush_macro" }
|
rush_macro = { path = "rush_macro" }
|
115
src/gp/genome.rs
Normal file
115
src/gp/genome.rs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
use crate::instructions::code::{
|
||||||
|
exec_do_count, exec_do_range, exec_do_times, exec_do_while, exec_if, exec_when, exec_while,
|
||||||
|
};
|
||||||
|
use crate::instructions::common::{
|
||||||
|
exec_dup, exec_dup_times, exec_pop, exec_rotate, exec_shove, exec_swap,
|
||||||
|
};
|
||||||
|
use crate::instructions::vector::{
|
||||||
|
string_iterate, vector_boolean_iterate, vector_char_iterate, vector_float_iterate,
|
||||||
|
vector_int_iterate, vector_string_iterate,
|
||||||
|
};
|
||||||
|
use crate::push::state::Gene;
|
||||||
|
use crate::push::state::Gene::StateFunc;
|
||||||
|
use rand::prelude::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
/// Generates a random plushy.
|
||||||
|
pub fn make_random_plushy(
|
||||||
|
genes: Vec<Gene>,
|
||||||
|
max_init_plushy_size: usize,
|
||||||
|
mut rng: impl Rng,
|
||||||
|
) -> Vec<Gene> {
|
||||||
|
let plushy_size = rng.random_range(0..=max_init_plushy_size);
|
||||||
|
let mut plushy = Vec::with_capacity(plushy_size);
|
||||||
|
for _ in 0..plushy_size {
|
||||||
|
plushy.push(genes[rng.random_range(0..genes.len())].clone());
|
||||||
|
}
|
||||||
|
plushy
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A map of genes to their number of blocks they open.
|
||||||
|
static OPEN_MAP: LazyLock<HashMap<Gene, u8>> = LazyLock::new(|| {
|
||||||
|
let mut temp_map = HashMap::default();
|
||||||
|
temp_map.insert(StateFunc(exec_dup), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_dup_times), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_pop), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_rotate), 3u8);
|
||||||
|
temp_map.insert(StateFunc(exec_shove), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_swap), 2u8);
|
||||||
|
temp_map.insert(StateFunc(exec_if), 2u8);
|
||||||
|
temp_map.insert(StateFunc(exec_when), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_while), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_do_while), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_do_range), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_do_count), 1u8);
|
||||||
|
temp_map.insert(StateFunc(exec_do_times), 1u8);
|
||||||
|
//exec_k, 2
|
||||||
|
//exec_s 3
|
||||||
|
//exec_y 1
|
||||||
|
temp_map.insert(StateFunc(string_iterate), 1u8);
|
||||||
|
temp_map.insert(StateFunc(vector_int_iterate), 1u8);
|
||||||
|
temp_map.insert(StateFunc(vector_float_iterate), 1u8);
|
||||||
|
temp_map.insert(StateFunc(vector_string_iterate), 1u8);
|
||||||
|
temp_map.insert(StateFunc(vector_boolean_iterate), 1u8);
|
||||||
|
temp_map.insert(StateFunc(vector_char_iterate), 1u8);
|
||||||
|
temp_map
|
||||||
|
});
|
||||||
|
|
||||||
|
fn has_openers(genes: &[Gene]) -> bool {
|
||||||
|
for gene in genes {
|
||||||
|
match gene {
|
||||||
|
Gene::Open(_) => return true,
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a plushy to a push program.
|
||||||
|
pub fn plushy_to_push(genes: Vec<Gene>) -> Vec<Gene> {
|
||||||
|
let mut plushy_buffer: Vec<Gene> = Vec::with_capacity(genes.len() * 2);
|
||||||
|
for gene in genes.into_iter() {
|
||||||
|
let open = OPEN_MAP.get(&gene);
|
||||||
|
plushy_buffer.push(gene);
|
||||||
|
if let Some(amt) = open {
|
||||||
|
plushy_buffer.push(Gene::Open(*amt))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut push_buffer = Vec::with_capacity(plushy_buffer.len());
|
||||||
|
loop {
|
||||||
|
// recur with one more close if there are openers
|
||||||
|
if plushy_buffer.is_empty() && has_openers(&push_buffer) {
|
||||||
|
plushy_buffer.push(Gene::Close);
|
||||||
|
} else if plushy_buffer.is_empty() {
|
||||||
|
return plushy_buffer;
|
||||||
|
} else {
|
||||||
|
let first_gene = plushy_buffer.pop().unwrap();
|
||||||
|
match &first_gene {
|
||||||
|
Gene::Close => if has_openers(&push_buffer) {
|
||||||
|
let ndx: usize;
|
||||||
|
let opener
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::instructions::vector::{string_iterate, vector_float_maximum};
|
||||||
|
use crate::push::interpreter::interpret_program;
|
||||||
|
use crate::push::state::Gene::StateFunc;
|
||||||
|
use crate::push::state::{EMPTY_STATE, PushState};
|
||||||
|
use crate::push::utils::most_genes;
|
||||||
|
use rand::SeedableRng;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn make_random_plushy_test() {
|
||||||
|
let rng = StdRng::seed_from_u64(42);
|
||||||
|
let rand_plushy = make_random_plushy(most_genes(), 15, rng);
|
||||||
|
let fin_result = vec![StateFunc(string_iterate), StateFunc(vector_float_maximum)];
|
||||||
|
assert_eq!(fin_result, rand_plushy);
|
||||||
|
}
|
||||||
|
}
|
1
src/gp/mod.rs
Normal file
1
src/gp/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod genome;
|
@ -666,6 +666,23 @@ pub fn exec_instructions() -> Vec<fn(&mut PushState)> {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn all_instructions() -> Vec<fn(&mut PushState)> {
|
||||||
|
let mut instructions = vec![];
|
||||||
|
instructions.append(&mut int_instructions());
|
||||||
|
instructions.append(&mut float_instructions());
|
||||||
|
instructions.append(&mut string_instructions());
|
||||||
|
instructions.append(&mut boolean_instructions());
|
||||||
|
instructions.append(&mut char_instructions());
|
||||||
|
instructions.append(&mut vector_int_instructions());
|
||||||
|
instructions.append(&mut vector_float_instructions());
|
||||||
|
instructions.append(&mut vector_string_instructions());
|
||||||
|
instructions.append(&mut vector_boolean_instructions());
|
||||||
|
instructions.append(&mut vector_char_instructions());
|
||||||
|
instructions.append(&mut code_instructions());
|
||||||
|
instructions.append(&mut exec_instructions());
|
||||||
|
instructions
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
//use super::*;
|
//use super::*;
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
|
pub mod gp;
|
||||||
pub mod instructions;
|
pub mod instructions;
|
||||||
pub mod push;
|
pub mod push;
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod interpreter;
|
pub mod interpreter;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
|
pub mod utils;
|
||||||
|
@ -35,7 +35,7 @@ pub const EMPTY_STATE: PushState = PushState {
|
|||||||
code: vec![],
|
code: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Debug, Clone)]
|
#[derive(PartialEq, Eq, Debug, Clone, Hash)]
|
||||||
#[allow(dead_code)] // remove this later. Is here bc Close, Skip, CrossoverPadding
|
#[allow(dead_code)] // remove this later. Is here bc Close, Skip, CrossoverPadding
|
||||||
pub enum Gene {
|
pub enum Gene {
|
||||||
GeneInt(i128),
|
GeneInt(i128),
|
||||||
@ -129,16 +129,13 @@ impl Gene {
|
|||||||
val.insert(n, gene.clone());
|
val.insert(n, gene.clone());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
match el {
|
if let iblock @ Gene::Block(_) = el {
|
||||||
iblock @ Gene::Block(_) => {
|
// This line has side effects on iblock if inserts properly.
|
||||||
// This line has side effects on iblock if inserts properly.
|
let success = iblock.attempt_code_insert(gene.clone(), idx - 1);
|
||||||
let success = iblock.attempt_code_insert(gene.clone(), idx - 1);
|
if success {
|
||||||
if success {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
idx -= iblock.rec_len() + 1
|
|
||||||
}
|
}
|
||||||
_ => (),
|
idx -= iblock.rec_len() + 1
|
||||||
}
|
}
|
||||||
idx -= 1;
|
idx -= 1;
|
||||||
}
|
}
|
||||||
|
12
src/push/utils.rs
Normal file
12
src/push/utils.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
use crate::instructions::all_instructions;
|
||||||
|
use crate::push::state::Gene;
|
||||||
|
|
||||||
|
pub fn most_genes() -> Vec<Gene> {
|
||||||
|
let mut instructions: Vec<Gene> = all_instructions()
|
||||||
|
.into_iter()
|
||||||
|
.map(|x| Gene::StateFunc(x))
|
||||||
|
.collect();
|
||||||
|
instructions.push(Gene::Close);
|
||||||
|
instructions.push(Gene::Skip);
|
||||||
|
instructions
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user