You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

circuit.rs 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. use crate::{gate::Gate, gate_type::GateType};
  2. #[derive(Debug, Clone)]
  3. pub struct Circuit {
  4. pub input_bits: Vec<bool>, // Input wires
  5. pub gates: Vec<Gate>, // All gates
  6. }
  7. impl Circuit {
  8. pub fn eval(self) -> bool {
  9. let mut evaluated_gates = vec!();
  10. for gate in self.gates {
  11. let result = gate.eval(&self.input_bits, &evaluated_gates);
  12. evaluated_gates.push(result);
  13. }
  14. match evaluated_gates.pop() {
  15. Some(result) => result,
  16. None => panic!("Bruh moment")
  17. }
  18. }
  19. /*
  20. This method should create a circuit that outputs 1 if the first number A (encoded in the first n
  21. bits) is greater than the second number B (encoded in the next n bits) .
  22. */
  23. pub fn compare_n_bit_numbers(input_bits: Vec<bool>, n: usize) -> Self {
  24. if input_bits.len() < 2*n {
  25. panic!("Expected input_bits to be of at least length {}, but it was {}", 2*n, input_bits.len())
  26. }
  27. /*
  28. base case n=1: 1-bit:
  29. A B | A > B
  30. -----------
  31. 0 0 | 0
  32. 0 1 | 0
  33. 1 0 | 1
  34. 1 1 | 0
  35. n+1 case: 2-bit:
  36. A1 A0 B1 B0 | A > B | (A1 > B1) || ((A1 == B1) && (A0 > B0))
  37. ----------------------|------------------------------------
  38. 0 0 0 0 | 0 | 0
  39. 0 0 0 1 | 0 | 0
  40. 0 0 1 0 | 0 | 0
  41. 0 0 1 1 | 0 | 0
  42. 0 1 0 0 | 1 | 1
  43. 0 1 0 1 | 0 | 0
  44. 0 1 1 0 | 0 | 0
  45. 0 1 1 1 | 1 | 1
  46. 1 0 0 0 | 1 | 1
  47. 1 0 0 1 | 1 | 1
  48. 1 0 1 0 | 0 | 0
  49. 1 0 1 1 | 0 | 0
  50. 1 1 0 0 | 1 | 1
  51. 1 1 0 1 | 1 | 1
  52. 1 1 1 0 | 1 | 1
  53. 1 1 1 1 | 0 | 0
  54. The inductive pattern should become apparent now.
  55. For illustration here's the case for n=4, which should show the
  56. recursive characteristics of the formula.
  57. (A3 > B3) ||
  58. ((A3 == B3) && (A2 > B2)) ||
  59. ((A3 == B3) && (A2 == B2) && (A1 > B1)) ||
  60. ((A3 == B3) && (A2 == B2) && (A1 == B1)) && (A0 > B0))
  61. */
  62. let gates = create_n_bit_comparator_gates(n);
  63. return Circuit { input_bits, gates }
  64. }
  65. }
  66. fn create_n_bit_comparator_gates(n: usize) -> Vec<Gate>{
  67. let mut indices: Vec<usize> = vec![0; n];
  68. let mut all_gates: Vec<Gate> = vec!();
  69. let mut and_gate_indices: Vec<usize> = vec!();
  70. rec_n_bit_comperator_gates(0, n, &mut all_gates, &mut and_gate_indices, &mut indices, );
  71. // the OR spanning all ANDs
  72. let or_gate = Gate::new( GateType::Or, and_gate_indices, vec!());
  73. all_gates.push(or_gate);
  74. return all_gates;
  75. }
  76. 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>){
  77. // Incrementing gate index
  78. let a_curr_gt_b_curr_gate_index = all_gates.len();
  79. // Gate(A_current > B_current)
  80. let a_curr_gt_b_curr_gate = Gate::new(GateType::Bigger, vec!(), vec!(curr, curr+max));
  81. // A_current>B_current
  82. //print!(" ( ({}) ", format!("{} > {}", format!("A{}", max-1-curr), format!("B{}", max-1-curr)));
  83. all_gates.push(a_curr_gt_b_curr_gate);
  84. let mut this_recursion_gate_indices: Vec<usize> = vec!(a_curr_gt_b_curr_gate_index);
  85. for i in 0..curr {
  86. let key = max-1-i;
  87. if i == curr-1 {
  88. // Gate(A_current > B_current)
  89. let a_i_eq_b_i_gate = Gate::new(GateType::Equal, vec!(), vec!(i, i+max));
  90. let a_curr_gt_b_curr_gate_index = all_gates.len();
  91. indices[key] = a_curr_gt_b_curr_gate_index;
  92. all_gates.push(a_i_eq_b_i_gate);
  93. }
  94. let eq_gate_index = indices[key];
  95. //print!("&& ({}) ", format!("{} = {}", format!("A{}", key), format!("B{}", key)));
  96. // Index of this equality gate
  97. this_recursion_gate_indices.push(eq_gate_index);
  98. }
  99. let and_curr_index = all_gates.len();
  100. let and_curr_gate = Gate::new(GateType::And, this_recursion_gate_indices, vec!());
  101. all_gates.push(and_curr_gate);
  102. and_gate_incides.push(and_curr_index);
  103. if curr+1 == max {
  104. //println!(")");
  105. return;
  106. }
  107. //println!(") ||");
  108. return rec_n_bit_comperator_gates(curr+1, max, all_gates, and_gate_incides, indices);
  109. }