Ejemplo n.º 1
0
 function AFNDaAFD()
 {
     $this->siguiente_ID = 1;
     $estados_desmarcados = array();
     $conjunto_estado_inicial_AFD = array();
     $conjunto_estado_inicial_AFND = array();
     // Extrae el estado inicial del AFND
     $tmp = $this->AFND->getEstados();
     if (empty($tmp)) {
         return;
     }
     $conjunto_estado_inicial_AFND[] = $tmp[0];
     // Calcula las transiciones vacías para el estado inicial del AFND
     // y crea el conjunto de estados que formará el estado inicial del AFD
     $conjunto_estado_inicial_AFD = $this->epsilonClosure($conjunto_estado_inicial_AFND);
     // Crea nuevo estado inicial del AFD con el conjunto de estados
     $q0 = new Estado($this->siguiente_ID++, true, false);
     $q0->agregarConjunto($conjunto_estado_inicial_AFD);
     // Agrega el estado al AFD
     $this->AFD->setEstado($q0);
     foreach ($this->simbolos as $simbolo) {
         if ($simbolo != 'ε') {
             $this->AFD->setSimbolo($simbolo);
         }
     }
     // Agrega el estado inciial a un conjunto de estados no procesados del AFD
     $estados_desmarcados[] = $q0;
     while (!empty($estados_desmarcados)) {
         // procesar un estado no procesado
         $estado_activo = array_pop($estados_desmarcados);
         $simbolos_AFD = $this->AFD->getSimbolos();
         foreach ($simbolos_AFD as $simbolo) {
             // guarda el conjunto de estados resultante de aplicacar la función move en el estado activo
             $move_res = $this->move($simbolo, $estado_activo->getEstadosAFND());
             // guarda el conjunto de estados resultante de las transiciones vacías sobre el resultado anterior
             $epsilonclosure_res = $this->epsilonClosure($move_res);
             $encontrado = false;
             $s = null;
             $se = $this->AFD->getEstados();
             // busca si el conjunto de estados encontrado ya existía previamente en el AFD
             for ($i = 0; $i < $this->AFD->getTotalEstados(); $i++) {
                 $s = $se[$i];
                 if ($s->getEstadosAFND() === $epsilonclosure_res) {
                     $encontrado = true;
                     break;
                 }
             }
             // si el conjunto ya existía, no se procesa; en caso contrario:
             if (!$encontrado) {
                 // se crea un nuevo estado en el AFD con el conjunto encontrado
                 $U = new Estado($this->siguiente_ID++);
                 $U->agregarConjunto($epsilonclosure_res);
                 // Se agrega el estado a los estados desmarcados, para procesarlo
                 $estados_desmarcados[] = $U;
                 // Se agrega el estado al AFD
                 $this->AFD->setEstado($U);
                 // Agregar transicion de estado en proceso a nuevo estado con el simbolo actual
                 $estado_activo->setTransicion($simbolo, $U);
             } else {
                 $estado_activo->setTransicion($simbolo, $s);
             }
         }
     }
     $this->reducirAFD();
 }