Пример #1
0
def check(formula):
    """Parse formula string and create abstract syntax tree (AST).
    """
    ast = lexyacc.parse(formula)

    dfa = trs.automata.FiniteWordAutomaton(atomic_proposition_based=False,
                                           deterministic=True)

    dfa.alphabet |= {'!', 'W', 'U', 'G', 'F',
                     'U_left', 'U_right',
                     'W_left', 'W_right'}

    dfa.states.add_from({'gf', 'fg', 'g', 'f'})
    dfa.states.initial.add('gf')

    dfa.transitions.add('gf', 'fg', letter='!')
    dfa.transitions.add('fg', 'gf', letter='!')
    dfa.transitions.add('g', 'f', letter='!')
    dfa.transitions.add('f', 'g', letter='!')

    dfa.transitions.add('gf', 'gf', letter='W')
    dfa.transitions.add('gf', 'gf', letter='U_left')
    dfa.transitions.add('gf', 'gf', letter='G')

    dfa.transitions.add('fg', 'fg', letter='U')
    dfa.transitions.add('fg', 'fg', letter='F')
    dfa.transitions.add('fg', 'fg', letter='W_right')

    dfa.transitions.add('gf', 'f', letter='U_right')
    dfa.transitions.add('gf', 'f', letter='F')

    dfa.transitions.add('fg', 'g', letter='W_left')
    dfa.transitions.add('fg', 'g', letter='G')

    dfa.transitions.add('g', 'g', letter='W')
    dfa.transitions.add('g', 'g', letter='G')

    dfa.transitions.add('f', 'f', letter='U')
    dfa.transitions.add('f', 'f', letter='F')

    # plot tree automaton
    # dfa.save('dfa.pdf')

    # plot parse tree
    sast.dump_dot(ast, 'ast.dot')

    # sync product of AST with DFA,
    # to check acceptance
    Q = [(ast, 'gf')]
    while Q:
        s, q = Q.pop()
        logger.info('visiting: ' + str(s) + ', ' + str(q))

        if isinstance(s, sast.Unary):
            op = s.operator

            if op in {'!', 'G', 'F'}:
                t = dfa.transitions.find(q, letter=op)

                if not t:
                    raise Exception('not in fragment')

                qi, qj, w = t[0]

                Q.append((s.operand, qj))
            else:
                # ignore
                Q.append((s.operand, q))
        elif isinstance(s, sast.Binary):
            op = s.operator

            if op in {'W', 'U'}:
                t = dfa.transitions.find(q, letter=op)
                if t:
                    qi, qj, w = t[0]
                    Q.append((s.op_l, qj))
                    Q.append((s.op_r, qj))
                else:
                    t = dfa.transitions.find(q, letter=op + '_left')

                    if not t:
                        raise Exception('not in fragment')

                    qi, qj, w = t[0]

                    Q.append((s.op_l, qj))

                    t = dfa.transitions.find(q, letter=op + '_right')

                    if not t:
                        raise Exception('not in fragment')

                    qi, qj, w = t[0]

                    Q.append((s.op_r, qj))
            else:
                # ignore
                Q.append((s.op_l, q))
                Q.append((s.op_r, q))
        elif isinstance(s, sast.Var):
            print('reached var')

    return ast
Пример #2
0
def check(formula):
    """Parse formula string and create abstract syntax tree (AST).
    """
    ast = lexyacc.parse(formula)

    dfa = trs.automata.FiniteWordAutomaton(atomic_proposition_based=False,
                                           deterministic=True)

    dfa.alphabet |= {
        '!', 'W', 'U', 'G', 'F', 'U_left', 'U_right', 'W_left', 'W_right'
    }

    dfa.states.add_from({'gf', 'fg', 'g', 'f'})
    dfa.states.initial.add('gf')

    dfa.transitions.add('gf', 'fg', letter='!')
    dfa.transitions.add('fg', 'gf', letter='!')
    dfa.transitions.add('g', 'f', letter='!')
    dfa.transitions.add('f', 'g', letter='!')

    dfa.transitions.add('gf', 'gf', letter='W')
    dfa.transitions.add('gf', 'gf', letter='U_left')
    dfa.transitions.add('gf', 'gf', letter='G')

    dfa.transitions.add('fg', 'fg', letter='U')
    dfa.transitions.add('fg', 'fg', letter='F')
    dfa.transitions.add('fg', 'fg', letter='W_right')

    dfa.transitions.add('gf', 'f', letter='U_right')
    dfa.transitions.add('gf', 'f', letter='F')

    dfa.transitions.add('fg', 'g', letter='W_left')
    dfa.transitions.add('fg', 'g', letter='G')

    dfa.transitions.add('g', 'g', letter='W')
    dfa.transitions.add('g', 'g', letter='G')

    dfa.transitions.add('f', 'f', letter='U')
    dfa.transitions.add('f', 'f', letter='F')

    # plot tree automaton
    # dfa.save('dfa.pdf')

    # plot parse tree
    sast.dump_dot(ast, 'ast.dot')

    # sync product of AST with DFA,
    # to check acceptance
    Q = [(ast, 'gf')]
    while Q:
        s, q = Q.pop()
        logger.info('visiting: ' + str(s) + ', ' + str(q))

        if isinstance(s, sast.Unary):
            op = s.operator

            if op in {'!', 'G', 'F'}:
                t = dfa.transitions.find(q, letter=op)

                if not t:
                    raise Exception('not in fragment')

                qi, qj, w = t[0]

                Q.append((s.operand, qj))
            else:
                # ignore
                Q.append((s.operand, q))
        elif isinstance(s, sast.Binary):
            op = s.operator

            if op in {'W', 'U'}:
                t = dfa.transitions.find(q, letter=op)
                if t:
                    qi, qj, w = t[0]
                    Q.append((s.op_l, qj))
                    Q.append((s.op_r, qj))
                else:
                    t = dfa.transitions.find(q, letter=op + '_left')

                    if not t:
                        raise Exception('not in fragment')

                    qi, qj, w = t[0]

                    Q.append((s.op_l, qj))

                    t = dfa.transitions.find(q, letter=op + '_right')

                    if not t:
                        raise Exception('not in fragment')

                    qi, qj, w = t[0]

                    Q.append((s.op_r, qj))
            else:
                # ignore
                Q.append((s.op_l, q))
                Q.append((s.op_r, q))
        elif isinstance(s, sast.Var):
            print('reached var')

    return ast