def cfpq_hellings(g: LabelGraph, cfg: GrammarCNF): num_vert = g.num_vert start_sym = cfg.start_symbol result = LabelGraph() result.num_vert = num_vert m = deque() for variable in cfg.variables: result.graph_dict[variable] = Matrix.sparse(BOOL, num_vert, num_vert) if cfg.generate_epsilon(): for v in range(num_vert): result.graph_dict[start_sym][v, v] = True for label in g.graph_dict: term = Terminal(label) result.graph_dict[term] = g.graph_dict[label].dup() for v_from, v_to in g.get_edges(label): for production in cfg.productions: if (len(production.body) == 1 and production.body[0] == term): head = production.head result.graph_dict[head][v_from, v_to] = True for label in result.graph_dict: for i, j in result.get_edges(label): m.append((label, i, j)) # 3rd step: cfpq on modified matrix while m: var, v, u = m.popleft() for var_left in result.graph_dict: for v_new, v_ in result.get_edges(var_left): if (v_ == v): for production in cfg.pair_productions: if (production.body[1] == var and production.body[0] == var_left): if (v_new, u) not in result.get_edges( production.head): result.graph_dict[production.head][v_new, u] = True m.append((production.head, v_new, u)) for var_right in result.graph_dict: for u_, u_new in result.get_edges(var_right): if (u_ == u): for production in cfg.pair_productions: if (production.body[1] == var_right and production.body[0] == var): if (v, u_new) not in result.get_edges( production.head): result.graph_dict[production.head][ v, u_new] = True m.append((production.head, v, u_new)) return result.graph_dict[start_sym]
def cfpq_matrix_mult(g: LabelGraph, cfg: GrammarCNF): num_vert = g.num_vert if (num_vert == 0): return Matrix.sparse(BOOL, num_vert, num_vert) result = LabelGraph() start_sym = cfg.start_symbol result.num_vert = num_vert for variable in cfg.variables: result.graph_dict[variable] = Matrix.sparse(BOOL, num_vert, num_vert) for label in g.graph_dict: term = Terminal(label) result.graph_dict[term] = g.graph_dict[label].dup() for v_from, v_to in g.get_edges(label): for production in cfg.productions: if (len(production.body) == 1 and production.body[0] == term): head = production.head result.graph_dict[head][v_from, v_to] = True if cfg.generate_epsilon(): for v in g.vertices: result.graph_dict[start_sym][v, v] = True matrix_changing = True with semiring.LOR_LAND_BOOL: while matrix_changing: matrix_changing = False for production in cfg.pair_productions: head = production.head body = production.body prev_nvals = result.graph_dict[head].nvals tmp = result.graph_dict[body[0]] @ result.graph_dict[body[1]] result.graph_dict[head] = result.graph_dict[head] + tmp if (prev_nvals != result.graph_dict[head].nvals): matrix_changing = True return result.graph_dict[start_sym]