225 lines
5.6 KiB
Java
225 lines
5.6 KiB
Java
/* Copyright (c) 2017 Christopher Cromer
|
|
* Copyright (c) 2017 Carlos Faúndez
|
|
*
|
|
* This file is part of mt. It is subject to the license terms in the LICENSE file found in the top-level directory of this distribution.
|
|
* This file may not be copied, modified, propagated, or distributed except according to the terms contained in the LICENSE file.
|
|
*/
|
|
|
|
package cl.cromer.mt;
|
|
|
|
import org.w3c.dom.Document;
|
|
|
|
/**
|
|
* Clase de la Maquina de Turing que renocerá algún asociado a las transiciones escritas en un archivo XML
|
|
*/
|
|
public class Maquina {
|
|
/**
|
|
* La automata destras de la maquina de turning
|
|
*/
|
|
private final Automata automata;
|
|
|
|
/**
|
|
* El estado actual donde se encuentra la maquina
|
|
*/
|
|
private Estado estadoActual;
|
|
|
|
/**
|
|
* El enlace actual
|
|
*/
|
|
private Enlace enlaceActual;
|
|
|
|
/**
|
|
* La cinta anterior para usar paso a paso
|
|
*/
|
|
private String cintaAnterior;
|
|
|
|
/**
|
|
* Donde está el cabezal
|
|
*/
|
|
private int cabezal;
|
|
|
|
/**
|
|
* Constructor de la clase
|
|
*
|
|
* @param document Document asociado al XML
|
|
*/
|
|
public Maquina(Document document) {
|
|
automata = new Automata(document);
|
|
reset();
|
|
}
|
|
|
|
/**
|
|
* Retorna la automata de Turing
|
|
*
|
|
* @return automata asociado a alguna función de transición
|
|
*/
|
|
public Automata getAutomata() {
|
|
return automata;
|
|
}
|
|
|
|
/**
|
|
* Retorna el estado en que esta la automata
|
|
*
|
|
* @return estado actual
|
|
*/
|
|
public Estado getEstadoActual() {
|
|
return estadoActual;
|
|
}
|
|
|
|
/**
|
|
* Asigna un estado actual que esta la automata en un instante de tiempo
|
|
*
|
|
* @param estadoActual En que estado es la automata
|
|
*/
|
|
public void setEstadoActual(Estado estadoActual) {
|
|
this.estadoActual = estadoActual;
|
|
}
|
|
|
|
/**
|
|
* Retorna un enlace en que la automata asocio a la cadena ingresada y al cabezal que se encuentra
|
|
*
|
|
* @return el enlace actual
|
|
*/
|
|
public Enlace getEnlaceActual() {
|
|
return enlaceActual;
|
|
}
|
|
|
|
/**
|
|
* Asigna un enlace actual que esta la automata en un instante de tiempo
|
|
*
|
|
* @param enlaceActual La enlace donde esta la automata
|
|
*/
|
|
public void setEnlaceActual(Enlace enlaceActual) {
|
|
this.enlaceActual = enlaceActual;
|
|
}
|
|
|
|
/**
|
|
* Retorna la cadena anterior a que la automata hiciera cambios
|
|
*
|
|
* @return la cadena anterior
|
|
*/
|
|
public String getCintaAnterior() {
|
|
return cintaAnterior;
|
|
}
|
|
|
|
/**
|
|
* Asigna la cadena anterior a que la automata hiciera cambios
|
|
* @param cintaAnterior La cinta a verificar
|
|
*/
|
|
public void setCintaAnterior(String cintaAnterior) {
|
|
this.cintaAnterior = cintaAnterior;
|
|
}
|
|
|
|
/**
|
|
* Retorna el indice en que se ubica en la cadena (Cabezal)
|
|
*
|
|
* @return un número asociado
|
|
*/
|
|
public int getCabezal() {
|
|
return cabezal;
|
|
}
|
|
|
|
/**
|
|
* Asigna el indice en que se ubica en la cadena (Cabezal)
|
|
*
|
|
* @param cabezal Donde poner la cabezal
|
|
*/
|
|
public void setCabezal(int cabezal) {
|
|
this.cabezal = cabezal;
|
|
}
|
|
|
|
/**
|
|
* Inicializa atributos
|
|
*/
|
|
public void reset() {
|
|
setEstadoActual(getAutomata().getEstados().get(0));
|
|
setEnlaceActual(null);
|
|
setCintaAnterior("");
|
|
setCabezal(1);
|
|
}
|
|
|
|
/**
|
|
* Comprueba que si la cadena ingresada es reconocida por la automata
|
|
*
|
|
* @param cinta cadena ingresada por el usuario
|
|
* @param estadosFinales Arreglo de estados finales, también ingresados por usuario
|
|
* @return Verdadero si lo reconoce, caso contrario, falso
|
|
*/
|
|
public boolean comprobarCadena(StringBuilder cinta, int[] estadosFinales) {
|
|
for (int i = 0; i < getEstadoActual().getEnlaces().size(); i++) {
|
|
if (getEstadoActual().getEnlaces().get(i).getSi() == cinta.charAt(getCabezal())) {
|
|
setEnlaceActual(getEstadoActual().getEnlaces().get(i));
|
|
cinta.setCharAt(getCabezal(), getEnlaceActual().getSj());
|
|
movimientoCabezal(getEnlaceActual().getMovimiento(), cinta);
|
|
setEstadoActual(getEnlaceActual().getQj());
|
|
i = -1;
|
|
}
|
|
}
|
|
for (int estadoFinal : estadosFinales) {
|
|
if (getEstadoActual().getQ() == estadoFinal) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Comprueba que si el simbolo en la cadena, identificado por el cabezal
|
|
* es reconocido por la automata. Este guarda la cadena anterior, estado actual y
|
|
* un enlace actual
|
|
*
|
|
* @param cinta Cadena ingresada por el usuario
|
|
* @param estadosFinales Arreglo de estados finales, también ingresados por usuario
|
|
* @return Verdadero si reconce la cinta, sino falso
|
|
*/
|
|
public int comprobarCadenaS2S(StringBuilder cinta, int[] estadosFinales) {
|
|
if (cintaAnterior.equals("")) {
|
|
setCintaAnterior(cinta.toString());
|
|
}
|
|
else {
|
|
cinta = new StringBuilder(getCintaAnterior());
|
|
}
|
|
for (int i = 0; i < getEstadoActual().getEnlaces().size(); i++) {
|
|
if (getEstadoActual().getEnlaces().get(i).getSi() == cinta.charAt(getCabezal())) {
|
|
setEnlaceActual(getEstadoActual().getEnlaces().get(i));
|
|
cinta.setCharAt(getCabezal(), getEnlaceActual().getSj());
|
|
movimientoCabezal(getEnlaceActual().getMovimiento(), cinta);
|
|
setEstadoActual(getEnlaceActual().getQj());
|
|
setCintaAnterior(cinta.toString());
|
|
return 0;
|
|
}
|
|
}
|
|
for (int estadoFinal : estadosFinales) {
|
|
if (getEstadoActual().getQ() == estadoFinal) {
|
|
return 1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Realiza el movimiento correspondiente a base del caracter guardado en [movimiento]
|
|
* @param mov caracter asociado al movimiento
|
|
* @param cinta Cadena ingresada por el usuario
|
|
*/
|
|
private void movimientoCabezal(char mov, StringBuilder cinta) {
|
|
switch (mov) {
|
|
case 'L': {
|
|
setCabezal(getCabezal() - 1);
|
|
if (getCabezal() == (-1)) {
|
|
cinta.insert(0, "#");
|
|
setCabezal(getCabezal() + 1);
|
|
}
|
|
break;
|
|
}
|
|
case 'R': {
|
|
setCabezal(getCabezal() + 1);
|
|
if (getCabezal() == cinta.length()) {
|
|
cinta.insert(getCabezal(), "#");
|
|
}
|
|
break;
|
|
}
|
|
default: {/*Se mantiene*/}
|
|
}
|
|
}
|
|
} |