1use core::panic;
2use std::{cell::RefCell, rc::Rc};
3
4pub struct Circuit {
5 component: Vec<LogicCircuit>, connection_path: Vec<(usize, usize, usize)>, input: Vec<Rc<RefCell<(bool, Vec<(usize, usize)>)>>>, output: Vec<Rc<RefCell<(Vec<usize>, bool)>>>, }
11
12impl Circuit {
13 pub fn new() -> Self {
15 Self {
16 component: vec![],
17 connection_path: vec![],
18 input: vec![],
19 output: vec![],
20 }
21 }
22 pub fn add_logic_gate(&mut self, new_comp: LogicCircuit) {
24 self.component.push(new_comp)
25 }
26 pub fn connection_scheme(&mut self, connection: (usize, usize, usize)) {
28 if self.component.len() < connection.0 {
29 dbg!(println!(
30 "WARNING: According your instructed FROM_ID is not Exist"
31 ))
32 }
33 self.connection_path.push(connection)
34 }
35 pub fn add_input(&mut self, no_of_input: usize) {
37 match no_of_input {
38 0 => dbg!(println!("WARNING: Number of Input Cannot be Zero")),
39 _ => {
40 for _ in 1..=no_of_input {
41 self.input.push(Rc::new(RefCell::new((false, vec![]))))
42 }
43 }
44 }
45 }
46 pub fn add_input_connection(&mut self, connection: (bool, Vec<(usize, usize)>)) {
48 self.input.push(Rc::new(RefCell::new(connection)))
49 }
50 pub fn change_input_signal(&mut self, input_index: usize, change_to: bool) {
52 match *(*self.input[input_index]).borrow_mut() {
53 (ref mut signal, _) => *signal = change_to,
54 }
55 }
56 pub fn change_input_config(
58 &mut self,
59 connection: (bool, Vec<(usize, usize)>),
60 input_index: usize,
61 ) {
62 if self.input.len() < input_index {
63 dbg!(println!(
64 "WARNING: according your instructed input index is out of Bound"
65 ))
66 } else {
67 *(*self.input[input_index]).borrow_mut() = connection
68 }
69 }
70 pub fn add_output_connection(&mut self, comp_id: usize) {
72 self.output
73 .push(Rc::new(RefCell::new((vec![comp_id], false))))
74 }
75 pub fn add_comp_onoutput(&mut self, comp_id: usize, output_index: usize) {
77 match *(*self.output[output_index]).borrow_mut() {
78 (ref mut x, _) => x.push(comp_id),
79 }
80 }
81 pub fn know_no_output(&self) -> usize {
83 self.output.len()
84 }
85 pub fn know_output_comp(&self, comp_id: usize) -> bool {
87 *(*self.component[comp_id].output).borrow_mut()
88 }
89 pub fn know_output(&mut self) -> Vec<bool> {
91 let mut out = vec![];
92 for out_each in self.output.clone() {
93 match *(*out_each).borrow_mut() {
94 (_, output) => out.push(output),
95 }
96 }
97 out
98 }
99 pub fn update(&mut self) {
101 let mut count = 0;
102 {
103 while count != self.input.len() {
104 match &(*(*self.input[count]).borrow_mut()) {
105 (x, y) => {
106 for i in y {
108 self.component[i.0].change_input_config(i.1, *x);
110 self.component[i.0].update()
111 }
112 }
113 }
114 count += 1;
115 }
116 count = 0;
117 }
118 {
119 while count != self.connection_path.len() {
120 match self.connection_path[count] {
121 (from_comp, to_comp, to_pin_index) => {
122 self.component[to_comp].input[to_pin_index] =
123 Rc::clone(&self.component[from_comp].output);
124 self.component[to_comp].update();
125 }
129 }
130 count += 1
131 }
132 count = 0
133 }
134 {
135 while count != self.output.len() {
136 match *(*self.output[count]).borrow_mut() {
137 (ref mut x, ref mut out) => {
138 let mut output = false;
139 for by_comp in x {
140 self.component[*by_comp].update();
141 output = output || self.know_output_comp(*by_comp);
142 }
143 *out = output
144 }
145 }
146 count += 1
147 }
148 }
149 }
150 }
152
153pub enum LogicGate {
154 AND, NOT, OR, }
158
159pub struct LogicCircuit {
160 input: Vec<Rc<RefCell<bool>>>, gate_type: LogicGate, output: Rc<RefCell<bool>>, }
164impl ToString for LogicCircuit {
166 fn to_string(&self) -> String {
167 use LogicGate::{AND, NOT, OR};
168 let mut input = String::new();
169 for i in 1..=self.input.len() {
170 input.push_str(match *(*self.input[i - 1]).borrow() {
171 true => "\x1b[32m \x1b[0m",
172 _ => "\x1b[31m \x1b[0m",
173 })
174 }
175 match self.gate_type {
176 NOT => {
177 format!("{} {}", input, {
178 if *(*self.output).borrow() {
179 "\x1b[32m\x1b[0m"
180 } else {
181 "\x1b[31m\x1b[0m"
182 }
183 })
184 }
185 AND => {
186 format!("{}{} {}", input, self.input.len(), {
187 if *(*self.output).borrow() {
188 "\x1b[32m\x1b[0m"
189 } else {
190 "\x1b[31m\x1b[0m"
191 }
192 })
193 }
194 OR => {
195 format!("{}{} {}", input, self.input.len(), {
196 if *(*self.output).borrow() {
197 "\x1b[32m\x1b[0m"
198 } else {
199 "\x1b[31m\x1b[0m"
200 }
201 })
202 }
203 }
204 }
205}
206
207impl LogicCircuit {
208 pub fn new(logic_type: LogicGate) -> Self {
210 match logic_type {
211 LogicGate::NOT => LogicCircuit {
212 input: vec![Rc::new(RefCell::new(false))],
213 gate_type: logic_type,
214 output: RefCell::new(true).into(),
215 },
216 _ => {
217 let mut sample_gate = LogicCircuit {
218 input: vec![Rc::new(RefCell::new(false)); 2],
219 gate_type: logic_type,
220 output: RefCell::new(false).into(),
221 };
222 sample_gate.update();
223 sample_gate
224 }
225 }
226 }
227 pub fn new_with_pins(logic_type: LogicGate, number: usize) -> Self {
229 match number {
230 0 | 1 => panic!("Zero or One It sould not Exist"),
231 _ => match logic_type {
232 LogicGate::NOT => panic!(
233 "NOT Gate Should have only single input pin
234 \n So you can try new instead of new_with_pins"
235 ),
236 _ => {
237 let mut sample_gate = LogicCircuit {
238 input: vec![Rc::new(RefCell::new(false)); number],
239 gate_type: logic_type,
240 output: RefCell::new(false).into(),
241 };
242 sample_gate.update();
243 sample_gate
244 }
245 },
246 }
247 }
248 pub fn update(&mut self) {
250 use LogicGate::{AND, NOT, OR};
251 let input = |index: usize| *(*self.input[index]).borrow_mut();
252 let input_len = self.input.len();
253 match self.gate_type {
254 NOT => match input_len {
255 1 => *(*self.output).borrow_mut() = !input(0),
256 _ => panic!("Wrong Input Config"),
257 },
258 AND => match input_len {
259 0 | 1 => dbg!(println!("Zero and Single input doesn't exist in AND Gate")),
260 _ => {
261 let mut step = 0;
262 while self.input.len() != step + 1 {
263 *(*self.output).borrow_mut() = input(step) && input(step + 1);
264 step += 1
265 }
266 }
267 },
268 OR => match input_len {
269 0 | 1 => dbg!(println!("Zero and Single input doesn't exist in AND Gate")),
270 _ => {
271 let mut step = 0;
272 while self.input.len() != step + 1 {
273 *(*self.output).borrow_mut() = input(step) || input(step + 1);
274 step += 1
275 }
276 }
277 },
278 }
279 }
280 pub fn change_input_config(&mut self, index: usize, change_to: bool) {
281 self.input[index] = Rc::new(change_to.into());
282 self.update()
283 }
284 #[deprecated]
288 pub fn connect_head_to(&mut self, other: &mut Self, index: usize) {
289 other.input[index] = Rc::clone(&self.output);
290 self.update();
291 other.update()
292 }
293}