1use blanket::blanket;
8
9use std::hash::Hash;
10use std::ops::*;
11
12use crate::networks::SimplifyResult;
13use crate::traits::BooleanFunction;
14use crate::traits::LogicValue;
15
16use crate::{traits::IdType, truth_table::small_lut::SmallTruthTable};
17
18#[blanket(derive(Ref, Mut))]
20pub trait Network {
21 type Node: NetworkNode<NodeId = Self::Signal>;
23 type NodeId: Clone + PartialEq + Eq + Hash + Send + Sync + std::fmt::Debug + 'static;
25 type Signal: Copy + Clone + PartialEq + Eq + Hash + Send + Sync + std::fmt::Debug + 'static;
27 type LogicValue: LogicValue;
29 type NodeFunction: BooleanFunction;
31
32 fn foreach_gate(&self, f: impl Fn(Self::Signal));
35
36 fn foreach_node(&self, f: impl Fn(&Self::Node));
38
39 fn get_constant(&self, value: Self::LogicValue) -> Self::Signal;
41
42 fn get_constant_value(&self, signal: Self::Signal) -> Option<Self::LogicValue>;
44
45 fn get_node_input(&self, node: &Self::NodeId, input_index: usize) -> Self::Signal;
47
48 fn get_node_output(&self, node: &Self::NodeId) -> Self::Signal;
50
51 fn get_source_node(&self, signal: &Self::Signal) -> Self::NodeId;
53
54 fn get_primary_input(&self, index: usize) -> Self::Signal;
56
57 fn get_primary_output(&self, index: usize) -> Self::Signal;
59
60 fn is_constant(&self, signal: Self::Signal) -> bool {
62 self.get_constant_value(signal).is_some()
63 }
64
65 fn is_input(&self, signal: Self::Signal) -> bool;
67
68 fn node_function(&self, node: Self::NodeId) -> Self::NodeFunction;
70
71 fn num_gates(&self) -> usize;
73
74 fn num_node_inputs(&self, node: &Self::NodeId) -> usize;
76
77 fn num_primary_inputs(&self) -> usize;
79
80 fn num_primary_outputs(&self) -> usize;
82}
83
84pub trait HomogeneousNetwork: Network {
86 const NUM_NODE_INPUTS: usize;
88
89 fn function(&self) -> Self::NodeFunction;
91}
92
93pub trait ImmutableNot: Network {
96 fn get_inverted(&self, a: Self::Signal) -> Self::Signal;
98
99 fn is_inverted(&self, a: Self::Signal) -> bool;
101}
102
103pub trait ReferenceCounted: Network {
105 fn num_references(&self, a: Self::Signal) -> usize;
107}
108
109#[blanket(derive(Mut))]
111pub trait NetworkEdit: Network {
112 fn create_primary_input(&mut self) -> Self::Signal;
114
115 fn create_primary_output(&mut self, signal: Self::Signal) -> Self::Signal;
117
118 fn substitute(&mut self, old: Self::Signal, new: Self::Signal);
120
121 fn create_node(&mut self, node: Self::Node) -> Self::NodeId;
125
126 fn foreach_node_mut(&mut self, f: impl Fn(&mut Self::Node));
128}
129
130#[blanket(derive(Mut))]
132pub trait SubstituteInNode: Network {
133 fn substitute_in_node(
135 &mut self,
136 node: Self::NodeId,
137 old_signal: Self::Signal,
138 new_signal: Self::Signal,
139 );
140}
141
142pub trait NetworkShortcuts: Network {
144 fn primary_inputs(&self) -> Box<dyn Iterator<Item = Self::NodeId> + '_> {
146 Box::new(
147 (0..self.num_primary_inputs())
148 .map(|i| self.get_source_node(&self.get_primary_input(i))),
149 )
150 }
151
152 fn primary_outputs(&self) -> Box<dyn Iterator<Item = Self::Signal> + '_> {
154 Box::new((0..self.num_primary_outputs()).map(|i| self.get_primary_output(i)))
155 }
156}
157impl<T> NetworkShortcuts for T where T: Network {}
158
159pub trait NetworkEditShortcuts: NetworkEdit {
161 fn create_primary_inputs<const NUM_INPUTS: usize>(&mut self) -> [Self::Signal; NUM_INPUTS] {
163 [(); NUM_INPUTS].map(|_| self.create_primary_input())
164 }
165}
166
167impl<T> NetworkEditShortcuts for T where T: NetworkEdit {}
168
169#[blanket(derive(Mut))]
171pub trait UnaryOp: NetworkEdit {
172 fn create_buffer(&mut self, signal: Self::Signal) -> Self::Signal {
174 signal
175 }
176 fn create_not(&mut self, signal: Self::Signal) -> Self::Signal;
178}
179
180#[blanket(derive(Mut))]
182pub trait BinaryOp: UnaryOp {
183 fn create_and(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal;
185 fn create_or(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal;
187 fn create_nand(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal;
189 fn create_nor(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal;
191 fn create_xor(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal;
193
194 fn create_xnor(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal {
196 let xor = self.create_xor(a, b);
197 self.create_not(xor)
198 }
199 fn create_lt(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal {
201 let a_not = self.create_not(a);
202 self.create_and(a_not, b)
203 }
204 fn create_le(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal {
206 let a_not = self.create_not(a);
207 self.create_or(a_not, b)
208 }
209 fn create_gt(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal {
211 self.create_lt(b, a)
212 }
213 fn create_ge(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal {
215 self.create_le(b, a)
216 }
217
218 fn create_implies(&mut self, a: Self::Signal, b: Self::Signal) -> Self::Signal {
220 let a_not = self.create_not(a);
221 self.create_or(a_not, b)
222 }
223}
224
225#[blanket(derive(Mut))]
227pub trait TernaryOp: BinaryOp {
228 fn create_maj3(&mut self, a: Self::Signal, b: Self::Signal, c: Self::Signal) -> Self::Signal {
230 let ab = self.create_and(a, b);
232 let bc = self.create_and(b, c);
233 let ac = self.create_and(a, c);
234
235 let bc_or_ac = self.create_or(bc, ac);
236
237 self.create_or(ab, bc_or_ac)
238 }
239
240 fn create_ite(
242 &mut self,
243 condition: Self::Signal,
244 then: Self::Signal,
245 otherwise: Self::Signal,
246 ) -> Self::Signal {
247 let condition_not = self.create_not(condition);
249 let a = self.create_and(condition, then);
250 let b = self.create_and(condition_not, otherwise);
251 self.create_or(a, b)
252 }
253
254 fn create_xor3(&mut self, a: Self::Signal, b: Self::Signal, c: Self::Signal) -> Self::Signal {
256 let axb = self.create_xor(a, b);
257 self.create_xor(axb, c)
258 }
259}
260
261#[blanket(derive(Mut))]
263pub trait NAryOp: TernaryOp {
264 fn create_nary_and(&mut self, inputs: impl Iterator<Item = Self::Signal>) -> Self::Signal {
266 inputs
268 .reduce(|acc, s| self.create_and(acc, s))
269 .unwrap_or(self.get_constant(<Self as Network>::LogicValue::one()))
270 }
271
272 fn create_nary_or(&mut self, inputs: impl Iterator<Item = Self::Signal>) -> Self::Signal {
274 inputs
276 .reduce(|acc, s| self.create_or(acc, s))
277 .unwrap_or(self.get_constant(<Self as Network>::LogicValue::zero()))
278 }
279}
280
281pub trait NetworkNode: Clone + Eq + PartialEq {
283 type NodeId: IdType;
285
286 fn num_inputs(&self) -> usize;
288
289 fn get_input(&self, i: usize) -> Self::NodeId;
293
294 fn function(&self) -> SmallTruthTable;
296
297 fn normalized(self) -> SimplifyResult<Self, Self::NodeId>;
304}
305
306pub trait MutNetworkNode: NetworkNode {
308 fn set_input(&mut self, i: usize, signal: Self::NodeId);
310}
311
312pub trait NetworkNodeWithReferenceCount: NetworkNode {
314 fn num_references(&self) -> usize;
316}
317
318pub trait StaticFunction {
320 }
322
323pub trait StaticInputDegree<const NUM_INPUTS: usize>: NetworkNode {
325 fn to_array(&self) -> [Self::NodeId; NUM_INPUTS];
327}
328
329pub trait MutNetworkNodeWithReferenceCount: NetworkNodeWithReferenceCount {
331 fn reference(&mut self);
333
334 fn dereference(&mut self);
338}
339
340pub trait Edge: Sized {}
342
343pub trait EdgeWithInversion: Edge {
345 fn is_inverted(&self) -> bool;
347
348 fn invert(self) -> Self;
350
351 fn invert_if(self, condition: bool) -> Self {
353 if condition {
354 self.invert()
355 } else {
356 self
357 }
358 }
359
360 fn non_inverted(self) -> Self {
362 if self.is_inverted() {
364 self.invert()
365 } else {
366 self
367 }
368 }
369}