def get_parse_chart(marginal, N, r3_lookupC): # {A, (B, C, k)} k is the splitting point parse_chart = make_tuple_chart(N) score_chart = make_chart(N) for i in range(N): for nonterm, score in marginal[i][i].items(): parse_chart[i][i][nonterm] = (-1, -1, -1) score_chart[i][i][nonterm] = score for length in range(2, N + 1): for i in range(N - length + 1): j = i + length - 1 for k in range(i, j): if len(parse_chart[k + 1][j]) == 0 or len( parse_chart[i][k]) == 0: continue for c in parse_chart[k + 1][j]: if c not in r3_lookupC: continue for rule in r3_lookupC[c]: a, b, _ = hash_backward(rule) if b not in parse_chart[i][k]: continue if a not in marginal[i][j]: continue score = marginal[i][j][a] + score_chart[i][k][ b] + score_chart[k + 1][j][c] if a not in parse_chart[i][ j] or score_chart[i][j][a] < score: parse_chart[i][j][a] = (b, c, k) score_chart[i][j][a] = score return parse_chart, score_chart
def fill_inside_base(inside, terminals, N, r1, r1_lookup, constrains): for i in range(N): for rule in r1_lookup[terminals[i]]: a, _, _ = hash_backward(rule) if a not in constrains[i][i]: continue inside[i][i][a] = r1[rule]
def fill_outside(outside, inside, N, r3, r3_lookupC): for length in range(N - 1, 0, -1): for i in range(N - length + 1): j = i + length - 1 if len(inside[i][j]) == 0: continue for k in range(i): if len(outside[k][j]) == 0 or len(inside[k][i - 1]) == 0: continue for c in inside[i][j]: if c not in r3_lookupC: continue for rule in r3_lookupC[c]: a, b, _ = hash_backward(rule) if a not in outside[k][j]: continue if b not in inside[k][i - 1]: continue res = Tij(r3[rule], outside[k][j][a], inside[k][i - 1][b]) if c not in outside[i][j]: outside[i][j][c] = res else: outside[i][j][c] += res for k in range(j + 1, N): if len(outside[i][k]) == 0 or len(inside[j + 1][k]) == 0: continue for c in inside[j + 1][k]: if c not in r3_lookupC: continue for rule in r3_lookupC[c]: a, b, _ = hash_backward(rule) if a not in outside[i][k]: continue if b not in inside[i][j]: continue res = Tik(r3[rule], outside[i][k][a], inside[j + 1][k][c]) if b not in outside[i][j]: outside[i][j][b] = res else: outside[i][j][b] += res
def add_unary_inside(d, r2, r2_lookupR): for b in d: if b not in r2_lookupR: continue for rule in r2_lookupR[b]: a, _, _ = hash_backward(rule) res = r2[rule] * d[b] if a not in d: d[a] = res else: d[a] += res
def add_unary_outside(d, r2, r2_lookupL, d_inside): for a in d: if a not in r2_lookupL: continue for rule in r2_lookupL[a]: _, b, _ = hash_backward(rule) if b not in d_inside: continue res = d[a] * r2[rule] if b not in d: d[b] = res else: d[b] += res
def fill_inside(inside, N, r3, r3_lookupC): for length in range(2, N + 1): for i in range(N - length + 1): j = i + length - 1 for k in range(i, j): if len(inside[k + 1][j]) == 0 or len(inside[i][k]) == 0: continue for c in inside[k + 1][j]: if c not in r3_lookupC: continue for rule in r3_lookupC[c]: a, b, _ = hash_backward(rule) if b not in inside[i][k]: continue res = r3[rule] * inside[i][k][b] * inside[k + 1][j][c] if a not in inside[i][j]: inside[i][j][a] = res else: inside[i][j][a] += res
def fill_inside_base(inside, terminals, N, r1, r1_lookup): for i in range(N): for rule in r1_lookup[terminals[i]]: a, _, _ = hash_backward(rule) inside[i][i][a] = r1[rule]