Compare commits

1 Commits

Author SHA1 Message Date
faa0608575 multi out 2025-10-22 16:17:07 -06:00

View File

@@ -3,11 +3,11 @@
use std::collections::HashMap; use std::collections::HashMap;
struct BakedGate { struct BakedGate {
table: Vec<bool> table: Vec<Vec<bool>>
} }
impl BakedGate { impl BakedGate {
fn test(&self, input: Vec<bool>) -> bool { fn test(&self, input: &[bool]) -> &[bool] {
let mut total = 0; let mut total = 0;
@@ -17,7 +17,7 @@ impl BakedGate {
} }
} }
self.table[total] &self.table[total]
} }
} }
@@ -28,14 +28,14 @@ struct Gate<T> {
} }
trait Logic = Fn(Vec<bool>) -> bool; trait Logic = Fn(&[bool]) -> Vec<bool>;
impl<T: Logic> Gate<T> { impl<T: Logic> Gate<T> {
fn new(expected_inputs: usize, f: T) -> Self { fn new(expected_inputs: usize, expected_outputs: usize, f: T) -> Self {
Self { Self {
function: f, function: f,
qty_inputs: expected_inputs, qty_inputs: expected_inputs,
qty_outputs: 1, qty_outputs: expected_outputs,
} }
} }
@@ -55,7 +55,7 @@ impl<T: Logic> Gate<T> {
} }
inputs.reverse(); inputs.reverse();
let output = self.tick(inputs); let output = self.tick(&inputs);
// The index is the question, and the item at the index is the answer // The index is the question, and the item at the index is the answer
options.push(output); options.push(output);
@@ -66,55 +66,74 @@ impl<T: Logic> Gate<T> {
} }
} }
fn tick(&self, inputs: Vec<bool>) -> bool { fn tick(&self, inputs: &[bool]) -> Vec<bool> {
assert!(self.qty_inputs == inputs.len()); assert!(self.qty_inputs == inputs.len());
(self.function)(inputs) let out = (self.function)(&inputs);
assert!(out.len() == self.qty_outputs);
out
} }
} }
#[test]
fn mimo() {
let gate = Gate::new(2, 2, |f| {
vec![true, f[0] | f[1]]
});
assert_eq!(gate.tick(&[true, false]), &[true, true]);
assert_eq!(gate.tick(&[false, false]), &[true, false]);
let baked = gate.bake();
assert_eq!(baked.test(&[true, false]), &[true, true]);
assert_eq!(baked.test(&[false, false]), &[true, false]);
}
#[test] #[test]
fn baked_gate() { fn baked_gate() {
let and = Gate::new(2, |f| { let and = Gate::new(2, 1, |f| {
let a = f[0]; let a = f[0];
let b = f[1]; let b = f[1];
a && b vec![a && b]
}); });
let baked = and.bake(); let baked = and.bake();
assert_eq!(baked.test(vec![true, true]), true); assert_eq!(baked.test(&[true, true])[0], true);
assert_eq!(baked.test(vec![true, false]), false); assert_eq!(baked.test(&[true, false])[0], false);
assert_eq!(baked.test(vec![false, true]), false); assert_eq!(baked.test(&[false, true])[0], false);
assert_eq!(baked.test(vec![false, false]), false); assert_eq!(baked.test(&[false, false])[0], false);
let or = Gate::new(2, |f| { let or = Gate::new(2, 1, |f| {
let a = f[0]; let a = f[0];
let b = f[1]; let b = f[1];
a || b vec![a || b]
}); });
let baked = or.bake(); let baked = or.bake();
assert_eq!(baked.test(vec![true, true]), true); assert_eq!(baked.test(&[true, true])[0], true);
assert_eq!(baked.test(vec![true, false]), true); assert_eq!(baked.test(&[true, false])[0], true);
assert_eq!(baked.test(vec![false, true]), true); assert_eq!(baked.test(&[false, true])[0], true);
assert_eq!(baked.test(vec![false, false]), false); assert_eq!(baked.test(&[false, false])[0], false);
let not = Gate::new(1, |f| { let not = Gate::new(1, 1, |f| {
!f[0] vec![!f[0]]
}); });
let baked = not.bake(); let baked = not.bake();
assert_eq!(baked.test(vec![true]), false); assert_eq!(baked.test(&[true])[0], false);
assert_eq!(baked.test(vec![false]), true); assert_eq!(baked.test(&[false])[0], true);
} }
#[test] #[test]
fn baked_registry() { fn baked_registry() {
let mut registry: HashMap<&str, BakedGate> = HashMap::new(); let mut registry: HashMap<&str, BakedGate> = HashMap::new();
let and = Gate::new(2, |f| f[0] && f[1]); let and = Gate::new(2, 1, |f| vec![f[0] && f[1]]);
let or = Gate::new(2, |f| f[0] | f[1]); let or = Gate::new(2, 1, |f| vec![f[0] | f[1]]);
let not = Gate::new(1, |f| !f[0]); let not = Gate::new(1, 1, |f| vec![!f[0]]);
registry.insert("AND", and.bake()); registry.insert("AND", and.bake());
registry.insert("OR", or.bake()); registry.insert("OR", or.bake());
@@ -122,18 +141,19 @@ fn baked_registry() {
if let (Some(and), Some(not)) = (registry.get("AND"), registry.get("NOT")) { if let (Some(and), Some(not)) = (registry.get("AND"), registry.get("NOT")) {
let nand = Gate::new(2, |f| { let nand = Gate::new(2, 1, |f| {
not.test(vec![and.test(f)]) let and_r = and.test(&f);
not.test(and_r).to_vec()
}); });
registry.insert("NAND", nand.bake()); registry.insert("NAND", nand.bake());
} }
if let Some(nand) = registry.get("NAND") { if let Some(nand) = registry.get("NAND") {
assert_eq!(nand.test(vec![true, true]), false); assert_eq!(nand.test(&[true, true])[0], false);
assert_eq!(nand.test(vec![false, true]), true); assert_eq!(nand.test(&[false, true])[0], true);
assert_eq!(nand.test(vec![true, false]), true); assert_eq!(nand.test(&[true, false])[0], true);
assert_eq!(nand.test(vec![false, false]), true); assert_eq!(nand.test(&[false, false])[0], true);
} else { } else {
unreachable!() unreachable!()
} }
@@ -148,110 +168,81 @@ fn unbaked_registry() {
let and: Gate<Box<dyn Logic>> = Gate::new( let and: Gate<Box<dyn Logic>> = Gate::new(
2, 2,
Box::new(|f| f[0] && f[1]), 1,
Box::new(|f| vec![f[0] && f[1]]),
); );
registry.insert("AND", and); registry.insert("AND", and);
let not: Gate<Box<dyn Logic>> = Gate::new(1, Box::new(|f| !f[0])); let not: Gate<Box<dyn Logic>> = Gate::new(1, 1, Box::new(|f| vec![!f[0]]));
registry.insert("NOT", not); registry.insert("NOT", not);
if let (Some(not), Some(and)) = (registry.get("NOT"), registry.get("AND")) { if let (Some(not), Some(and)) = (registry.get("NOT"), registry.get("AND")) {
let nand: Gate<Box<dyn Logic>> = Gate::new( let nand: Gate<Box<dyn Logic>> = Gate::new(
2, 2,
1,
Box::new(|f| { Box::new(|f| {
let a = f[0]; let a = f[0];
let b = f[1]; let b = f[1];
let n = and.tick(vec![a, b]); let n = and.tick(&[a, b]);
not.tick(vec![n]) not.tick(&n)
}), }),
); );
assert_eq!(not.tick(vec![true]), false); assert_eq!(not.tick(&[true])[0], false);
assert_eq!(not.tick(vec![false]), true); assert_eq!(not.tick(&[false])[0], true);
assert_eq!(and.tick(vec![true, true]), true); assert_eq!(and.tick(&[true, true])[0], true);
assert_eq!(and.tick(vec![true, false]), false); assert_eq!(and.tick(&[true, false])[0], false);
assert_eq!(and.tick(vec![false, true]), false); assert_eq!(and.tick(&[false, true])[0], false);
assert_eq!(and.tick(vec![false, false]), false); assert_eq!(and.tick(&[false, false])[0], false);
assert_eq!(nand.tick(vec![true, true]), false); assert_eq!(nand.tick(&[true, true])[0], false);
assert_eq!(nand.tick(vec![true, false]), true); assert_eq!(nand.tick(&[true, false])[0], true);
assert_eq!(nand.tick(vec![false, true]), true); assert_eq!(nand.tick(&[false, true])[0], true);
assert_eq!(nand.tick(vec![false, false]), true); assert_eq!(nand.tick(&[false, false])[0], true);
}; };
} }
#[test]
fn nand_gate() {
let and = Gate::new(2, |f| {
let a = f[0];
let b = f[1];
a && b
});
let not = Gate::new(1, |f| !f[0]);
let nand = Gate::new(2, |f| not.tick(vec![and.tick(f)]));
assert_eq!(nand.tick(vec![true, true]), false);
assert_eq!(nand.tick(vec![true, false]), true);
assert_eq!(nand.tick(vec![false, true]), true);
assert_eq!(nand.tick(vec![false, false]), true);
}
#[test] #[test]
fn generic_gates() { fn generic_gates() {
let and = Gate::new(2, |f| { let and = Gate::new(2, 1,|f| {
let a = f[0]; let a = f[0];
let b = f[1]; let b = f[1];
a && b vec![a && b]
}); });
assert_eq!(and.tick(vec![true, true]), true); assert_eq!(and.tick(&[true, true])[0], true);
assert_eq!(and.tick(vec![true, false]), false); assert_eq!(and.tick(&[true, false])[0], false);
assert_eq!(and.tick(vec![false, true]), false); assert_eq!(and.tick(&[false, true])[0], false);
assert_eq!(and.tick(vec![false, false]), false); assert_eq!(and.tick(&[false, false])[0], false);
let not = Gate::new(1, |f| !f[0]); let not = Gate::new(1, 1, |f| vec![!f[0]]);
assert_eq!(not.tick(vec![true]), false); assert_eq!(not.tick(&[true])[0], false);
assert_eq!(not.tick(vec![false]), true); assert_eq!(not.tick(&[false])[0], true);
let or = Gate::new(2, |f| { let or = Gate::new(2, 1, |f| {
let a = f[0]; let a = f[0];
let b = f[1]; let b = f[1];
a | b vec![a | b]
}); });
assert_eq!(or.tick(vec![true, true]), true); assert_eq!(or.tick(&[true, true])[0], true);
assert_eq!(or.tick(vec![true, false]), true); assert_eq!(or.tick(&[true, false])[0], true);
assert_eq!(or.tick(vec![false, true]), true); assert_eq!(or.tick(&[false, true])[0], true);
assert_eq!(or.tick(vec![false, false]), false); assert_eq!(or.tick(&[false, false])[0], false);
let nand = Gate::new(2, 1, |f| not.tick(&and.tick(f)));
assert_eq!(nand.tick(&[true, true])[0], false);
assert_eq!(nand.tick(&[true, false])[0], true);
assert_eq!(nand.tick(&[false, true])[0], true);
assert_eq!(nand.tick(&[false, false])[0], true);
} }
fn main() { fn main() {
let g = Gate::new(2, |f| {true}); println!("hello world");
let mut registry: HashMap<&str, BakedGate> = HashMap::new();
let and = Gate::new(2, |f| f[0] && f[1]);
let or = Gate::new(2, |f| f[0] | f[1]);
let not = Gate::new(1, |f| !f[0]);
registry.insert("AND", and.bake());
registry.insert("OR", or.bake());
registry.insert("NOT", not.bake());
if let (Some(and), Some(not)) = (registry.get("AND"), registry.get("NOT")) {
let nand = Gate::new(2, |f| {
not.test(vec![and.test(f)])
});
registry.insert("NAND", nand.bake());
}
g.bake();
} }