hu.bme.mit.theta.xcfa.cli.portfolio.stm.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
/*
* 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.portfolio
import hu.bme.mit.theta.analysis.algorithm.SafetyResult
import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig
abstract class Node(val name: String) {
val outEdges: MutableSet = LinkedHashSet()
var parent: STM? = null
abstract fun execute(): Pair
abstract fun visualize(): String
}
class HierarchicalNode(name: String, private val innerSTM: STM) : Node(name) {
override fun execute(): Pair = innerSTM.execute()
override fun visualize(): String = """state $name {
${innerSTM.visualize()}
}""".trimIndent()
}
class ConfigNode(name: String, private val config: XcfaConfig<*, *>,
private val check: (config: XcfaConfig<*, *>) -> SafetyResult<*, *>) : Node(name) {
override fun execute(): Pair {
println("Current configuration: $config")
return Pair(config, check(config))
}
override fun visualize(): String = config.toString().lines() // TODO: reintroduce visualize()
.map { "state ${name.replace(Regex("[:\\.-]+"), "_")}: $it" }.reduce { a, b -> "$a\n$b" }
}
data class Edge(val source: Node,
val target: Node,
val trigger: (Exception) -> Boolean,
val guard: (Node, Edge) -> Boolean = { _, _ -> true }) {
init {
source.outEdges.add(this)
}
fun visualize(): String = """${source.name.replace(Regex("[:\\.-]+"), "_")} --> ${
target.name.replace(Regex("[:\\.-]+"), "_")
} : $trigger """
}
// if the exceptions set is empty, it catches all exceptions
class ExceptionTrigger(
val exceptions: Set = emptySet(),
val fallthroughExceptions: Set = emptySet(),
val label: String? = null
) : (Exception) -> Boolean {
constructor(vararg exceptions: Exception, label: String? = null) : this(exceptions.toSet(),
label = label)
override fun invoke(e: Exception): Boolean =
if (exceptions.isNotEmpty())
exceptions.contains(e) && !fallthroughExceptions.contains(e)
else
!fallthroughExceptions.contains(e)
override fun toString(): String =
label ?: ((if (exceptions.isNotEmpty()) exceptions.toString() else "*") +
(if (fallthroughExceptions.isNotEmpty()) ", not $fallthroughExceptions" else ""))
}
data class STM(val initNode: Node, val edges: Set) {
init {
val nodes = edges.map { listOf(it.source, it.target) }.flatten().toSet()
nodes.forEach {
check(
it.parent == null || it.parent === this) { "Edges to behave encapsulated (offender: $it)" }
it.parent = this
}
}
private fun visualizeNodes(): String = edges.map { listOf(it.source, it.target) }.flatten()
.toSet().map { it.visualize() }.reduce { a, b -> "$a\n$b" }
fun visualize(): String = """
${visualizeNodes()}
[*] --> ${initNode.name.replace(Regex("[:\\.-]+"), "_")}
${edges.map { it.visualize() }.reduce { a, b -> "$a\n$b" }}
""".trimMargin()
fun execute(): Pair {
var currentNode: Node = initNode
while (true) {
try {
return currentNode.execute()
} catch (e: Exception) {
println("Caught exception: $e")
val edge: Edge? = currentNode.outEdges.find { it.trigger(e) }
if (edge != null) {
println("Handling exception as ${edge.trigger}")
currentNode = edge.target
} else {
println("Could not handle trigger $e (Available triggers: ${
currentNode.outEdges.map { it.trigger }.toList()
})")
throw e
}
}
}
}
}
//fun XcfaConfig<*, CegarConfig>.visualize(inProcess: Boolean): String =
// """solvers: $abstractionSolver, $refinementSolver
// |domain: $domain, search: $search, initprec: $initPrec, por: $porLevel
// |refinement: $refinement, pruneStrategy: $pruneStrategy
// |timeout: $timeoutMs ms, inProcess: $inProcess""".trimMargin()
© 2015 - 2024 Weber Informatics LLC | Privacy Policy