123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- use crate::{gate::Gate, gate_type::GateType};
-
-
- #[derive(Debug, Clone)]
- pub struct Circuit {
- pub input_bits: Vec<bool>, // Input wires
- pub gates: Vec<Gate>, // All gates
- }
-
- impl Circuit {
- pub fn eval(self) -> bool {
- let mut evaluated_gates = vec!();
-
- for gate in self.gates {
- let result = gate.eval(&self.input_bits, &evaluated_gates);
- evaluated_gates.push(result);
- }
-
- match evaluated_gates.pop() {
- Some(result) => result,
- None => panic!("Bruh moment")
- }
- }
-
- /*
- This method should create a circuit that outputs 1 if the first number A (encoded in the first n
- bits) is greater than the second number B (encoded in the next n bits) .
- */
- pub fn compare_n_bit_numbers(input_bits: Vec<bool>, n: usize) -> Self {
- if input_bits.len() < 2*n {
- panic!("Expected input_bits to be of at least length {}, but it was {}", 2*n, input_bits.len())
- }
-
- /*
- base case n=1: 1-bit:
-
- A B | A > B
- -----------
- 0 0 | 0
- 0 1 | 0
- 1 0 | 1
- 1 1 | 0
-
- n+1 case: 2-bit:
-
- A1 A0 B1 B0 | A > B | (A1 > B1) || ((A1 == B1) && (A0 > B0))
- ----------------------|------------------------------------
- 0 0 0 0 | 0 | 0
- 0 0 0 1 | 0 | 0
- 0 0 1 0 | 0 | 0
- 0 0 1 1 | 0 | 0
- 0 1 0 0 | 1 | 1
- 0 1 0 1 | 0 | 0
- 0 1 1 0 | 0 | 0
- 0 1 1 1 | 1 | 1
- 1 0 0 0 | 1 | 1
- 1 0 0 1 | 1 | 1
- 1 0 1 0 | 0 | 0
- 1 0 1 1 | 0 | 0
- 1 1 0 0 | 1 | 1
- 1 1 0 1 | 1 | 1
- 1 1 1 0 | 1 | 1
- 1 1 1 1 | 0 | 0
-
- The inductive pattern should become apparent now.
- For illustration here's the case for n=4, which should show the
- recursive characteristics of the formula.
-
- (A3 > B3) ||
- ((A3 == B3) && (A2 > B2)) ||
- ((A3 == B3) && (A2 == B2) && (A1 > B1)) ||
- ((A3 == B3) && (A2 == B2) && (A1 == B1)) && (A0 > B0))
-
- */
-
- let gates = create_n_bit_comparator_gates(n);
- return Circuit { input_bits, gates }
- }
- }
-
-
- fn create_n_bit_comparator_gates(n: usize) -> Vec<Gate>{
- let mut indices: Vec<usize> = vec![0; n];
- let mut all_gates: Vec<Gate> = vec!();
- let mut and_gate_indices: Vec<usize> = vec!();
-
-
-
- rec_n_bit_comperator_gates(0, n, &mut all_gates, &mut and_gate_indices, &mut indices, );
-
- // the OR spanning all ANDs
- let or_gate = Gate::new( GateType::Or, and_gate_indices, vec!());
-
- all_gates.push(or_gate);
-
- return all_gates;
- }
-
- fn rec_n_bit_comperator_gates(curr: usize, max: usize, all_gates: &mut Vec<Gate>, and_gate_incides: &mut Vec<usize>, indices: &mut Vec<usize>){
- // Incrementing gate index
- let a_curr_gt_b_curr_gate_index = all_gates.len();
-
- // Gate(A_current > B_current)
- let a_curr_gt_b_curr_gate = Gate::new(GateType::Bigger, vec!(), vec!(curr, curr+max));
-
- // A_current>B_current
- //print!(" ( ({}) ", format!("{} > {}", format!("A{}", max-1-curr), format!("B{}", max-1-curr)));
-
- all_gates.push(a_curr_gt_b_curr_gate);
-
- let mut this_recursion_gate_indices: Vec<usize> = vec!(a_curr_gt_b_curr_gate_index);
-
- for i in 0..curr {
- let key = max-1-i;
- if i == curr-1 {
- // Gate(A_current > B_current)
- let a_i_eq_b_i_gate = Gate::new(GateType::Equal, vec!(), vec!(i, i+max));
- let a_curr_gt_b_curr_gate_index = all_gates.len();
- indices[key] = a_curr_gt_b_curr_gate_index;
- all_gates.push(a_i_eq_b_i_gate);
- }
- let eq_gate_index = indices[key];
-
- //print!("&& ({}) ", format!("{} = {}", format!("A{}", key), format!("B{}", key)));
-
- // Index of this equality gate
- this_recursion_gate_indices.push(eq_gate_index);
- }
-
- let and_curr_index = all_gates.len();
- let and_curr_gate = Gate::new(GateType::And, this_recursion_gate_indices, vec!());
-
- all_gates.push(and_curr_gate);
- and_gate_incides.push(and_curr_index);
-
- if curr+1 == max {
- //println!(")");
- return;
- }
- //println!(") ||");
- return rec_n_bit_comperator_gates(curr+1, max, all_gates, and_gate_incides, indices);
- }
|