예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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]
예제 #6
0
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)
예제 #7
0
 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
예제 #8
0
 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
예제 #9
0
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
예제 #12
0
    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)
예제 #13
0
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)")
예제 #14
0
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))
예제 #15
0
 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)
예제 #16
0
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)
예제 #17
0
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
예제 #18
0
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, {})
예제 #20
0
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))
예제 #21
0
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')
예제 #23
0
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
예제 #25
0
    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
예제 #26
0
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))
예제 #27
0
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)