hu.bme.mit.theta.xcfa.cli.witnesses.GraphmlWitness.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of theta-xcfa-cli Show documentation
Show all versions of theta-xcfa-cli Show documentation
Xcfa Cli subproject in the Theta model checking framework
The newest version!
/*
* Copyright 2024 Budapest University of Technology and Economics
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package hu.bme.mit.theta.xcfa.cli.witnesses
import hu.bme.mit.theta.analysis.Trace
import java.io.File
import java.io.StringReader
import java.io.StringWriter
import javax.xml.XMLConstants
import javax.xml.transform.OutputKeys
import javax.xml.transform.Source
import javax.xml.transform.Transformer
import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamResult
import javax.xml.transform.stream.StreamSource
class GraphmlWitness(private val trace: Trace, programFile: File) {
private val attributes: MutableList = ArrayList()
private val data: MutableList> = ArrayList()
init {
attributes.add(GraphmlWitnessAttribute("sourcecodelang", "string", "graph", "sourcecodelang"))
attributes.add(GraphmlWitnessAttribute("creationtime", "string", "graph", "creationtime"))
attributes.add(GraphmlWitnessAttribute("witness-type", "string", "graph", "witness-type"))
attributes.add(GraphmlWitnessAttribute("producer", "string", "graph", "producer"))
attributes.add(GraphmlWitnessAttribute("architecture", "string", "graph", "architecture"))
attributes.add(GraphmlWitnessAttribute("programHash", "string", "graph", "programhash"))
attributes.add(GraphmlWitnessAttribute("programfile", "string", "graph", "programfile"))
attributes.add(GraphmlWitnessAttribute("specification", "string", "graph", "specification"))
attributes.add(GraphmlWitnessAttribute("assumption", "string", "edge", "assumption"))
attributes.add(
GraphmlWitnessAttribute("assumption.scope", "string", "edge", "assumption.scope")
)
attributes.add(
GraphmlWitnessAttribute(
"assumption.resultfunction",
"string",
"edge",
"assumption.resultfunction",
)
)
attributes.add(GraphmlWitnessAttribute("control", "string", "edge", "control"))
attributes.add(GraphmlWitnessAttribute("startline", "string", "edge", "startline"))
attributes.add(GraphmlWitnessAttribute("endline", "string", "edge", "endline"))
attributes.add(GraphmlWitnessAttribute("startoffset", "string", "edge", "startoffset"))
attributes.add(GraphmlWitnessAttribute("endoffset", "string", "edge", "endoffset"))
attributes.add(GraphmlWitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead"))
attributes.add(GraphmlWitnessAttribute("enterFunction", "string", "edge", "enterFunction"))
attributes.add(
GraphmlWitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction")
)
attributes.add(GraphmlWitnessAttribute("threadId", "string", "edge", "threadId"))
attributes.add(GraphmlWitnessAttribute("createThread", "string", "edge", "createThread"))
attributes.add(GraphmlWitnessAttribute("stmt", "string", "edge", "stmt"))
attributes.add(GraphmlWitnessAttribute("cSource", "string", "edge", "cSource"))
attributes.add(GraphmlWitnessAttribute("entry", "string", "node", "entry", "false"))
attributes.add(GraphmlWitnessAttribute("sink", "string", "node", "sink", "false"))
attributes.add(GraphmlWitnessAttribute("violation", "string", "node", "violation", "false"))
attributes.add(GraphmlWitnessAttribute("locationStacks", "string", "node", "locationStacks"))
attributes.add(GraphmlWitnessAttribute("sourceLines", "string", "node", "sourceLines"))
attributes.add(GraphmlWitnessAttribute("state", "string", "node", "state"))
data.add(Pair("witness-type", "violation_witness"))
data.add(Pair("producer", "theta"))
data.add(Pair("sourcecodelang", "C"))
data.add(Pair("specification", "CHECK( init(main()), LTL(G ! call(reach_error())) )"))
data.add(Pair("programfile", programFile.absolutePath))
data.add(Pair("programhash", createTaskHash(programFile.path)))
data.add(Pair("architecture", "32bit"))
data.add(Pair("creationtime", getIsoDate()))
}
fun toPrettyXml(): String = prettyFormat(toXml(), 4)
fun toXml(): String =
"""
${attributes.map(GraphmlWitnessAttribute::toXml).reduce { a, b -> "$a\n$b" }}
${data.map { "${it.second}" }.reduce { a, b -> "$a\n$b" }}
${trace.states.map(WitnessNode::toXml).reduce { a, b -> "$a\n$b" }}
${trace.actions.map(WitnessEdge::toXml).reduce { a, b -> "$a\n$b" }}
"""
.trimIndent()
}
data class GraphmlWitnessAttribute(
val name: String,
val type: String,
val `for`: String,
val id: String,
val defaultValue: String? = null,
) {
fun toXml(): String =
"""
" else """
>
$defaultValue
""".trimIndent()
}
"""
.trimIndent()
}
private fun escapeXml(toEscape: String): String {
var toEscape = toEscape
toEscape = toEscape.replace("&", "&")
toEscape = toEscape.replace("\"", """)
toEscape = toEscape.replace("'", "'")
toEscape = toEscape.replace("<", "<")
toEscape = toEscape.replace(">", ">")
return toEscape
}
// from https://stackoverflow.com/a/1264912
private fun prettyFormat(input: String, indent: Int): String {
return try {
val xmlInput: Source = StreamSource(StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), "")))
val stringWriter = StringWriter()
val xmlOutput = StreamResult(stringWriter)
val transformerFactory: TransformerFactory = TransformerFactory.newInstance()
transformerFactory.setAttribute("indent-number", indent)
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, "")
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "")
val transformer: Transformer = transformerFactory.newTransformer()
transformer.setOutputProperty(OutputKeys.INDENT, "yes")
transformer.transform(xmlInput, xmlOutput)
xmlOutput.getWriter().toString()
} catch (e: Exception) {
System.err.println(input.replace(Regex("( )|[\\t\\n\\r]"), ""))
throw RuntimeException(e)
}
}
fun WitnessNode.toXml(): String =
"""
${if (entry) "true" else ""}
${if (sink) "true" else ""}
${if (violation) "true" else ""}
${
if (xcfaLocations.isNotEmpty()) "${
escapeXml(xcfaLocations.toString())
}" else ""
}
${
if (cSources.isNotEmpty()) "${
escapeXml(cSources.toString())
}" else ""
}
${
if (globalState != null) "${
escapeXml(globalState.toString())
}" else ""
}
"""
.trimIndent()
fun WitnessEdge.toXml(): String =
"""
${if (assumption != null) "$assumption" else ""}
${if (assumption_scope != null) "$assumption_scope" else ""}
${if (assumption_resultfunction != null) "$assumption_resultfunction" else ""}
${if (control != null) "condition-$control" else ""}
${if (startline != null && startline != -1) "$startline" else ""}
${if (endline != null && endline != -1) "$endline" else ""}
${if (startoffset != null && startoffset != -1) "$startoffset" else ""}
${if (endoffset != null && endoffset != -1) "$endoffset" else ""}
${if (enterLoopHead) "true" else ""}
${if (enterFunction != null) "$enterFunction" else ""}
${if (returnFromFunction != null) "$returnFromFunction" else ""}
${if (threadId != null) "$threadId" else ""}
${if (createThread != null) "$createThread" else ""}
${if (stmt != null) "${escapeXml(stmt)}" else ""}
${
if (cSource != null && cSource != "") "${
escapeXml(cSource)
}" else ""
}
"""
.trimIndent()
© 2015 - 2024 Weber Informatics LLC | Privacy Policy