package org.overture.isapog;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.overture.ast.analysis.AnalysisException;
import org.overture.ast.node.INode;
import org.overture.codegen.utils.GeneratedData;
import org.overture.codegen.utils.GeneratedModule;
import org.overture.pog.pub.IProofObligation;
import org.overture.pog.pub.IProofObligationList;
import org.overture.pog.pub.ProofObligationGenerator;
import org.overturetool.cgisa.IsaGen;
/**
* Main class for Isabelle Translation and POG integration. <br>
* <br>
* Usage: instantiate the class with the module you wish to analyse. THen use {@link #getModelThyString()} and
* {@link #getPosThyString()} to obtain the Strings for the model and POs translations respectively. <br>
* You can also use {@link #writeThyFiles(String)} to write the theory files directly.
*
* @author ldc
*/
public class IsaPog
{
private static final String POS_THY = "_POs";
private static final String ISA_THEORY = "theory";
private static final String ISA_IMPORTS = "imports";
private static final String SINGLE_SPACE = " ";
private static final String LINEBREAK = "\n";
private static final String ISA_BEGIN = "begin\n";
private static final String ISA_END = "end";
private static final String ISA_LEMMA = "lemma";
private static final String BY_TAC = " by vdm_auto_tac";
private static final String THY_EXT = ".thy";
private static final String ISA_OPEN_COMMENT = "(*";
private static final String ISA_CLOSE_COMMENT = "*)";
private GeneratedModule modelThy;
private String modelThyName;
private String posThy;
private String posThyName;
public IsaPog(List<INode> ast) throws AnalysisException,
org.overture.codegen.ir.analysis.AnalysisException
{
IProofObligationList pos = ProofObligationGenerator.generateProofObligations(ast);
pos.renumber();
IsaGen ig = new IsaGen();
modelThy = ig.generate(ast).getClasses().get(0);
modelThyName = modelThy.getName() + THY_EXT;
posThy = makePosThy(pos, modelThy.getName());
posThyName = modelThy.getName() + POS_THY + THY_EXT;
}
public String getModelThyString()
{
return modelThy.getContent();
}
public String getPosThyString()
{
return posThy;
}
public String getModelThyName()
{
return modelThyName;
}
public String getPosThyName()
{
return posThyName;
}
public boolean hasErrors()
{
return modelThy.hasMergeErrors() || modelThy.hasUnsupportedIrNodes()
|| modelThy.hasUnsupportedTargLangNodes();
}
public String getErrorMessage()
{
StringBuilder sb = new StringBuilder();
sb.append(modelThy.getMergeErrors().toString());
sb.append(LINEBREAK);
sb.append(modelThy.getUnsupportedInIr().toString());
sb.append(LINEBREAK);
sb.append(modelThy.getUnsupportedInTargLang().toString());
return sb.toString();
}
/**
* Write Isabelle theory files to disk for the model and proof obligations
*
* @param path
* Path to the directory to write the files to. Must end with the {@link File#separatorChar}
* @return true if write is successful
* @throws IOException
*/
public Boolean writeThyFiles(String path) throws IOException
{
File modelThyFile = new File(path + modelThyName);
FileUtils.writeStringToFile(modelThyFile, modelThy.getContent());
File posThyFile = new File(path + posThyName);
FileUtils.writeStringToFile(posThyFile, posThy);
return true;
}
private String makePosThyHeader(String moduleName)
{
StringBuilder sb = new StringBuilder();
sb.append(ISA_THEORY);
sb.append(SINGLE_SPACE);
sb.append(moduleName);
sb.append(POS_THY);
sb.append(LINEBREAK);
sb.append(ISA_IMPORTS);
sb.append(SINGLE_SPACE);
sb.append(moduleName);
sb.append(LINEBREAK);
sb.append(ISA_BEGIN);
return sb.toString();
}
private String makePoLemma(IProofObligation po) throws AnalysisException,
org.overture.codegen.ir.analysis.AnalysisException
{
StringBuilder sb = new StringBuilder();
sb.append(ISA_OPEN_COMMENT);
sb.append(" ");
sb.append(po.toString());
sb.append(" ");
sb.append(ISA_CLOSE_COMMENT);
sb.append(LINEBREAK);
sb.append(ISA_LEMMA);
sb.append(SINGLE_SPACE);
sb.append(po.getIsaName());
sb.append(": ");
sb.append("\"+|");
sb.append(IsaGen.vdmExp2IsaString(po.getValueTree().getPredicate()));
sb.append("|+\"");
sb.append(BY_TAC);
sb.append(LINEBREAK);
return sb.toString();
}
private String makePosThy(IProofObligationList pos, String moduleName)
throws AnalysisException,
org.overture.codegen.ir.analysis.AnalysisException
{
StringBuilder sb = new StringBuilder();
sb.append(makePosThyHeader(moduleName));
sb.append(LINEBREAK);
Iterator<IProofObligation> iter = pos.iterator();
IProofObligation po;
while (iter.hasNext())
{
po = iter.next();
sb.append(makePoLemma(po));
sb.append(LINEBREAK);
}
sb.append(ISA_END);
return sb.toString();
}
}