@@ -39,6 +39,13 @@ class Latch:
3939 init : bool = attr .ib (converter = bool )
4040
4141
42+ @attr .s (auto_attribs = True , frozen = True )
43+ class And :
44+ lhs : int
45+ rhs0 : int
46+ rhs1 : int
47+
48+
4249@attr .s (auto_attribs = True , frozen = True )
4350class Symbol :
4451 kind : str
@@ -60,9 +67,10 @@ class SymbolTable:
6067@attr .s (auto_attribs = True )
6168class State :
6269 header : Optional [Header ] = None
63- inputs : List [str ] = attr .ib (factory = list )
64- outputs : List [str ] = attr .ib (factory = list )
65- latches : List [str ] = attr .ib (factory = list )
70+ inputs : List [int ] = attr .ib (factory = list )
71+ outputs : List [int ] = attr .ib (factory = list )
72+ latches : List [Latch ] = attr .ib (factory = list )
73+ ands : List [And ] = attr .ib (factory = list )
6674 symbols : SymbolTable = attr .ib (factory = SymbolTable )
6775 comments : Optional [List [str ]] = None
6876 nodes : SortedDict = attr .ib (factory = SortedDict )
@@ -79,6 +87,10 @@ def remaining_outputs(self):
7987 def remaining_inputs (self ):
8088 return self .header .num_inputs - len (self .inputs )
8189
90+ @property
91+ def remaining_ands (self ):
92+ return self .header .num_ands - len (self .ands )
93+
8294
8395def _consume_stream (stream , delim ) -> str :
8496 line = bytearray ()
@@ -225,40 +237,38 @@ def _read_delta(data):
225237
226238
227239def _add_and (state , elems ):
228- elems = fn .lmap (int , elems )
229- state .header . num_ands -= 1
230- deps = set ( elems [ 1 :])
231- state .nodes [elems [ 0 ] ] = deps
240+ lhs , rhs0 , rhs1 = fn .lmap (int , elems )
241+ state .ands . append ( And ( lhs , rhs0 , rhs1 ))
242+ deps = { rhs0 , rhs1 }
243+ state .nodes [lhs ] = deps
232244 for dep in deps :
233245 if dep & 1 :
234246 state .nodes [dep ] = {dep ^ 1 }
235247
236248
237249def parse_and (state , stream ) -> bool :
238- if state .header . num_ands <= 0 :
250+ if state .remaining_ands <= 0 :
239251 return False
240252
241253 if state .header .binary_mode :
242- lhs = 2 * (state .header .num_inputs + state .header .num_latches )
243- for i in range (state .header .num_ands ):
244- lhs += 2
245- delta = _read_delta (stream )
246- if delta > lhs :
247- raise ValueError (f"Invalid lhs { lhs } or delta { delta } " )
248- rhs0 = lhs - delta
249- delta = _read_delta (stream )
250- if delta > rhs0 :
251- raise ValueError (f"Invalid rhs0 { rhs0 } or delta { delta } " )
252- rhs1 = rhs0 - delta
253- _add_and (state , (lhs , rhs0 , rhs1 ))
254-
254+ idx = state .header .num_inputs + state .header .num_latches + len (state .ands ) + 1
255+ lhs = 2 * idx
256+ delta = _read_delta (stream )
257+ if delta > lhs :
258+ raise ValueError (f"Invalid lhs { lhs } or delta { delta } " )
259+ rhs0 = lhs - delta
260+ delta = _read_delta (stream )
261+ if delta > rhs0 :
262+ raise ValueError (f"Invalid rhs0 { rhs0 } or delta { delta } " )
263+ rhs1 = rhs0 - delta
255264 else :
256265 line = _consume_stream (stream , '\n ' )
257266 match = AND_PATTERN .match (line )
258267 if match is None :
259268 raise ValueError (f"Expecting an and: { line } " )
269+ lhs , rhs0 , rhs1 = match .groups ()
260270
261- _add_and (state , match . groups ( ))
271+ _add_and (state , ( lhs , rhs0 , rhs1 ))
262272 return True
263273
264274
@@ -334,7 +344,7 @@ def parse(stream):
334344 if parser not in (parse_header , parse_output , parse_comment , parse_symbol ):
335345 raise ValueError (DONE_PARSING_ERROR .format (state ))
336346
337- assert state .header . num_ands == 0
347+ assert state .remaining_ands == 0
338348 assert state .remaining_inputs == 0
339349 assert state .remaining_outputs == 0
340350 assert state .remaining_latches == 0
@@ -349,6 +359,7 @@ def parse(stream):
349359
350360 # Create expression DAG.
351361 latch_ids = {latch .id : name for name , latch in latches .items ()}
362+ and_ids = {and_ .lhs : and_ for and_ in state .ands }
352363 lit2expr = {0 : A .aig .ConstFalse ()}
353364 for lit in toposort_flatten (state .nodes ):
354365 if lit == 0 :
@@ -361,6 +372,7 @@ def parse(stream):
361372 elif lit & 1 :
362373 lit2expr [lit ] = A .aig .Inverter (lit2expr [lit & - 2 ])
363374 else :
375+ assert lit in and_ids
364376 nodes = [lit2expr [lit2 ] for lit2 in state .nodes [lit ]]
365377 lit2expr [lit ] = reduce (A .aig .AndGate , nodes )
366378
0 commit comments