#!/usr/bin/env python3
# Compare stage-C parses window by window: our Link Grammar run vs Linas's recorded parses-C.
# A parse is compared as the multiset of its Sections (bond names are issued by a counter, so they differ).
# diffsect.py <linas-parses-C.tsv> <ours.tsv> [max-window]
import sys
from collections import Counter, defaultdict
def load(path, maxw):
d = defaultdict(Counter)
for line in open(path):
parts = line.rstrip('\n').split('\t', 2)
if len(parts) != 3: continue # LG trace lines on stdout
w, p, atom = parts
w = int(w)
if maxw is not None and w >= maxw: continue
if atom.startswith('(Section '): d[(w, int(p))][atom] += 1
return d
maxw = int(sys.argv[3]) if len(sys.argv) > 3 else None
L, O = load(sys.argv[1], maxw), load(sys.argv[2], maxw)
wins = sorted({k[0] for k in L} | {k[0] for k in O})
exact = top1 = same_set = 0
first_bad = []
for w in wins:
lp = [L[k] for k in sorted(k for k in L if k[0] == w)]
op = [O[k] for k in sorted(k for k in O if k[0] == w)]
if lp == op: exact += 1
elif len(first_bad) < 3: first_bad.append(w)
if lp and op and lp[0] == op[0]: top1 += 1
if sorted(map(lambda c: tuple(sorted(c.items())), lp)) == sorted(map(lambda c: tuple(sorted(c.items())), op)): same_set += 1
print(f'windows {len(wins)}: identical parses in order {exact}; same top parse {top1}; same set of parses (any order) {same_set}')
for w in first_bad:
lp = [L[k] for k in sorted(k for k in L if k[0] == w)]
op = [O[k] for k in sorted(k for k in O if k[0] == w)]
print(f'-- window {w}: linas {len(lp)} parses, ours {len(op)}')
if lp and op:
print(' only linas (parse 0):', list((lp[0] - op[0]).elements())[:3])
print(' only ours (parse 0):', list((op[0] - lp[0]).elements())[:3])