Last active
August 7, 2023 01:22
-
-
Save Lipen/f96b7803783123a8837a6060c0ca1e0d to your computer and use it in GitHub Desktop.
Binary DRAT parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mmap | |
import tqdm | |
def parse_binary_drat_mmap(path): | |
with open(path, "rb") as f: | |
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm: | |
state = 0 | |
# state = 0 -- reading the mode: b'a' or b'd' | |
# state = 1 -- reading the clause | |
mode = None # "a" or "d", for user | |
lit = 0 | |
shift = 0 | |
clause = [] | |
for b in mm: | |
if state == 0: | |
# Begin parsing a clause | |
if b == b"a": | |
mode = "a" | |
elif b == b"d": | |
mode = "d" | |
else: | |
raise ValueError(f"Bad clause header: {b}") | |
clause = [] | |
lit = 0 | |
shift = 0 | |
state = 1 | |
elif state == 1: | |
lit |= (ord(b) & 127) << shift | |
shift += 7 | |
if ord(b) <= 127: | |
# Finish parsing a literal | |
if lit % 2: | |
lit = -(lit >> 1) | |
else: | |
lit = lit >> 1 | |
if lit == 0: | |
# Finish parsing a clause | |
yield (mode, clause) | |
mode = None | |
state = 0 | |
else: | |
clause.append(lit) | |
# Reset parsing a literal | |
lit = 0 | |
shift = 0 | |
else: | |
raise ValueError(f"Bad state: {state}") | |
def parse_binary_drat(path): | |
def read_lit(file): | |
lit = 0 | |
shift = 0 | |
while True: | |
lc = file.read(1) | |
if not lc: | |
return | |
lit |= (ord(lc) & 127) << shift | |
shift += 7 | |
if ord(lc) <= 127: | |
break | |
if lit % 2: | |
return -(lit >> 1) | |
else: | |
return lit >> 1 | |
with open(path, "rb") as f: | |
while True: | |
b = f.read(1) | |
# Handle EOF: | |
if not b: | |
return | |
# Determine whether the clause was "added" or "deleted": | |
if b == b"a": | |
mode = "a" | |
elif b == b"d": | |
mode = "d" | |
else: | |
raise ValueError(f"Bad clause header: {mode}") | |
# Read the clause: | |
clause = [] | |
while True: | |
lit = read_lit(f) | |
if lit == 0: | |
# End of the clause | |
break | |
elif lit is None: | |
raise ValueError("Could not read literal") | |
else: | |
# Another literal in the clause | |
clause.append(lit) | |
# Return the clause: | |
yield (mode, clause) | |
clauses_added = [] | |
clauses_deleted = [] | |
for mode, clause in tqdm.tqdm(parse_binary_drat_mmap("proof.drat")): | |
if mode == "a": | |
clauses_added.append(clause) | |
elif mode == "d": | |
clauses_deleted.append(clause) | |
else: | |
raise ValueError(f"Bad clause mode '{mode}'") | |
print(f"Parsed {len(clauses_added)} added clauses from DRAT file") | |
print(f"Parsed {len(clauses_deleted)} deleted clauses from DRAT file") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment