def test_empty_productions(): """Testa a simplificação de produções vazias""" terminals = ["a", "b"] variables = ["S", "X", "Y"] initial = "S" rules = { "S": [["a", "X", "a"], ["b", "X", "b"], ["V"]], "X": [["a"], ["b"], ["Y"]], "Y": [["V"]] } original_grammar = Grammar(variables, terminals, rules, initial) terminals = ["a", "b"] variables = ["S", "X", "Y"] initial = "S" rules = { "S": [["a", "X", "a"], ["b", "X", "b"], ["a", "a"], ["b", "b"], ["V"]], "X": [["a"], ["b"], ["Y"]] } expected_grammar = Grammar(variables, terminals, rules, initial) simplified_grammar = Simplifier.empty_productions(original_grammar) assert_equals(expected_grammar, simplified_grammar)
def test_chomsky_form(): """Testa a transformação de uma gramática para a Forma Normal de Chomsky""" terminals = ["+", "*", "[", "]", "x"] variables = ["E"] initial = "E" rules = {"E": [["E", "+", "E"], ["E", "*", "E"], ["[", "E", "]"], ["x"]]} original_grammar = Grammar(variables, terminals, rules, initial) terminals = ["+", "*", "[", "]", "x"] variables = ["E", "C+", "C*", "C[", "C]", "D1", "D2", "D3"] initial = "E" rules = {"E": [["E", "D1"], ["E", "D2"], ["C[", "D3"], ["x"]], "D1": [["C+", "E"]], "D2": [["C*", "E"]], "D3": [["E", "C]"]], "C+": [["+"]], "C*": [["*"]], "C[": [["["]], "C]": [["]"]]} expected_grammar = Grammar(variables, terminals, rules, initial) normalized_grammar = Normalizer.to_chomsky_form(original_grammar) assert_equals(expected_grammar, normalized_grammar)
def test_simple_production_simplification(): """Testa a simplificação de produções que substituem variáveis""" terminals = ["a", "b"] variables = ["S", "X"] initial = "S" rules = { "S": [["a", "X", "a"], ["b", "X", "b"]], "X": [["a"], ["b"], ["S"], ["V"]] } original_grammar = Grammar(variables, terminals, rules, initial) terminals = ["a", "b"] variables = ["S", "X"] initial = "S" rules = { "S": [["a", "X", "a"], ["b", "X", "b"]], "X": [["a"], ["b"], ["V"], ["a", "X", "a"], ["b", "X", "b"]] } expected_grammar = Grammar(variables, terminals, rules, initial) simplified_grammar = Simplifier.simple_production(original_grammar) assert_equals(expected_grammar, simplified_grammar)
def test_simple_production_simplification_step_2(): """Testa a segunda etapa da simplificação de produções que substituem variáveis""" terminals = ["a", "b", "c", "d", "e"] variables = ["A", "B", "C", "D", "E"] initial = "A" rules = { "A": [["A", "a"], ["B"], ["C"]], "B": [["b", "B", "b"], ["D"]], "C": [["c"], ["E"]], "D": [["d"]], "E": [["e"]] } original_grammar = Grammar(variables, terminals, rules, initial) terminals = ["a", "b", "c", "d", "e"] variables = ["A", "B", "C", "D", "E"] initial = "A" rules = { "A": [["A", "a"], ["b", "B", "b"], ["c"], ["d"], ["e"]], "B": [["b", "B", "b"], ["d"]], "C": [["c"], ["e"]], "D": [["d"]], "E": [["e"]] } expected_grammar = Grammar(variables, terminals, rules, initial) transitive_closure_list = Simplifier.simple_production_step_1( original_grammar) simplified_grammar = Simplifier.simple_production_step_2( original_grammar, transitive_closure_list) assert_equals(expected_grammar, simplified_grammar)
def cyk(g: Grammar, s: str): if len(s) == 0: deduce_eps = False for left, rules in g.rules.items(): for rule in rules: if rule == ['eps']: deduce_eps = True break return deduce_eps g.to_cnf() d = [] s = s.split() n = len(s) for i in range(n): d += [[]] for j in range(n): d[i] += [[]] for i in range(n): for left, rules in g.rules.items(): for rule in rules: if s[i] in rule: d[i][i] += [left] for m in range(1, n): for i in range(n): j = min(i + m, n - 1) for k in range(i, j): for left, rules in g.rules.items(): for rule in rules: if len(rule) == 2: if rule[0] in d[i][k] and rule[1] in d[k + 1][j]: d[i][j] += [left] return g.start in d[0][n - 1]
def cyk_my_grammar(str_file): g = Grammar() path = os.path.dirname(__file__) + '/resources/Grammar.txt' g.read_from_file(path) s = open(str_file) s = s.readlines() for i in range(len(s)): s[i] = s[i].replace('\n', ' ') s = ' '.join(s) return cyk(g, s)
def exitSelect_stmt(self, ctx: GrammarParser.Select_stmtContext): new_g = Grammar() new_g.rules = deepcopy(self.g.rules) new_g.nonterminals = self.g.nonterminals.copy() new_g.added_nonterminals = self.g.added_nonterminals new_start = new_g.add_nonterminal() new_g.start = new_start new_g.add_antlr_rule(new_start + ' ' + self.cur_right) if self.graphs_path is None: raise Exception('Graph is not loaded') graph_path = self.graphs_path + '/' + self.cur_graph gr = Graph() gr.read_graph(graph_path) vs_len = len(gr.vertices) if self.start_id is not None and self.start_id >= vs_len: raise Exception('wrong ID') if self.finish_id is not None and self.finish_id >= vs_len: raise Exception('wrong ID') t = evalCFPQ(new_g, gr) m = t[new_g.start].toarray() if self.cur_op == 'exists': self.handle_exist(m, vs_len) elif self.cur_op == 'count': self.handle_count(m, vs_len) else: self.handle_select(m, vs_len) self.cur_right = '' self.cur_op = '' self.start_v = None self.finish_v = None self.start_id = None self.finish_id = None self.vs = [] self.cur_graph = None self.cur_left = None
def __init__(self): self.graphs_path = None self.g = Grammar() self.cur_left = None self.cur_right = '' self.cur_graph = None self.cur_op = '' self.vs = [] self.start_v = None self.start_id = None self.finish_v = None self.finish_id = None
def test_simple_production_simplification_step_1(): """Testa a primeira etapa da simplificação de produções que substituem variáveis""" terminals = ["a", "b", "c", "d", "e"] variables = ["A", "B", "C", "D", "E"] initial = "A" rules = { "A": [["A", "a"], ["B"], ["C"]], "B": [["b", "B", "b"], ["D"]], "C": [["c"], ["E"]], "D": [["d"]], "E": [["e"]] } grammar = Grammar(variables, terminals, rules, initial) expected_transitive_closure_list = { "A": ["B", "C", "D", "E"], "B": ["D"], "C": ["E"], "D": [], "E": [] } transitive_closure_list = Simplifier.simple_production_step_1(grammar) # Converte as listas para contadores para a comparação # Dessa forma a ordem dos elementos não afeta o resultado, mas sim suas quantidades for key in expected_transitive_closure_list: expected_transitive_closure_list[key] = Counter( expected_transitive_closure_list[key]) for key in transitive_closure_list: transitive_closure_list[key] = Counter(transitive_closure_list[key]) assert_equals(transitive_closure_list, expected_transitive_closure_list)
def test_shuffle(self): data = Dataset(os.path.join("test", "test_dataset"), shuffle=True, rng=np.random.RandomState(0)) grammar = Grammar(data.node_types, data.rules, data.tokens(0) + [CLOSE_NODE]) data.prepare({"foo": 1, "bar": 2, "<unknown>": 0}, grammar) d = data.next() self.assertEqual(d.annotation.query, ["test"]) self.assertEqual(d.annotation.mappings, {"foo": "bar"})
def evalCFPQ(g: Grammar, gr: Graph): g.to_reduced_cnf() n = len(gr.vertices) t = {} rows = {} cols = {} data = {} for term in g.nonterminals: rows[term] = [] cols[term] = [] data[term] = [] for i, x, j in gr.edges: for left, rules in g.rules.items(): for rule in rules: if len(rule) == 1 and rule[0] == x: rows[left] += [i] cols[left] += [j] data[left] += [True] for left, rules in g.rules.items(): for rule in rules: if rule == ['eps']: for i in range(n): rows[left] += [i] cols[left] += [i] data[left] += [True] for term in g.nonterminals: t[term] = csr_matrix((data[term], (rows[term], cols[term])), shape=(n, n), dtype=bool) good_rules = [] for left, rules in g.rules.items(): for rule in rules: if len(rule) == 2: good_rules += [(left, rule)] changed = True while changed: changed = False for left, rule in good_rules: tmp = t[left] + (t[rule[0]] * t[rule[1]]) if (tmp != t[left]).nnz > 0: t[left] = tmp changed = True return t
def test_add(self): g = Grammar() r = alt("MyAlt", lit('a'), lit('b')) g.add(r) self.assertEqual(3, len(g.rules)) rec = lazy() C = seqn("At", rec, lit('t')) B = seqn("Cd", C, lit('d')) A = alt("A", seqn("Br", B, lit('r')), eps()) rec.set_rule(A) g.add(A) self.assertEqual(11, len(g.rules)) g.set_nullables() for r in g.rules.values(): print(r, r.is_nullable) print("---") g.set_left_recursives() for r in g.rules.values(): print(r, r.is_left_recursive)
def test_grammar_to_string(): """Testa a representação em string do objeto que representa a gramática""" terminals = ["a", "b", "u", "v"] variables = ["S", "Z", "B", "X", "Y", "A"] initial = "S" rules = { "S": [["X", "Y", "Z"]], "A": [["a"]], "B": [["b"]], "X": [["A", "X", "A"], ["B", "X", "B"], ["Z"], ["V"]], "Y": [["A", "Y", "B"], ["B", "Y", "A"], ["Z"], ["V"]], "Z": [["Z", "u"], ["Z", "v"], ["V"]] } grammar = Grammar(variables, terminals, rules, initial) assert_equals( grammar.__str__(), "G = ({S,Z,B,X,Y,A}, {a,b,u,v}, {S -> XYZ | A -> a | B -> b | " "X -> AXA | X -> BXB | X -> Z | X -> V | Y -> AYB | Y -> BYA | " "Y -> Z | Y -> V | Z -> Zu | Z -> Zv | Z -> V}, S)")
def test_cyk(): """Testa o reconhecimento de sentença utilizando o algoritmo cyk""" terminals = ["a", "b"] variables = ["S", "A"] initial = "S" rules = {"S": [["A", "A"], ["A", "S"], ["b"]], "A": [["S", "A"], ["A", "S"], ["a"]]} grammar = Grammar(variables, terminals, rules, initial) sentence = ["abaab"] assert(Parser.parse_cyk(grammar, sentence))
def test_indirect_left_recursion(self): rec = lazy() C = seqn("At", rec, lit('t')) B = seqn("Cd", C, lit('d')) A = alt("Br|eps", seqn("Br", B, lit('r')), eps()) rec.set_rule(A) g = Grammar() g.add(A) g.set_nullables() g.set_left_recursives() # A.remove_lazy_rules() Rule.DEBUG = True pn = A.apply("tdr", 0, 0) self.check(pn, True, 0, 3)
def test_useless_symbols(): """Testa a simplificação de símbolos inúteis""" terminals = ["a", "b", "c"] variables = ["S", "A", "B", "C"] initial = "S" rules = { "S": [["a", "A", "a"], ["b", "B", "b"]], "A": [["a"], ["S"]], "C": [["c"]] } original_grammar = Grammar(variables, terminals, rules, initial) terminals = ["a"] variables = ["S", "A"] initial = "S" rules = {"S": [["a", "A", "a"]], "A": [["a"], ["S"]]} expected_grammar = Grammar(variables, terminals, rules, initial) simplified_grammar = Simplifier.useless_symbols(original_grammar) assert_equals(expected_grammar, simplified_grammar)
def hellings(g: Grammar, gr: Graph): g.to_reduced_cnf() r = [] m = [] for v1, label, v2 in gr.edges: for left, rules in g.rules.items(): for rule in rules: if len(rule) == 1 and rule[0] == label: r += [(left, v1, v2)] m += [(left, v1, v2)] for left, rules in g.rules.items(): for rule in rules: if len(rule) == 1 and rule == ['eps']: for v in gr.vertices: r += [(left, v, v)] m += [(left, v, v)] while len(m) > 0: N, v, u = m.pop(0) for term, v1, v2 in r: if v2 != v: continue for left, rules in g.rules.items(): for rule in rules: if len(rule) == 2 and rule[0] == term and rule[ 1] == N and (left, v1, u) not in r: m += [(left, v1, u)] r += [(left, v1, u)] for term, v1, v2 in r: if v1 != u: continue for left, rules in g.rules.items(): for rule in rules: if len(rule) == 2 and rule[0] == N and rule[ 1] == term and (left, v, v2) not in r: m += [(left, v, v2)] r += [(left, v, v2)] return r
def test_grammar_has_productions_longer_than(): """Testa a função que verifica se a gramática tem produções maiores que x""" terminals = ["a", "b", "u", "v"] variables = ["S", "Z", "B", "X", "Y", "A"] initial = "S" rules = {"S": [["X", "Y", "Z"]], "A": [["a"]], "B": [["b"]], "X": [["A", "X", "A"], ["B", "X", "B"], ["Z"], ["V"]], "Y": [["A", "Y", "B"], ["B", "Y", "A"], ["Z"], ["V"]], "Z": [["Z", "u"], ["Z", "v"], ["V"]]} grammar = Grammar(variables, terminals, rules, initial) assert grammar_has_productions_longer_than(grammar, 2) assert not grammar_has_productions_longer_than(grammar, 3)
def test_next(self): data = Dataset(os.path.join("test", "test_dataset")) grammar = Grammar(data.node_types, data.rules, data.tokens(0) + [CLOSE_NODE]) data.prepare({"foo": 1, "bar": 2, "<unknown>": 0}, grammar) d = data.next() self.assertEqual(d.annotation.query, ["foo", "bar"]) self.assertEqual(d.annotation.mappings, {}) self.assertTrue(len(d.sequence) != 0) d = data.next() self.assertEqual(d.annotation.query, ["test"]) self.assertEqual(d.annotation.mappings, {"foo": "bar"}) d = data.next() self.assertEqual(d.annotation.query, ["foo", "bar"]) self.assertEqual(d.annotation.mappings, {})
def test_cyk_2(): """Testa o reconhecimento de sentença utilizando o algoritmo cyk para um segundo caso""" terminals = ["she", "eats", "fish", "with", "a", "fork"] variables = ["S", "VP", "PP", "NP", "V_", "P", "N", "Det"] initial = "S" rules = {"S": [["NP", "VP"]], "VP": [["VP", "PP"], ["V", "NP"], ["eats"]], "PP": [["P", "NP"]], "NP": [["Det", "N"], ["she"]], "V": [["eats"]], "P": [["with"]], "N": [["fish"], ["fork"]], "Det": [["a"]]} grammar = Grammar(variables, terminals, rules, initial) sentence = ["she", "eats", "a", "fish", "with", "a", "fork"] assert(Parser.parse_cyk(grammar, sentence))
def hellings_from_file(grammar_file, graph_file, output_file): g = Grammar() g.read_from_file(grammar_file) gr = Graph() gr.read_graph(graph_file) lines = hellings(g, gr) g.print_grammar(output_file) out_file = open(output_file, 'a') s = '\n' for line in lines: if line[0] == g.start: s += line[1] + ' ' + line[2] + '\n' out_file.write(s)
def evalCFPQ_from_file(grammar_file, graph_file, output_file): g = Grammar() g.read_from_file(grammar_file) gr = Graph() gr.read_graph(graph_file) t = evalCFPQ(g, gr) g.print_grammar(output_file) m = t[g.start].toarray() out_file = open(output_file, 'a') out_file.write('\n') for i in range(len(gr.vertices)): for j in range(len(gr.vertices)): if m[i][j] == 1: out_file.write(str(i) + ' ' + str(j) + '\n')
class ScriptHandler(ParseTreeListener): def __init__(self): self.graphs_path = None self.g = Grammar() self.cur_left = None self.cur_right = '' self.cur_graph = None self.cur_op = '' self.vs = [] self.start_v = None self.start_id = None self.finish_v = None self.finish_id = None def enterComplete_script(self, ctx: GrammarParser.Complete_scriptContext): pass def exitComplete_script(self, ctx: GrammarParser.Complete_scriptContext): pass def enterScript(self, ctx: GrammarParser.ScriptContext): pass def exitScript(self, ctx: GrammarParser.ScriptContext): pass def enterStmt(self, ctx: GrammarParser.StmtContext): if type(ctx.children[0]) is TerminalNodeImpl: if ctx.children[0].symbol.text == 'connect': self.handle_connect_stmt(ctx) elif ctx.children[0].symbol.text == 'list': self.handle_list_stmt() def exitStmt(self, ctx: GrammarParser.StmtContext): pass def enterNamed_pattern_stmt(self, ctx: GrammarParser.Named_pattern_stmtContext): self.cur_left = ctx.children[0].symbol.text def exitNamed_pattern_stmt(self, ctx: GrammarParser.Named_pattern_stmtContext): self.cur_left = None def enterSelect_stmt(self, ctx: GrammarParser.Select_stmtContext): self.cur_graph = ctx.children[3].symbol.text[1:-1] def exitSelect_stmt(self, ctx: GrammarParser.Select_stmtContext): new_g = Grammar() new_g.rules = deepcopy(self.g.rules) new_g.nonterminals = self.g.nonterminals.copy() new_g.added_nonterminals = self.g.added_nonterminals new_start = new_g.add_nonterminal() new_g.start = new_start new_g.add_antlr_rule(new_start + ' ' + self.cur_right) if self.graphs_path is None: raise Exception('Graph is not loaded') graph_path = self.graphs_path + '/' + self.cur_graph gr = Graph() gr.read_graph(graph_path) vs_len = len(gr.vertices) if self.start_id is not None and self.start_id >= vs_len: raise Exception('wrong ID') if self.finish_id is not None and self.finish_id >= vs_len: raise Exception('wrong ID') t = evalCFPQ(new_g, gr) m = t[new_g.start].toarray() if self.cur_op == 'exists': self.handle_exist(m, vs_len) elif self.cur_op == 'count': self.handle_count(m, vs_len) else: self.handle_select(m, vs_len) self.cur_right = '' self.cur_op = '' self.start_v = None self.finish_v = None self.start_id = None self.finish_id = None self.vs = [] self.cur_graph = None self.cur_left = None def enterObj_expr(self, ctx: GrammarParser.Obj_exprContext): pass def exitObj_expr(self, ctx: GrammarParser.Obj_exprContext): if len(ctx.children) > 1: self.cur_op = ctx.children[0].symbol.text def enterVs_info(self, ctx: GrammarParser.Vs_infoContext): if len(ctx.children) == 1: self.vs = [ctx.children[0].symbol.text] else: self.vs = [ ctx.children[1].symbol.text, ctx.children[3].symbol.text ] def exitVs_info(self, ctx: GrammarParser.Vs_infoContext): pass def enterWhere_expr(self, ctx: GrammarParser.Where_exprContext): pass def exitWhere_expr(self, ctx: GrammarParser.Where_exprContext): pass def enterV_expr(self, ctx: GrammarParser.V_exprContext): if ctx.parentCtx.children[1] == ctx: if len(ctx.children) == 1: self.start_v = ctx.children[0].symbol.text else: self.start_v = ctx.children[0].symbol.text self.start_id = int(ctx.children[4].symbol.text) else: if len(ctx.children) == 1: self.finish_v = ctx.children[0].symbol.text else: self.finish_v = ctx.children[0].symbol.text self.finish_id = int(ctx.children[4].symbol.text) def exitV_expr(self, ctx: GrammarParser.V_exprContext): pass def enterPattern(self, ctx: GrammarParser.PatternContext): pass def exitPattern(self, ctx: GrammarParser.PatternContext): if type(ctx.parentCtx) is GrammarParser.Named_pattern_stmtContext: self.g.add_antlr_rule(self.cur_left + ' ' + self.cur_right) self.cur_left = None self.cur_right = '' def enterAlt_elem(self, ctx: GrammarParser.Alt_elemContext): if type(ctx.children[0]) is TerminalNodeImpl: self.cur_right += 'eps ' def exitAlt_elem(self, ctx: GrammarParser.Alt_elemContext): if len(ctx.parentCtx.children) > 1: self.cur_right += '| ' def enterSeq_elem(self, ctx: GrammarParser.Seq_elemContext): pass def exitSeq_elem(self, ctx: GrammarParser.Seq_elemContext): if len(ctx.children) > 1: self.cur_right += ctx.children[1].symbol.text + ' ' def enterPrim_pattern(self, ctx: GrammarParser.Prim_patternContext): if len(ctx.children) == 1: self.cur_right += ctx.children[0].symbol.text + ' ' else: self.cur_right += '( ' def exitPrim_pattern(self, ctx: GrammarParser.Prim_patternContext): if len(ctx.children) > 1: self.cur_right += ') ' def handle_connect_stmt(self, ctx: GrammarParser.StmtContext): self.graphs_path = ctx.children[2].symbol.text[1:-1] def handle_list_stmt(self): for file in sorted(os.listdir(self.graphs_path)): cur_file = open(self.graphs_path + '/' + file) self.print_file(file, cur_file) cur_file.close() def handle_select(self, m, vs_len): if len(self.vs) == 1: ret = self.handle_select_v(m, vs_len) else: ret = self.handle_select_pair(m, vs_len) print(sorted(ret)) def handle_select_v(self, m, vs_len): ret = set() is_start = self.start_v == self.vs[0] is_finish = self.finish_v == self.vs[0] if is_start and is_finish: for i in range(vs_len): if m[i][i] == 1: ret.add(i) return ret if is_start and self.start_id is not None: if self.finish_id is None: for j in range(vs_len): if m[self.start_id][j] == 1: return set(self.start_id) elif m[self.start_id][self.finish_id] == 1: return set(self.start_id) return set() if is_finish and self.finish_id is not None: if self.start_id is None: for i in range(vs_len): if m[i][self.finish_id] == 1: return set(self.finish_id) elif m[self.start_id][self.finish_id] == 1: return set(self.finish_id) return set() if is_start: ret = set() if self.finish_id is None: for i in range(vs_len): for j in range(vs_len): if m[i][j] == 1: ret.add(i) return ret for i in range(vs_len): if m[i][self.finish_id] == 1: ret.add(i) return ret if is_finish: ret = set() if self.start_id is None: for i in range(vs_len): for j in range(vs_len): if m[i][j] == 1: ret.add(j) return ret for j in range(vs_len): if m[self.start_id][j] == 1: ret.add(j) return ret return set() def handle_select_pair(self, m, vs_len): ret = set() if self.start_v not in self.vs or self.finish_v not in self.vs: raise Exception('Wrong vertices') if self.start_id is not None and self.finish_id is not None: if m[self.start_id][self.finish_id]: ret.add((self.start_id, self.finish_id)) return ret if self.start_id is not None: for j in range(vs_len): if m[self.start_id][j] == 1: ret.add((self.start_id, j)) return ret if self.finish_id is not None: for i in range(vs_len): if m[i][self.finish_id] == 1: ret.add((i, self.finish_id)) for i in range(vs_len): for j in range(vs_len): if m[i][j] == 1: ret.add((i, j)) return ret def handle_count(self, m, vs_len): if len(self.vs) == 1: ret = self.handle_count_v(m, vs_len) else: ret = self.handle_count_pair(m, vs_len) print(ret) def handle_count_v(self, m, vs_len): is_start = self.start_v == self.vs[0] is_finish = self.finish_v == self.vs[0] ret = 0 if is_start and is_finish: for i in range(vs_len): ret += m[i][i] return ret if is_start and self.start_id is not None: if self.finish_id is None: return self.count_row(m, vs_len, self.start_id) return int(m[self.start_id][self.finish_id]) if is_finish and self.finish_id is not None: if self.start_id is None: return self.count_column(m, vs_len, self.finish_id) return int(m[self.start_id][self.finish_id]) if is_start: if self.finish_id is None: s = set() for i in range(vs_len): for j in range(vs_len): if m[i][j]: s.add(i) return len(s) return self.count_column(m, vs_len, self.finish_id) if is_finish: if self.start_id is None: s = set() for i in range(vs_len): for j in range(vs_len): if m[i][j]: s.add(j) return len(s) return self.count_column(m, vs_len, self.start_id) return 0 def handle_count_pair(self, m, vs_len): if self.start_id is not None and self.finish_id is not None: return int(m[self.start_id][self.finish_id]) if self.start_id is not None: return self.count_row(m, vs_len, self.start_id) if self.finish_id is not None: ret = 0 for i in range(vs_len): ret += self.count_column(m, vs_len, self.finish_id) return ret if self.start_v in self.vs and self.finish_v in self.vs: ret = 0 for i in range(vs_len): for j in range(vs_len): ret += int(m[i][j]) return ret return 0 def count_row(self, m, vs_len, i): ret = 0 for j in range(vs_len): ret += int(m[i][j]) return ret def count_column(self, m, vs_len, j): ret = 0 for i in range(vs_len): ret += int(m[i][j]) return ret def handle_exist(self, m, vs_len): if len(self.vs) == 1: ret = self.handle_exists_v(m, vs_len) else: ret = self.handle_exists_pair(m, vs_len) print(ret) def handle_exists_v(self, m, vs_len): is_start = self.start_v == self.vs[0] is_finish = self.finish_v == self.vs[0] if is_start and is_finish: for i in range(vs_len): if m[i][i]: return True elif is_start and self.start_id is not None: if self.finish_id is None: return self.check_row(m, vs_len, self.start_id) else: return m[self.start_id][self.finish_id] elif is_finish and self.finish_id is not None: if self.start_id is None: return self.check_column(m, vs_len, self.finish_id) else: return m[self.start_id][self.finish_id] elif is_start: if self.finish_id is None: return self.check_all(m, vs_len) else: return self.check_column(m, vs_len, self.start_id) elif is_finish: if self.start_id is None: return self.check_all(m, vs_len) else: return self.check_column(m, vs_len, self.start_id) def handle_exists_pair(self, m, vs_len): if self.start_id is not None and self.finish_id is not None: return m[self.start_id][self.finish_id] elif self.start_v in self.vs and self.finish_v in self.vs: if self.start_id is not None: return self.check_row(m, vs_len, self.start_id) elif self.finish_id is not None: for i in range(vs_len): return self.check_column(m, vs_len, self.finish_id) else: return self.check_all(m, vs_len) def check_all(self, m, vs_len): for i in range(vs_len): for j in range(vs_len): if m[i][j]: return True return False def check_row(self, m, vs_len, i): for j in range(vs_len): if m[i][j]: return True return False def check_column(self, m, vs_len, j): for i in range(vs_len): if m[i][j]: return True return False def print_file(self, name, lines): print('FILE ' + name + ':') s = '' for line in lines: s += line print(s + '\n')
def evalCFPQ_tensor(g_lines, gr: Graph): my_g = Grammar() my_g.split_hard_lines(g_lines) t = {} rows = {} cols = {} data = {} vertices = 0 vs = {} terms = {} S = {} F = {} for line in g_lines: left = line[0] if left not in terms: terms[left] = 1 right = line[1:] a_graph, starts, finals = str_to_graph(right) g = set() for (u, v, _), label in sorted(a_graph.items()): if label not in terms: terms[label] = 1 if u not in g: g.add(u) vs[(left, u)] = vertices vertices += 1 if v not in g: g.add(v) vs[(left, v)] = vertices vertices += 1 if label not in rows: rows[label] = [] cols[label] = [] data[label] = [] rows[label] += [vs[(left, u)]] cols[label] += [vs[(left, v)]] data[label] += [True] for v in starts: if vs[(left, v)] not in S: if left not in S: S[left] = [] S[left] += [(vs[(left, v)])] for v in finals: if vs[(left, v)] not in F: if left not in F: F[left] = [] F[left] += [(vs[(left, v)])] n = vertices for term in terms.keys(): if term not in rows: rows[term] = [] cols[term] = [] data[term] = [] t[term] = csr_matrix((data[term], (rows[term], cols[term])), shape=(n, n), dtype=bool) eps_nonterms = my_g.get_eps_gen_nonterminals() gr_n = len(gr.vertices) rows_gr = {} cols_gr = {} data_gr = {} for u, label, v in gr.edges: if label not in rows_gr: rows_gr[label] = [] cols_gr[label] = [] data_gr[label] = [] rows_gr[label] += [u] cols_gr[label] += [v] data_gr[label] += [True] for label in eps_nonterms: if label not in rows_gr: rows_gr[label] = [] cols_gr[label] = [] data_gr[label] = [] for j in range(gr_n): rows_gr[label] += [j] cols_gr[label] += [j] data_gr[label] += [True] t_gr = {} for term in terms.keys(): if term not in rows_gr: rows_gr[term] = [] cols_gr[term] = [] data_gr[term] = [] t_gr[term] = csr_matrix( (data_gr[term], (rows_gr[term], cols_gr[term])), shape=(gr_n, gr_n), dtype=bool) changed = True m = {} n1 = 0 while changed: changed = False total = False for term in terms: m[term] = sparse.kron(t[term], t_gr[term]).astype(bool) n1, _ = m[term].shape if total is False: total = m[term] else: total = total + m[term] t_cl = total totals = [total, total * total] cnt = 2 while (t_cl + get_total(cnt, totals) != t_cl).nnz > 0: t_cl += get_total(cnt, totals) cnt += 1 for (u, v) in zip(*t_cl.nonzero()): s = u // gr_n f = v // gr_n for left in my_g.nonterminals: if left in S and s in S[left] and f in F[left]: new_i = u % gr_n new_j = v % gr_n new_term = left tmp = t_gr[new_term] + csr_matrix( (np.array([True]), (np.array([new_i]), np.array([new_j]))), shape=(gr_n, gr_n), dtype=bool) if (tmp != t_gr[new_term]).nnz > 0: t_gr[new_term] = tmp changed = True return t_gr, t, terms, my_g.start
def import_from_file(self, file_name): # Lê o arquivo e guarda as linhas em uma lista with open(file_name) as f: content = f.readlines() terminals = [] variables = [] initial = "" rules = defaultdict() for line in content: # Remove espaços, tabs e newlines line = line.replace(" ", "") line = line.replace("\t", "") line = line.replace("\n", "") # Verifica se a linha é uma keyword, se sim atualiza o estado if self.state < 4 and line.startswith(self.keywords[self.state]): self.state += 1 continue # Remove comentários line = line.split('#', 1)[0] # Terminais if self.state == 1: # Remove [ e ] line = line.split('[', 1)[1] line = line.split(']', 1)[0] terminals.append(line) # Variáveis if self.state == 2: # Remove [ e ] line = line.split('[', 1)[1] line = line.split(']', 1)[0] variables.append(line) # Inicial if self.state == 3: # Remove [ e ] line = line.split('[', 1)[1] line = line.split(']', 1)[0] initial = line # Regras de produção if self.state == 4: # Separa em origem e produção origin = line.split('>')[0] production = line.split('>')[1] # Origem origin = origin.split('[', 1)[1] origin = origin.split(']', 1)[0] # Produção # Separa por '[' e remove a string vazia do início production = production.split('[') production = list(filter(None, production)) # Remove ']' de cada elemento production[:] = [s[:-1] for s in production] if origin in rules: rules[origin].append(production) else: rules[origin] = [production] grammar = Grammar(variables, terminals, rules, initial) print("Gramática importada:") print(grammar) return grammar
def cyk_from_file(g_file, s_file): g = Grammar() g.read_from_file(g_file) s_f = open(s_file) s = s_f.readline() print(cyk(g, s))
from itertools import islice import src.sexp as sexp from src.enumerator import BestFirstEnumerator from src.grammar import Grammar from src.heuristic import PCFGHeuristic from src.stat import PCFG if __name__ == '__main__': sygus_file = '../benchmark/string/train/dr-name.sl' with open(sygus_file, 'r') as f: sygus_sexp = sexp.load(f) grammar = Grammar.from_sygus(sygus_sexp) pcfg = PCFG.from_json('../benchmark/pcfg.json') heuristic = PCFGHeuristic(pcfg, grammar) enumerator = BestFirstEnumerator(grammar, heuristic) for cost, program in islice(enumerator.enumerate(), 0, 10): print(cost, program)