diff --git a/Cargo.toml b/Cargo.toml index 8dc7530..54805bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,8 @@ version = "0.1.0" edition = "2021" [dependencies] + +[lib] +name = "logic_o3" +path = "./src/lib.rs" + diff --git a/Logo.svg b/Logo.svg new file mode 100644 index 0000000..eb1123d --- /dev/null +++ b/Logo.svg @@ -0,0 +1,324 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lo + + + + + + diff --git a/README.md b/README.md index ebf0b8d..98f6e57 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# Logic-TriOxide (WIP) +| ![LOGO](https://raw.githubusercontent.com/unknownK19/Logic-TriOxide/3f63015a71fca7dfea67a442c858710aee49de1c/Logo.svg) | Logic-TriOxide (WIP) | +|:--- | :--- | + Logic Gate API written in rust + +# This is Midnight Branch AKA Testing Branch + diff --git a/examples/example01.rs b/examples/example01.rs new file mode 100644 index 0000000..63de6ad --- /dev/null +++ b/examples/example01.rs @@ -0,0 +1,21 @@ +use logic_o3::logic::{Circuit, LogicCircuit}; + +fn main() { + let and1 = LogicCircuit::new(logic_o3::logic::LogicGate::AND); + let not1 = LogicCircuit::new(logic_o3::logic::LogicGate::NOT); + + let mut nand = Circuit::new(); + + nand.add_logic_gate(and1); + nand.add_logic_gate(not1); + + nand.connection_scheme((0, 1, 0)); + + nand.add_input_connection((true, vec![(0, 0)])); + nand.add_input_connection((false, vec![(0, 1)])); + + nand.add_output_connection(1); + + nand.update(); + println!("{:?}", nand.know_output()); +} diff --git a/examples/example02.rs b/examples/example02.rs new file mode 100644 index 0000000..35a6a56 --- /dev/null +++ b/examples/example02.rs @@ -0,0 +1,21 @@ +use logic_o3::logic::{Circuit, LogicCircuit}; + +fn main() { + let or1 = LogicCircuit::new(logic_o3::logic::LogicGate::OR); + let not1 = LogicCircuit::new(logic_o3::logic::LogicGate::NOT); + + let mut nor = Circuit::new(); + + nor.add_logic_gate(or1); + nor.add_logic_gate(not1); + + nor.connection_scheme((0, 1, 0)); + + nor.add_input_connection((false, vec![(0, 0)])); + nor.add_input_connection((false, vec![(0, 1)])); + + nor.add_output_connection(1); + + nor.update(); + println!("{:?}", nor.know_output()); +} diff --git a/examples/example03.rs b/examples/example03.rs new file mode 100644 index 0000000..78d6245 --- /dev/null +++ b/examples/example03.rs @@ -0,0 +1,28 @@ +use logic_o3::logic::{Circuit, LogicCircuit}; + +fn main() { + let or1 = LogicCircuit::new(logic_o3::logic::LogicGate::OR); + let and1 = LogicCircuit::new(logic_o3::logic::LogicGate::AND); + let not1 = LogicCircuit::new(logic_o3::logic::LogicGate::NOT); + + let mut circuit01 = Circuit::new(); + + circuit01.add_logic_gate(and1); + circuit01.add_logic_gate(or1); + circuit01.add_logic_gate(not1); + + circuit01.add_input_connection((false, vec![(0, 0)])); + circuit01.add_input_connection((true, vec![(0, 1)])); + + circuit01.add_input_connection((true, vec![(1, 0)])); + circuit01.add_input_connection((false, vec![(1, 1)])); + + circuit01.connection_scheme((0, 2, 0)); + + circuit01.add_output_connection(2); + circuit01.add_output_connection(0); + circuit01.add_output_connection(1); + + circuit01.update(); + println!("{:?}", circuit01.know_output()); +} diff --git a/src/logic/mod.rs b/src/lib.rs similarity index 100% rename from src/logic/mod.rs rename to src/lib.rs diff --git a/src/logic.rs b/src/logic.rs new file mode 100644 index 0000000..7a4b543 --- /dev/null +++ b/src/logic.rs @@ -0,0 +1,278 @@ +use core::panic; +use std::{cell::RefCell, rc::Rc}; + +pub struct Circuit { + component: Vec, // Vec[and1, or1, not1] + connection_path: Vec<(usize, usize, usize)>, // Vev[(from_comp_id, to_comp_id, to_input_index)] + input: Vec)>>>, // Vec[(Input_Binary , Vec[(to_id, to_input_index)])] + output: Vec, bool)>>>, // Vec[(from_id, Output_Binary)] + // update method require for change output +} + +impl Circuit { + pub fn new() -> Self { + Self { + component: vec![], + connection_path: vec![], + input: vec![], + output: vec![], + } + } + pub fn add_logic_gate(&mut self, new_comp: LogicCircuit) { + self.component.push(new_comp) + } + pub fn connection_scheme(&mut self, connection: (usize, usize, usize)) { + if self.component.len() < connection.0 { + dbg!(println!( + "WARNING: According your instructed FROM_ID is not Exist" + )) + } + self.connection_path.push(connection) + } + pub fn add_input(&mut self, no_of_input: usize) { + match no_of_input { + 0 => dbg!(println!("WARNING: Number of Input Cannot be Zero")), + _ => { + for _ in 1..=no_of_input { + self.input.push(Rc::new(RefCell::new((false, vec![])))) + } + } + } + } + pub fn add_input_connection(&mut self, connection: (bool, Vec<(usize, usize)>)) { + self.input.push(Rc::new(RefCell::new(connection))) + } + pub fn change_input_signal(&mut self, input_index: usize, change_to: bool) { + match *(*self.input[input_index]).borrow_mut() { + (ref mut signal, _) => *signal = change_to, + } + } + pub fn change_input_config( + &mut self, + connection: (bool, Vec<(usize, usize)>), + input_index: usize, + ) { + if self.input.len() < input_index { + dbg!(println!( + "WARNING: according your instructed input index is out of Bound" + )) + } else { + *(*self.input[input_index]).borrow_mut() = connection + } + } + pub fn add_output_connection(&mut self, comp_id: usize) { + self.output + .push(Rc::new(RefCell::new((vec![comp_id], false)))) + } + pub fn add_comp_onoutput(&mut self, comp_id: usize, at_index: usize) { + match *(*self.output[at_index]).borrow_mut() { + (ref mut x, _) => x.push(comp_id), + } + } + pub fn know_no_output(&self) -> usize { + self.output.len() + } + pub fn know_output_comp(&self, comp_id: usize) -> bool { + *(*self.component[comp_id].output).borrow_mut() + } + pub fn know_output(&mut self) -> Vec { + let mut out = vec![]; + for out_each in self.output.clone() { + match *(*out_each).borrow_mut() { + (_, output) => out.push(output), + } + } + out + } + pub fn update(&mut self) { + let mut count = 0; + { + while count != self.input.len() { + match &(*(*self.input[count]).borrow_mut()) { + (x, y) => { + // KNOW: x is input boolean and y is input connection + for i in y { + // KNOW: i has two value tuples (id_component, index_component) + self.component[i.0].change_input_config(i.1, *x); + self.component[i.0].update() + } + } + } + count += 1; + } + count = 0; + } + { + while count != self.connection_path.len() { + match self.connection_path[count] { + (from_comp, to_comp, to_pin_index) => { + self.component[to_comp].input[to_pin_index] = + Rc::clone(&self.component[from_comp].output); + self.component[to_comp].update(); + // Due to borrowing Conflict + // self.component[from_comp] + // .connect_head_to(&mut self.component[to_comp], to_pin_index); + } + } + count += 1 + } + count = 0 + } + { + while count != self.output.len() { + match *(*self.output[count]).borrow_mut() { + (ref mut x, ref mut out) => { + let mut output = false; + for by_comp in x { + self.component[*by_comp].update(); + output = output || self.know_output_comp(*by_comp); + } + *out = output + } + } + count += 1 + } + } + } + //TODO +} + +pub enum LogicGate { + AND, // AND Gate + NOT, + OR, + /*More TODO*/ +} + +pub struct LogicCircuit { + input: Vec>>, // Input pin indexing like [true, false, false, false] + gate_type: LogicGate, // Which Logic Gate + output: Rc>, // Single output pin +} + +impl ToString for LogicCircuit { + fn to_string(&self) -> String { + use LogicGate::{AND, NOT, OR}; + let mut input = String::new(); + for i in 1..=self.input.len() { + input.push_str(match *(*self.input[i - 1]).borrow() { + true => "\x1b[32m \x1b[0m", + _ => "\x1b[31m \x1b[0m", + }) + } + match self.gate_type { + NOT => { + format!("{}󰣤 {}", input, { + if *(*self.output).borrow() { + "\x1b[32m\x1b[0m" + } else { + "\x1b[31m\x1b[0m" + } + }) + } + AND => { + format!("{}{}󰣡 {}", input, self.input.len(), { + if *(*self.output).borrow() { + "\x1b[32m\x1b[0m" + } else { + "\x1b[31m\x1b[0m" + } + }) + } + OR => { + format!("{}{}󰣥 {}", input, self.input.len(), { + if *(*self.output).borrow() { + "\x1b[32m\x1b[0m" + } else { + "\x1b[31m\x1b[0m" + } + }) + } + } + } +} + +impl LogicCircuit { + pub fn new(logic_type: LogicGate) -> Self { + match logic_type { + LogicGate::NOT => LogicCircuit { + input: vec![Rc::new(RefCell::new(false))], + gate_type: logic_type, + output: RefCell::new(true).into(), + }, + _ => { + let mut sample_gate = LogicCircuit { + input: vec![Rc::new(RefCell::new(false)); 2], + gate_type: logic_type, + output: RefCell::new(false).into(), + }; + sample_gate.update(); + sample_gate + } + } + } + pub fn new_with_pins(logic_type: LogicGate, number: usize) -> Self { + match number { + 0 | 1 => panic!("Zero or One It sould not Exist"), + _ => match logic_type { + LogicGate::NOT => panic!( + "NOT Gate Should have only single input pin + \n So you can try new instead of new_with_pins" + ), + _ => { + let mut sample_gate = LogicCircuit { + input: vec![Rc::new(RefCell::new(false)); number], + gate_type: logic_type, + output: RefCell::new(false).into(), + }; + sample_gate.update(); + sample_gate + } + }, + } + } + pub fn update(&mut self) { + use LogicGate::{AND, NOT, OR}; + let input = |index: usize| *(*self.input[index]).borrow_mut(); + let input_len = self.input.len(); + match self.gate_type { + NOT => match input_len { + 1 => *(*self.output).borrow_mut() = !input(0), + _ => panic!("Wrong Input Config"), + }, + AND => match input_len { + 0 | 1 => dbg!(println!("Zero and Single input doesn't exist in AND Gate")), + _ => { + let mut step = 0; + while self.input.len() != step + 1 { + *(*self.output).borrow_mut() = input(step) && input(step + 1); + step += 1 + } + } + }, + OR => match input_len { + 0 | 1 => dbg!(println!("Zero and Single input doesn't exist in AND Gate")), + _ => { + let mut step = 0; + while self.input.len() != step + 1 { + *(*self.output).borrow_mut() = input(step) || input(step + 1); + step += 1 + } + } + }, + } + } + pub fn change_input_config(&mut self, index: usize, change_to: bool) { + self.input[index] = Rc::new(change_to.into()); + self.update() + } + // Connect self output pin to other input gate pin + // KNOW: `self` is own LogicCircuit where `other` is other LogicCircuit where`index` represent + // other gate input pin index + #[deprecated] + pub fn connect_head_to(&mut self, other: &mut Self, index: usize) { + other.input[index] = Rc::clone(&self.output); + self.update(); + other.update() + } +} diff --git a/src/logic/logic.rs b/src/logic/logic.rs deleted file mode 100644 index 68392e8..0000000 --- a/src/logic/logic.rs +++ /dev/null @@ -1,136 +0,0 @@ -use core::panic; -use std::rc::Rc; - -pub enum LogicGate { - AND, // AND Gate - NOT, - /*More TODO*/ -} - -pub struct LogicCircut { - input: Vec>, - gate_type: LogicGate, // Which Logic Gate - output: bool, -} - -impl ToString for LogicCircut { - fn to_string(&self) -> String { - use LogicGate::{AND, NOT}; - let mut input = String::new(); - for i in 1..=self.input.len() { - input.push_str(match *self.input[i - 1] { - true => " ", - _ => " ", - }) - } - match self.gate_type { - NOT => { - format!("{}󰣤 {}", input, { - if self.output { - "" - } else { - "" - } - }) - } - AND => { - format!("{}{}󰣡 {}", input, self.input.len(), { - if self.output { - "" - } else { - "" - } - }) - } - } - } -} - -impl LogicCircut { - pub fn new(logic_type: LogicGate) -> Self { - match logic_type { - LogicGate::NOT => LogicCircut { - input: vec![Rc::new(false)], - gate_type: logic_type, - output: true, - }, - _ => { - let mut sample_gate = LogicCircut { - input: vec![Rc::new(false), Rc::new(false)], - gate_type: logic_type, - output: false, - }; - sample_gate.update(); - sample_gate - } - } - } - pub fn new_with_pins(logic_type: LogicGate, number: usize) -> Self { - match number { - 0 | 1 => panic!("Zero or One It sould not Exist"), - _ => match logic_type { - LogicGate::NOT => panic!( - "NOT Gate Should have only single input pin - \n So you can try new instead of new_with_pins" - ), - _ => { - let mut sample_gate = LogicCircut { - input: vec![Rc::new(false); number], - gate_type: logic_type, - output: false, - }; - sample_gate.update(); - sample_gate - } - }, - } - } - pub fn update(&mut self) { - use LogicGate::{AND, NOT}; - let input = |index: usize| *self.input[index]; - match self.gate_type { - NOT => match self.input.len() { - 1 => self.output = !input(0), - _ => panic!("Wrong Input Config"), - }, - AND => match self.input.len() { - 0 | 1 => panic!("Zero and Single input doesn't exist in AND Gate"), - _ => { - let mut step = 0; - while self.input.len() != step + 1 { - self.output = input(step) && input(step + 1); - step += 1 - } - } - }, - } - } - pub fn change_input_config(&mut self, index: usize, change_to: bool) { - self.input[index] = Rc::new(change_to); - self.update() - } -} - -pub fn run_example_1() { - // create AND gate - println!("*AND Gate*"); - let mut and1 = LogicCircut::new(LogicGate::AND); - println!("{}", and1.to_string()); - - and1.change_input_config(0, true); - println!("{}", and1.to_string()); - - and1.change_input_config(0, false); - and1.change_input_config(1, true); - println!("{}", and1.to_string()); - - and1.change_input_config(0, true); - println!("{}", and1.to_string()); - - println!("*NOT Gate*"); - let mut not1 = LogicCircut::new(LogicGate::NOT); - println!("{}", not1.to_string()); - - not1.change_input_config(0, true); - println!("{}", not1.to_string()); -} diff --git a/src/main.rs b/src/main.rs index ff10f01..f328e4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1 @@ -use logic::logic::run_example_1; - -mod logic; -fn main() { - run_example_1() -} +fn main() {}