Kripke Module
Introduction
This module defines the Kripke structure used to represent the different branches of a potentially nested conditional expression. The labels for each state represent a single combination of evaluations for the conditional expression guards. For example, given the following simple function:
def example(x: int) -> int:
if x <= 10:
return x + 1 # s1
else:
return x - 5 # s2
the resulting Kripke structure will contain two states \(\{S_1, S_2\}\) representing the two possible outcomes of the evaluating the conditional statement with the labels, \(L(S_1)=\{x \leq 10\}\) and \(L(S_2) = \{x > 10\}\). For the more complex example:
def example2(x: int, y: int) -> int:
if x <= 10:
if y <= 20:
return x + y # s1
else:
return x - y # s2
else:
if y >= 30:
return y # s3
else:
return x # s4
the Kripke structure will have four states \(\{S_1, S_2, S_3, S_4\}\) with the labeling
\(L(S_1)=\{x \leq 10, y \leq 20\}\)
\(L(S_2)=\{x \leq 10, y > 20\}\)
\(L(S_3)=\{x > 10, y \geq 30\}\)
\(L(S_4)=\{x > 10, y < 30\}\)
An example of creating a Kripke structure can be seen below:
from bsa.kripke import Kripke, State
states = [State(), State(), State()]
initial = {
state[0]: True,
state[1]: False,
state[2]: False,
}
labels = {
state[0]: [
"color = green",
"timer <= 10"
],
state[1]: [
"color = yellow",
"timer <= 5"
],
state[2]: [
"color = red",
"timer <= 10"
],
}
edges = [
(states[0], states[1]),
(states[1], states[2]),
(states[2], states[0]),
]
kripke = Kripke(states, initial, labels, edges)