/*
* Copyright (C) 2013-2015 Vincent Langenfeld (langenfv@informatik.uni-freiburg.de)
*
* This file is part of the ULTIMATE LTL2Aut plug-in.
*
* The ULTIMATE LTL2Aut plug-in is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ULTIMATE LTL2Aut plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ULTIMATE LTL2Aut plug-in. If not, see .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify the ULTIMATE LTL2Aut plug-in, or any covered work, by linking
* or combining it with Eclipse RCP (or a modified version of Eclipse RCP),
* containing parts covered by the terms of the Eclipse Public License, the
* licensors of the ULTIMATE LTL2Aut plug-in grant you additional permission
* to convey the resulting work.
*/
package de.uni_freiburg.informatik.ultimate.ltl2aut;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import de.uni_freiburg.informatik.ultimate.core.lib.models.ObjectContainer;
import de.uni_freiburg.informatik.ultimate.core.model.models.IElement;
import de.uni_freiburg.informatik.ultimate.core.model.services.ILogger;
import de.uni_freiburg.informatik.ultimate.model.acsl.ACSLNode;
import de.uni_freiburg.informatik.ultimate.model.acsl.ast.GlobalLTLInvariant;
/***
* Transforms the LTL formula in SVComp format to a formula in ACSL_LTL.
* SVComp format:
\phi := "P" | \phi || \phi | \phi && \phi | !\phi | G \phi | F \phi |
\phi U \phi | \phi W \phi | \phi R \phi
where \phi is a temporal formula and "P" is an atomic proposition.
* additional comments in the file with "//"
*/
public class LTLFileParser {
private ILogger mLogger;
public LTLFileParser(ILogger logger){
mLogger = logger;
}
public IElement parse(File file) throws Exception{
mLogger.info("Using LTL file parser");
String line = null;
String ltlProperty = null;
//get property from file
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
while ((line = br.readLine()) != null) {
if(!line.startsWith("//") && !line.isEmpty()){
ltlProperty = line;
break;
}
}
} catch (final IOException e) {
line = null;
throw e;
}
if (ltlProperty == null){
throw new RuntimeException("LTL invariant file supplied but no LTL invariant found!");
}
String formula = transformToACSLComment(ltlProperty);
//pack into ACSL node
final ACSLNode node = de.uni_freiburg.informatik.ultimate.acsl.parser.Parser.parseComment(formula, 0, 0);
if(! (node instanceof GlobalLTLInvariant)){
throw new RuntimeException("Some ACSL Annotation, but no LTL Invariant found!");
} else {
mLogger.info("LTLInvariant: " + ((GlobalLTLInvariant)node).getFormula().toString());
}
return new ObjectContainer(node);
}
private String transformToACSLComment(String comment){
String ltlProperty = transformToACSLLTLSyntax(comment);
final StringBuilder template = new StringBuilder();
template.append("gstart");
template.append('\n');
template.append("ltl invariant positive: ");
template.append(ltlProperty);
template.append(";");
return template.toString();
}
/***
* replace
* "..." -> AP(...)
* G -> []
* F -> <>
* @param formula
* @return
*/
private String transformToACSLLTLSyntax(String formula){
final StringBuilder aux = new StringBuilder();
boolean open = false;
for(int i = 0; i < formula.length(); i++){
char c = formula.charAt(i);
if(c == '\"'){
if(open){
aux.append(")");
open = false;
} else {
aux.append("AP(");
open = true;
}
} else {
aux.append(c);
}
}
assert(!open);
formula = aux.toString();
formula = formula.replace("G", "[]");
formula = formula.replace("F", "<>");
return formula;
}
}