/** * Aplica el algoritmo de construcción de subconjunto para obtener a partir de un AFN su AFD * equivalente. * * @param afn * @return */ public AFD build(AFN afn) { automata.setProduction(afn.getProduction()); // Calculamos la cerradura ε para el estado inicial. Cerradura cerraduraInicial = new Cerradura(0, afn.getInitState(), buildCerradura(afn.getInitState())); cerraduras.add(cerraduraInicial); // Mientras existan cerraduras sin procesar. while (isProcess()) { // Hallamos el subconjunto para cada simbolo for (String symbol : afn.getSymbols()) { if (!symbol.equals(ε)) { List<Estado> states = new ArrayList<>(); for (Estado state : next().getEstadosAcanzables()) { merge(states, buildSubconjuntoBySymbol(state, symbol, new ArrayList<Estado>())); } next().addSubconjunto(symbol, states); } } // Para cada subconjunto calculamos la cerradura for (pol.una.py.model.lexico.Cerradura.Subconjunto subconjunto : next().getSubconjuntos()) { if (!subconjunto.getStates().isEmpty()) { addCerradura(subconjunto.getStates(), buildCerradura(subconjunto.getStates())); } } // Finalizamos el proceso de la cerradura actual. next().setProcess(true); } return buildAFD(); }
/** * Contruye el AFD equivalente * * @return <b>AFD</b> Automata finito equivalente al AFN recibido */ private AFD buildAFD() { for (Cerradura cerradura : cerraduras) { Estado origen = getState(cerradura); Estado destino = null; for (pol.una.py.model.lexico.Cerradura.Subconjunto conjunto : cerradura.getSubconjuntos()) { String codigoUnico = conjunto.getCodCerradura(); // Conjunto vacio if (codigoUnico.equals("{}")) { destino = getStateError(); } else { destino = getState(getCerradura(codigoUnico)); } origen.addTransition(new Transicion(origen, destino, conjunto.getSymbol())); } automata.addEstado(origen); } // Puede darse el caso de que el estado inicial del AFN no sea mas un // estado inicial, sino un estado de aceptacion. Si no es un estado de // aceptacion, indicamos que es el estado inicial. if (!automata.getInitState().isAcceptation()) { automata.getInitState().setInit(true); } return automata; }