| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 | 
							- use crate::gate_type::GateType;
 - 
 - #[derive(Debug, Clone)]
 - pub struct Gate {
 -     pub gate_type: GateType,
 -     pub input_gates_indices: Vec<usize>, // Which previous gates to use
 -     pub input_bits_indices: Vec<usize>,  // Which input bits to use
 - }
 - 
 - impl Gate {
 -     pub fn new(
 -         gate_type: GateType,
 -         input_gates_indices: Vec<usize>,
 -         input_bits_indices: Vec<usize>,
 -     ) -> Self {
 -         let num_input_wires = input_bits_indices.len() + input_gates_indices.len();
 - 
 -         if num_input_wires == 0 {
 -             panic!("A gate without inputs is invalid");
 -         }
 - 
 -         if gate_type == GateType::Bigger && num_input_wires != 2 {
 -             if num_input_wires != 2 {
 -                 panic!("Bigger gates need exactly two inputs")
 -             }
 -         }
 - 
 -         if gate_type == GateType::Equal && num_input_wires != 2 {
 -             if num_input_wires != 2 {
 -                 panic!("Equal gates need exactly two inputs")
 -             }
 -         }
 -         Self {
 -             gate_type,
 -             input_gates_indices,
 -             input_bits_indices,
 -         }
 -     }
 - 
 -     pub fn eval(&self, input_bits: &Vec<bool>, evaluated_gates: &Vec<bool>) -> bool {
 -         /*
 -             The goal is to perform short-circuit evaluation with the minimum number of vector lookups.
 -         */
 - 
 -         match self.gate_type {
 -             /*
 -                 A multi-input gate that outputs 1 if all input bits are 1, and 0 otherwise
 -             */
 -             GateType::And => {
 - 
 -                 for &index in self.input_bits_indices.iter(){
 -                     if !input_bits[index] {
 -                         return false;
 -                     }
 -                 }
 -                 for &index in self.input_gates_indices.iter(){
 -                     if !evaluated_gates[index] {
 -                         return false;
 -                     }
 -                 }
 - 
 -                 return true;
 -             }
 - 
 -             /*
 -                 A multi-input gate that outputs 1 if at least one input bit is 1, and 0 otherwise.   
 -             */
 -             GateType::Or => {
 -                 for &index in self.input_bits_indices.iter(){
 -                     if input_bits[index] {
 -                         return true;
 -                     }
 -                 }
 -                 for &index in self.input_gates_indices.iter(){
 -                     if evaluated_gates[index] {
 -                         return true;
 -                     }
 -                 }
 -                 return false;
 -             },
 - 
 -             /*
 -                 A gate with exactly two inputs. It outputs 1 if the two input bits are equal 
 -                 (i.e., both 0 or both 1), and 0 otherwise
 -             */            
 -             GateType::Equal => match self.input_bits_indices.len() {
 -                 0 => evaluated_gates[self.input_gates_indices[0]] == evaluated_gates[self.input_gates_indices[1]],
 -                 1 => input_bits[self.input_bits_indices[0]] == evaluated_gates[self.input_gates_indices[0]],
 -                 2 => {
 -                     input_bits[self.input_bits_indices[0]] == input_bits[self.input_bits_indices[1]]
 -                 },
 -                 _ => panic!{"How'd we get here?"}
 -             },
 - 
 -             /*
 -                 A gate with exactly two inputs. It outputs 1 if the first input is 1 and the second
 -                 input is 0; otherwise, it outputs 0. This gate is used to compare individual bits a_i > b_i
 - 
 -                 A B | A > B | A && !B
 -                 --------------------
 -                 0 0 |   0   | 0 0  1
 -                 0 1 |   0   | 0 0  0
 -                 1 0 |   1   | 1 1  1
 -                 1 1 |   0   | 1 0  0
 -             */
 -             GateType::Bigger => match self.input_bits_indices.len() {
 -                 // bits: [] gates: [A,B]
 -                 0 => evaluated_gates[self.input_gates_indices[0]] && !evaluated_gates[self.input_gates_indices[1]],
 -                 
 -                 // bits: [A] gates: [B]
 -                 1 => input_bits[self.input_bits_indices[0]] && !evaluated_gates[self.input_gates_indices[0]],
 -                 
 -                 // bits: [A,B] gates: []
 -                 2 => {
 -                     input_bits[self.input_bits_indices[0]] && !input_bits[self.input_bits_indices[1]]
 -                 },
 - 
 -                 _ => panic!{"How'd we get here? {}", input_bits.len()}
 -             },
 -         }
 -     }
 - }
 
 
  |