/*
* JFLAP - Formal Languages and Automata Package
*
*
* Susan H. Rodger
* Computer Science Department
* Duke University
* August 27, 2009
* Copyright (c) 2002-2009
* All rights reserved.
* JFLAP is open source software. Please see the LICENSE for terms.
*
*/
package file.xml;
import java.io.Serializable;
import java.util.ArrayList;
import org.w3c.dom.*;
import pumping.*;
/**
* This is the transducer for encoding and decoding
* {@link pumping.ContextFreePumpingLemma} objects.
*
* @author Jinghui Lim
* @see gui.pumping.PumpingLemmaChooser
*
*/
public class CFPumpingLemmaTransducer extends PumpingLemmaTransducer
{
/**
* The type of pumping lemma.
*/
public static String TYPE = "context-free pumping lemma";
/**
* The tag for the length of u.
*/
public static String U_NAME = "uLength";
/**
* The tag for the length of v.
*/
public static String V_NAME = "vLength";
/**
* The tag for the length of x.
*/
public static String X_NAME = "xLength";
/**
* The tag for the length of y.
*/
public static String Y_NAME = "yLength";
/**
* The tag for a case.
*/
public static String CASE_NAME = "case";
/**
* The tag for the i of a case.
*/
public static String CASE_I_NAME = "caseI";
/**
* The tag for the length of u of a case.
*/
public static String CASE_U_NAME = "caseULength";
/**
* The tag for the length of v of a case.
*/
public static String CASE_V_NAME = "caseVLength";
/**
* The tag for the length of x of a case.
*/
public static String CASE_X_NAME = "caseXLength";
/**
* The tag for the length of y of a case.
*/
public static String CASE_Y_NAME = "caseYLength";
public Serializable fromDOM(Document document)
{
ContextFreePumpingLemma pl = (ContextFreePumpingLemma)PumpingLemmaFactory.createPumpingLemma
(TYPE, document.getElementsByTagName(LEMMA_NAME).item(0).getTextContent());
/*
* Decode m, w, & i.
*/
pl.setM(Integer.parseInt(document.getElementsByTagName(M_NAME).item(0).getTextContent()));
pl.setW(document.getElementsByTagName(W_NAME).item(0).getTextContent());
pl.setI(Integer.parseInt(document.getElementsByTagName(I_NAME).item(0).getTextContent()));
/*
* Decode cases.
*
* Must decode cases before decoding the decomposition, otherwise
* the decomposition will be that of the last case. This is because,
* when add case is called, the pumping lemma chooses the decomposition
* to check if it's legal.
*/
readCases(document, pl);
//Decode the attempts
NodeList attempts = document.getDocumentElement().getElementsByTagName(ATTEMPT);
for(int i = 0; i < attempts.getLength(); i++)
pl.addAttempt(attempts.item(i).getTextContent());
//Decode the first player.
pl.setFirstPlayer(document.getElementsByTagName(FIRST_PLAYER).item(0).getTextContent());
// Decode the decomposition.
int uLength = Integer.parseInt(document.getElementsByTagName(U_NAME).item(0).getTextContent());
int vLength = Integer.parseInt(document.getElementsByTagName(V_NAME).item(0).getTextContent());
int xLength = Integer.parseInt(document.getElementsByTagName(X_NAME).item(0).getTextContent());
int yLength = Integer.parseInt(document.getElementsByTagName(Y_NAME).item(0).getTextContent());
pl.setDecomposition(new int[]{uLength, vLength, xLength, yLength});
//Return!
return pl;
}
protected void readCases(Document doc, ContextFreePumpingLemma pl)
{
NodeList caseNodes = doc.getDocumentElement().getElementsByTagName(CASE_NAME);
for(int i = 0; i < caseNodes.getLength(); i++)
{
Node caseNode = caseNodes.item(i);
if(caseNode.getNodeType() != Node.ELEMENT_NODE)
continue;
int u = Integer.parseInt(((Element)caseNode).getElementsByTagName(CASE_U_NAME).item(0).getTextContent());
int v = Integer.parseInt(((Element)caseNode).getElementsByTagName(CASE_V_NAME).item(0).getTextContent());
int x = Integer.parseInt(((Element)caseNode).getElementsByTagName(CASE_X_NAME).item(0).getTextContent());
int y = Integer.parseInt(((Element)caseNode).getElementsByTagName(CASE_Y_NAME).item(0).getTextContent());
int j = Integer.parseInt(((Element)caseNode).getElementsByTagName(CASE_I_NAME).item(0).getTextContent());
pl.addCase(new int[]{u, v, x, y}, j);
}
}
public Document toDOM(Serializable structure)
{
ContextFreePumpingLemma pl = (ContextFreePumpingLemma)structure;
Document doc = newEmptyDocument();
Element elem = doc.getDocumentElement();
elem.appendChild(createElement(doc, LEMMA_NAME, null, pl.getTitle()));
elem.appendChild(createElement(doc, FIRST_PLAYER, null, pl.getFirstPlayer()));
elem.appendChild(createElement(doc, M_NAME, null, "" + pl.getM()));
elem.appendChild(createElement(doc, W_NAME, null, "" + pl.getW()));
elem.appendChild(createElement(doc, I_NAME, null, "" + pl.getI()));
elem.appendChild(createElement(doc, U_NAME, null, "" + pl.getU().length()));
elem.appendChild(createElement(doc, V_NAME, null, "" + pl.getV().length()));
elem.appendChild(createElement(doc, X_NAME, null, "" + pl.getX().length()));
elem.appendChild(createElement(doc, Y_NAME, null, "" + pl.getY().length()));
//Encode the list of attempts.
ArrayList attempts = pl.getAttempts();
if(attempts != null && attempts.size() > 0)
for(int i = 0; i < attempts.size(); i++)
elem.appendChild(createElement(doc, ATTEMPT, null, (String)attempts.get(i)));
//Encode the list of attempts.
ArrayList cases = pl.getDoneCases();
if(cases != null && cases.size() > 0)
for(int i = 0; i < cases.size(); i++)
elem.appendChild(createCaseElement(doc, (Case)cases.get(i)));
return doc;
}
protected Element createCaseElement(Document doc, Case c)
{
Element elem = createElement(doc, CASE_NAME, null, null);
int[] decomposition = c.getInput();
elem.appendChild(createElement(doc, CASE_U_NAME, null, "" + decomposition[0]));
elem.appendChild(createElement(doc, CASE_V_NAME, null, "" + decomposition[1]));
elem.appendChild(createElement(doc, CASE_X_NAME, null, "" + decomposition[2]));
elem.appendChild(createElement(doc, CASE_Y_NAME, null, "" + decomposition[3]));
elem.appendChild(createElement(doc, CASE_I_NAME, null, "" + c.getI()));
return elem;
}
public String getType()
{
return TYPE;
}
}