22from functools import reduce
33from typing import Tuple , FrozenSet , NamedTuple , Union
44
5+ import attr
56import funcy as fn
67from toposort import toposort
78
@@ -66,7 +67,8 @@ def _is_const_true(node):
6667Node = Union [AndGate , ConstFalse , Inverter , Input , LatchIn ]
6768
6869
69- class AIG (NamedTuple ):
70+ @attr .s (frozen = True , slots = True , auto_attribs = True , repr = False )
71+ class AIG :
7072 inputs : FrozenSet [str ] = frozenset ()
7173 node_map : FrozenSet [Tuple [str , Node ]] = frozenset ()
7274 latch_map : FrozenSet [Tuple [str , Node ]] = frozenset ()
@@ -79,9 +81,7 @@ def __repr__(self):
7981 return repr (self ._to_aag ())
8082
8183 def __getitem__ (self , others ):
82- if not isinstance (others , tuple ):
83- return super ().__getitem__ (others )
84-
84+ assert isinstance (others , tuple ) and len (others ) == 2
8585 kind , relabels = others
8686 assert kind in {'i' , 'o' , 'l' }
8787
@@ -98,6 +98,9 @@ def __getitem__(self, others):
9898 input_kinds = (Input ,) if kind == 'i' else (LatchIn ,)
9999 return seq_compose (cmn .tee (relabels ), self , input_kinds = input_kinds )
100100
101+ def evolve (self , ** kwargs ):
102+ return attr .evolve (self , ** kwargs )
103+
101104 @property
102105 def outputs (self ):
103106 return frozenset (fn .pluck (0 , self .node_map ))
@@ -165,7 +168,7 @@ def sub(node):
165168
166169 circ = self ._modify_leafs (sub )
167170 _cones = {(l_map [k ][0 ], v ) for k , v in circ .latch_map if k in latches }
168- aig = self ._replace (
171+ aig = self .evolve (
169172 node_map = circ .node_map | _cones ,
170173 inputs = self .inputs | {n for n , _ in l_map .values ()},
171174 latch_map = {(k , v ) for k , v in circ .latch_map if k not in latches },
@@ -201,7 +204,7 @@ def sub(node):
201204 out2latch = {oname : lname for oname , lname in zip (outputs , latches )}
202205 _latch_map = {(out2latch [k ], v ) for k , v in _latch_map }
203206 l2init = frozenset ((n , val ) for n , val in zip (latches , initials ))
204- return aig ._replace (
207+ return aig .evolve (
205208 inputs = aig .inputs - set (inputs ),
206209 node_map = aig .node_map if keep_outputs else frozenset (node_map ),
207210 latch_map = aig .latch_map | _latch_map ,
@@ -261,7 +264,7 @@ def _mod(node):
261264
262265 node_map = ((name , _mod (cone )) for name , cone in self .node_map )
263266 latch_map = ((name , _mod (cone )) for name , cone in self .latch_map )
264- return self ._replace (
267+ return self .evolve (
265268 node_map = frozenset (node_map ),
266269 latch_map = frozenset (latch_map )
267270 )
0 commit comments