Abstract
Given a behavior of interest, automatically determining the corresponding responsible entity (i.e., the root cause) is a task of critical importance in program static analysis. In this article, a novel definition of responsibility based on the abstraction of trace semantics is proposed, which takes into account the cognizance of observer, which, to the best of our knowledge, is a new innovative idea in program analysis. Compared to current dependency and causality analysis methods, the responsibility analysis is demonstrated to be more precise on various examples.
However, the concrete trace semantics used in defining responsibility is uncomputable in general, which makes the corresponding concrete responsibility analysis undecidable. To solve this problem, the article proposes a sound framework of abstract responsibility analysis, which allows a balance between cost and precision. Essentially, the abstract analysis builds a trace partitioning automaton by an iteration of over-approximating forward reachability analysis with trace partitioning and under/over-approximating backward impossible failure accessibility analysis, and determines the bounds of potentially responsible entities along paths in the automaton. Unlike the concrete responsibility analysis that identifies exactly a single action as the responsible entity along every concrete trace, the abstract analysis may lose some precision and find multiple actions potentially responsible along each automaton path. However, the soundness is preserved, and every responsible entity in the concrete is guaranteed to be also found responsible in the abstract.
1 Introduction
Determining the responsible entity (or, say, the root cause) of given behaviors of interest is an essential problem in the field of program analysis, especially for safety and security critical systems. For instance, given an undesired behavior (e.g., rounding error, buffer overflow) in the program, it is of significance to identify the responsible entity and configure the program accordingly, such that the undesired behavior can be prevented; similarly, determining the responsible entity for desired behaviors (e.g., no occurrence of runtime errors, non-interference) helps programmers discovering solutions that ensure the program safety and security.
In this article, we aim at designing a generic theoretical framework of responsibility analysis, which can be instantiated in a broad range of cases to determine responsibility automatically. Contrary to accountability mechanisms [29, 39, 76] that track down perpetrators after the fact, we need to detect the responsible entity before deploying the analyzed system. Due to the massive scale of modern software, it is virtually impossible to identify responsible entities manually. Thus, the only possible solution is to use the static analysis, which can examine all possible executions of a program without executing them.
Currently, the existing static analysis techniques, such as dependency analysis [1, 12, 73], taint analysis [64], and program slicing [75], do help in narrowing down the scope of possible locations of responsible entities. However, no matter whether adopting semantic or syntactic methods, these techniques are not precise enough to explicitly identify responsibility. Meanwhile, the recent research on causality, such as the actual causality [34, 35, 63] that is based on the structural equations model (SEM) [15], succeeds in detecting cause-effect relationships in various scenarios that cannot be handled well by classic counterfactual causality [51, 52]. While the actual causality analysis is initially designed for artificial intelligence, it has been extended to reason about computational models and applied to bounded model checking [9, 47, 49]. Nevertheless, it cannot directly analyze the program syntax, and the adopted SEM unnecessarily misses some information (e.g., the temporal ordering of actions, whether an entity is free to make choices or not) that are inherent in the program semantics and indispensable in determining responsibility accurately.
To solve the above problems, we propose a novel definition of responsibility (Section 3) based on the abstraction of trace semantics, which is demonstrated to be more precise than current dependency/causality analysis. Roughly speaking, to the cognizance of an observer, an action \({a}_{\, \mbox{R}}\) is responsible for the behavior \(\mathcal {B}\) of interest in a given execution if and only if, according to the observer’s observation, \({a}_{\, \mbox{R}}\) is free to make choices, and such a choice is the first one that guarantees the occurrence of \(\mathcal {B}\) in that execution. It is worth noting that our definition of responsibility in this article is a variant of the original one proposed in References [25, 26], such that the revised definition is more suitable for analyzing programs and handling system behaviors of complex structure.
In addition, another major challenge encountered is that the concrete trace semantics used in the definition of responsibility is uncomputable in general, making the corresponding concrete responsibility analysis undecidable. To solve this problem, this article seeks to compute a sound over-approximation of responsibility by abstract interpretation [18, 20, 21]. Abstract interpretation is a general theory to reason on computer programs by the approximations of program semantics, and its principle is to replace the computations on concrete semantics with computations in computer-represented abstractions that, for the sake of efficiency, only represent a selected subset of program properties and ignore others [61]. Specifically, here we propose to abstract the program trace semantics by trace partitioning automata (Section 5) that can be constructed by over-approximating forward (possible success) reachability analysis with trace partitioning [53, 70]. Furthermore, together with the under-approximating [60, 61] and over-approximating backward impossible failure accessibility analysis (Section 4), we present a sound framework of abstract responsibility analysis (Section 7), which determines the possible range of responsible entities along paths in the automaton. Although the abstract analysis loses precision to some extent, the soundness is preserved. That is to say, it is guaranteed that every action that is found responsible in the concrete must be also determined responsible in the abstract, and every action that is not found responsible in the abstract cannot be responsible in the concrete.
The application of responsibility analysis is pervasive. Although the implementation of an automatic responsibility analyzer is not provided here, we have demonstrated its effectiveness by various simple examples (Section 3.3), which includes the access control, negative balance/buffer overflow, division by zero/login attack, and information leakage.
Contribution. In this article, we present preliminary work towards the fully automatic responsibility analysis by abstract interpretation. To be more precise, the key contributions are:
A novel definition of responsibility based on the abstract interpretation of trace semantics is introduced, where the observer’s cognizance allows analyzing the responsibility from the perspective of different observers. Compared with the initial definition [25, 26] that is defined on event trace semantics, the revised definition in this article is based on the abstraction of state trace semantics, making it more suitable to analyze programs. Moreover, the definition is enhanced to handle the lattice of system behaviors of more complex structures.
Two types of reachability/accessibility semantics are formalized: the forward possible success reachability semantics and the backward impossible failure accessibility semantics. Similar to the under-approximating backward impossible failure accessibility analysis proposed by Miné [60, 61], we take three popular numerical abstract domains (i.e., intervals [19], polyhedra [24], and octagons [56, 57, 58]) as examples, and discuss the design of an over-approximating forward possible success reachability analysis, as well as an over-approximating backward impossible failure accessibility analysis.
The trace partitioning domain proposed by Mauborgne and Rival [53, 70] is extended with partitioning directives based on program invariants, and trace partitioning automata are introduced to intuitively represent partitioned trace semantics.
The method of specifying behaviors of interest and the observer’s cognizance in the abstract domain is presented, as well as a sound approach of checking the validity of partitioning directives with respect to the given abstract cognizance.
A sound framework of abstract responsibility analysis is proposed, which consists of an iteration of over-approximating forward possible success reachability analysis with trace partitioning and under/over-approximating backward impossible failure accessibility analysis.
Outline. Section 2 introduces the syntax and semantics of a transition system, which is generic to handle programs written in various languages. Section 3 discusses the characteristics of responsibility, formalizes the concrete definition of responsibility as an abstraction of the program trace semantics, and exemplifies the applications of responsibility analysis. The next two sections are the basis for abstract responsibility analysis: Section 4 formalizes four types of reachability/accessibility semantics and summarizes the design of over-approximating forward possible success reachability analysis and under/over-approximating backward impossible failure accessibility analysis; Section 5 proposes to construct the trace partitioning automaton by over-approximating forward reachability analysis with trace partitioning. Section 6 describes the user specification of behaviors and cognizance in the abstract, and Section 7 illustrates the framework of abstract responsibility analysis. Section 8 reviews related work, and Section 9 concludes and discusses future work. Last, we have the proofs of all non-trivial results, most of which are relegated to Appendix A.
2 Program Syntax and Semantics
In this article, programs are modeled as transition systems [71, Ch.2.4], providing a language-independent small-step operational semantics that is generic to handle various programming languages (including a simple language introduced here, which is similar to a subset of C language).
2.1 Program Syntax
Transition Systems. As illustrated in Figure 1, \(\mathbb {V}\) is the set of all possible values. \(\mathbb {X}\) is the set of variables. \(\mathbb {M}\) is the set of environments, each of which maps all the variables to their values. \(\mathbb {L}\) is the set of program points; specially, \({ {l}}^{i}\in \mathbb {L}\) is the initial program point, and \({ {l}}^{f}\in \mathbb {L}\) is the final program point. \(\mathbb {S}= \mathbb {L}\times \mathbb {M}\) is the set of states, each of which is a pair of a program point \({l}\in \mathbb {L}\) and an environment \(\rho \in \mathbb {M}\). Specially, \(\mathbb {S}^{i}\in \wp (\mathbb {S})\) denotes the set of initial states, which can be implemented as \(\mathbb {S}^{i}= \lbrace { {l}}^{i}\rbrace \times \mathbb {M}\) in practice; \(\mathbb {S}^{f}\in \wp (\mathbb {S})\) denotes the set of final states, which is implemented as \(\mathbb {S}^{f}= \lbrace { {l}}^{f}\rbrace \times \mathbb {M}\) and represents correct program termination; and ω denotes the error state, which represents the incorrect program termination (e.g., division by zero). By abuse of notation, ω also denotes the error in expression evaluations and the error environment. \(\mathbb {A}\) is the set of all actions (i.e., atomic instructions) in the program, e.g., assignments, Boolean tests, skip, external inputs, random number generations, variable initialization, and so on.
Fig. 1. Transition system domains.
The transition relation can be defined as \(\rightarrow \, \in \wp (\mathbb {S}\;\times \;\mathbb {A}\,\times \,\mathbb {S})\), such that \(\langle {s},\: {a},\: {s}^{\prime }\rangle \in \rightarrow\) (or, \({s}\xrightarrow {a} {s}^{\prime }\)) denotes an atomic step from one state \({s}\) to another state \({s}^{\prime }\) after executing the action \({a}\). Alternatively, we can omit the action \({a}\), and define the transition relation as \(\rightarrow \; \in \wp (\mathbb {S}\times \mathbb {S})\), such that an atomic step from \({s}\) to \({s}{^{\prime }}\) is denoted as \({ {s}}\rightarrow { {s}^{\prime }}\). To be consistent with the notations in Reference [70], here we adopt the later definition of transition relation, and the omitted actions can be easily retrieved from the program source code. In addition, it is assumed that there is no outgoing transition from final states or the error state (i.e. \(\forall {s}\in \mathbb {S}^{f}\cup \lbrace \omega \rbrace .\; \forall {s}^{\prime } \in \mathbb {S}.\; { {s}} \not\rightarrow { {s}^{\prime }}\)).
A transition system (or, program) \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\) is defined as a pair of the set of initial states and the transition relation, which is generic to represent programs written in various languages.
A Simple Language. To formalize the forward reachability analysis and backward accessibility analysis for numerical programs in Section 4, we instantiate the transition system by a simple programming language in Figure 2. It is similar to the language used in Reference [60], except the ternary operation (or conditional operation) “\({bexpr}\; ?\; {expr}: {expr}\),” which can be equivalently represented by a conditional. More precisely, \(\mathbb {X}\) is a finite fixed set of real-valued variables (i.e., \(\mathbb {V}= \mathbb {R}\) are real numbers and can be further restricted to integers \(\mathbb {Z}\)), expr denotes numerical expressions, and bexpr denotes Boolean expressions. Besides, an interval \([ {a};{b} ]\) returns a random number between the left bound a and the right bound b, which facilitates directly representing non-determinism. Specially, when a = b, the interval \([{a};{b}]\) denotes the constant number a. In addition, it is assumed that each atomic statement is associated with a unique program point \({l}\) from \(\mathbb {L}\).
Fig. 2. The syntax of a simple language.
Every program written in this simple language can be modeled by a transition system, in which each action is either an assignment \({x} := {expr}\) or a Boolean test bexpr. In addition, as shown in Figure 3, for every (numerical or Boolean) expression e, its semantics \([\![ {e}]\!] {\rho }\) is defined as the set of all possible (numerical or Boolean) values that e may take in a given environment ρ (tt denotes true, while ff denotes false); for each action \({a}\), we define an environment transfer function \(\tau \lbrace \mid {{a}}\mid \rbrace \in \wp (\mathbb {M})\rightarrow^{\nearrow} \wp (\mathbb {M}\cup \lbrace \omega \rbrace)\), which maps a set of environments before \({a}\) to the set of reachable environments after it, including the error state ω if the execution of \({a}\) encounters an error. From these environment transfer functions, the corresponding transition relation \(\rightarrow\) can be easily derived: For any atomic action of the form \({}^{ {l}} {a}\;{}^{ {l}^{\prime }}\), the transition relation is \(\lbrace \langle {l},\:\rho \rangle \rightarrow \langle {l}^{\prime },\:\rho ^{\prime }\rangle \mid \rho , \rho ^{\prime }\in \mathbb {M}\wedge \rho ^{\prime }\in \tau \lbrace \mid { {a}}\mid \rbrace (\lbrace \rho \rbrace)\rbrace \cup \lbrace \langle {l},\:\rho \rangle \rightarrow \omega \mid \rho \in \mathbb {M}\wedge \omega \in \tau \lbrace \mid { {a}}\mid \rbrace (\lbrace \rho \rbrace)\rbrace\); for any program \(\textrm {P}\), its transition relation is the union of transition relations defined for all its atomic actions.
Fig. 3. The environment transfer functions and expression semantics.
2.2 Program Semantics
Traces. For any program (i.e., transition system), an execution is represented by a finite or infinite sequence of states, which is called as a trace; the program semantics is a set of such executions, and a trace property is a set of traces that have this property.
In the following, we write \(\sigma = { {s}_{0}}{\cdots }{ {s}_{n-1}}\) to denote a finite trace of exactly length n, where the \((i+1)^{th}\) state \({s}_{i} = \langle {l}_{i},\:\rho _{i}\rangle \in \mathbb {S}\) along the trace is denoted as \({\sigma }_{[i]}\); equivalently, such a finite trace of length n can be represented as a mapping from natural numbers in 0, n-1 to states. Similarly, we write \(\sigma = { {s}_{0}}{\cdots }{ {s}_{i}}{\cdots }\) to denote an infinite trace that does not terminate, and such a trace can be equivalently represented as a mapping from all natural numbers to states. Specially, ε denotes the empty trace. In addition, by abuse of notation, we say a state \({s}\) belongs to a trace σ (i.e., \({s}\in \sigma\)), if there exists a natural number \(i\in \mathbb {N}\) such that \({\sigma }_{[i]} = {s}\).
For any trace σ, its length |σ| is the number of states in σ. Specially, the length of the empty trace |ε| is 0; for an infinite trace σ, its length |σ| is denoted as ∞. \[\begin{equation*} \begin{array}{rclcl} \sigma &\in &\mathbb {S}^+&\triangleq &\bigcup _{n\geqslant 1}([0,n-1]\mapsto \mathbb {S})\text{finite traces}\\ \sigma &\in &\mathbb {S}^\ast &\triangleq &\lbrace \varepsilon \rbrace \cup \mathbb {S}^+\text{empty or finite traces}\\ \sigma &\in &\mathbb {S}^\infty &\triangleq &\mathbb {N}\mapsto \mathbb {S}\text{infinite traces}\\ \sigma &\in &\mathbb {S}^{+\infty }&\triangleq &\mathbb {S}^+\cup \mathbb {S}^\infty \text{finite or infinite traces}\\ \sigma &\in &\mathbb {S}^{\ast \infty }&\triangleq &\lbrace \varepsilon \rbrace \cup \mathbb {S}^{+\infty }\text{empty or finite or infinite traces}\end{array} \end{equation*}\]
The concatenation of a finite trace \(\sigma = { {s}_{0}}{\cdots }{ {s}_{n-1}}\) and a state \({s}\) is defined by juxtaposition \(\sigma {s}\) such that \(\sigma {s}= { {s}_{0}}{\cdots }{ {s}_{n-1}}{ {s}}\); the concatenation of a finite trace \(\sigma = { {s}_{0}}{\cdots }{ {s}_{n-1}}\) and a transition \(\tau = { {s}_{n-1}}\rightarrow { {s}_{n}}\) is denoted as \(\sigma \tau\) such that \(\sigma \tau = { {s}_{0}}{\cdots }{ {s}_{n-1}}{ {s}_{n}}\); the concatenation of a finite traces \(\sigma = { {s}_{0}}{\cdots }{ {s}_{n-1}}\) and another (finite or infinite) trace \(\sigma ^{\prime } = { {s}^{\prime }_{0}}{\cdots }\) is denoted as \(\sigma \sigma ^{\prime }\) such that \(\sigma \sigma ^{\prime } = { {s}_{0}}{\cdots }{ {s}_{n-1}}{ {s}^{\prime }_{0}}{\cdots }\); the concatenation of an infinite trace σ and another trace (or a state, a transition) is the same as σ itself.
A trace σ is said to be ⪯ - less than or equal to another trace \(\sigma ^{\prime }\) if and only if σ is a prefix of \(\sigma ^{\prime }\). Besides, for any set \(\mathcal {T}\) of traces, we define \({\mathtt {Pref}} {\mathcal {T}}\) as the set of prefixes of traces in \(\mathcal {T}\). \[\begin{equation*} \begin{array}{@{}rcl} \sigma \preceq \sigma ^{\prime }&\triangleq & \;|\sigma | \leqslant |\sigma ^{\prime }| \wedge \forall \, 0 \leqslant i \lt |\sigma |: {\sigma }_{[i]} = {\sigma ^{\prime }}_{[i]}\text{ordering of traces} \\ {\mathtt {Pref}} {} &\in & \wp (\mathbb {S}^{\ast \infty })\mapsto \wp (\mathbb {S}^{\ast \infty }) \text{prefixes of traces} \\ {\mathtt {Pref}} {\mathcal {T}}&\triangleq & \lbrace \sigma ^{\prime }\in \mathbb {S}^{\ast \infty }\mid \exists \sigma \in \mathcal {T}.\;\sigma ^{\prime }\preceq \sigma \rbrace \end{array} \end{equation*}\]
Trace semantics. For a program \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\), a valid intermediate (partial) trace σ is a finite or infinite trace, along which every two successive states are bounded by the transition relation →. The intermediate (partial) trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {It}}\in \wp (\mathbb {S}^{\ast \infty })\) is the set of all valid intermediate traces for \(\textrm {P}\), i.e., \([\![ \textrm {P}]\!] ^{\mathsf {It}} \triangleq \lbrace { {s}_{0}}{\cdots }{ {s}_{n-1}} \in \mathbb {S}^\ast \mid \forall i\in [0, n-2].\, {s}_{i}\rightarrow {s}_{i+1}\rbrace \cup \lbrace { {s}_{0}}{\cdots }{ {s}_{i}}{\cdots } \in \mathbb {S}^\infty \mid \forall i\in \mathbb {N}.\, {s}_{i}\rightarrow {s}_{i+1}\rbrace\). This semantics is a formal description of the executions of \(\textrm {P}\), which start from any state and stop at any time or do not ever stop.
A valid prefix trace σ is a finite or infinite trace, such that it starts from an initial state \({s}\in \mathbb {S}^{i}\) and every two successive states along the trace are related by the transition relation →. The prefix trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Pref}}\in \wp (\mathbb {S}^{\ast \infty })\) of \(\textrm {P}\) is the set of valid prefix traces, i.e., \([\![ \textrm {P}]\!] ^{\mathsf {Pref}} \triangleq \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {It}} \mid {\sigma }_{[0]} \in \mathbb {S}^{i}\rbrace = \lbrace { {s}_{0}}{\cdots }{ {s}_{n-1}} \in \mathbb {S}^\ast \mid {s}_{0} \in \mathbb {S}^{i}\wedge \forall i\in [0, n-2].\, {s}_{i}\rightarrow {s}_{i+1}\rbrace \cup \lbrace { {s}_{0}}{\cdots }{ {s}_{i}}{\cdots } \in \mathbb {S}^\infty \mid {s}_{0} \in \mathbb {S}^{i}\wedge \forall i\in \mathbb {N}.\, {s}_{i}\rightarrow {s}_{i+1}\rbrace\). This semantics is a formal description of the executions of \(\textrm {P}\), which start from any initial state and stop at any time or do not ever stop.
A valid maximal trace σ is a finite or infinite trace, such that it starts from an initial state \({s}\in \mathbb {S}^{i}\), every two successive states are related by the transition relation →, and either it terminates at a final state \({s}^{\prime }\in \mathbb {S}^{f}\) or the error state ω, or it does not ever terminate. The maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\in \wp (\mathbb {S}^{\ast \infty })\) of \(\textrm {P}\) is the set of valid maximal traces, i.e., \([\![ \textrm {P}]\!] ^{\mathsf {Max}} \triangleq \lbrace { {s}_{0}}{\cdots }{ {s}_{n-1}} \in \mathbb {S}^\ast \mid {s}_{0} \in \mathbb {S}^{i}\wedge \forall i\in [0, n-2].\, {s}_{i}\rightarrow {s}_{i+1} \wedge {s}_{n-1} \in \mathbb {S}^{f}\cup \lbrace \omega \rbrace \rbrace \cup \lbrace { {s}_{0}}{\cdots }{ {s}_{i}}{\cdots } \in \mathbb {S}^\infty \mid {s}_{0} \in \mathbb {S}^{i}\wedge \forall i\in \mathbb {N}.\, {s}_{i}\rightarrow {s}_{i+1}\rbrace\). This semantics is a formal description of the executions of \(\textrm {P}\), which start from any initial state and stop only at final states or crash or last forever. It is not hard to see that \([\![ \textrm {P}]\!] ^{\mathsf {Max}} \subseteq [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \subseteq [\![ \textrm {P}]\!] ^{\mathsf {It}}\). In addition, the prefix trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Pref}}\) is an abstraction of the maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) via the function \({\mathtt {Pref}} {}\), i.e., \([\![ \textrm {P}]\!] ^{\mathsf {Pref}} = {\mathtt {Pref}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}\).
(Access Control).
The program in Figure 4 can be interpreted as an access control program for an object o (e.g., a confidential file) such that o can be accessed if and only if both two admins approve the access and the permission type of o from system settings is greater than or equal to “read only.” For the sake of clarity, it is assumed that in this example the evaluation of an interval returns only integers (i.e., \(\mathbb {V}= \mathbb {Z}\)), and the analysis is similar to analyzing real numbers. Specifically, in lines 2 and 4, the variable \({i1}\) and \({i2}\) assigned by a non-deterministic integer from \([{-1};{2}]\) are used to mimic external inputs that correspond to the decisions of two independent admins, where a positive value (i.e., 1 or 2) represents approving the access to o, while 0 or a negative value (i.e., -1) represents rejecting the access; in line 6, the variable \({typ}\) assigned by \([{1};{2}]\) mimics the action of reading the permission type of o specified in the system settings (e.g., we can assume that 1 represents “read only,” and 2 represents “read and write,” which is similar to the file permissions system in Unix); in line 8, the access to o succeeds only when the value of \({acs}\) is strictly positive (i.e., 1 or 2), which guarantees that both admins approve the access and the permission type of o is at least as high as “read only.”
Fig. 4. Access control program example.
Here, we are interested in: When the access to o fails in the execution (referred as “Access Failure,” i.e., \({acs} \le 0\) at point \({l}_8\)), which action (actions) shall be responsible?
Throughout this article, we use this example to illustrate responsibility analysis. To begin with, we represent the above program as a transition system: the set of program points \(\mathbb {L}= \lbrace {l}_{1}, {l}_{2}, {l}_{3}, {l}_{4}, {l}_{5}, {l}_{6}, {l}_{7}, {l}_{8}\rbrace\); the set of variables \(\mathbb {X}= \lbrace {apv}, {i1}, {i2}, {typ}, {acs}\rbrace\); the set of environments \(\mathbb {M}= \mathbb {X}\mapsto \mathbb {Z}\), where \(\mathbb {Z}\) is the set of integers; the set of states \(\mathbb {S}= \mathbb {L}\times \mathbb {M}\), the set of initial states \(\mathbb {S}^{i}= \lbrace {l}_{1}\rbrace \times \mathbb {M}\), and the set of final states \(\mathbb {S}^{f}= \lbrace {l}_{8}\rbrace \times \mathbb {M}\). Moreover, the transition relation → can be easily derived from the environment transfer functions for the atomic actions (e.g., \(\tau \lbrace \mid { {i1} := [-1; 2]}\mid \rbrace\), \(\tau \lbrace \mid { {apv} := ( {i1} \le 0)\; ?\; -1 : {apv}}\mid \rbrace\)).
Next, consider its trace semantics. It is obvious that there is no valid infinite trace and there is no possibility to reach the error state ω, thus a valid maximal trace must start from the initial point \({l}_1\) and terminate at the final point \({l}_8\). More precisely, its maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}} = \lbrace \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2\rangle \langle {l}_3,\:\rho _3\rangle \langle {l}_4,\:\rho _4\rangle \langle {l}_5,\:\rho _5\rangle \langle {l}_6,\:\rho _6\rangle \langle {l}_7,\:\rho _7\rangle \langle {l}_8,\:\rho _8\rangle \mid (\rho _1 \in \mathbb {M}) \wedge (\rho _2 = {\rho _1}{ {apv}}{1}) \wedge (\rho _3 = {\rho _2}{ {i1}}{ {v}_1} \wedge {v}_1 \in \lbrace -1, 0, 1, 2\rbrace) \wedge (\rho _4 = {\rho _3}{ {apv}}{((\rho _3( {i1}) \lt = 0) ? -1 : \rho _3( {apv}))}) \wedge (\rho _5 = {\rho _4}{ {i2}}{ {v}_2} \wedge {v}_2 \in \lbrace -1, 0, 1, 2\rbrace) \wedge (\rho _6 = {\rho _5}{ {apv}}{((\rho _5( {apv}) \gt = 1 \wedge \rho _5( {i2}) \lt = 0) ? -1 : \rho _5( {apv}))}) \wedge (\rho _7 = {\rho _6}{ {typ}}{ {v}_3} \wedge {v}_3 \in \lbrace 1, 2\rbrace) \wedge (\rho _8 = {\rho _7}{ {acs}}{\rho _7( {apv}) \times \rho _7( {typ})}) \rbrace\). In addition, the trace property “Access Failure” can be represented by a set of maximal traces in which the value of \({acs}\) is less than or equal to 0 at point \({l}_8\), i.e., \(\lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[7]} = \langle {l}_8,\:\rho \rangle \wedge \rho ( {acs}) \lt = 0\rbrace\).
3 THE DEFINITION OF RESPONSIBILITY
The objective of this section is to give a formal definition of responsibility in the concrete. To start with, we introduce a simple but thought-provoking example of forest fire, which characterizes the difference of responsibility with dependency and causality. Inspired by this forest fire example, we suggest an informal definition of responsibility, which is quite intuitive and applicable to analyzing various behaviors. Furthermore, we design a framework of concrete responsibility analysis, in which the responsibility is formally defined as an abstraction of the trace semantics. The application of responsibility analysis is demonstrated to be pervasive by examples, including negative balance/buffer overflow, division by zero/login attack, and information leakage.
3.1 The Characteristics of Responsibility
Here, we start with a simple intuitive example of forest fire used in defining actual cause [34, 35] and further characterize three indispensable elements in defining responsibility.
(Forest Fire).
Suppose that two arsonists drop lit matches in different parts of a dry forest on a windy day, and both cause trees to start burning. Here it is assumed that one arsonist named A drops the lit match before the other arsonist B, and there are two scenarios. In the first scenario, called the disjunctive scenario, either match by itself suffices to burn down the whole forest. That is to say, even if only one match were lit, the forest would burn down. In the second scenario, called the conjunctive scenario, two lit matches are necessary to burn down the whole forest; if only one match were lit, some trees would be burnt, but the fire dies down before the whole forest is destroyed.
It is quite natural to bring up this question: Who shall be responsible for burning down the whole forest? The literature has several possible answers. First, a simple but popular solution is the dependency analysis [1, 12, 17, 48, 73] that determines how entities (e.g., values of variables) depend upon other entities. Suppose we use variables to represent all the entities in the forest fire example (e.g., the decisions of two arsonists, the status of matches, the fire condition of the forest, the weather), then the real-life example of forest fire can be viewed as an equivalent computer program. By the definition of dependency, in both scenarios the forest fire depends on those two arsonists, as well as many other non-decisive factors, such as the wind, which influences the spreading speed of forest fire. Such a result is correct, but far from precise: The wind could not either enforce or prevent the fire, and it is against the intuition to take such non-decisive factors as responsible entities.
Next, the classic counterfactual causality [51, 52] determines causality according to a criterion: An event e is a cause of the occurrence of another event \(e^{\prime }\) if and only if were e not to occur, \(e^{\prime }\) would not happen. Such a criterion excludes non-decisive factors (e.g., the wind) from causes. For instance, if there was no wind, then the forest would still be burnt down, hence the wind is not a cause of the forest fire. However, the counterfactual causality may be too strict in some circumstances. Take the disjunctive scenario of forest fire as an example, if A (respectively, B) did not drop a lit match, then the forest would still be burnt down due to the other arsonist, hence the forest fire does not counterfactually depend on any single event, and no entity is determined as the cause of fire.
Last, consider the actual cause [34, 35, 63] that is based on the structural equations model (SEM) [15] and allows “contingent counterfactual dependency.” More precisely, events are represented by variable values in the SEM, and an event e is an actual cause of another event \(e^{\prime }\) if there exists a contingency (where the values for other variables may be changed) such that \(e^{\prime }\) counterfactually depends on e. Taking the disjunctive scenario of forest fire as an example, the arsonist A is determined as an actual cause of the forest fire, since the forest fire counterfactually depends on A’s action of dropping a lit match under the contingency where the other arsonist B does not drop a lit match; in a similar way, the arsonist B is also determined as an actual cause of the forest fire. Such a structural model method has allowed for a great progress in causality analysis, solving many problems of previous approaches. In addition, it has been extended to reason about computational models and applied to bounded model checking [9, 47, 49]. However, as an abstraction of the concrete semantics, the SEM unnecessarily misses the following three essential points in determining responsibility:
(P1) | The temporal ordering of events/actions should be taken into account. For instance, in the forest fire example, the SEM cannot tell the difference whether A or B drops a lit match first, hence determines both arsonists as the cause of forest fire. Such a result may not seem to be absurd, but imagine the case that the forest has already been burnt down by A before B lit her/his match in the disjunctive scenario. In such a case, it is against intuition to put B as a cause of the forest fire. To deal with this problem, Reference [11] suggests to modify the SEM and introduce some new variable to distinguish whether the forest was actually destroyed by A or B, which is difficult to accomplish in practice for programs. In contrast, a much simpler method is to keep the temporal ordering of events/actions, such that only the first action that guarantees the behavior of interest is counted as the responsible entity. For instance, in the disjunctive scenario of forest fire, the action of dropping a lit match by A ensures burning down the whole forest even before B makes her/his choice, thus only A is responsible for burning down the forest; in the conjunctive scenario of forest fire, the lit match dropped by A starts a forest fire that would die down unless B drops a second lit match, thus A is only responsible for starting a forest fire, while B is responsible for burning down the whole forest. | ||||
(P2) | The responsible entity must be free to make choices. In the forest fire example, suppose that the match is taken as a separate entity, and its value (i.e., lit or not-lit) solely depends on the corresponding arsonist. In the SEM of actual cause, both the arsonists and the matches are represented by endogenous variables and further determined as actual causes of burning down the forest. However, it is common sense that the match itself does not have a choice to light or not, and it is inappropriate to identify matches as responsible entities for the forest fire. Hence, only the action that can make choices at its own discretion can possibly be responsible for a behavior. Specifically, in computer programs, such actions include but are not limited to user inputs, system settings, parameters of procedures or modules, variable initialization, random number generations, and the parallelism. To be more accurate, it is the external subject (who does the input, configures the system settings, etc.) that is free to make choices, but we say that actions like user inputs are free to make choices, as an abuse of language. | ||||
(P3) | It is necessary to explicitly specify “to whose cognizance” when analyzing the responsibility. All the above reasoning on causality is implicitly based on the cognizance/knowledge of an omniscient observer who knows everything that occurred, yet it is non-trivial to consider the cognizance of a non-omniscient observer. For instance, we can adopt the cognizance of the second arsonist B in the forest fire example. In the disjunctive scenario, if B is aware that A has already dropped a lit match in the forest, then B is not responsible to his/her cognizance, since B knows that the forest is guaranteed to burn down no matter whether she/he drops a lit match or not; otherwise, if B does not know a lit match has been dropped, then B is responsible for the forest fire to her/his cognizance, although she/he is not responsible to the cognizance of an omniscient observer. Similarly, in the conjunctive scenario, if B is aware that A has already dropped a lit match in the forest, then B understands that it is her/his own action that ensures burning down the whole forest, hence she/he shall take the responsibility to her/his cognizance; otherwise, if B does not know that a lit match has been dropped, then she/he does not expect the whole forest to be burnt down, hence to her/his own cognizance B is only responsible for starting a forest fire, but not burning down the whole forest. In most cases, the cognizance of an omniscient observer will be adopted, but not always. | ||||
An Informal Definition of Responsibility. To take the above three points into account, this article proposes responsibility whose informal definition is as follows.
(Responsibility, Informally).
To the cognizance of an observer, an action \({a}_{\, \mbox{R}}\) is responsible for the behavior \(\mathcal {B}\) of interest in a given execution if and only if, according to the observer’s observation, \({a}_{\, \mbox{R}}\) is free to make choices, and such a choice is the first one that guarantees the occurrence of \(\mathcal {B}\) in that execution.
It is necessary to point out that, for the whole system whose concrete semantics is a set of executions, there may exist more than one action that is responsible for \(\mathcal {B}\). Nevertheless, in every single execution where \(\mathcal {B}\) occurs, there is only one action that is responsible for \(\mathcal {B}\). To decide which action in an execution is responsible, the execution alone is not sufficient, and it is required to reason on the whole semantics to exhibit the action’s “free choices” and guarantee of \(\mathcal {B}\). Thus, responsibility is not a trace property (neither safety nor liveness property), but a hyper-property [16], which is a property of sets of execution traces.
In the following, we consider the access control program example in Figure 4 again and discuss the advantage of the responsibility analysis over the classic dependency/causality analysis in an informal way, while the responsibility analysis procedure of this access control program will be formalized in Section 3.2.
(Access Control, Continued).
For the access control program in Figure 4, the question that we are interested in is: When the access to o fails in the program execution (referred as “Access Failure,” i.e., \({acs} \le 0\) at point \({l}_8\)), which action (actions) shall be responsible?
First, we consider the dependency analysis and corresponding slicing techniques. No matter whether we adopt the syntactic dependency or semantic dependency, it is not hard to see that the value of \({acs}\) at point \({l}_8\) depends on the value of \({apv}\) and \({typ}\) at point \({l}_7\), which further depend on the inputs from the two admins and system settings. That is to say, the behavior “access failure” depends on all variables in the program, thus program slicing techniques (both syntactic slicing [75] and semantic slicing [69]) would take the whole program as the slice related with access failure. Although the slicing technique intends to rule out parts of the program that are completely irrelevant with the behavior of interest, it is too imprecise to be practically useful in this example. For instance, the computed slice includes the actions such as \({apv} := 1\), \({apv} := ( {i1} \le 0)\; ?\; -1 : {apv}\) and \({acs} := {apv}\; \times \; {typ}\), which have no free choices: They are completely deterministic and act merely as the intermediary between causes and effects, thus shall not be treated as responsible entities. Moreover, similar to the wind in the forest fire example, the action \({typ} := [1; 2]\) representing the input from system settings is a non-decisive factor for the access failure behavior (i.e., no matter whether \({typ}\) is 1 or 2, it cannot either enforce or prevent the access failure), although it does affect the value of \({acs}\) at point \({l}_8\). Therefore, the dependency analysis and slicing are not precise enough to identify responsible entities.
Second, using the counterfactual causality proposed by Lewis [51, 52], we can exclude non-decisive factors (i.e., the action \({typ} := [1; 2]\) in this example), but it fails to find any cause of the access failure behavior in the executions where the inputs from both admins are negative or zero. For example, in the execution where \({i1} = 0\) and \({i2} = 0\), neither inputs would be determined as the cause, because the behavior of access failure does not counterfactually depend on either of them. More precisely, if the input from one admin (either \({i1}\) or \({i2}\)) is changed to a strictly positive value (i.e., 1 or 2), then the access failure would still occur due to the input 0 from the other admin.
Third, we consider the definition of actual cause proposed by Halpern and Pearl [34, 35, 63], and represent the access control program by a SEM: three non-deterministic inputs from admins and system settings (i.e., \([{-1};{2}]\) and \([{1};{2}]\)) are represented by exogenous variables, and each program variable is presented by an endogenous variable, whose value is deterministically decided by the values of other (exogenous or endogenous) variables. Similar to the counterfactual causality by Lewis, non-decisive factors (i.e., the assignment to \({typ}\)) would not be counted as actual causes. Yet, the actual cause allows reasoning counterfactual dependency under a contingency, such that it can identify causes in the executions where the inputs from both two admins are negative or zero. For example, in the execution where the inputs from two admins are 0, both \({i1} = 0\) and \({i2} = 0\) are determined as actual causes of access failure, because the access failure counterfactually depends on \({i1} = 0\) (respectively, \({i2} = 0\)) under the contingency where the value of \({i2}\) (respectively, \({i1}\)) is changed to 1 or 2. Besides, similar to the dependency analysis, the intermediate events between causes and effects (e.g., \({apv} = -1\) and \({acs} = -1\)) are also determined as actual causes of access failure.
Last, compared with the above dependency/causality analysis, the responsibility analysis according to the Definition 1 would be much more precise, and it can accurately identify the responsible entities of access failure in various cases. Here, we list the entire desired responsibility analysis results, while the detailed procedure of producing such results is formalized in the next section. (1) To the cognizance of an omniscient observer: For any execution, if the input from the 1st admin is negative or zero, then no matter what the other two inputs are, only the action \({i1} := [-1; 2]\) (which represents the input from the 1st admin) is responsible for the access failure behavior, because it guarantees the access failure even before the 2nd admin inputs her/his decision; if the input from the 1st admin is positive and the input from the 2nd admin is negative or zero, then only the action \({i2} := [-1; 2]\) (which represents the input from the 2nd admin) is responsible for the access failure behavior, because the positive input from the 1st admin does not either enforce or prevent the access failure, while the negative or zero input from the 2nd admin is the first action that guarantees the access failure; otherwise, if the inputs from both admins are positive, then the access failure behavior does not occur, thus there is no responsible entity. (2) To the cognizance of a non-omniscient observer who does not know the input from the 1st admin: For any execution, if the input from the 2nd admin is negative or zero, then no matter what the input from the 1st admin is, only the action \({i2} := [-1; 2]\) (i.e., the input from the 2nd admin) is responsible for the access failure behavior, because from the knowledge of the non-omniscient observer, the access failure behavior is ensured only after the 2nd admin inputs a negative value or zero; otherwise, if the input from the 2nd admin is positive, then whether the access failure occurs or not is uncertain from the perspective of non-omniscient observer, thus no entity is responsible for the access failure.
After finishing the responsibility analysis, it is time for the user to configure permissions granted to each responsible entity at her/his discretion. In this example, suppose the cognizance of an omniscient observer is adopted, then we find that only the inputs from two admins are possibly responsible for the access failure behavior. If the two admins are authorized to control the access, then their permissions to input negative values or zero can be kept; otherwise, if those two admins have no authorization to decline the access to o, then their permissions to input negative values or zero shall be removed.
3.2 The Framework of Concrete Responsibility Analysis
To put the informal definition of responsibility (Definition 1) into effect, we design a framework of concrete responsibility analysis as illustrated in Figure 5, which essentially consists of three components: (1) Program semantics, i.e., the set of all possible executions, each of which can be analyzed individually. (2) A lattice of system behaviors of interest, which is ordered such that the stronger/stricter a behavior is, the lower is its position in the lattice. (3) An observation function for each observer, which maps every (probably unfinished) execution to a behavior in the lattice that is guaranteed to occur, even though such a behavior may not have occurred yet.
Fig. 5. Framework of concrete responsibility analysis for access control example.
In this framework of concrete analysis, if an observer’s observation finds that the guaranteed behavior grows stronger after extending an execution by an action, then the extended part of execution (i.e., the action) must be responsible for ensuring the occurrence of the stronger behavior. Consider the example in Figure 5 that sketches the analysis for a certain execution of the access control program, where the inputs from both admins are zeros while the input from system settings is one. Suppose in the lattice of system behaviors, the top \(\top ^{\mathsf {Max}}\) represents the behavior “not sure if the access to o fails or not,”
As illustrated in Figure 5, the omniscient observer finds that the execution from point \({l}_1\) to point \({l}_2\) can guarantee only \(\top ^{\mathsf {Max}}\) (i.e., before the 1st admin inputs her/his decision, whether the access to o fails or succeeds is undecided), while the stronger behavior
More formally, this section presents the program trace semantics, builds a lattice of system behaviors by trace properties, proposes an observation function that derives from the observer’s cognizance and an inquiry function on system behaviors. Furthermore, this section formally defines responsibility as an abstraction of program semantics, using the observation function. To strengthen the intuition of responsibility analysis, the analysis of the access control program example will be illustrated step-by-step in the following:
3.2.1 Program Semantics.
Generally speaking, no matter what type of program we are concerned with and no matter which programming language is used to implement that program, the corresponding program semantics can be represented as a set of execution traces.
We assume programs to be modeled as a transition system of the form \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\), as introduced in Section 2, where the intermediate trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {It}}\) is defined as the set of traces such that every two successive states are related by →; the prefix trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Pref}}\) is defined as the set of intermediate traces that start from initial states; and the maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) is the set of prefix traces that either terminate at final states or the error state ω, or do not ever terminate. A trace σ is said to be valid for a program \(\textrm {P}\) if and only if \(\sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\). Obviously, the intermediate/prefix/maximal trace semantics do preserve the temporal ordering of actions, which is missed by the SEM used by actual causes [34, 35, 63].
Specifically, for the access control program example in Figure 4, its definition of maximal trace semantics refers to Example 1. For the sake of simplicity, it is assumed that the initial environment is fixed (e.g., the value of each variable is assumed to be 0 at the initial point \({l}_1\)), hence its maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) consists of 32 traces that correspond to different input values from two admins and the system settings.
3.2.2 Lattice of System Behaviors of Interest.
Trace Property. A trace property is a set of traces. For any given system, many behaviors can be represented as a maximal trace property \(\mathcal {T}\in \wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}})\).
(Access Control, Continued).
For the access control program example in Figure 4, the behavior “Access Success”
The behavior “Access Failure”
Furthermore, the behavior
Lattice of System Behaviors of Interest. Here, we build a complete lattice of maximal trace properties, each of which represents a behavior of interest. Typically, such a lattice is of the form \(\langle \mathcal {L}^{\mathsf {Max}},\:\subseteq ,\:\top ^{\mathsf {Max}},\:\bot ^{\mathsf {Max}},\:\cup\!\!\!\!\cdot ,\:\cap\!\!\!\!\cdot \rangle\), where
\(\mathcal {L}^{\mathsf {Max}}\in \wp (\wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}}))\) is a set of behaviors of interest, each of which is represented by a maximal trace property;
\(\top ^{\mathsf {Max}}= [\![ \textrm {P}]\!] ^{\mathsf {Max}}\), i.e., the top of the lattice is the weakest maximal trace property, which holds in every valid maximal trace;
\(\bot ^{\mathsf {Max}}= \emptyset\), i.e., the bottom of the lattice is the strongest property such that no valid trace has this property, hence it is used to represent the property of invalidity;
\(\cup\!\!\!\!\cdot\) and \(\cap\!\!\!\!\cdot\) are join and meet operations, which might not be the standard \(\cup\) and \(\cap\), since \(\mathcal {L}^{\mathsf {Max}}\) is a subset of \(\wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}})\) but not necessarily a sublattice.
For any given system, there is possibly more than one way to build the complete lattice of maximal trace properties, depending on which behaviors are of interest. A special case of lattice is the power set of maximal trace semantics, i.e., \(\mathcal {L}^{\mathsf {Max}}\) \(=\) \(\wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}})\), which can be used to examine the responsibility for every possible behavior in the system. However, in most cases, a single behavior is of interest, and it is sufficient to adopt a lattice with only four elements: \(\mathcal {B}\) representing the behavior of interest, \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\backslash \mathcal {B}\) representing the complement of the behavior of interest, as well as the top \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and bottom \(\emptyset\). Particularly, if \(\mathcal {B}\) is equal to \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), i.e., every valid maximal trace in the system has this behavior of interest, then a trivial lattice with only the top and bottom is built, from which no responsibility can be found, making the corresponding analysis futile.
(Access Control, Continued).
For the access control program, there are two possible ways to build the lattice of maximal trace properties. To start with, we consider the lattice displayed in Figure 5, which consists of six elements. Regarding whether the access to o fails or not, the top \(\top ^{\mathsf {Max}}= [\![ \textrm {P}]\!] ^{\mathsf {Max}}\) is split into two properties “Access Failure”
Meanwhile, if we are interested in only one behavior (e.g., “Access Failure”
Prediction Abstraction. Although the maximal trace property is well-suited to represent system behaviors, it does not reveal the point along the maximal trace from which a property is guaranteed to hold later in the execution. Thus, we propose to abstract every maximal trace property \(\mathcal {X}\in \mathcal {L}^{\mathsf {Max}}\) into a set \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {X}}\) of prefixes of maximal traces in \(\mathcal {X}\), excluding those whose maximal prolongation may not satisfy the property \(\mathcal {X}\). This abstraction is called prediction abstraction, and \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {X}}\) is called the prediction trace property corresponding to \(\mathcal {X}\). It is easy to see that \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {X}}\) is a superset of \(\mathcal {X}\) and is not necessarily prefix-closed.

By the above definition, for any program \(\textrm {P}\), every valid maximal trace \(\sigma ^{\prime }\) that is greater than or equal to a prefix trace σ in \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {X}}\) is guaranteed to have the maximal trace property \(\mathcal {X}\) (i.e., \(\sigma ^{\prime }\in \mathcal {X}\)). Hence, the prefix traces in \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {X}}\) gives a hint on the point along the maximal trace from which the property \(\mathcal {X}\) is guaranteed to hold. Formally, we have the following lemma:
For any maximal trace property \(\mathcal {X}\in \wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}})\), if a prefix trace σ belongs to the prediction trace property \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {X}}\), then σ guarantees the satisfaction of property \(\mathcal {X}\) (i.e., every valid maximal trace that is greater than or equal to σ is guaranteed to have property \(\mathcal {X}\)).
Moreover, we have a Galois isomorphism between maximal trace properties and prediction trace properties:

Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, for any maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\), if a trace σ belongs to the prediction trace property that corresponds to \(\mathcal {T}\), then every valid trace greater than σ belongs to that prediction trace property too. I.e., \(\forall \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}.\;\forall \sigma ,\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}.\;(\sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\wedge \sigma \preceq \sigma ^{\prime })\Rightarrow \sigma ^{\prime }\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, for any maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\) and any valid prefix trace \(\pi\) that is not maximal, if every valid prefix trace \(\pi {s}\) that concatenates \(\pi\) with a new event \({s}\) belongs to the prediction trace property \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\), then π belongs to \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\) too.
Formally, \(\forall \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}.\) \(\forall \pi \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\) \((\forall {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \Rightarrow \pi {s}\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}})\Rightarrow \pi \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).
(Access Control, Continued).
By the function \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{}\), each behavior in the lattice \(\mathcal {L}^{\mathsf {Max}}\) of Example 5 can be abstracted into a prediction trace property:
\(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\top ^{\mathsf {Max}}}\) \(=[\![ \textrm {P}]\!] ^{\mathsf {Pref}}\), i.e., every valid prefix trace in \([\![ \textrm {P}]\!] ^{\mathsf {Pref}}\) guarantees \(\top ^{\mathsf {Max}}\).
\(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\texttt {AF}} =\lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \mid \exists \rho _1\in \mathbb {M}, {v}\in \lbrace -1, 0\rbrace , {v}^{\prime }\in \lbrace 1, 2\rbrace .\; \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle \preceq \sigma \vee \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}^{\prime }}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5 = {\rho _4}{ {i2}}{ {v}}\rangle \preceq \sigma \rbrace\). For any valid prefix trace σ, if at least one input from the two admins is -1 or 0, then the behavior “Access Failure” \(\texttt {AF}\) is guaranteed to occur in all the maximal traces that are greater than or equal to σ.
\(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\texttt {AS}}=\lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \mid \exists \rho _1\in \mathbb {M}, {v}\in \lbrace 1, 2\rbrace , {v}^{\prime }\in \lbrace 1, 2\rbrace .\; \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5 = {\rho _4}{ {i2}}{ {v}^{\prime }}\rangle \preceq \sigma \rbrace\). For any valid prefix trace σ, if the inputs from both admins are 1 or 2, then “Access Success” \(\texttt {AS}\) is guaranteed.
\(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\texttt {RO}}=\lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \mid \exists \rho _1\in \mathbb {M}, {v}\in \lbrace 1, 2\rbrace , {v}^{\prime }\in \lbrace 1, 2\rbrace .\; \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5 = {\rho _4}{ {i2}}{ {v}^{\prime }}\rangle \langle {l}_6,\:\rho _6 = \rho _5\rangle \langle {l}_7,\:\rho _7= {\rho _6}{ {typ}}{1}\rangle \preceq \sigma \rbrace\). For any valid trace, if the inputs from both admins are 1 or 2 and the input from system settings is 1, then it guarantees “Read Only access is granted” \(\texttt {RO}\).
\(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\texttt {RW}}=\lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \mid \exists \rho _1\in \mathbb {M}, {v}\in \lbrace 1, 2\rbrace , {v}^{\prime }\in \lbrace 1, 2\rbrace .\; \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5 = {\rho _4}{ {i2}}{ {v}^{\prime }}\rangle \langle {l}_6,\:\rho _6 = \rho _5\rangle \langle {l}_7,\:\rho _7= {\rho _6}{ {typ}}{2}\rangle \preceq \sigma \rbrace\). For any valid trace, if the inputs from both admins are 1 or 2 and the input from system settings is 2, then it guarantees “Read and Write access is granted” \(\texttt {RW}\).
\(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\bot ^{\mathsf {Max}}}\) \(=\emptyset\), i.e., no valid trace can guarantee the bottom \(\bot ^{\mathsf {Max}}\).
3.2.3 Observation of System Behaviors.
Let \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) be the maximal trace semantics and \(\mathcal {L}^{\mathsf {Max}}\) be the lattice of system behaviors designed as in Section 3.2.2. Given any prefix trace \(\sigma \in \mathbb {S}^{\ast \infty }\), an observer can learn some information from it, more precisely, a maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\) that is guaranteed by σ from the observer’s perspective. In this section, an observation function \({\mathbb {O}} {}{}{}\) is proposed to represent such a “property learning process” of the observer, which is formally defined in the following three steps.
(1) Inquiry Function. First, an inquiry function \(\mathbb {I}\) is defined to map every trace \(\sigma \in \mathbb {S}^{\ast \infty }\) to the strongest maximal trace property in \(\mathcal {L}^{\mathsf {Max}}\) that σ can guarantee. \[\begin{equation*} \begin{array}{@{}l} \mathbb {I} \in \wp (\mathbb {S}^{\ast \infty })\mapsto \wp (\wp (\mathbb {S}^{\ast \infty }))\mapsto \mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty }) \text{inquiry (2)}\\ \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\triangleq \\ \quad let\;\alpha_{\text {Pred}} {\mathcal {S}}{\mathcal {T}}=\lbrace \psi \in {\mathtt {Pref}} {\mathcal {T}}\mid \forall \psi ^{\prime }\in \mathcal {S}.\;\psi \preceq \psi ^{\prime }\Rightarrow \psi ^{\prime }\in \mathcal {T}\rbrace \;in\text{abstraction from (1)}\\ \quad \quad \cap\!\!\!\!\cdot \lbrace \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\mid \sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\rbrace \end{array} \end{equation*}\]
Specially, for every invalid trace \(\sigma \not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\), there does not exist any \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\) such that \(\sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\), thus \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\) \(=\emptyset =\bot ^{\mathsf {Max}}\). In contrast, for any valid trace \(\sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\), it is ensured that \(\sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\top ^{\mathsf {Max}}}\), hence \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma } \ne \bot ^{\mathsf {Max}}\). Therefore, \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma } = \bot ^{\mathsf {Max}}\) if and only if σ is invalid.
(Access Control, Continued).
Using the maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) from Example 1 and the lattice of system behaviors \(\mathcal {L}^{\mathsf {Max}}\) from Example 5, here we define the inquiry function \(\mathbb {I}\) for the access control program such that for any initial environment \(\rho _1\in \mathbb {M}\):
\(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle }\) = \(\top ^{\mathsf {Max}}\), i.e., every prefix trace that terminates at point \({l}_2\) (before the admins input their decisions) can guarantee only \(\top ^{\mathsf {Max}}\).
\(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle }\) = \(\texttt {AF}\), i.e., after the 1st admin inputs 0, the behavior “Access Failure” \(\texttt {AF}\) is guaranteed.
\(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle } = \mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle) = \top ^{\mathsf {Max}}\), i.e., if the first admin inputs 1, then only the top \(\top ^{\mathsf {Max}}\) can be guaranteed before the second admin inputs her/his decision.
\(\mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle)=\texttt {AF}\), i.e., after the second admin inputs 0, the behavior “Access Failure” \(\texttt {AF}\) is guaranteed.
\(\mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{1}\rangle)=\texttt {AS}\), i.e., if both two admin inputs 1, then “Access Success” \(\texttt {AS}\) is guaranteed.
\(\mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{1}\rangle \langle {l}_6,\:\rho _6 = \rho _5\rangle \langle {l}_7,\:\rho _7= {\rho _6}{ {typ}}{1}\rangle)=\texttt {RO}\), i.e., if both two admin input 1, then after the input from system settings is set as 1, a stronger property “Read Only access is granted” \(\texttt {RO}\) is guaranteed.
\(\mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{1}\rangle \langle {l}_6,\:\rho _6 = \rho _5\rangle \langle {l}_7,\:\rho _7= {\rho _6}{ {typ}}{2}\rangle)=\texttt {RW}\), i.e., if both two admin input 1, then after the input from system settings is set as 2, a stronger property “Read and Write access is granted” \(\texttt {RW}\) is guaranteed.
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, if the inquiry function \(\mathbb {I}\) maps a trace σ to a maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\), then σ guarantees the satisfaction of \(\;\mathcal {T}\) (i.e., every valid maximal trace that is greater than or equal to σ is guaranteed to have property \(\mathcal {T}\)).
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, the inquiry function \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}}\) is decreasing on the inquired trace σ: the greater (longer) σ is, the stronger property it can guarantee. I.e., \(\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\;\sigma \preceq \sigma ^{\prime }\Rightarrow \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\supseteq \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\).
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of behaviors, \(\forall \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\) \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }=\underset{ {s}\in \mathbb {S}}{\bigcup \!\!\!\!\!{\cdot} }\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}=\underset{\sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}}{\bigcup \!\!\!\!\!{\cdot} }\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\).
(2) Cognizance Function. As discussed in (P3) of Section 3.1, it is necessary to take the observer’s cognizance into account. Specifically, in program security, the cognizance can represent attackers’ capabilities, e.g., what they can learn from program executions (see Section 3.3.2 for more details). Given a trace σ (not necessarily valid), if the observer cannot distinguish σ from some other traces, then she/he does not have an omniscient cognizance of σ, and the cognizance function \({\mathbb {C}{(\sigma)}}\) is defined to include all traces indistinguishable from σ. \[\begin{equation*} \begin{array}{@{}rcl} {\mathbb {C}} {}{} &\in & \mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty }) \text{cognizance (3)}\\ {\mathbb {C}{(\sigma)}}&\triangleq & \lbrace \sigma ^{\prime }\in \mathbb {S}^{\ast \infty }\mid \text{the observer cannot distinguish} \sigma ^{\prime } \text{from } \sigma \rbrace \end{array} \end{equation*}\]
Such a cognizance function is extensive, i.e., \(\forall \sigma \in \mathbb {S}^{\ast \infty }.\) \(\sigma \in {\mathbb {C}{(\sigma)}}\). In particular, there is an omniscient observer and its corresponding cognizance function is denoted as \({\mathbb {C}}_{O} {}{}\) such that \(\forall \sigma \in \mathbb {S}^{\ast \infty }.\ {\mathbb {C}}_{O} {}{\sigma }=\lbrace \sigma \rbrace\), which means that every trace is unambiguous to the omniscient observer.
To facilitate the proof of some desired properties for the observation function defined later, two assumptions are made here without loss of generality:
In practice, we can define an equivalence relation on traces that satisfy the above two assumptions, thus it is assumed that the observer cannot distinguish two traces if and only if they are equivalent. That is to say, for any trace σ, \({\mathbb {C}{(\sigma)}}\) is a class of traces that are equivalent to σ, and \(\lbrace \langle \sigma ,\:\sigma ^{\prime }\rangle \mid \sigma ^{\prime }\in {\mathbb {C}{(\sigma)}}\rbrace\) is an equivalence relation. By (A2) the cognizance cannot abstract an invalid trace into a valid one, it is therefore different from the abstractions in Reference [30] to define the “power of an attacker.”
For any cognizance function \({\mathbb {C}}\), we have \(\underset{ {s} \in \mathbb {S}}{\bigcup \!\!\!\!\!{\cdot}}{\mathbb {C}({ {s})}}\supseteq \mathbb {S}\).
This corollary follows the fact that the cognizance function \({\mathbb {C}}\) is extensive.□
(Access Control, Continued).
For the access control program, consider the cognizance function for two different observers.
(i) For an omniscient observer: \(\forall \sigma \in \mathbb {S}^{\ast \infty }.\) \({\mathbb {C}}_{O} {}{\sigma }=\lbrace \sigma \rbrace\).
(ii) For an observer who is unaware of the input from 1st admin or the value of \({apv}\): \({\mathbb {C}}(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle) = \lbrace \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{-1}\rangle , \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle , \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle , \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{2}\rangle \rbrace\), i.e., this observer cannot distinguish whether the input from 1st admin is -1 or 0 or 1 or 2.
Similarly, for a prefix trace in which the inputs from both two admins are zeros, \({\mathbb {C}}(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle) = \lbrace \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{-1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle , \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle , \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{1}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle , \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{2}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle \rbrace\) consists of four traces, such that the value of \({i1}\) is not distinguishable while the value of \({i2}\) is. In the same way, the cognizance on other traces can be defined.
(3) Observation Function. For an observer with cognizance function \({\mathbb {C}}\), given a single trace σ, the observer cannot distinguish σ with other traces in \({\mathbb {C}{(\sigma)}}\). To formalize the information that the observer can learn from σ, we apply the inquiry function \(\mathbb {I}\) on each trace in \({\mathbb {C}{(\sigma)}}\) and get a set of maximal trace properties. By joining them together, we get the strongest property in \(\mathcal {L}^{\mathsf {Max}}\) that σ can guarantee from the observer’s perspective. Such a process is defined as the observation function \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\). \[\begin{equation*} \begin{array}{@{}l} {\mathbb {O}} {}{}{}\in \wp (\mathbb {S}^{\ast \infty })\mapsto \wp (\wp (\mathbb {S}^{\ast \infty }))\mapsto (\mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty }))\mapsto \mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty }) \\ {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\triangleq \text{observation (4)}\\ \quad let\;\alpha_{\text {Pred}} {\mathcal {S}}{\mathcal {T}}=\lbrace \psi \in {\mathtt {Pref}} {\mathcal {T}}\mid \forall \psi ^{\prime }\in \mathcal {S}.\;\psi \preceq \psi ^{\prime }\Rightarrow \psi ^{\prime }\in \mathcal {T}\rbrace \;in\text{abstraction from (1)}\\ \quad \quad let\;\mathbb {I}{\mathcal {S}, \mathcal {L},\psi } = \cap\!\!\!\!\cdot \lbrace \mathcal {T}\in \mathcal {L}\mid \psi \in \alpha_{\text {Pred}} {\mathcal {S}}{\mathcal {T}}\rbrace \;in\text{inquiry from (2)} \\ \quad \quad \quad \cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\mid \sigma ^{\prime }\in {\mathbb {C}{(\sigma)}}\rbrace . \end{array} \end{equation*}\]
From the above definition, it is easy to see that, for every invalid trace \(\sigma \not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\), we have \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }=\bot ^{\mathsf {Max}}\), since every trace \(\sigma ^{\prime }\) in \({\mathbb {C}{(\sigma)}}\) is invalid by (A2) and \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}=\) \(\bot ^{\mathsf {Max}}\). In addition, for an omniscient observer with cognizance function \({\mathbb {C}}_{O} {}{}\), its observation function \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}_{O} {}{}, \sigma }\) \(=\) \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\).
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, for any observer with cognizance \({\mathbb {C}}\), if the corresponding observation function maps a trace σ to a maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\), then σ guarantees the satisfaction of property \(\mathcal {T}\) (i.e., every valid maximal trace that is greater than or equal to σ is guaranteed to have property \(\mathcal {T}\)).
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, and the cognizance function \({\mathbb {C}}\), we have: \(\forall \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\) \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\)\(=\mathop {\bigcup \!\!\!\!\!{\cdot} }\nolimits _{ {s}\in \mathbb {S}}{\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma {s}}= \mathop {\bigcup \!\!\!\!\!{\cdot} }\nolimits _{\sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}}{\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma {s}}\).
Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, and cognizance function \({\mathbb {C}}\), the observation function \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}}\) is decreasing on the observed trace σ: the greater (longer) σ is, the stronger property it can observe. I.e., \(\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\;\sigma \preceq \sigma ^{\prime }\Rightarrow {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\supseteq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}\).
(Access Control, Continued).
For an omniscient observer, the observation function is identical to the inquiry function in Example 7. If the cognizance of a non-omniscient observer defined in Example 8 is adopted, then we get an observation function that works exactly the same as the dashed arrows in Figure 5:
\({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle } = \cup\!\!\!\!\cdot \lbrace \mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle) \mid {v}\in \lbrace -1, 0,\) \(1, 2\rbrace \rbrace = \texttt {AF} \cup\!\!\!\!\cdot \texttt {AF} \cup\!\!\!\!\cdot \top ^{\mathsf {Max}}\cup\!\!\!\!\cdot \top ^{\mathsf {Max}}= \top ^{\mathsf {Max}}\), i.e., even if the 1st admin already inputs 0, only \(\top ^{\mathsf {Max}}\) can be guaranteed from the perspective of the non-omniscient observer.
\({\mathbb {O}} {}{}{}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle) = \cup\!\!\!\!\cdot \lbrace \mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{0}\rangle) \mid {v}\in \lbrace -1, 0, 1, 2\rbrace \rbrace = \texttt {AF} \cup\!\!\!\!\cdot \texttt {AF} \cup\!\!\!\!\cdot \texttt {AF} \cup\!\!\!\!\cdot \texttt {AF} = \texttt {AF}\), i.e., only after the 2nd admin inputs 0 (or -1), “Access Failure”
AF can be guaranteed from the perspective of the non-omniscient observer.\({\mathbb {O}} {}{}{}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{0}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{1}\rangle) = \cup\!\!\!\!\cdot \lbrace \mathbb {I}([\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2= {\rho _1}{ {apv}}{1}\rangle \langle {l}_3,\:\rho _3= {\rho _2}{ {i1}}{ {v}}\rangle \langle {l}_4,\:\rho _4 = \rho _3\rangle \langle {l}_5,\:\rho _5= {\rho _4}{ {i2}}{1}\rangle) \mid {v}\in \lbrace -1, 0, 1, 2\rbrace \rbrace = \texttt {AF} \cup\!\!\!\!\cdot \texttt {AF} \cup\!\!\!\!\cdot \top ^{\mathsf {Max}}\cup\!\!\!\!\cdot \top ^{\mathsf {Max}}= \top ^{\mathsf {Max}}\), i.e., if the 2nd admin inputs 1 (or 2), then only the top \(\top ^{\mathsf {Max}}\) can be guaranteed from the perspective of the non-omniscient observer, even if the 1st admin already inputs 0 or -1.
3.2.4 Formal Definition of Responsibility.
Using the three components of responsibility analysis introduced above, responsibility is formally defined as the responsibility abstraction \({\alpha_{R}}\) in (2). \[\begin{equation*} \begin{array}{@{}l@{}} ~{\alpha_{R}} \in \wp (\mathbb {S}^{\ast \infty })\mapsto \wp (\wp (\mathbb {S}^{\ast \infty }))\mapsto (\mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty }))\mapsto \wp (\mathbb {S}^{\ast \infty })\mapsto \wp (\mathbb {S}^{\ast \infty }) \nonumber \nonumber \\ \qquad \mapsto \wp (\mathbb {S}^\ast \times (\mathbb {S}\times \mathbb {S})\times \mathbb {S}^{\ast \infty }) \text{(5)~~} \\ ~{\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \mathcal {B}, \mathcal {T}}\triangleq \nonumber \nonumber \\ let\;\alpha_{\text {Pred}} {\mathcal {S}}{T}=\lbrace \sigma \in {\mathtt {Pref}} {T}\mid \forall \sigma ^{\prime }\in \mathcal {S}.\;\sigma \preceq \sigma ^{\prime }\Rightarrow \sigma ^{\prime }\in T\rbrace \;in\nonumber \nonumber \\ \quad let\;\mathbb {I}{\mathcal {S}, \mathcal {L},\sigma } = \cap\!\!\!\!\cdot \lbrace T\in \mathcal {L}\mid \sigma \in \alpha_{\text {Pred}} {\mathcal {S}}{T}\rbrace \;in\nonumber \nonumber \\ \quad \quad let\; {\mathbb {O}} {}{}{\mathcal {S}, \mathcal {L}, {\mathbb {C}}, \sigma } = \cup\!\!\!\!\cdot \lbrace \mathbb {I}{\mathcal {S}, \mathcal {L}, \sigma ^{\prime }}\mid \sigma ^{\prime }\in {\mathbb {C}{(\sigma)}}\rbrace \;in\nonumber \nonumber \\ \quad \quad \quad \lbrace \langle \sigma _{\mbox{H}},\:\tau _{\mbox{R}},\:\sigma _{\mbox{F}}\rangle \mid \sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\in \mathcal {T}\;\wedge \;\emptyset \subsetneq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}}\subseteq \mathcal {B}\;\wedge {}\nonumber \nonumber \\ \qquad \qquad \qquad \qquad \quad \; {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\not\subseteq \mathcal {B}\rbrace \nonumber \nonumber \end{array} \end{equation*}\]
Specifically, the first parameter is the maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the second parameter is the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, the third parameter is the cognizance function of a given observer, the fourth parameter is the behavior \(\mathcal {B}\) whose responsibility is of interest, and the last parameter is the analyzed traces \(\mathcal {T}\).
For every trace \(\sigma \in \mathcal {T}\) to be analyzed, we split it into three parts such that \(\sigma = \sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\), where \(\sigma _{\mbox{H}}= { {s}_{0}}{\cdots }{ {s}_{r-1}} \in \mathbb {S}^\ast\) represents the History part of trace σ, the transition \(\tau _{\mbox{R}}= {s}_{r-1}\underrightarrow{\alpha_{R}} {s}_{r}\) represents the Responsible part of trace σ (which is a transition between two states, and the corresponding action \({a}_{\, \mbox{R}}\) can be retrieved from the source code), and \(\sigma _{\mbox{F}}= { {s}_{r}}{\cdots } \in \mathbb {S}^{\ast \infty }\) represents the Future part of trace σ.
If \(\emptyset \subsetneq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}}\subseteq \mathcal {B}\wedge {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\not\subseteq \mathcal {B}\) holds, then \(\sigma _{\mbox{H}}\) does not guarantee the behavior \(\mathcal {B}\), while \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\) guarantees a behavior that is at least as strong as \(\mathcal {B}\) and is not the invalid trace property represented by \(\bot ^{\mathsf {Max}}=\emptyset\). Therefore, to the cognizance \({\mathbb {C}}\) of a given observer, the transition \(\tau _{\mbox{R}}= {s}_{r-1}\underrightarrow{\alpha_{R}} {s}_{r}\) (or, say, the action \({a}_{\, \mbox{R}}\)) is said to be responsible for the behavior \(\mathcal {B}\) in the trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\).
Since \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \mathcal {B}}\) preserves joins on analyzed traces \(\mathcal {T}\), we have a Galois connection [68]:
.
It is worth noting that, compared with our original definition of responsibility abstraction \({\alpha_{R}}\) in References [25, 26] (which adopts the condition \(\emptyset \,{\subsetneq }\,{\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}\!, \mathcal {L}^{\mathsf {Max}}\!, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}}\subseteq \mathcal {B}\subsetneq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}\!, \mathcal {L}^{\mathsf {Max}}\!, {\mathbb {C}}, \sigma _{\mbox{H}}}\)), definition (2) proposed in this article is more generic: When the lattice of system behavior \(\mathcal {L}^{\mathsf {Max}}\) is of complex structure (i.e., it consists of more than four elements), the observation \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\) may return a behavior that is incomparable with \(\mathcal {B}\); as long as \(\emptyset \subsetneq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}}\subseteq \mathcal {B}\) holds after extending \(\sigma _{\mbox{H}}\) with \(\tau _{\mbox{R}}\), we know the transition \(\tau _{\mbox{R}}\) shall be responsible for \(\mathcal {B}\).
If \(\tau _{\mbox{R}}\) is said to be responsible for a behavior \(\mathcal {B}\) in a valid trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\), then \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\) guarantees the occurrence of behavior \(\mathcal {B}\), and there must exist another valid prefix trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}^{\prime }\) such that the behavior \(\mathcal {B}\) is not guaranteed.
Now recall the three essential characteristics for defining responsibility (i.e., the temporal ordering of actions, free choices, and the observer’s cognizance) in Section 3.1. It is obvious that the responsibility abstraction \({\alpha_{R}}\) has taken both the temporal ordering of actions and the observer’s cognizance into account. As for the free choices, from Theorem 1 it is easy to find that, if the transition \(\tau _{\mbox{R}}\) is completely determined by its history trace \(\sigma _{\mbox{H}}\) and is not free to make choices (i.e., \(\forall \sigma _{\mbox{H}}\tau _{\mbox{R}},\sigma _{\mbox{H}}\tau _{\mbox{R}}^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}.\) \(\tau _{\mbox{R}}=\tau _{\mbox{R}}^{\prime }\)), then \(\tau _{\mbox{R}}\) cannot be responsible for any behavior in the trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\).
3.2.5 Concrete Responsibility Analysis.
To sum up, the responsibility analysis in the concrete typically consists of four steps: (1) collect the system’s trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) (in Section 2.2 and 3.2.1); (2) build the lattice of system behaviors of interest \(\mathcal {L}^{\mathsf {Max}}\) (in Section 3.2.2); (3) derive an inquiry function \(\mathbb {I}\) from \(\mathcal {L}^{\mathsf {Max}}\), define a cognizance function \({\mathbb {C}}\) for each observer, and create the corresponding observation function \({\mathbb {O}} {}{}{}\) (in Section 3.2.3); (4) specify the behavior \(\mathcal {B}\in \mathcal {L}^{\mathsf {Max}}\) of interest and the analyzed traces \(\mathcal {T}\in \wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}})\), and apply the responsibility abstraction \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \mathcal {B}, \mathcal {T}}\) to get the analysis result (in Section 3.2.4). Hence, the responsibility analysis is essentially an abstract interpretation of the program trace semantics.
Moreover, in definition (2) of responsibility, the sets of traces involved in the trace semantics, system behaviors, and the cognizance function are concrete. For the simple access control program, such concrete traces are explicitly displayed for the sake of clarity. However, they are uncomputable in general, and we cannot require the user to directly provide concrete traces in the implementation of responsibility analysis. To solve this problem, an abstract responsibility analysis that can soundly over-approximate the concrete responsibility analysis results is proposed in Section 7.
(Access Control, Continued).
Using the observation functions in Example 9, the abstraction \({\alpha_{R}}\) can analyze the responsibility of any behavior \(\mathcal {B}\) in the specified set \(\mathcal {T}\) of traces. If we intend to analyze “Access Failure” in every possible execution, then \(\mathcal {B}\) is set as \(\texttt {AF}\), and \(\mathcal {T}\) includes all valid maximal traces, i.e., \(\mathcal {T}\) = \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\). Thus, by the responsibility abstraction \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \texttt {AF}, [\![ \textrm {P}]\!] ^{\mathsf {Max}}}\), we could compute the responsibility analysis result, which is essential the same as described in Example 3 and omitted here.
In addition, if we would like to analyze the responsibility of “Read and Write access is granted,” then the behavior of interest \(\mathcal {B}\) shall be replaced by \(\texttt {RW}\) instead, and we can get the following result. To the cognizance of an omniscient observer, in every execution that both two admins input 1 or 2, the input from system settings (i.e., \({typ} := [{1};{2}]\)) is responsible for \(\texttt {RW}\). Meanwhile, to the cognizance of the non-omniscient observer who is unaware of the input from 1st admin or the value of \({apv}\), no one would be found responsible for \(\texttt {RW}\), because whether the write access is granted or not is always uncertain due to the unknown input from 1st admin.
3.3 Applications of Responsibility Analysis
Responsibility is a broad concept, and our definition of responsibility based on the abstraction of trace semantics is applicable in various scientific fields. We have examined every example supplied in actual cause [34, 35] and found that our definition of responsibility can handle them well, in which events like “drop a lit match in the forest” or “throw a rock at the bottle” are treated as actions along the trace.
In this section, we focus on analyzing computer programs and illustrate the application of responsibility analysis by three more examples: (i) the “negative balance” problem of a withdrawal transaction, which can be equivalently viewed as the “buffer overflow” problem; (ii) a program with “division by zero” error, which can be also interpreted as a scenario of “login attack”; and (iii) the “information leakage” problem. It is worth noting that, for any behavior \(\mathcal {B}\) of interest, our responsibility analysis is designed to analyze the programs where the behavior \(\mathcal {B}\) does not always occur, i.e., \(\mathcal {B}\subsetneq [\![ \textrm {P}]\!] ^{\mathsf {Max}}\). Yet, for the programs where every trace has the behavior \(\mathcal {B}\), we need to admit that the responsibility analysis cannot identify any responsible entity, unless “launching the program” is treated as a separate action and it would be found responsible for \(\mathcal {B}\).
3.3.1 Example of Negative Balance/Buffer Overflow.
Consider a withdrawal transaction scenario, which is simplified into a program with only three lines of code as in Figure 7 for the sake of clarity. At point \({l}_1\), we read the bank account balance before the withdrawal transaction, which is assumed to be a positive integer or zero; in practice, this read action is typically implemented by a query in the database system. At point \({l}_2\), the user inputs the withdrawal amount, which is assumed to be a strictly positive integer. At point \({l}_3\), we update the bank account balance after the withdrawal transaction by subtracting \({num}\) from \({balance}\). When the withdrawal transaction completes at point \({l}_4\), if the account balance is negative (i.e., \({balance} \lt 0\)), then it is an error and we would like to detect the responsible entity for it.
Fig. 6. The withdrawal transaction program with negative balance problem.
It is not hard to see that, the “negative balance” problem can be transformed into an equivalent “buffer overflow” problem, where a memory of size \({balance}\) is allocated, the index at \({num} - 1\) is visited, and a buffer overflow error occurs when \({balance} \le {num} - 1\) holds. Although this problem has been well studied, it suffices to demonstrate the advantages of responsibility analysis over dependency/causality analysis.
In this example, we consider only the cognizance of the omniscient observer, and the responsibility analysis consists of four steps, as discussed in Section 3.2.5:
(1) | Collect the trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\). In the withdrawal transaction program, each maximal trace is of length 4, and \([\![ \textrm {P}]\!] ^{\mathsf {Max}} = \lbrace \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2\rangle \langle {l}_3,\:\rho _3\rangle \langle {l}_4,\:\rho _4\rangle \mid (\rho _1 \in \mathbb {M}) \wedge (\rho _2 = {\rho _1}{ {balance}}{ {v}} \wedge {v}\in [ {0}{{INT\_MAX}}]) \wedge (\rho _3 = {\rho _2}{ {num}}{ {v}^{\prime }} \wedge {v}^{\prime } \in [ {1}{{INT\_MAX}})] \wedge (\rho _4 = {\rho _3}{ {balance}}{\rho _3( {balance}) - \rho _3( {num})}) \rbrace\) consists of a very large number of traces. For example, \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {balance}}{0}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {num}}{1}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {balance}}{-1}\rangle\) denotes a maximal trace such that the balance before the transaction is 0 and the withdrawal amount is 1; and \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {balance}}{5}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {num}}{9}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {balance}}{-4}\rangle\) denotes a maximal trace such that the balance before the transaction is 5 and the withdrawal amount is 9. Both the above two traces have the negative balance problem. | ||||
(2) | Build the lattice of system behaviors of interest. Since “negative balance” is the only behavior that we are interested here, we can build the lattice \(\mathcal {L}^{\mathsf {Max}}\) with only four elements, as in Figure 9, where \(\texttt {NB}\) is the set of valid maximal traces where the value of \({balance}\) is negative at point \({l}_4\) (i.e., \(\texttt {NB} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[3]} = \langle {l}_4,\:\rho \rangle \wedge \rho ( {balance}) \lt 0\rbrace\)), and \(\lnot \texttt {NB}\) is its complement (i.e., \(\lnot \texttt {NB} = [\![ \textrm {P}]\!] ^{\mathsf {Max}} \backslash \texttt {NB} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[3]} = \langle {l}_4,\:\rho \rangle \wedge \rho ( {balance}) \ge 0\rbrace\)). Lattice of system behaviors regarding negative balance. | ||||
(3) | Create the observation function. Using the omniscient observer’s cognizance \({\mathbb {C}}_{O} {}{}\) such that \({\mathbb {C}}_{O} {}{\sigma } = \lbrace \sigma \rbrace\), the observation function \({\mathbb {O}} {}{}{}\) can be easily derived from the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, such that:
| ||||
(4) | Last, by setting the behavior \(\mathcal {B}=\texttt {NB}\) and the analyzed traces \(\mathcal {T}\) \(=[\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the abstraction \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}_{O} {}{}, \mathcal {B}, \mathcal {T}}\) can find: If the balance before the transaction is 0 (e.g., \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {balance}}{0}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {num}}{1}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {balance}}{-1}\rangle\)), then no matter what the withdrawal amount is, the action \({balance} := [0; {INT\_MAX}]\) is responsible for “negative balance”; otherwise, if the balance before the transaction is strictly positive (e.g., \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {balance}}{5}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {num}}{9}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {balance}}{-4}\rangle\)), then the action \({num} := [1; {INT\_MAX}]\) shall take the responsibility. | ||||
Using the responsibility analysis result above, we could prevent the “negative balance” behavior by configuring the program (e.g., a test guard for the withdrawal operation), such that the balance before the withdrawal transaction is ensured to be strictly positive, and the withdrawal amount is ensured to be less than or equal to the balance.
3.3.2 Example of Division by Zero/Login Attack.
Consider the program in Figure 11, in which there is obviously a potential division-by-zero error at point \({l}_5\). Alternatively, the division-by-zero error can be interpreted as a behavior of “login attack success” by interpreting the program as a simplified login scenario of some complex system for a malicious user (e.g., an attacker attempts to login the account of a normal user in a website).
Fig. 8. The program with division by zero/login attack problem.
More precisely, at point \({l}_1\), the program reads the real password of a normal user that is stored in the system and saves it in the variable \({pwd}\). Typically, in practice, a password of valid format consists of letters/numbers and meets the requirement of length, while a password of invalid format contains special characters or does not meet the length requirement. For the sake of simplicity, it is assumed that the passwords of valid format are represented by positive integers in this simplified program, while the passwords of invalid format are represented by zero or negative integers. At point \({l}_2\), the input \({i1}\) is used to mimic the attacker’s attempt of entering a guessed password of valid format (i.e., a positive integer). If the guessed password coincides with the real password \({pwd}\), then the attacker succeeds to log into the normal user’s account. Further, at point \({l}_3\), the input \({i2}\) is used to mimic the attacker’s attempt of entering a password that is of invalid format (i.e., zero or a negative integer). Specially, the value zero represents a piece of malicious code (e.g., SQL statements) that could bypass the authentication. Thus, the attacker succeeds to log into the normal user’s account if the guessed password coincides with the real password (i.e., \({pwd} = {i1}\)) or the attacker injects malicious code (i.e., \({i2} = 0\)). Such an attack is represented by the computation of \({res}\) at point \({l}_4\), and the division by zero error at point \({l}_5\) represents the behavior of login attack success.
Now the question is: Which action is responsible for “login attack success” (or, say, “division by zero”)? In the following, we illustrate the four steps of responsibility analysis for “login attack success.” Different from the analysis of “negative balance” in Section 3.3.1, in this example, we shall take the cognizance of an non-omniscient observer.
(1) | Collect the trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\). For the program in Figure 11, each maximal trace is of length 6, and \([\![ \textrm {P}]\!] ^{\mathsf {Max}} = \lbrace \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2\rangle \langle {l}_3,\:\rho _3\rangle \langle {l}_4,\:\rho _4\rangle \langle {l}_5,\:\rho _5\rangle \langle {l}_6,\:\rho _6\rangle \mid (\rho _1 \in \mathbb {M}) \wedge (\rho _2 = {\rho _1}{ {pwd}}{ {v}} \wedge {v}\in [ {1}{{INT\_MAX}}]) \wedge (\rho _3 = {\rho _2}{ {i1}}{ {v}^{\prime }} \wedge {v}^{\prime } \in [ {1}{{INT\_MAX}}]) \wedge (\rho _4 = {\rho _3}{ {i1}}{ {v}^{\prime \prime }} \wedge {v}^{\prime \prime } \in [ {{INT\_MIN}}{0}]) \wedge (\rho _5 = {\rho _4}{ {res}}{(\rho _4( {pwd}) - \rho _4( {i1})) * \rho _4( {i2})}) \wedge (\rho _6 = {\rho _5}{ {check}}{1 \backslash \rho _5( {res})}) \rbrace\) consists of a large number of traces. For example, \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {pwd}}{911}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {i1}}{911}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {i2}}{-5}\rangle \langle {l}_5,\:\rho _5 = {\rho _4}{ {res}}{0}\rangle \langle {l}_6,\:\omega \rangle\) denotes a maximal trace such that the guessed password (\({i1}\)) coincides with the real password (\({pwd}\)), and the execution ends with an error state representing “login attack success”; and \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {pwd}}{911}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {i1}}{123}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {i2}}{0}\rangle \langle {l}_5,\:\rho _5 = {\rho _4}{ {res}}{0}\rangle \langle {l}_6,\:\omega \rangle\) denotes a maximal trace such that the attacker enters a piece of malicious code that bypasses the authentication (i.e., \({i2} = 0\)). Both the above two traces have the behavior of “login attack success.” | ||||
(2) | Build the lattice of system behaviors of interest. Here, “login attack success” is the only behavior that we are interested in, and the corresponding lattice \(\mathcal {L}^{\mathsf {Max}}\) consists of only four elements as in Figure 13, where \(\texttt {AS}\) (login Attack Success) is the set of valid maximal traces where the value of \({res}\) is zero at point \({l}_5\) (i.e., \(\texttt {AS} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[4]} = \langle {l}_5,\:\rho \rangle \wedge \rho ( {res}) = 0\rbrace\)), and \(\lnot \texttt {AS}\) (login Attack Failure) is its complement (i.e., \(\lnot \texttt {AS} = [\![ \textrm {P}]\!] ^{\mathsf {Max}} \backslash \texttt {AS} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[4]} = \langle {l}_4,\:\rho \rangle \wedge \rho ( {res}) \ne 0\rbrace\)). Lattice of system behaviors regarding login attack. | ||||
(3) | Create the observation function. In this case, it is intuitive to adopt the cognizance of the attacker, and it is assumed that the attacker does not know the real password of the normal user (otherwise, there is no way to prevent the login attack). Hence, a non-omniscient cognizance shall be designed such that it cannot distinguish the value of \({pwd}\), e.g., \(\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {pwd}}{123}\rangle \in {\mathbb {C}}{\langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {pwd}}{911}\rangle }\) denotes that the attacker does not know whether the real password is 123 or 911. Then, the observation function \({\mathbb {O}} {}{}{}\) can be derived from the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors and the cognizance function \({\mathbb {C}}\), such that:
| ||||
(4) | Last, by setting the behavior \(\mathcal {B}=\texttt {AS}\) and the analyzed traces \(\mathcal {T}\) \(=[\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the abstraction \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \mathcal {B}, \mathcal {T}}\) can find: Only the action \({i2} := [{INT\_MIN}; 0]\) representing entering passwords of invalid format is responsible for the behavior “login attack success,” and the action \({i1} := [1; {INT\_MAX}]\) representing entering passwords of valid format is not responsible. Meanwhile, if we take \(\lnot \texttt {AS}\) as the behavior of interest \(\mathcal {B}\), then the corresponding responsibility analysis would find that there is no responsible action for \(\lnot \texttt {AS}\). That is to say, we cannot take any action to prevent the attacker from succeeding to login the system, since there is always a possibility (although it is low) that the attacker succeeds to guess the correct password. | ||||
Using the responsibility analysis result above, we could configure the program to exclude the value of zero from the range of second input (or, say, we forbid the attacker to enter malicious code like SQL statements), so the attacker can never ensure to login the account of a normal user.
3.3.3 Example of Information Leakage.
From the example of access control in Section 3.2 as well as the two examples in Sections 3.3.1 and 3.3.2, it is not hard to see that the responsibility analysis process is essentially the same for all behaviors, and the only significant distinction among these examples is on defining the behaviors of interest and the cognizance function.
Non-interference. In this section, we consider the responsibility analysis of the behavior “information leakage,” which is represented by the notion of non-interference [31]. More precisely, the inputs and outputs in the analyzed program are classified as either Low (public, low sensitivity) or High (private, high sensitivity). For any valid maximal trace \(\sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\), if there is another valid maximal trace \(\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\) such that they have the same low inputs but different low outputs, then the trace σ is said to leak private information, and the analyzed program is possibly insecure. If there is no valid maximal trace in the analyzed program that leaks private information (i.e., every two valid maximal traces with the same low inputs must have the same low outputs, regardless of the high inputs), then the program has the “non-interference” property, hence it is secure.
Here, we take the simple program in Figure 14 as an example, which does not have the desired “non-interference” property. At point \({l}_{1}\), a high (private) input of positive integer is read and saved in the variable \({input\_h}\). Similarly, at point \({l}_2\), a low (public) input is stored in the variable \({input\_l}\), which is assumed to be either zero or one. At point \({l}_3\), a variable \({output\_l}\) is initialized as zero. After the execution of the while loop between points \({l}_4\) and \({l}_7\), the value of \({output\_l}\) is output as low (public). It is not hard to find that, although there is no direct data flow from \({input\_h}\) to \({output\_l}\) (e.g., an assignment \({output\_l} := {input\_h}\)) in the program, the low output \({output\_l}\) at point \({l}_7\) is equal to the high input, if the value of low input \({input\_l}\) is 1 at point \({l}_3\). Therefore, there is a potential behavior of information leakage from \({input\_h}\) to \({output\_l}\) in this program.
Fig. 10. The program with potential information leakage.
Similar to previous examples, the responsibility analysis of information leakage consists of four steps, and we adopt the cognizance of omniscient observer.
(1) | Collect the trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\). For the program in Figure 14, \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) consists of \(2\times {INT\_MAX}\) maximal traces, and here we take two of them as examples: (i) \(\sigma = \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {input\_h}}{2}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {input\_l}}{1}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {output\_l}}{0}\rangle \langle {l}_5,\:\rho _5 = \rho _4\rangle \langle {l}_6,\:\rho _6 = {\rho _5}{ {output\_l}}{1}\rangle \langle {l}_4,\:\rho _4^{\prime } = {\rho _6}{ {input\_h}}{1}\rangle \langle {l}_5,\:\rho _5^{\prime } = \rho _4^{\prime }\rangle \langle {l}_6,\:\rho _6^{\prime } = {\rho _5^{\prime }}{ {output\_l}}{2}\rangle \langle {l}_4,\:\rho _4^{\prime \prime } = {\rho _6^{\prime }}{ {input\_h}}{0}\rangle \langle {l}_7,\:\rho _7 = \rho _4^{\prime \prime }\rangle\). In this trace, the high input is 2, and the low input is 1. After two iterations of the while loop, the value of \({output\_l}\) is assigned to 2, which is equal to the high input. (ii) \(\sigma ^{\prime } = \langle {l}_1,\:\rho _1\rangle \langle {l}_2,\:\rho _2 = {\rho _1}{ {input\_h}}{2}\rangle \langle {l}_3,\:\rho _3 = {\rho _2}{ {input\_l}}{0}\rangle \langle {l}_4,\:\rho _4 = {\rho _3}{ {output\_l}}{0}\rangle \langle {l}_7,\:\rho _7 = \rho _4\rangle\). Different from the previous trace σ, the low input in this trace is 0, such that the while loop is never entered, and the value of \({output\_l}\) remains as 0 at point \({l}_7\). | ||||
(2) | Build the lattice of system behaviors of interest. In general, for the responsibility analysis of information leakage, the corresponding lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors consists of four elements, as shown in Figure 15. Lattice of behaviors regarding information leakage. More specifically, the behavior of “Information Leakage” \(\texttt {IL}\) is represented as the set of valid maximal traces that leak private information, i.e., \(\texttt {IL} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\; \texttt {low_inputs}(\sigma) = \texttt {low_inputs}(\sigma ^{\prime }) \wedge \texttt {low_outputs}(\sigma) \ne \texttt {low_outputs}(\sigma ^{\prime })\rbrace\), where the functions \(\texttt {low_inputs}\) (respectively, \(\texttt {low_outputs}\)) collects the list of low inputs (respectively, low outputs) along the trace σ. In contrast, the behavior of “No information Leakage” \(\lnot \texttt {IL}\) is the complement of \(\texttt {IL}\), which is the set of valid maximal traces that do not leak private information, i.e., \(\lnot \texttt {IL} = [\![ \textrm {P}]\!] ^{\mathsf {Max}} \backslash \texttt {IL} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \forall \sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\; \texttt {low_inputs}(\sigma) = \texttt {low_inputs}(\sigma ^{\prime }) \Rightarrow \texttt {low_outputs}(\sigma) = \texttt {low_outputs}(\sigma ^{\prime })\rbrace\). For the program in Figure 14, \(\texttt {IL} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \exists \rho , \rho ^{\prime }\in \mathbb {M}.\, {\sigma }_{[1]} = \langle {l}_2,\:\rho \rangle \wedge {\sigma }_{[\mathopen {|}\sigma \mathclose {|} - 1]} = \langle {l}_7,\:\rho ^{\prime }\rangle \wedge \rho ( {input\_h}) = \rho ^{\prime }( {output\_l})\rbrace = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \exists \rho .\, {\sigma }_{[2]} = \langle {l}_3,\:\rho \rangle \wedge \rho ( {input\_l}) = 1\rbrace\) (i.e., \(\texttt {IL}\) is the set of valid maximal traces where the value of \({output\_l}\) at \({l}_7\) is equal to the high input, which is also the set of valid maximal traces where the value of \({input\_l}\) is 1 at \({l}_3\)); \(\lnot \texttt {IL} = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \exists \rho \in \mathbb {M}.\, {\sigma }_{[\mathopen {|}\sigma \mathclose {|} - 1]} = \langle {l}_7,\:\rho \rangle \wedge \rho ( {output\_l}) = 0\rbrace = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \exists \rho .\, {\sigma }_{[2]} = \langle {l}_3,\:\rho \rangle \wedge \rho ( {input\_l}) = 0\rbrace\) (i.e., \(\lnot \texttt {IL}\) is the set of valid maximal traces where the value of \({output\_l}\) is 0 at \({l}_7\), which is also the set of valid maximal traces where the value of \({input\_l}\) is 0 at \({l}_3\)). | ||||
(3) | Create the observation function. Using the omniscient observer’s cognizance \({\mathbb {C}}_{O} {}{}\), the observation function \({\mathbb {O}} {}{}{}\) can be easily derived from \(\mathcal {L}^{\mathsf {Max}}\) such that:
| ||||
(4) | Last, by setting the behavior \(\mathcal {B}=\texttt {IL}\) and the analyzed traces \(\mathcal {T}\) \(=[\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the abstraction \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}_{O} {}{}, \mathcal {B}, \mathcal {T}}\) can find that only the action \({input\_l} := [0; 1]\) representing a low input is responsible for the information leakage, while the action \({input\_h} := [1; {INT\_MAX}]\) representing a high input is not responsible. | ||||
After the responsibility analysis of information leakage completes, it is of interest to discuss the procedure of configuring the analyzed program, especially for the programs where the information leakage is acceptable or even desirable under certain circumstances. For instance, imagine a more complex analyzed program that is a social network, where every user can enter some public information (e.g., name, gender) as well as some private information (e.g., birth date, photos). If the private information of any user called A flows to another user called B (e.g., the user B accesses a photo uploaded by A), then it can be viewed as a behavior “information leakage”
4 Forward Reachability and Backward Accessibility Analysis
Abstract interpretation [18, 20, 21] is a mathematical theory to reason on the executions of computer programs. It formalizes formal methods and allows to discuss the guarantees they provide such as soundness (the conclusions about programs are always correct under suitable explicitly stated hypotheses), completeness (all true facts are provable), or incompleteness (showing the limits of applicability of the formal method).
This section presents some notations and techniques in the abstract interpretation framework, which will be referenced later in designing the abstract responsibility analysis. To be more precise, Section 4.1 introduces the abstract domain of environments and invariants. In Section 4.2, we define the classic forward (possible success) reachability semantics of a program as an abstraction of the trace semantics and sketch the design of an over-approximating abstract forward reachability analysis, which can automatically infer program invariants. In Section 4.3, the backward impossible failure accessibility semantics is defined as the adjoint of forward reachability semantics, which specifies the sufficient precondition for a given postcondition to hold. Compared with the classic forward reachability analysis, the abstract backward impossible failure accessibility analysis has not been well studied yet, and there are few literature on this topic. We summarize the under-approximating abstract backward analysis proposed by Miné [60, 61] and propose a similar over-approximating abstract backward analysis, both of which will be used to determine responsibility in the abstract.
4.1 Abstract Domains
The concrete trace semantics of transition systems introduced in Section 2.2 is not computable in general, thus we propose to abstract sets of concrete traces into invariants. To accomplish that, this section introduces the abstract environment domain, the concrete invariant domain, and the abstract invariant domain.
4.1.1 Abstract Environment Domain.
Let \(\langle \mathcal {D}^{\sharp }_{\mathbb {M}},\:\sqsubseteq ^{\sharp }_{\mathbb {M}},\:\bot ^{\sharp }_{\mathbb {M}},\:\top ^{\sharp }_{\mathbb {M}},\:\sqcup ^{\sharp }_{\mathbb {M}},\:\sqcap ^{\sharp }_{\mathbb {M}}\rangle\) be an abstract environment domain, and \(\gamma _{\mathbb {M}}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \wp (\mathbb {M})\) be the corresponding concretization function that associates each abstract element \(\mbox{M}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) to the set of concrete environments it represents. In particular, \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) features an infimum \(\bot ^{\sharp }_{\mathbb {M}}\) and a supremum \(\top ^{\sharp }_{\mathbb {M}}\) such that \(\gamma _{\mathbb {M}}(\bot ^{\sharp }_{\mathbb {M}}) = \emptyset\) and \(\gamma _{\mathbb {M}}(\top ^{\sharp }_{\mathbb {M}}) = \mathbb {M}\), and an abstract join operator \(\sqcup ^{\sharp }_{\mathbb {M}}\) that soundly approximates the concrete join operator \(\cup\) (more precisely, \(\forall \mbox{M}^{\sharp }, \mbox{M}^{\sharp \prime } \in \mathcal {D}^{\sharp }_{\mathbb {M}}.\; \gamma _{\mathbb {M}}(\mbox{M}^{\sharp })\cup \gamma _{\mathbb {M}}(\mbox{M}^{\sharp \prime }) \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }\sqcup ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp \prime })\)).
This article focuses on the analysis of numerical programs and takes three popular abstract domains that can express constraints on program variables as examples. The interval domain introduced in Reference [19] bounds the value of numerical variables by minimal and maximal values between which all reachable values of a variable must stand, and each abstract element in this domain can be defined as a mapping from program variables to intervals (e.g., \({x}\in [l, h] \wedge {y}\in [l^{\prime }, h^{\prime }]\)). It is a simple but useful domain, and it has been applied not only to prove the absence of integers or array index overflows but also to detect unseen inputs of neural networks [37]. However, the interval domain is not expressive enough to be useful for a relational reachability analysis, in which the constraints involving more than one variable are needed. One example of relational abstractions is the polyhedra domain introduced in Reference [24] that can express conjunctions of affine inequalities on variables. In this domain, an abstract element (i.e., polyhedron) is defined as a finite set of affine constraints of form \(\vec{a} \cdot \vec{ {x}} \ge b\) (e.g., \(2 * {x} - 3 * {y} + 5 * {z} \ge 4\)), where \(\vec{ {x}}\) denotes the vector of all variables, \(\vec{a}\) denotes a vector of coefficients, and b denotes a constant. In addition, strict inequalities are supported in current polyhedron domain [5, 6, 41] . Another example is the octagon domain [56, 57, 58], which restricts the affine constraints used in the polyhedron domain to unit binary inequality constraints of form \(\pm {x}_1\pm {x}_2 \le c\) (e.g., \(x-y\le 0\)). The above three numerical domains are similar semantically in that they infer conjunctions of inequality constraints and represent convex sets, but they are based on different algorithms and achieve different tradeoffs between precision and efficiency. Operators in the interval domain have a linear cost in the number of variables, while octagon operators have a cubic cost. The cost of polyhedra is unbounded in theory (since it can construct arbitrarily many constraints), but it is at most exponential in practice [61, 62].
It is assumed that, for every concrete environment transfer function \(\mbox{F}\in \wp (\mathbb {M})\mapsto \wp (\mathbb {M})\) specified for atomic actions in the program (e.g., \(\tau \lbrace \mid { {x} := {expr}}\mid \rbrace\) and \(\tau \lbrace \mid { {bexpr}}\mid \rbrace\) for the simple language described in Figure 3), the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) (e.g., interval/polyhedron/octagon) provides a sound abstract function \(\mbox{F}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), such that the soundness condition \(\forall \mbox{M}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\; (\mbox{F}\circ \gamma _{\mathbb {M}})(\mbox{M}^{\sharp }) \subseteq (\gamma _{\mathbb {M}}\circ \mbox{F}^{\sharp })(\mbox{M}^{\sharp })\) holds.
In addition, it is worth noting that, in some abstract domains, we have an abstraction function \(\alpha _{\mathbb {M}}\in \wp (\mathbb {M}) \mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\alpha _{\mathbb {M}}\) and \(\gamma _{\mathbb {M}}\) form a Galois connection
. In this case, every concrete element \(\mbox{M}\subseteq \mathbb {M}\) (i.e., every set of concrete environments) has a best abstraction \(\alpha _{\mathbb {M}}(\mbox{M}) \in \mathcal {D}^{\sharp }_{\mathbb {M}}\), and every function \(\mbox{F}\in \wp (\mathbb {M}) \mapsto \wp (\mathbb {M})\) in the concrete domain has also a best abstraction \(\alpha _{\mathbb {M}}\circ \mbox{F}\circ \gamma _{\mathbb {M}}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\). Specifically, the interval and octagon domain have this desirable property, while the polyhedron domain does not.
(Access Control, Continued).
For the access control program in Figure 4, it is sufficient to use the interval domain as \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) to express environment properties such as “the access to o fails” (i.e., the value of \({acs}\) is less than or equal to 0 at point \({l}_8\)), since no relational constraints on variables are required. To be more precise, the abstract environment element \(\mbox{M}^{\sharp }= {apv}\in [-\infty , \infty ] \wedge {i1}\in [-\infty , \infty ] \wedge {i2}\in [-\infty , \infty ] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , 0]\) represents the set of environments \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }) = \lbrace \rho \in \mathbb {M}\mid \rho ( {acs}) \le 0\rbrace\), in which the value of variable \({acs}\) is less than or equal to 0 while the values of other variables are arbitrary. Similarly, an environment property “the access to o succeeds” (i.e., the value of \({acs}\) is greater than or equal to 1 at point \({l}_8\)) can be over-approximated by \(\mbox{M}^{\sharp \prime } = {apv}\in [-\infty , \infty ] \wedge {i1}\in [-\infty , \infty ] \wedge {i2}\in [-\infty , \infty ] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [1, \infty ]\).
4.1.2 Concrete Invariant Domain.
For any set \(\mathcal {T}\) of concrete traces (which can be either the program semantics or a trace property), we would like to abstract it into an invariant, which collects the set of environments for each program point that are visited by traces in \(\mathcal {T}\). Hence, the concrete invariant domain \(\mathcal {D}_{\mathbb {I}}\) is defined as \(\langle \mathbb {L}\mapsto \wp (\mathbb {M}),\:\dot{\subseteq }\rangle\), and there exists a Galois connection between concrete traces and the concrete invariant domain \(\mathcal {D}_{\mathbb {I}}\):

4.1.3 Abstract Invariant Domain.
The concrete invariants introduced above can be further abstracted into abstract invariants, in which every set of concrete environments is represented by an abstract element in \(\mathcal {D}^{\sharp }_{\mathbb {M}}\). Here, we define the abstract invariant domain \(\mathcal {D}^{\sharp }_{\mathbb {I}}\) as \(\langle \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}},\:\dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\rangle\), where the program points are mapped to abstract elements in \(\mathcal {D}^{\sharp }_{\mathbb {M}}\), and \(\dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\) is the pointwise ordering induced by \(\sqsubseteq ^{\sharp }_{\mathbb {M}}\) (i.e., \(\forall \mathsf {I}^{\sharp }, \mathsf {I}^{\sharp \prime } \in \mathcal {D}^{\sharp }_{\mathbb {I}}.\; \mathsf {I}^{\sharp }\dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\mathsf {I}^{\sharp \prime } \Leftrightarrow (\forall {l}\in \mathbb {L}.\; \mathsf {I}^{\sharp }( {l}) \sqsubseteq ^{\sharp }_{\mathbb {M}}\mathsf {I}^{\sharp \prime }( {l}))\)). The corresponding concretization function \(\dot{\gamma }_{\mathbb {M}}\) to the concrete invariant domain is: \[\begin{equation*} \begin{array}{@{}rcl} \dot{\gamma }_{\mathbb {M}}&\in &\left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{abstract invariant concretization}\\ \dot{\gamma }_{\mathbb {M}}(\mathsf {I}^{\sharp }) {l}&\triangleq &\gamma _{\mathbb {M}}(\mathsf {I}^{\sharp }( {l})).\end{array} \end{equation*}\]
Similar to the abstract environment domain, \(\mathcal {D}^{\sharp }_{\mathbb {I}}\) features an infimum \(\bot ^{\sharp }_{\mathbb {I}}\triangleq \lambda {l}\in \mathbb {L}.\; \bot ^{\sharp }_{\mathbb {M}}\) and a supremum \(\top ^{\sharp }_{\mathbb {I}}\triangleq \lambda {l}\in \mathbb {L}.\; \top ^{\sharp }_{\mathbb {M}}\) such that \(\dot{\gamma }_{\mathbb {M}}(\bot ^{\sharp }_{\mathbb {I}}) = \lambda {l}\in \mathbb {L}.\; \emptyset\) and \(\dot{\gamma }_{\mathbb {M}}(\top ^{\sharp }_{\mathbb {I}}) = \lambda {l}\in \mathbb {L}.\; \mathbb {M}\). When the environment abstraction \(\alpha _{\mathbb {M}}\in \wp (\mathbb {M}) \mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) does exist (e.g., in the interval or octagon domain), we can construct the corresponding pointwise abstraction function \(\dot{\alpha }_{\mathbb {M}}\) for the abstract invariant domain: \[\begin{equation*} \begin{array}{@{}rcl} \dot{\alpha }_{\mathbb {M}}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M})) \mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{abstract invariant abstraction}\\ \dot{\alpha }_{\mathbb {M}}(\mathsf {I}) {l}&\triangleq &\alpha _{\mathbb {M}}(\mathsf {I}( {l})).\end{array} \end{equation*}\]
Furthermore, we can build a combination of Galois connections:

(Access Control, Continued).
For the access control program in Figure 4, its maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) given in Example 1 can be over-approximated by an abstract invariant \(\mathsf {I}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that: \(\mathsf {I}^{\sharp }( {l}_1) = \top ^{\sharp }_{\mathbb {M}}= {apv}\in [-\infty , \infty ] \wedge {i1}\in [-\infty , \infty ] \wedge {i2}\in [-\infty , \infty ] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_2) = {apv}\in [1, 1] \wedge {i1}\in [-\infty , \infty ] \wedge {i2}\in [-\infty , \infty ] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_3) = {apv}\in [1, 1] \wedge {i1}\in [-1, 2] \wedge {i2}\in [-\infty , \infty ] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_4) = {apv}\in [-1, 1] \wedge {i1}\in [-1, 2] \wedge {i2}\in [-\infty , \infty ] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_5) = {apv}\in [-1, 1] \wedge {i1}\in [-1, 2] \wedge {i2}\in [-1, 2] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_6) = {apv}\in [-1, 1] \wedge {i1}\in [-1, 2] \wedge {i2}\in [-1, 2] \wedge {typ}\in [-\infty , \infty ] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_7) = {apv}\in [-1, 1] \wedge {i1}\in [-1, 2] \wedge {i2}\in [-1, 2] \wedge {typ}\in [1, 2] \wedge {acs}\in [-\infty , \infty ]\), \(\mathsf {I}^{\sharp }( {l}_8) = {apv}\in [-1, 1] \wedge {i1}\in [-1, 2] \wedge {i2}\in [-1, 2] \wedge {typ}\in [1, 2] \wedge {acs}\in [-2, 2]\).
In addition, the concrete trace property “the access to o fails” is over-approximated by another abstract invariant \(\mathsf {I}^{\sharp \prime } \in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that its abstract environment element attached to every program point is the same as \(\mathsf {I}^{\sharp }\) defined above, except the value bound of \({acs}\) at point \({l}_8\) is refined to \([-2, 0]\). More precisely, when \({l}= {l}_8\), \(\mathsf {I}^{\sharp \prime } ( {l}) = {apv}\in [0, 1] \wedge {i1}\in [0, 1] \wedge {i2}\in [0, 1] \wedge {typ}\in [1, 2] \wedge {acs}\in [-2, 0]\); otherwise, \(\mathsf {I}^{\sharp \prime }( {l}) = \mathsf {I}^{\sharp }( {l})\).
4.2 Forward Reachability Analysis
Given a program \(\textrm {P}\), the corresponding forward reachability semantics specifies the set of states that are possibly reachable at any program point. Section 4.2.1 formalizes a variant of the classic forward reachability (invariant) semantics, which is defined as an abstraction of the program’s intermediate trace semantics. Section 4.2.2 briefly presents an abstract forward reachability analysis that soundly over-approximates the concrete forward reachability semantics.
4.2.1 Forward Reachability Semantics.
(1) Classic Forward Reachability Semantics. In the literature, usually the forward reachability semantics of a program is defined as an abstraction of its prefix trace semantics, which attaches to each program point a set of environments that are possibly encountered during any execution from a given set of initial environments. More precisely, given a set of initial environments \(\mbox{M}^i\in \wp (\mathbb {M})\), the forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{r} [\![{\textrm {P}}]\!]{\mbox{M}^i}{} \in \mathbb {L}\mapsto \wp (\mathbb {M})\) is defined as a mapping from each program point \({l}\) to a set of environments at \({l}\) that are reachable from \(\mbox{M}^i\). The formal definition is given as below, where \(\langle { {l}}^{i},\:\rho ^i\rangle \sigma \langle {l},\:\rho \rangle\) denotes the concatenation of an initial state \(\langle { {l}}^{i},\:\rho ^i\rangle\), a (possibly empty) finite trace σ and a state \(\langle {l},\:\rho \rangle\). Specially, if σ is empty and \(\langle {l},\:\rho \rangle\) is equal to \(\langle { {l}}^{i},\:\rho ^i\rangle\), then \(\langle { {l}}^{i},\:\rho ^i\rangle \sigma \langle {l},\:\rho \rangle\) represents a trace with only one state \(\langle { {l}}^{i},\:\rho ^i\rangle\). \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {S}\mathop{\rightarrow}\limits_{r} [\![{\textrm {P}}]\!]{}{}&\in &\wp (\mathbb {M})\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{classic forward reachability semantics}\\ \mathcal {S}\mathop{\rightarrow}\limits_{r} [\![{\textrm {P}}]\!]{\mbox{M}^i}{ {l}}&\triangleq &\lbrace \rho \in \mathbb {M}\mid \exists \sigma \in \mathbb {S}^\ast , \rho ^i\in \mbox{M}^i.\; \langle { {l}}^{i},\:\rho ^i\rangle \sigma \langle {l},\:\rho \rangle \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace \end{array} \end{equation*}\]
The classic forward reachability semantics defined above specifies an invariant property of the program executions. If the set of initial environments \(\mbox{M}^i\) is taken as a precondition, then \(\mathcal {S}\mathop{\rightarrow}\limits_{r} [\![{\textrm {P}}]\!]{\mbox{M}^i}{ {l}}\) is an invariant at \({l}\), which holds if and when the execution of \(\textrm {P}\) starting with an initial state satisfying \(\mbox{M}^i\) reaches program point \({l}\). Such a forward reachability semantics is quite useful in verifying program correctness.
(2) Forward (Possible Success) Reachability Semantics. To build a Galois connection between the forward reachability semantics and the backward accessibility semantics (defined in Section 4.3) and facilitate the trace partitioning by invariants during the forward reachability analysis (introduced later in Section 5), we define a variant of forward reachability semantics, in which the considered execution traces are not required to start from the initial point \({ {l}}^{i}\).
To be more precise, instead of collecting reachable states from a set of initial environments \(\mbox{M}^i\), here the precondition \(\mathsf {I}_\mathsf {pre}\in \mathbb {L}\mapsto \wp (\mathbb {M})\) is specified by sets of environments attached to any (not necessarily initial) program point, and the forward (possible success) reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\) collects all the reachable states in the intermediate execution traces, which start from states satisfying the precondition \(\mathsf {I}_\mathsf {pre}\). \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{forward reachability semantics}\\ \mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{ {l}^{\prime }}&\triangleq &\lbrace \rho ^{\prime }\in \mathbb {M}\mid \exists \sigma \in \mathbb {S}^\ast , {l}\in \mathbb {L}, \rho \in \mathsf {I}_\mathsf {pre}( {l}).\; \langle {l},\:\rho \rangle \sigma \langle {l}^{\prime },\:\rho ^{\prime }\rangle \in [\![ \textrm {P}]\!] ^{\mathsf {It}}\rbrace \end{array} \end{equation*}\]
Given a precondition \(\mathsf {I}_\mathsf {pre}\in \mathbb {L}\mapsto \wp (\mathbb {M})\), the forward (possible success) reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{ {l}}\) specifies an invariant at each point \({l}\), which holds if and when an execution of \(\textrm {P}\) starting with a state satisfying \(\mathsf {I}_\mathsf {pre}\) reaches the point \({l}\).
To distinguish from the classic forward reachability semantics and the forward impossible failure reachability semantics introduced in Reference [18], the semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\) defined above is formally named “forward possible success reachability semantics.” Nevertheless, in the rest of this article, the notation of forward reachability semantics (where “possible success” or its abbreviation “ps” is omitted) refers to \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\).
It is easy to see that the classic forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{r} [\![{\textrm {P}}]\!]{}{} \in \wp (\mathbb {M})\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\) is an abstraction of our definition \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\in (\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\), and \(\mathcal {S}\mathop{\rightarrow}\limits_{r} [\![{\textrm {P}}]\!]{\mbox{M}^i}{}\) is equal to \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}\) if \(\mathsf {I}_\mathsf {pre}= \lambda {l}\in \mathbb {L}.\; ( {l}== { {l}}^{i})\; ?\; \mbox{M}^i: \emptyset\).
(3) Forward (Possible Success) Reachability Semantics in Fixpoint Form. The forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\) of a program \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\) can be defined by structural induction on the language-specific syntax of the program or in the fixpoint form with a forward transfer function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\): \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{forward reachability semantics}\\ \mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}&\triangleq &{\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {pre}}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\\ \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{forward transfer function}\\ \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}}&\triangleq &\mathsf {I}\;\dot{\cup }\;\lambda {l}^{\prime }\in \mathbb {L}.\lbrace \rho ^{\prime }\in \mathbb {M}\mid \exists {l}\in \mathbb {L}, \rho \in \mathsf {I}( {l}).\;\langle {l},\:\rho \rangle \rightarrow \;\langle {l}^{\prime },\:\rho ^{\prime }\rangle \rbrace ,\end{array} \end{equation*}\] where \(\dot{\subseteq }\) and \(\dot{\cup }\) are pointwise extensions of the standard inclusion relation \(\subseteq\) and union operator \(\cup\), respectively, and \({\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}}}\,\mbox{F}\) denotes the \(\dot{\subseteq }\)-least fixpoint of \(\mbox{F}\) that is \(\dot{\subseteq }\)-greater than or equal to \(\mathsf {I}\), if it exists, which is the case for \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) by Tarski’s fixpoint theorem [72].
Essentially, the monotonic function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) described above can be constructed by combining atomic forward transfer functions, each of which is typically defined for an atomic action (instruction/computation step) in the program and associates a set of environments before the action with the set of environments reachable after the action.
More formally, here we assume that for every pair of program points \(\langle {l},\: {l}^{\prime }\rangle\) in the program \(\textrm {P}\), an atomic transfer function \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!] \in \wp (\mathbb {M}) \mapsto \wp (\mathbb {M})\) is provided such that for any set \(\mbox{M}\) of environments at point \({l}\), the function \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!](\mbox{M})\) returns the set of environments at point \({l}^{\prime }\) that are reachable from \(\mbox{M}\): (i) if \({l}= {l}^{\prime }\), then \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!](\mbox{M}) = \mbox{M}\); (ii) if \({l}\ne {l}^{\prime }\) and there is not an atomic action from \({l}\) to \({l}^{\prime }\), then \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!](\mbox{M}) = \emptyset\); and (iii) otherwise, there is an atomic action from \({l}\) to \({l}^{\prime }\), then \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!](\mbox{M})\) is the set of environments after executing the action from \(\mbox{M}\). Taking the simple language in Figure 2 as an example, there are only two types of atomic actions: For an assignment \(^{ {l}_1} {x} := {e}\,^{ {l}_2}\), the corresponding atomic transfer function \({\mathrm {F}}{ {l}_{1}} \rightarrow { {l}_{2}}[\![{\textrm {P}}]\!](\mbox{M}) = \tau \lbrace \mid { {x} := {e}}\mid \rbrace \mbox{M}\), which is defined in Figure 3; similarly, for a Boolean test \(^{ {l}_1} {b}\,^{ {l}_2}\), the corresponding atomic transfer function \({\mathrm {F}}{ {l}_{1}} \rightarrow { {l}_{2}}[\![{\textrm {P}}]\!](\mbox{M}) = \tau \lbrace \mid { {b}}\mid \rbrace \mbox{M}\).
Therefore, the definition of forward transfer function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) can be rephrased into: \[\begin{equation*} \begin{array}{@{}rcl} \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{forward transfer function}\\ \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}}&\triangleq &\lambda {l}^{\prime }\in \mathbb {L}.\cup _{ {l}\in \mathbb {L}} {\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!](\mathsf {I}( {l})).\end{array} \end{equation*}\]
(Access Control, Continued).
For the access control program, the forward transfer function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) can be derived by combining the following atomic transfer functions: \(\tau \lbrace \mid { {apv} := 1}\mid \rbrace\), \(\tau \lbrace \mid { {i1} := [-1; 2]}\mid \rbrace\), \(\tau \lbrace \mid { {apv} := ( {i1} \le 0)\, ?\, -1 : {apv}}\mid \rbrace\), \(\tau \lbrace \mid { {i2} := [-1; 2]}\mid \rbrace\), \(\tau \lbrace \mid { {apv} := ( {apv} \ge 1 \wedge {i2} \le 0)\, ?\, -1 : {apv}}\mid \rbrace\), \(\tau \lbrace \mid { {typ} := [1; 2]}\mid \rbrace\), and \(\tau \lbrace \mid { {acs} := {apv} \times {typ}}\mid \rbrace\). Then, from a precondition \(\mathsf {I}_\mathsf {pre}\in \mathbb {L}\mapsto \wp (\mathbb {M})\) such that \(\mathsf {I}_\mathsf {pre}( {l}_1) = \mathbb {M}\) and \(\mathsf {I}_\mathsf {pre}( {l}) = \emptyset\) for \({l}\ne {l}_1\), we can compute the forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}\) by the least fixpoint \({\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {pre}}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\), which is equal to the classic invariant semantics.
To be more precise, the result \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}\) is listed in Table 1
Table 1. Concrete Forward Reachability Semantics for the Access Control Program
4.2.2 Over-approximating Abstract Forward Reachability Analysis.
Although the concrete forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\) can be easily computed in the Example 13 (since there are no infinite loops in the access control program and the variable values are bounded integers), it is not computable in general, and an over-approximation is necessary.
(1) Over-approximating Abstract Forward Transfer Function. For the forward transfer function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\in (\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\) on the concrete invariant domain, we need to construct an abstract forward transfer function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{} \in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) that over-approximates \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\), where the symbol \(\,\hat{}\,\) denotes over-approximations.
In Section 4.1.1, it is assumed that for each transfer function \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!] \in \wp (\mathbb {M}) \mapsto \wp (\mathbb {M})\) defined for atomic actions, the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) provides an abstract function \(\mathrm {\hat {F}}^{\sharp}{l}{\rightarrow}{l}^{\prime }[\![{\textrm {P}}]\!] \in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\forall \mbox{M}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\; ({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!]\circ \gamma _{\mathbb {M}})(\mbox{M}^{\sharp }) \subseteq (\gamma _{\mathbb {M}}\circ \mathrm {\hat {F}}^{\sharp}{l}{\rightarrow}{l}^{\prime }[\![{\textrm {P}}]\!])(\mbox{M}^{\sharp })\). For instance, the interval/polyhedron/octagon domain provides the over-approximating abstract transfer versions \(\tau ^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace\) and \(\tau ^{\sharp }\lbrace \mid { {b}}\mid \rbrace\) for \(\tau \lbrace \mid { {x} := {e}}\mid \rbrace\) and \(\tau \lbrace \mid { {b}}\mid \rbrace\). Therefore, \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) can be constructed by the join of \(\mathrm {\hat {F}}^{\sharp}{l}{\rightarrow}{l}^{\prime }[\![{\textrm {P}}]\!]\) functions: \[\begin{equation*} \begin{array}{@{}rcl} \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}&\in & \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right) \mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{abstract forward transfer function}\\ \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}^{\sharp }}&\triangleq &\lambda {l}^{\prime }\in \mathbb {L}.\sqcup ^{\sharp }_{\mathbb {M}}{}_{ {l}\in \mathbb {L}}\, \mathrm {\hat {F}}^{\sharp}{l}{\rightarrow}{l}^{\prime }[\![{\textrm {P}}]\!](\mathsf {I}^{\sharp }( {l})).\end{array} \end{equation*}\]
The abstract function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) is monotonic and obeys soundness condition: (3) \[\begin{equation} \begin{array}{c} \forall \mathsf {I}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\circ \dot{\gamma }_{\mathbb {M}}(\mathsf {I}^{\sharp })\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}\circ \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}(\mathsf {I}^{\sharp }).\end{array} \end{equation}\]
By the monotonic property and the soundness condition (3) of \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\), we know that: For any \(\mathsf {I}_\mathsf {pre}\in \mathbb {L}\mapsto \wp (\mathbb {M})\) and \(\mathsf {I}_\mathsf {pre}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), if \(\mathsf {I}_\mathsf {pre}\;\dot{\subseteq }\;\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })\), then \({\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {pre}}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\;\dot{\subseteq }\;\dot{\gamma }_{\mathbb {M}}({\mbox{lfp}}^{\scriptscriptstyle \dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {pre}^{\sharp }}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{})\). That is to say, the concrete forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}\) can be soundly over-approximated by the least fixpoint of the abstract forward transfer function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\).
(2) Widening. In most abstract environment domains (e.g., intervals, polyhedra, octagons), there may exist infinite increasing chains, hence the iteration of \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) may not converge in finite time. To address this problem, we need a widening operator \(\triangledown _{\mathbb {I}}\in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \times (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) on the abstract invariant domain, which satisfies the following soundness and termination conditions:
(i) \(\forall x^{\sharp }, y^{\sharp } \in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\; \dot{\gamma }_{\mathbb {M}}(x^{\sharp })\; \dot{\cup }\; \dot{\gamma }_{\mathbb {M}}(y^{\sharp })\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}(x^{\sharp }\; \triangledown _{\mathbb {I}}\; y^{\sharp })\);
(ii) for any sequence \((x^{\sharp }_i)_{i \in \mathbb {N}}\), the sequence \((y^{\sharp }_i)_{i \in \mathbb {N}}\) defined as \(y^{\sharp }_0 = x^{\sharp }_0\) and \(\forall i \in \mathbb {N}.\; y^{\sharp }_{i + 1} = y^{\sharp }_i\; \triangledown _{\mathbb {I}}\; x^{\sharp }_{i + 1}\) converges in finite time.
The implementation of \(\triangledown _{\mathbb {I}}\in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \times (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) naturally follows the widening operator \(\triangledown _{\mathbb {M}}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) provided by the abstract environment domain, such that \(\mathsf {I}^{\sharp }\; \triangledown _{\mathbb {I}}\; \mathsf {I}^{\sharp \prime } \triangleq \lambda {l}\in \mathbb {L}.\; \mathsf {I}^{\sharp }( {l})\; \triangledown _{\mathbb {M}}\; \mathsf {I}^{\sharp \prime }( {l})\). It is easy to prove such a definition of \(\triangledown _{\mathbb {I}}\) obeys the soundness and termination conditions, and we omit it here.
(3) Abstract Forward Reachability Semantics. Given a precondition represented by \(\mathsf {I}_\mathsf {pre}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), the corresponding concrete reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })}{}\) is the least fixpoint of function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) that is greater than or equal to \(\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })\). That is to say, \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })}{} = {\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\). By Cousot and Cousot’s upward iteration with widening theorem, \({\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) can be soundly over-approximated by the limit of a ultimately stationary sequence \((\mathsf {I}^{\sharp }_i)_{i \in \mathbb {N}}\), where \(\mathsf {I}^{\sharp }_0 = \mathsf {I}_\mathsf {pre}^{\sharp }\) and \(\forall i \in \mathbb {N}.\; \mathsf {I}^{\sharp }_{i + 1} = \mathsf {I}^{\sharp }_i\; \triangledown _{\mathbb {I}}\; \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp }_i)}\). (4) \[\begin{equation} \begin{array}{c} \forall \mathsf {I}_\mathsf {pre}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;{\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {pre}^{\sharp })}}\,\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}\left({lim}_{\scriptscriptstyle \mathsf {I}_\mathsf {pre}^{\sharp }}\,\lambda \mathsf {I}^{\sharp }.\; \mathsf {I}^{\sharp }\,\triangledown _{\mathbb {I}}\; \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp })}\right).\end{array} \end{equation}\]
In the rest of this article, the abstract forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\) refers to the following definition, which gives a sound over-approximation of the concrete reachability semantics and can be computed in finite time: \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}&\in &\left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{abstract forward reachability semantics}\\ \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}&\triangleq &{lim}_{\scriptscriptstyle \mathsf {I}_\mathsf {pre}^{\sharp }}\,\lambda \mathsf {I}^{\sharp }.\; \mathsf {I}^{\sharp }\,\triangledown _{\mathbb {I}}\; \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp }).}\end{array} \end{equation*}\]
(Access Control, Continued).
For the access control program in Figure 4, we use the interval domain as the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\). Given an abstract precondition \(\mathsf {I}_\mathsf {pre}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\mathsf {I}_\mathsf {pre}^{\sharp }( {l}_1) = \top ^{\sharp }_{\mathbb {M}}\) and \(\mathsf {I}_\mathsf {pre}^{\sharp }( {l}) = \bot ^{\sharp }_{\mathbb {M}}\) for \({l}\ne {l}_1\), the corresponding abstract forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) is listed in Table 2
Table 2. Abstract Forward Reachability Semantics for the Access Control Program
Compared with the concrete reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{ {l}}\) in Table 1, it is obvious that \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) is an over-approximation and contains some spurious environments that are not reachable in the concrete (e.g., the value of \({acs}\) cannot be 0 at \({l}_8\) in the concrete).
4.3 Backward Accessibilty Analysis
Given a precondition on states, the forward reachability analysis collects states that are possibly reachable by the executions from states satisfying the precondition. Inversely, given a postcondition on states, the backward accessibility analysis collects states from which the executions reach states satisfying the postcondition.
In general, there are two types of backward accessibility analysis: (1) the backward impossible failure accessibility analysis computes the states, from which the executions can reach only the states satisfying the given postcondition (i.e., it is impossible to reach states that fail the postcondition); (2) the backward possible success accessibility analysis introduced in Reference [18] computes the states, from which the executions may reach a state satisfying the given postcondition (i.e., it is possible to succeed to reach a state satisfying the postcondition). This section discusses the backward impossible failure accessibility semantics, which is essentially equivalent to the sufficient condition semantics in References [60, 61]. More precisely, we briefly review the under-approximating abstract analysis introduced by Miné and propose a new over-approximating abstract backward impossible failure accessibility analysis.
4.3.1 Backward Impossible Failure Accessibility Semantics.
The forward (possible success) reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\in (\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\) is the lower adjoint in a Galois connection, and the corresponding upper adjoint is defined as the backward impossible failure accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\in (\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\), such that any execution from states satisfying \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}}{}\) can reach only the states satisfying the given postcondition \(\mathsf {I}_\mathsf {post}\in \mathbb {L}\mapsto \wp (\mathbb {M})\):

For any postcondition \(\mathsf {I}_\mathsf {post}\in \mathbb {L}\mapsto \wp (\mathbb {M})\) that can represent a trace property of interest \(\gamma _{\mathbb {IV}}(\mathsf {I}_\mathsf {post})\), the backward impossible failure accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}}{}\) computes the states from which all the execution traces must have the property \(\gamma _{\mathbb {IV}}(\mathsf {I}_\mathsf {post})\), or, say, it infers the sufficient preconditions for the postcondition \(\mathsf {I}_\mathsf {post}\) to hold. It is of great importance to know that our \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\) is equivalent to the sufficient condition semantics introduced in References [60, 61].
Backward Impossible Failure Accessibility Semantics in Fixpoint Form. Similar to the forward (possible success) reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\), the backward impossible failure accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\) of a program \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\) can be also defined in the fixpoint form with a concrete backward transfer function \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\): \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{backward IF accessibility semantics}\\ \mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}}{}&\triangleq &{\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {post}}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\\ \mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{backward IF transfer function}\\ \mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}}&\triangleq &\mathsf {I}\;\dot{\cap }\;\lambda {l}\in \mathbb {L}.\lbrace \rho \in \mathbb {M}\mid \forall {l}^{\prime }\in \mathbb {L}, \rho ^{\prime }\in \mathbb {M}.\;\langle {l},\:\rho \rangle \rightarrow \;\langle {l}^{\prime },\:\rho ^{\prime }\rangle \Rightarrow \rho ^{\prime }\in \mathsf {I}( {l}^{\prime })\rbrace ,\end{array} \end{equation*}\] where \(\dot{\subseteq }\) and \(\dot{\cap }\) are pointwise extensions of the standard set inclusion relation \(\subseteq\) and intersection operator \(\cap\), respectively, and \({\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}}}\,\mbox{F}\) is the order-dual of \({\mbox{lfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}}}\,\mbox{F}\).
As \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) is constructed by combining atomic forward transfer functions \({\mathrm {F}}{ {l}} \rightarrow { {l}}^{\prime }[\![{\textrm {P}}]\!]\), we can construct \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) by atomic backward transfer functions \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!]\in \wp (\mathbb {M}) \mapsto \wp (\mathbb {M})\), which are defined for every pair of program points \(\langle {l},\: {l}^{\prime }\rangle\) in the program such that, if there exists a single atomic action from \({l}\) to \({l}^{\prime }\), then executions from environments in \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!]\mbox{M}\) at point \({l}\) can only reach environments in \(\mbox{M}\) at point \({l}^{\prime }\). To be more precise: (i) if \({l}= {l}^{\prime }\), then \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!](\mbox{M}) = \mbox{M}\); (ii) if \({l}\ne {l}^{\prime }\) and there is not an atomic action from \({l}\) to \({l}^{\prime }\), then \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!](\mbox{M}) = \mathbb {M}\); and (iii) otherwise, there is an atomic action from \({l}\) to \({l}^{\prime }\), then \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!](\mbox{M})\) is the set of environments at point \({l}\) that guarantee the environments after executing the atomic action belong to \(\mbox{M}\).
Specifically, for the simple language described in Figure 2, there are only two types of atomic actions, and for each of them we define an atomic backward transfer function. For an assignment \(^{ {l}_1} {x} := {e}\,^{ {l}_2}\), the corresponding atomic backward transfer function \(\mathrm {F}_{{ {l}_1}\leftarrow{ {l}_2}}[\![{\textrm {P}}]\!](\mbox{M}) = \overleftarrow{\tau }\lbrace \mid { {x} := {e}}\mid \rbrace \mbox{M}\), which is defined as: \[\begin{equation*} \begin{array}{c} \overleftarrow{\tau }\lbrace \mid { {x} := {e}}\mid \rbrace \mbox{M}\triangleq \lbrace \rho \in \mathbb {M}\mid \forall {v}\in [\![ {e}]\!] {\rho }.\; {\rho }{ {x}}{ {v}}\in \mbox{M}\rbrace .\end{array} \end{equation*}\]
Similarly, for a Boolean test \(^{ {l}_1} {b}\,^{ {l}_2}\), the atomic backward transfer function \(\mathrm {F}_{{ {l}_1}\leftarrow{ {l}_2}}[\![{\textrm {P}}]\!](\mbox{M}) = \overleftarrow{\tau }\lbrace \mid { {b}}\mid \rbrace \mbox{M}\), which is defined as: \[\begin{equation*} \begin{array}{c} \overleftarrow{\tau }\lbrace \mid { {b}}\mid \rbrace \mbox{M}\triangleq \mbox{M}\cup \lbrace \rho \in \mathbb {M}\mid [\![ {b}]\!] {\rho } = \lbrace \mathsf {ff}\rbrace \rbrace .\end{array} \end{equation*}\]
Therefore, the definition of backward transfer function \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) can be rephrased into: \[\begin{equation*} \begin{array}{@{}rcl} \mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}&\in &(\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\text{backward IF transfer function}\\ \mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}}&\triangleq &\lambda {l}\in \mathbb {L}.\cap _{ {l}^{\prime }\in \mathbb {L}} \mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!](\mathsf {I}( {l}^{\prime })).\end{array} \end{equation*}\]
(Access Control, Continued).
For the access control program in Figure 4, the transfer function \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) can be constructed by combining the atomic backward transfer functions: \(\overleftarrow{\tau }\lbrace \mid { {apv} := 1}\mid \rbrace\), \(\overleftarrow{\tau }\lbrace \mid { {i1} := [-1; 2]}\mid \rbrace\), \(\overleftarrow{\tau }\lbrace \mid { {apv} := ( {i1} \le 0)\, ?\, -1 : {apv}}\mid \rbrace\), \(\overleftarrow{\tau }\lbrace \mid { {i2} := [-1; 2]}\mid \rbrace\), \(\overleftarrow{\tau }\lbrace \mid { {apv} := ( {apv} \ge 1 \wedge {i2} \le 0)\, ?\, -1 :}\)\({apv}\mid \rbrace\), \(\overleftarrow{\tau }\lbrace \mid { {typ} := [1; 2]}\mid \rbrace\), and \(\overleftarrow{\tau }\lbrace \mid { {acs} := {apv} \times {typ}}\mid \rbrace\).
Suppose we are interested in inferring sufficient preconditions of the trace property “the access to o fails,” a simple idea is to specify a postcondition \(\mathsf {I}_\mathsf {post}\in \mathbb {L}\mapsto \wp (\mathbb {M})\) such that \(\mathsf {I}_\mathsf {post}( {l}_8) = \lbrace \rho \in \mathbb {M}\mid \rho ( {acs}) \lt = 0\rbrace\) and \(\mathsf {I}_\mathsf {post}( {l}) = \mathbb {M}\) for \({l}\ne {l}_8\), and then compute the corresponding backward accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}}{}\). However, such a result is too imprecise. Take the semantics at the point \({l}_7\) as an example: \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}}{ {l}_7} = \mathsf {I}_\mathsf {post}( {l}_7) \cap \mathrm {{F}}{l_{7}}{\leftarrow}{l_{8}}[\![{\textrm {P}}]\!](\mathsf {I}_\mathsf {post}( {l}_8)) = \mathbb {M}\cap \overleftarrow{\tau }\lbrace \mid { {acs} := {apv} \times {typ}}\mid \rbrace (\lbrace \rho \in \mathbb {M}\mid \rho ( {acs}) \lt = 0\rbrace) = \lbrace \rho \in \mathbb {M}\mid (\rho ( {apv}) \lt = 0 \wedge \rho ( {typ}) \gt = 0) \vee (\rho ( {apv}) \gt = 0 \wedge \rho ( {typ}) \lt = 0)\rbrace\). This semantics does provide correct sufficient preconditions of “the access to o fails,” but it is not precise enough, since the value of \({typ}\) is never zero or negative at point \({l}_7\) in the real executions.
To get a more precise result, the specified postcondition \(\mathsf {I}_\mathsf {post}\) can be refined by the intersection with the forward reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}\) computed in Example 13, i.e., we define \(\mathsf {I}_\mathsf {post}^{\prime } = \mathsf {I}_\mathsf {post}\, \dot{\cap }\, \mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}}{}\), and the semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\prime }}{}\) would be more precise, whose result is in Table 3
Table 3. Concrete Backward Impossible Failure Accessibility Semantics for the Access Control Program
4.3.2 Under-approximating Abstract Backward Impossible Failure Accessibility Analysis.
Similar to the forward reachability semantics, the backward impossible failure accessibility semantics may be not computable in the concrete, hence it is necessary to reason on the abstract domain instead. Although classic abstract domains come with abstract transfer functions (operators) for both forward and backward analyses, these functions are over-approximating and are suitable only for inferring invariants (i.e., reachability semantics) or necessary preconditions, but not for inferring sufficient preconditions. The reason comes from that an over-approximation of the tightest program invariant (respectively, the strongest necessary precondition) is still an invariant (respectively, a necessary precondition), but an over-approximation of the weakest sufficient precondition is not a sufficient precondition anymore (which will be discussed later in Section 4.3.3), thus under-approximations are needed instead to preserve the soundness for inferring sufficient preconditions. To solve this problem, Miné [60, 61] presents under-approximating abstract operators (including a dual widening) for the classic interval/octagon/polyhedron domain, which makes inferring sufficient preconditions directly by under-approximating backward analysis possible. Other attempts to infer sufficient preconditions include References [7, 44, 50], but none of them can directly work on the classic numeric abstract domains.
In this section, we briefly summarize the framework of an under-approximating abstract backward impossible failure accessibility analysis and refer to References [60, 61] and Banal analyzer [55] for the details of implementing the under-approximating abstract operators (including a dual widening).
(1) Under-approximating Abstract Backward Transfer Function. For the transfer function \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\in (\mathbb {L}\mapsto \wp (\mathbb {M}))\mapsto (\mathbb {L}\mapsto \wp (\mathbb {M}))\) on the concrete invariant domain, we need to construct the corresponding abstract backward transfer function \(\mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{} \in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) (the symbol \(\,\check{}\,\) denotes under-approximations), which satisfies the following soundness condition: (6) \[\begin{equation} \begin{array}{c} \forall \mathsf {I}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\dot{\gamma }_{\mathbb {M}}\circ \mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}(\mathsf {I}^{\sharp })\; \dot{\subseteq }\; \mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\circ \dot{\gamma }_{\mathbb {M}}(\mathsf {I}^{\sharp }).\end{array} \end{equation}\]
Since \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}}\) is defined by combining atomic backward transfer function \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!]\) together (i.e., \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}}\triangleq \lambda {l}\in \mathbb {L}.\cap _{ {l}^{\prime }\in \mathbb {L}} \mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!](\mathsf {I}( {l}^{\prime }))\)), it is necessary to build the under-approximating versions \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) for atomic backward transfer functions \(\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!]\in \wp (\mathbb {M}) \mapsto \wp (\mathbb {M})\), such that condition (7) holds: (7) \[\begin{equation} \begin{array}{c} \forall \mbox{M}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\gamma _{\mathbb {M}}\circ \mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]{}(\mbox{M}^{\sharp })\; \subseteq \; \mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!]{}\circ \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }).\end{array} \end{equation}\]
To satisfy the soundness condition (7), we design \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\) such that: (i) if \({l}= {l}^{\prime }\), then \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp }) = \mbox{M}^{\sharp }\); (ii) if \({l}\ne {l}^{\prime }\) and there is not an atomic action from \({l}\) to \({l}^{\prime }\), then \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp }) = \top ^{\sharp }_{\mathbb {M}}\); and (iii) otherwise, there is an atomic action from \({l}\) to \({l}^{\prime }\), then \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp })\) is an abstract environment element in \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) that guarantees \(\mbox{M}^{\sharp }\) to hold after executing the atomic action. It is obvious that the case (iii) is the difficult one, and fortunately for the atomic actions of assignments and Boolean tests in the interval/polyhedron/octagon domain, Miné has proposed the corresponding under-approximating atomic backward transfer function \(\overleftarrow{\tau }^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace \mbox{M}^{\sharp }\) and \(\overleftarrow{\tau }^{\sharp }\lbrace \mid { {b}}\mid \rbrace \mbox{M}^{\sharp }\), which satisfies the soundness condition. Details are given in Sections 3.2–3.4 of Reference [61]. Now we can build the backward transfer function \(\mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) by the following definition: \[\begin{equation*} \begin{array}{@{}rcl} \mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}&\in &\left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right) \mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{under-approximating backward IF function}\\ \mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}^{\sharp }}&\triangleq &\lambda {l}\in \mathbb {L}.\sqcap ^{\sharp }_{\mathbb {M}}{}_{ {l}^{\prime }\in \mathbb {L}} \mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mathsf {I}^{\sharp }( {l}^{\prime })).\end{array} \end{equation*}\]
The backward transfer function \(\mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) satisfies the condition (6), and its greatest fixpoint soundly under-approximates the concrete backward impossible failure accessibility semantics: \[\begin{equation*} \begin{array}{c} \forall \mathsf {I}_\mathsf {post}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\dot{\gamma }_{\mathbb {M}}\left({\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}}\,\mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\right)\, \dot{\subseteq }\, {\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}\left(\mathsf {I}_\mathsf {post}^{\sharp }\right)}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{} = \mathcal {S}\mathop{\leftarrow}\limits_{if}s [\![{\textrm {P}}]\!]{\dot{\gamma }_{\mathbb {M}}\left(\mathsf {I}_\mathsf {post}^{\sharp }\right)}{}.\end{array} \end{equation*}\]
(2) Dual Widening. The iteration of the above defined \(\mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) may not converge in finite time, since there may exist infinite decreasing chains in the abstract environment domain (e.g., intervals, polyhedra, octagons). To address this problem, we need a dual widening operator \(\underline{\triangledown }_{\mathbb {I}}\in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \times (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) on the abstract invariant domain, which obeys the following soundness and termination conditions:
(i) \(\forall x^{\sharp }, y^{\sharp } \in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}).\; \dot{\gamma }_{\mathbb {M}}(x^{\sharp }\; \underline{\triangledown }_{\mathbb {I}}\; y^{\sharp })\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}(x^{\sharp })\; \dot{\cap }\; \dot{\gamma }_{\mathbb {M}}(y^{\sharp })\);
(ii) for any sequence \((x^{\sharp }_i)_{i \in \mathbb {N}}\), the sequence \((y^{\sharp }_i)_{i \in \mathbb {N}}\) defined as \(y^{\sharp }_0 = x^{\sharp }_0\) and \(\forall i \in \mathbb {N}.\; y^{\sharp }_{i + 1} = y^{\sharp }_i\; \underline{\triangledown }_{\mathbb {I}}\; x^{\sharp }_{i + 1}\) converges in finite time.
Notice that the above soundness condition is different from the one for classic widening \(\triangledown _{\mathbb {I}}\) in the forward reachability analysis.
In Section 3.5 of Reference [61], Miné has proposed a so-called “lower widening” operator \(\underline{\triangledown } \in \mathcal {D}^{\sharp }_{\mathbb {M}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) for the interval/polyhedron/octagon domain. Correspondingly, we define \(\underline{\triangledown }_{\mathbb {I}}\) as the pointwise version of \(\underline{\triangledown }\) (i.e., \(\mathsf {I}^{\sharp }\; \underline{\triangledown }_{\mathbb {I}}\; \mathsf {I}^{\sharp \prime } \triangleq \lambda {l}\in \mathbb {L}.\; \mathsf {I}^{\sharp }( {l})\; \underline{\triangledown } \; \mathsf {I}^{\sharp \prime }( {l})\)), and it can satisfy both the soundness and the termination condition above.
(3) Under-approximating Abstract Backward Accessibility Semantics. Given a postcondition specified as \(\mathsf {I}_\mathsf {post}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), the corresponding concrete backward impossible failure accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}{}\) is the greatest fixpoint of function \(\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{},\) which is less than or equal to \(\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })\). That is to say, \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}{} = {\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\), and it can be soundly under-approximated by the limit of a ultimately stationary sequence \((\mathsf {I}^{\sharp }_i)_{i \in \mathbb {N}}\), where \(\mathsf {I}^{\sharp }_0 = \mathsf {I}_\mathsf {post}^{\sharp }\) and \(\forall i \in \mathbb {N}.\; \mathsf {I}^{\sharp }_{i + 1} = \mathsf {I}^{\sharp }_i\; \underline{\triangledown }_{\mathbb {I}}\; \mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp }_i)}\). (8) \[\begin{equation} \begin{array}{c} \forall \mathsf {I}_\mathsf {post}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\dot{\gamma }_{\mathbb {M}}\left({lim}_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}\,\lambda \mathsf {I}^{\sharp }.\; \mathsf {I}^{\sharp }\,\underline{\triangledown }_{\mathbb {I}}\; \mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp })}\right)\; \dot{\subseteq }\;{\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{} .\end{array} \end{equation}\]
In the rest of this article, the under-approximating abstract backward impossible failure accessibility semantics \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\) refers to the following definition, which computes a sound under-approximation of the concrete backward impossible failure accessibility semantics and can automatically infer the sufficient precondition of any given postcondition in finite time. \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}&\in &\left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{under-approximating backward IF semantics}\\ \mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\sharp }}{}&\triangleq &{lim}_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}\,\lambda \mathsf {I}^{\sharp }.\; \mathsf {I}^{\sharp }\,\underline{\triangledown }_{\mathbb {I}}\; \mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp })}\end{array} \end{equation*}\]
(Access Control, Continued).
Consider the access control program in Figure 4 again. We are interested in inferring the sufficient preconditions of the trace property “the access to o fails.” Suppose the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) is chosen as the interval domain, then “the access to o fails” can be expressed by an abstract postcondition \(\mathsf {I}_\mathsf {post}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\mathsf {I}_\mathsf {post}^{\sharp }( {l}_8) = {acs} \in [{-\infty };{0}]\) and \(\mathsf {I}_\mathsf {post}^{\sharp }( {l}) = \top ^{\sharp }_{\mathbb {M}}\) for \({l}\ne {l}_8\).
Like in the Example 15, the postcondition \(\mathsf {I}_\mathsf {post}^{\sharp }\) can be refined by the intersection with the abstract forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) from the Table 2, and we get \(\mathsf {I}_\mathsf {post}^{\sharp \prime } = \mathsf {I}_\mathsf {post}^{\sharp }\; \dot{\sqcap }^{\sharp }_{\mathbb {M}}\; \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\), which is listed in the Table 4
Table 4. Refined Abstract Postcondition for “the Access to o Fails”
From the above refined abstract postcondition \(\mathsf {I}_\mathsf {post}^{\sharp \prime }\), there are two possible results of the backward impossible failure accessibility analysis \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\sharp \prime }}{}\), and they are, respectively, displayed in Table 5
Table 5. The Under-approximating Abstract Backward Impossible Failure Accessibility Semantics (Option 1) for “the Access to o Fails”
Table 6. The Under-approximating Abstract Backward Impossible Failure Accessibility Semantics (Option 2) for “the Access to o Fails”
The difference between these two possible results comes from the assignment “\({apv} := ( {apv} \ge 1 \wedge {i2} \le 0)\; ?\; -1 : {apv}\)” at the point \({l}_5\). To guarantee that “\({apv} \le 0\)” at point \({l}_6\), we have two possible choices: either “\({apv} \ge 1 \wedge {i2} \le 0\),” or “\({apv} \le 0\)” at point \({l}_5\). Since \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\sharp \prime }}{}\) is an under-approximation, we cannot join two cases together like in the over-approximating forward reachability analysis. Instead, we keep one case and discard the other case (e.g., the Banal analyzer adopts the former choice and produces results as in Table 5).
Alternatively, we could use the disjunctive completion [21] and maintain the abstract environment elements (i.e., sufficient preconditions) from both two tables. In this example, the disjunctive completion could provide us with the exact backward impossible failure accessibility semantics and its cost is not too heavy, because we need to keep a disjunction of two abstract environment elements only at the point \({l}_5\), while the abstract environment elements at other points are either the same from two tables or the bottom in one table (which can be omitted). To distinguish from the over-approximating analysis introduced later in Section 4.3.3, here we adopt the result (from the Banal analyzer) in Table 5 as an under-approximation.
Therefore, we have successfully inferred some sufficient preconditions of “the Access to o Fails”: “\({acs}\in [{-2};{0}]\)” at \({l}_8\), “\({apv}\in [{-1};{0}]\)” at \({l}_7\) and \({l}_6\), and “\({apv}\in [{1};{1}]\wedge {i2}\in [{-1};{0}]\)” at \({l}_5\), which implies that the zero or negative value of \({i2}\) (i.e., the input from 2nd admin) guarantees the access failure.
4.3.3 Over-approximating Abstract Backward Impossible Failure Accessibility Analysis.
Besides the under-approximating backward analysis above, we design an over-approximating abstract backward impossible failure accessibility analysis as well, which computes an over-approximation of the set of states from which all the executions must satisfy the given postcondition \(\mathsf {I}_\mathsf {post}^{\sharp }\).
Such an over-approximation is neither a sufficient precondition for \(\mathsf {I}_\mathsf {post}^{\sharp }\) to hold, nor a necessary precondition, due to the possible non-determinism of the program. Thus, it may seem to be not of practical use. However, instead of directly using such an over-approximating abstract backward impossible failure accessibility semantics in the responsibility analysis, we intend to utilize its set-complement as partitioning directives (which will be further discussed in Section 7), and it represents a set of states from which there must exist at least one concrete execution trace that fails the postcondition \(\mathsf {I}_\mathsf {post}^{\sharp }\). This may seem to be counter-intuitive at first sight, since most abstract domains (e.g., intervals, octagons, polyhedra) do not support complements. For instance, the complement of a polyhedron is a disjunction of affine inequalities, which cannot be expressed by a single polyhedron. However, it would not be a problem for our responsibility analysis, since we do not require to represent the complement set by a single abstract environment element. Instead, we could keep multiple partitioning directives at every program point. Take the complement of a polyhedron as an example: Each affine inequality (or the heuristically selected ones when the number of affine inequalities exceeds a threshold) can be used as a partitioning directive in the responsibility analysis.
In the following, we formalize the framework of over-approximating backward impossible failure accessibility analysis, which essentially corresponds to an over-approximating version of Section 3 of Reference [61] and Section 4.3.2 of this article. More precisely, it consists of the over-approximating backward transfer functions (e.g., for the Boolean tests and assignments in our simple programming language) and a narrowing operator that over-approximates meets and enforces termination.
(1) Over-approximating Abstract Backward Transfer Function. Here, we need an over-approximating abstract backward transfer function \(\mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{} \in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) (the symbol \(\,\hat{}\,\) denotes over-approximations) that satisfies the following soundness condition (9): (9) \[\begin{equation} \begin{array}{c} \forall \mathsf {I}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\circ \dot{\gamma }_{\mathbb {M}}(\mathsf {I}^{\sharp })\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}\circ \mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}(\mathsf {I}^{\sharp }).\end{array} \end{equation}\]
Like \(\mathrm {\hat F}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) is defined by the combination of \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\), the over-approximating version \(\mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) can be defined by combining \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!] \in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\): \[\begin{equation*} \begin{array}{@{}rcl} \mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}&\in &\left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right) \mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{over-approximating backward IF function}\\ \mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}^{\sharp }}&\triangleq &\lambda {l}\in \mathbb {L}.\sqcap ^{\sharp }_{\mathbb {M}}{}_{ {l}^{\prime }\in \mathbb {L}} \mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mathsf {I}^{\sharp }( {l}^{\prime })),\end{array} \end{equation*}\] where the meet \(\sqcap ^{\sharp }_{\mathbb {M}}\) is exact and \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\) needs to satisfy the condition (10): (10) \[\begin{equation} \begin{array}{c} \forall \mbox{M}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\mathrm {F}_{{ {l}}\leftarrow{ {l}^{\prime }}}[\![{\textrm {P}}]\!]{}\circ \gamma _{\mathbb {M}}(\mbox{M}^{\sharp })\; \subseteq \; \gamma _{\mathbb {M}}\circ \mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]{}(\mbox{M}^{\sharp }).\end{array} \end{equation}\]
Similar to the definition of \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\), here \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\) is defined such that: (i) if \({l}= {l}^{\prime }\), then \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp }) = \mbox{M}^{\sharp }\); (ii) if \({l}\ne {l}^{\prime }\) and there is not an atomic action from \({l}\) to \({l}^{\prime }\), then \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp }) = \top ^{\sharp }_{\mathbb {M}}\); and (iii) otherwise, there is an atomic action from \({l}\) to \({l}^{\prime }\), then \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp })\) over-approximates the sufficient precondition that guarantees \(\mbox{M}^{\sharp }\) to hold after executing the atomic action.
Among the above three cases, (iii) is the difficult one. In the following, we take the simple programming language in Figure 2 as an example, mimic Section 3 of Reference [61], and discuss how \(\mathrm {\check {F}}^{\sharp}{l}{\leftarrow}{l}^{\prime}[\![{\textrm {P}}]\!]\) is implemented for atomic actions of form \(^{ {l}_1} {a}\,^{ {l}_2}\) (e.g., Boolean tests \(^{ {l}_1} {b}\,^{ {l}_2}\), assignments \(^{ {l}_1} {x} := {e}\,^{ {l}_2}\)), where \(\mathrm {\hat {F}}^{\sharp}{l}_{1}{\leftarrow}{l}_{2}[\![{\textrm {P}}]\!](\mbox{M}^{\sharp }) \triangleq \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {a}}\mid \rbrace \mbox{M}^{\sharp }\) such that \(\forall \mbox{M}^{\sharp }\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\overleftarrow{\tau }\lbrace \mid { {a}}\mid \rbrace \circ \gamma _{\mathbb {M}}(\mbox{M}^{\sharp })\; \subseteq \; \gamma _{\mathbb {M}}\circ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {a}}\mid \rbrace (\mbox{M}^{\sharp })\).
(1.1) Boolean tests (guards).
Affine guards. First, we consider the polyhedron domain, and the guard is of form \(\vec{a} \cdot \vec{ {x}} \ge b\) such that it can be exactly represented by polyhedra. In this case, the concrete backward transfer function can be rephrased into: \[\begin{equation*} \begin{array}{c} \overleftarrow{\tau }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \ge b}\mid \rbrace \mbox{M}= \mbox{M}\cup \lbrace \rho \in \mathbb {M}\mid [\![ \vec{a} \cdot \vec{ {x}} \ge b]\!] {\rho } = \lbrace \mathsf {ff}\rbrace \rbrace = \mbox{M}\cup \lbrace \rho \in \mathbb {M}\mid \vec{a} \cdot \vec{\rho } \lt b\rbrace ,\end{array} \end{equation*}\] where \(\vec{\rho }\) denotes the vector of variable values in the environment ρ.
To over-approximate \(\overleftarrow{\tau }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \ge b}\mid \rbrace\), we define the corresponding abstract transfer function \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \ge b}\mid \rbrace \in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) as: (11) \[\begin{equation} \begin{array}{c} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \ge b}\mid \rbrace \mbox{M}^{\sharp }\triangleq \mbox{M}^{\sharp }\; \sqcup ^{\sharp }_{\mathbb {M}}\; \vec{a} \cdot \vec{x} \lt b.\end{array} \end{equation}\]
Since \(\sqcup ^{\sharp }_{\mathbb {M}}\) soundly approximates the concrete join operator \(\cup\), it is easy to see the soundness condition (10) holds. Moreover, if we use the disjunctive completion [21], then both \(\mbox{M}^{\sharp }\) and \(\vec{a} \cdot \vec{x} \lt b\) can be kept without the join, i.e., \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \ge b}\mid \rbrace \mbox{M}^{\sharp }\triangleq \lbrace \mbox{M}^{\sharp },\; \vec{a} \cdot \vec{x} \lt b\rbrace\), which can greatly improve the precision of analysis. When the number of disjunctive elements exceeds a threshold, we can replace them by their join. It is worth mentioning that current polyhedra abstract domain [41] supports strict constraints like \(\vec{a} \cdot \vec{x} \lt b\). For the original polyhedra abstract domain that cannot express strict constraints, it is sound to replace \(\vec{a} \cdot \vec{x} \lt b\) by \(\vec{a} \cdot \vec{x} \le b\) in Equation (11).
For the interval domain, the same technique can be applied to \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\pm {x} \ge b}\mid \rbrace\), since a box (i.e., a Cartesian products of intervals) is a special case of polyhedron. Similarly, we can handle \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\pm {x} \pm {y} \ge b}\mid \rbrace\) for the octagon domain in the same way.
Extended affine guards. For strict guards and the guards with a non-deterministic constant, the corresponding abstract transfer function is defined as: \[\begin{equation*} \begin{array}{@{}rcl} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \gt b}\mid \rbrace \mbox{M}^{\sharp }&\triangleq & \mbox{M}^{\sharp }\; \sqcup ^{\sharp }_{\mathbb {M}}\; \vec{a} \cdot \vec{x} \le b\\ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \gt [{b};{c}]}\mid \rbrace \mbox{M}^{\sharp }&\triangleq & \mbox{M}^{\sharp }\; \sqcup ^{\sharp }_{\mathbb {M}}\; \vec{a} \cdot \vec{x} \le c\nonumber \nonumber \\ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\vec{a} \cdot \vec{ {x}} = [{b};{c}]}\mid \rbrace \mbox{M}^{\sharp }&\triangleq & \mbox{M}^{\sharp }\; \sqcup ^{\sharp }_{\mathbb {M}}\; \vec{a} \cdot \vec{x} \lt b\; \sqcup ^{\sharp }_{\mathbb {M}}\; \vec{a} \cdot \vec{x} \gt c.\end{array} \end{equation*}\]
Boolean operations. For the Boolean conjunctions and disjunctions of affine guards, Section 3.2 of Reference [61] has shown that the concrete transfer function has the following property: (12) \[\begin{equation} \begin{array}{c} \overleftarrow{\tau }\lbrace \mid {t_1 \vee t_2}\mid \rbrace = \overleftarrow{\tau }\lbrace \mid {t_1}\mid \rbrace \cap \overleftarrow{\tau }\lbrace \mid {t_2}\mid \rbrace \\ \overleftarrow{\tau }\lbrace \mid {t_1 \wedge t_2}\mid \rbrace = \overleftarrow{\tau }\lbrace \mid {t_1}\mid \rbrace \circ \overleftarrow{\tau }\lbrace \mid {t_2}\mid \rbrace .\end{array} \end{equation}\]
Since the abstract meet \(\sqcap ^{\sharp }_{\mathbb {M}}\) is exact in the interval/octagon/polyhedron domain, we can define the corresponding abstract transfer functions that are also exact: (13) \[\begin{equation} \begin{array}{c} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {t_1 \vee t_2}\mid \rbrace = \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {t_1}\mid \rbrace \sqcap ^{\sharp }_{\mathbb {M}}\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {t_2}\mid \rbrace \\ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {t_1 \wedge t_2}\mid \rbrace = \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {t_1}\mid \rbrace \circ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {t_2}\mid \rbrace .\end{array} \end{equation}\]
In addition, the Boolean negation of affine guard \(\overleftarrow{\tau }\lbrace \mid {\lnot (\vec{a} \cdot \vec{ {x}} \ge b)}\mid \rbrace\) is equivalent to \(\overleftarrow{\tau }\lbrace \mid {\vec{a} \cdot \vec{ {x}} \lt b}\mid \rbrace\), and the negation of conjunctions or disjunctions can be eliminated by De Morgan’s law.
(1.2) Projection. To reduce the backward transfer function of assignments to the backward transfer function of guards, Reference [61] introduces a projection action \({x} := [{-\infty };{+\infty }]\), which is a special form of assignment that forgets the value of a variable. Here, we do the same and reuse the under-approximating abstract backward transfer function for projections in Reference [61], since it is proved to be exact (i.e., it is both an over-approximation and an under-approximation of the concrete transfer function): (14) \[\begin{equation} \begin{array}{c} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := [{-\infty };{+\infty }]}\mid \rbrace \mbox{M}^{\sharp }\triangleq {\left\lbrace \begin{array}{ll}\mbox{M}^{\sharp }&\text{if } \gamma _{\mathbb {M}}(\tau ^{\sharp }\lbrace \mid { {x} := [{-\infty };{+\infty }]}\mid \rbrace \mbox{M}^{\sharp }) = \gamma _{\mathbb {M}}(\mbox{M}^{\sharp })\\ \bot ^{\sharp }_{\mathbb {M}}&\text{otherwise}.\end{array}\right.}\end{array} \end{equation}\]
The projection is used to model variable addition “\(\textrm {add}\; {x}\)” and removal “\(\textrm {del}\; {x}\),” which are not included in the language syntax but implicitly created to model assignments. Again, since the under-approximating abstract backward transfer functions for these two actions in Reference [61] are exact, we can simply reuse them: (15) \[\begin{equation} \begin{array}{c} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\textrm {del}\; {x}}\mid \rbrace = \tau ^{\sharp }\lbrace \mid {\textrm {add}\; {x}}\mid \rbrace \\ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid {\textrm {add}\; {x}}\mid \rbrace = \tau ^{\sharp }\lbrace \mid {\textrm {del}\; {x}}\mid \rbrace \circ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := [{-\infty };{+\infty }]}\mid \rbrace .\end{array} \end{equation}\]
(1.3) Assignments.
Reduction to guards. As shown in Section 3.4 of Reference [61], assignments \({x} := {e}\) can be reduced to: add a temporary variable \({x}^{\prime }\), then pass a guard \({x}^{\prime } = {e}\), remove the variable \({x}\), and rename \({x}^{\prime }\) as \({x}\). Furthermore, the backward transfer function is reduced to:
\[\begin{equation*} \begin{array}{c} \overleftarrow{\tau }\lbrace \mid { {x} := {e}}\mid \rbrace = \tau \lbrace \mid {\textrm {del}\; {x}^{\prime }}\mid \rbrace \circ \overleftarrow{\tau }\lbrace \mid { {x}^{\prime } := [{-\infty };{+\infty }]}\mid \rbrace \circ \overleftarrow{\tau }\lbrace \mid { {x}^{\prime } = {e}}\mid \rbrace \circ \tau \lbrace \mid {\textrm {add}\; {x}}\mid \rbrace \circ [ {x}^{\prime }\backslash {x}], \nonumber \nonumber \end{array} \end{equation*}\]where \([ {x}^{\prime }\backslash {x}]\) represents renaming \({x}\) as \({x}^{\prime }\). Correspondingly, the over-approximating backward transfer function can be defined as: (16) \[\begin{equation} \begin{array}{@{}rcl} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace &=&\tau ^{\sharp }\lbrace \mid {\textrm {del}\; {x}^{\prime }}\mid \rbrace \circ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x}^{\prime } := [{-\infty };{+\infty }]}\mid \rbrace \circ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x}^{\prime } = {e}}\mid \rbrace \circ \; \tau ^{\sharp }\lbrace \mid {\textrm {add}\; {x}}\mid \rbrace \circ [ {x}^{\prime }\backslash {x}],\end{array} \end{equation}\] in which \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x}^{\prime } = {e}}\mid \rbrace\) for the guard \({x}^{\prime } = {e}\) is over-approximating, while \(\tau ^{\sharp }\lbrace \mid {\textrm {del}\; {x}^{\prime }}\mid \rbrace\), \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x}^{\prime } := [{-\infty };{+\infty }]}\mid \rbrace\), \(\tau ^{\sharp }\lbrace \mid {\textrm {add}\; {x}}\mid \rbrace\) and \([ {x}^{\prime }\backslash {x}]\) are exact.
Special cases of assignments. There are a few special cases such that the above general definition \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace\) can be simplified. For the case where \({x}\) is not used in the expression e, there is no need to introduce the temporary variable \({x} ^{\prime }\), and the corresponding \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace\) is simplified into: (17) \[\begin{equation} \begin{array}{@{}rcl} \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace &=&\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := [{-\infty };{+\infty }]}\mid \rbrace \circ \hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} = {e}}\mid \rbrace .\end{array} \end{equation}\]
Moreover, for purely non-deterministic assignments \({x} := [{a};{b}]\), variable shifts \({x} := {x} + [{a};{b}],\) and variable copies \({x} := {y}\), Theorem 9 of Reference [61] yields sound and exact backward transfer function, thus we can reuse them.
Another case is when the assigned expression e is invertible, i.e., there exists an expression \({e}^{-1}\) that allows recovering the initial value of \({x}\). For example, in the assignment \({x} := {x} + 1\), the expression \({x} + 1\) can be inverted by \({x} - 1\). In such a case, the backward transfer function for \({x} := {e}\) can be replaced by the forward transfer function for \({x} := {e}^{-1}\), i.e., \(\hat{\overleftarrow{\tau }}^{\sharp }\lbrace \mid { {x} := {e}}\mid \rbrace = \tau ^{\sharp }\lbrace \mid { {x} := {e}^{-1}}\mid \rbrace\), which provides a sound over-approximation.
(1.4) Expression approximation. In the above, we have discussed how to handle affine expressions in guards and assignments. As for non-affine numeric expressions, Reference [61] proposes to over-approximate arbitrary expressions by affine ones, and this is accomplished by the linearization technique [59] that performs interval arithmetic on non-linear expression parts. Similarly, here we could convert non-affine expressions into affine expressions with some non-determinism embedded in a constant interval (or constant coefficients), such that the original non-affine expressions are under-approximated. Then, by replacing the original non-affine expressions with affine ones, we can reuse the solution designed for affine expressions and correspondingly get over-approximating backward transfer functions for arbitrary guards and assignments.
(2) Narrowing. Up to now, we have discussed the design of over-approximating backward transfer function \(\mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\). By the soundness condition 6, the greatest fixpoint \({\mbox{gfp}}^{\scriptscriptstyle \dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}}\,\mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) would be an over-approximation of the concrete backward impossible failure accessibility semantics \({\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\). However, it is generally difficult to compute \({\mbox{gfp}}^{\scriptscriptstyle \dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}}_{_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}}\,\mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\), since the decreasing iteration may be infinite. In many cases, a (dual) widening is used to accelerate the convergence, but it does not apply here, since the (dual) widening makes downwards extrapolation, which may jump below the greatest fixpoint. Therefore, we propose to over-approximate a decreasing iteration by narrowing, because the narrowing can only do interpolations that prevent jumping below any fixpoint.
The narrowing operator \(\triangle _{\mathbb {I}}\in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \times (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}) \mapsto (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}})\) on the abstract invariant domain satisfies the following soundness and termination conditions:
(i) \(\forall x^{\sharp }, y^{\sharp } \in (\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}).\; y^{\sharp }\, \dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\, x^{\sharp } \Rightarrow y^{\sharp }\; \dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\; (x^{\sharp }\; \triangle _{\mathbb {I}}\; y^{\sharp })\; \dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\; x^{\sharp }\);
(ii) for any sequence \((x^{\sharp }_i)_{i \in \mathbb {N}}\), the sequence \((y^{\sharp }_i)_{i \in \mathbb {N}}\) defined as \(y^{\sharp }_0 = x^{\sharp }_0\) and \(\forall i \in \mathbb {N}.\; y^{\sharp }_{i + 1} = y^{\sharp }_i\; \triangle _{\mathbb {I}}\; x^{\sharp }_{i + 1}\) converges in finite time.
The implementation of \(\triangle _{\mathbb {I}}\) naturally follows the narrowing operator \(\triangle _{\mathbb {M}}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) provided by the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\), such that \(\mathsf {I}^{\sharp }\; \triangle _{\mathbb {I}}\; \mathsf {I}^{\sharp \prime } \triangleq \lambda {l}\in \mathbb {L}.\; \mathsf {I}^{\sharp }( {l})\; \triangle _{\mathbb {M}}\; \mathsf {I}^{\sharp \prime }( {l})\).
(3) Over-approximating Abstract Backward impossible failure Accessibility Semantics. Given a postcondition specified as \(\mathsf {I}_\mathsf {post}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), the concrete backward impossible failure accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}{} = {\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) can be over-approximated by the limit of a ultimately stationary sequence \((\mathsf {I}^{\sharp }_i)_{i \in \mathbb {N}}\), where \(\mathsf {I}^{\sharp }_0 = \mathsf {I}_\mathsf {post}^{\sharp }\) and \(\forall i \in \mathbb {N}.\; \mathsf {I}^{\sharp }_{i + 1} = \mathsf {I}^{\sharp }_i\; \triangle _{\mathbb {I}}\; \mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp }_i)}\): (18) \[\begin{equation} \begin{array}{c} \forall \mathsf {I}_\mathsf {post}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;{\mbox{gfp}}^{\scriptscriptstyle \dot{\subseteq }}_{_{\scriptscriptstyle \dot{\gamma }_{\mathbb {M}}(\mathsf {I}_\mathsf {post}^{\sharp })}}\,\mathrm {F}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}\left({lim}_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}\,\lambda \mathsf {I}^{\sharp }.\; \mathsf {I}^{\sharp }\,\triangle _{\mathbb {I}}\; \mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\left(\mathsf {I}^{\sharp }\right)}\right).\end{array} \end{equation}\]
In the rest of this article, the over-approximating abstract backward impossible failure accessibility semantics \(\mathcal {\hat {S}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\) refers to the following definition, which gives an over-approximation of \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\) and can be computed in finite time: \[\begin{equation*} \begin{array}{@{}rcl} \mathcal {\hat {S}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}&\in &\left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\mapsto \left(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{over-approximating IF semantics}\\ \mathcal {\hat {S}}^{\sharp}\mathop{\leftarrow}\limits_{if}s [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\sharp }}{}&\triangleq &{lim}_{\scriptscriptstyle \mathsf {I}_\mathsf {post}^{\sharp }}\,\lambda \mathsf {I}^{\sharp }.\; \mathsf {I}^{\sharp }\,\triangle _{\mathbb {I}}\; \mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{(\mathsf {I}^{\sharp }).}\end{array} \end{equation*}\]
In practice, the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) may not have an effective narrowing operator \(\triangle _{\mathbb {M}}\), which makes the corresponding \(\triangle _{\mathbb {I}}\) of no practical use. If this is the case, like in the forward reachability analysis, then we can just omit the narrowing operator and iterate the function \(\mathrm {\hat {F}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}\) until the analysis result is satisfactory (typically, the number of iterations needed is quite low).
(Access Control, Continued).
Using the refined abstract postcondition \(\mathsf {I}_\mathsf {post}^{\sharp \prime }\) from Example 16 that represents the trace property “the access to o fails,” an over-approximating backward impossible failure accessibility analysis \(\mathcal {\hat {S}}^{\sharp}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\sharp \prime }}{}\) creates the result displayed in Table 7
Table 7. Over-approximating Abstract Backward Impossible Failure Accessibility Semantics for “the Access to o Fails” with Disjunctive Completion
5 Trace Partitioning
The forward reachability analysis discussed in Section 4 intends to compute an over-approximation of reachable states of the program, while the information about the execution history and concrete flow paths is lost, making the correspondingly generated over-approximating reachability semantics in some cases imprecise to determine if a behavior really occurs or not.
In References [53, 70], Mauborgne and Rival propose a trace partitioning domain, which allows partitioning traces by the history of memory and control states. Essentially, for any given transition system, they build an extended transition system by augmenting the program points (i.e., control states, labels) with partitioning tokens, which can distinguish traces by the control flow or variable values. This technique has been successfully implemented in the abstract interpretation-based Astrée analyzer [22, 23], significantly improving the precision of analysis and reducing the execution time.
This section briefly summarizes the key idea of trace partitioning, proposes to represent elements in the trace partitioning abstract domain as trace partitioning automata, and extends the existing types of partitioning directive to include program invariants, which facilitates determining responsibility in the abstract (see Section 7). For more details about the theoretical framework and practical implementation of the trace partitioning domain, we refer to Reference [70].
5.1 The Trace Partitioning Abstract Domain
This section starts with a simple motivating example from Reference [70] and illustrates how the trace partitioning improves the precision of forward reachability analysis.
In the program of Figure 16, it is obvious that the value of \({sgn}\) is either 1 or -1 at point \({l}_{5}\), and in particular it cannot be 0 in the concrete. Therefore, dividing by \({sgn}\) at point \({l}_5\) is safe, and there is no possible “division by zero” error in the program. However, if we use the interval domain as the abstract environment domain, then by the over-approximating forward reachability analysis introduced in Section 4.2.2, we would get the reachability semantics (or, say, program invariants) \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) listed in the Table 8, where \(\mathsf {I}_\mathsf {pre}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) is defined such that \(\mathsf {I}_\mathsf {pre}^{\sharp }( {l}_0) = \top ^{\sharp }_{\mathbb {M}}\) and \(\mathsf {I}_\mathsf {pre}^{\sharp }( {l}) = \bot ^{\sharp }_{\mathbb {M}}\) for \({l}\ne {l}_0\). Particularly, the value of \({sgn}\) at point \({l}_5\) belongs to the interval \([{-1};{1}]\), which is not precise enough to exclude the possibility of “division by zero” in the program.
Fig. 12. Motivating example for trace partitioning.
Table 8. Abstract Forward Reachability Semantics of the Motivating Example
An intuitive idea to solve the imprecision problem is to relate the value of \({sgn}\) to the way it is computed. In this very example here, if the true branch of the conditional was taken, then the value of \({sgn}\) at point \({l}_5\) is -1; otherwise, it is 1. That is to say, we partition the set of all possible concrete traces into two parts: in one partition, the true branch is taken; in the other partition, the false is taken. For each partition, the standard over-approximating forward reachability analysis can be performed, and the analysis results together would be more precise.
To generalize the idea of partitioning, Mauborgne and Rival [53, 70] propose a trace partitioning abstract domain, which is flexible and general to analyze and verify semantic properties in the same way as other classic abstract domains. In the following, we will briefly describe how to construct the trace partitioning abstract domain.
(1) Extended Transition Systems. Suppose \({T}\,\) is a set of partitioning tokens, which are used to capture useful information about the history of execution and to guide trace partitioning. In practice, each partitioning token \({t}\in {T}\,\) is defined as a stack of partitioning directives that have been encountered during the execution, and all the possible partitioning directives are listed in Figure 17, each of which creates a partition as its name implies. For example, in the case of a conditional at point \({l}\), by the partitioning directives \(\textrm {part}\langle \textrm {If},\: {l},\:\mathsf {tt}\rangle\) and \(\textrm {part}\langle \textrm {If},\: {l},\:\mathsf {ff}\,\rangle\), two partitions are created right after testing the Boolean condition, which, respectively, correspond to “true branch of the conditional at point \({l}\)” and “false branch of the conditional at point \({l}\).”
Fig. 13. Partitioning directives \( {d}\in {D} \) and tokens \( {t}\in {T}. \)
Given a set of partitioning tokens T, the extended transition systems are defined as transition systems over the set of program points (or, control states, labels) extended with the partitioning tokens T. More formally, let \(\mathbb {L}_{ {T}}\triangleq \mathbb {L}\times {T}\,\) be the set of extended program points, \(\mathbb {S}_{ {T}}\triangleq \mathbb {L}_{ {T}}\times \mathbb {M}\) be the set of extended states, \(\mathbb {S}^{i}_{ {T}}\subseteq \mathbb {S}_{ {T}}\) be the set of extended initial states, and \(\rightarrow _{ {T}}\, \in \wp (\mathbb {S}_{ {T}}\times \mathbb {S}_{ {T}})\) be the transition relation among extended states. Then, we define an extended transition system as a tuple \(\langle {T},\:\mathbb {S}^{i}_{ {T}},\: \rightarrow _{ {T}}\rangle\). In addition, a forget function \(\pi _{\tau }\) can be defined to remove the partitioning tokens from extended program points, extended states, and transition relations, such that an extended transition system \(\langle {T},\:\mathbb {S}^{i}_{ {T}},\: \rightarrow _{ {T}}\rangle\) can be transformed back into a standard transition system \(\langle \mathbb {S}^{i},\:\rightarrow \rangle\).
(2) Trace Partitioning Abstract Domain. An extended transition system \(\textrm {P}_{ {T}}= \langle {T},\:\mathbb {S}^{i}_{ {T}},\: \rightarrow _{ {T}}\rangle\) is a covering of the original transition system \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\) if and only if every initial state \({s}\in \mathbb {S}^{i}\) has at least one corresponding initial state \({s}^{\prime }\in \mathbb {S}^{i}_{ {T}}\) such that \(\pi _{\tau }( {s}^{\prime }) = {s}\), and every transition step in \(\textrm {P}\) is simulated (mimicked) by at least one transition step in \(\textrm {P}_{ {T}}\). Therefore, if \(\textrm {P}_{ {T}}\) is a covering of \(\textrm {P}\), then every trace in \(\textrm {P}\) is simulated by one or more traces in \(\textrm {P}_{ {T}}\). For the formal definitions of covering and partition see Section 3.2 of Reference [70].
The trace partitioning abstract domain \(\mathbb {D}^{\sharp }\) is the set of tuples \(\langle \textrm {P}_{ {T}},\:\Phi ^{\sharp }\rangle\), where T is a set of partitioning tokens, \(\textrm {P}_{ {T}}= \langle {T},\:\mathbb {S}^{i}_{ {T}},\: \rightarrow _{ {T}}\rangle\) is a covering of the original transition system \(\textrm {P}= \langle \mathbb {S}^{i},\:\rightarrow \rangle\), and \(\Phi ^{\sharp }\in \mathbb {L}_{ {T}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) is a function mapping each extended program point \(\langle {l},\: {t}\rangle\) of \(\textrm {P}_{ {T}}\) into an abstract environment in \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) that approximates the set of environments observed at point \(\langle {l},\: {t}\rangle\).
Taking the program in Figure 16 as an example, if we use partitioning directives designed for the conditional, then the forward reachability analysis with trace partitioning would construct the corresponding \(\Phi ^{\sharp }\) function, which is listed in the Table 9.
Table 9. Partitioned Forward Reachability Semantics of the Motivating Example
From the above table, we can see that there are two extended program points for \({l}_5\): \(\langle {l}_5,\:\textrm {part}\langle \textrm {If},\: {l}_0,\:\mathsf {tt}\rangle \rangle\) and \(\langle {l}_5,\:\textrm {part}\langle \textrm {If},\: {l}_0,\:\mathsf {ff}\,\rangle \rangle\), and the corresponding abstract environments indicates the value of \({sgn}\) is either -1 or 1, which is exactly the desired result.
However, if we have successive creations of partitions in the extended transition system, the cost would be prohibitive in practice. For instance, the partitioning of a conditional multiplies by 2 the number of partitions in the current flow, thus a series of n conditionals would lead to \(2^{n}\) partitions, which brings an exponential cost. To solve this issue, we can merge partitions together when they are no longer necessary, which is implemented by popping (or removing) partitioning directives from the token. For example, at point \({l}_6\) of the program in Figure 16, the partitions based on “which branch of the conditional was taken” are not expected to lead to improvement in the precision of further analysis, so we can merge those two partitions and replace the last two rows of Table 9 by \(\Phi ^{\sharp }(\langle {l}_6,\:\epsilon \rangle) = {x}\in [{-\infty };{\infty }]\wedge {sgn}\in [{-1};{1}]\wedge {y}\in [{0};{\infty }]\), which is still more precise than the standard forward reachability analysis.
5.2 The Trace Partitioning Automata
To facilitate determining abstract responsibility on graph structures (in Section 7), this section proposes to represent the result of forward reachability analysis with trace partitioning as automata, which are called trace partitioning automata.
More formally, each element \(\langle \textrm {P}_{ {T}}= \langle {T},\:\mathbb {S}^{i}_{ {T}},\:\rightarrow _{ {T}}\rangle ,\:\Phi ^{\sharp }\rangle\) in the trace partitioning abstract domain \(\mathbb {D}^{\sharp }\) can be represented as an automaton \(\mathcal {A}= \langle \mathcal {Q}^{i},\:\delta \rangle\), where:
The set of initial nodes (extended initial abstract states) \(\mathcal {Q}^{i}= \lbrace \langle { {l}}^{i},\: {t},\:\mbox{M}^{\sharp }\rangle \in \mathbb {L}_{ {T}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}\mid \exists \rho \in \mathbb {M}.\; \langle { {l}}^{i},\: {t},\:\rho \rangle \in \mathbb {S}^{i}_{ {T}}\wedge \mbox{M}^{\sharp }= \Phi ^{\sharp }(\langle { {l}}^{i},\: {t}\rangle)\rbrace\) such that every initial state \(\langle { {l}}^{i},\: {t},\:\rho \rangle\) in \(\textrm {P}_{ {T}}\) is represented by an initial node, which is associated with an abstract environment element \(\mbox{M}^{\sharp }= \Phi ^{\sharp }(\langle { {l}}^{i},\: {t}\rangle)\). By the property of \(\Phi ^{\sharp }\) in the trace partitioning abstract domain, it is guaranteed that \(\rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp })\).
The set of edges (extended abstract transition relations) \(\delta = \lbrace \langle {l},\: {t},\:\mbox{M}^{\sharp }\rangle \rightarrow \langle {l}^{\prime },\: {t}^{\prime },\:\mbox{M}^{\sharp \prime }\rangle \in (\mathbb {L}_{ {T}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}) \times (\mathbb {L}_{ {T}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}) \mid \exists \rho , \rho ^{\prime }\in \mathbb {M}.\; \langle {l},\: {t},\:\rho \rangle \rightarrow _{ {T}}\langle {l}^{\prime },\: {t}^{\prime },\:\rho ^{\prime }\rangle \; \wedge \; \mbox{M}^{\sharp }= \Phi ^{\sharp }(\langle {l},\: {t}\rangle) \wedge \mbox{M}^{\sharp \prime } = \Phi ^{\sharp }(\langle {l}^{\prime },\: {t}^{\prime }\rangle)\rbrace\) such that every concrete transition relation in \(\textrm {P}_{ {T}}\) has a corresponding edge in the automaton.
Again, consider the program in Figure 16: Its partitioned forward reachability analysis result from Table 9 can be represented as a trace partitioning automaton, which is depicted as in Figure 18. For the sake of concision, instead of explicitly drawing partitioning tokens inside the nodes, we comment some edges with “push \({d}\,\)” such that every node after the edge has the partitioning directive d pushed into its stack of directives (i.e., its partitioning token). For instance, in Figure 18, all the nodes after the edge commented with “push \(\textrm {part}\langle \textrm {If},\: {l}_0,\:\mathsf {tt}\rangle\)” has \(\textrm {part}\langle \textrm {If},\: {l}_0,\:\mathsf {tt}\rangle\) in their partitioning tokens.
Fig. 14. Trace partitioning automaton for the motivating example without merge.
In addition, to represent the merge of partitions, we comment some edges with “pop \({d}\,\)” such that the partitioning directive d is popped from the stack of directives of every node after the edge. For instance, Figure 19 depicts the trace partitioning automaton for the program in Figure 16 with partitions merged at point \({l}_6\), so the partitioning token in the node \({l}_6\) is \(\epsilon\) (i.e., its stack of partitioning directives is empty).
Fig. 15. Trace partitioning automaton for the motivating example with merge.
5.3 The Extension of Partitioning Directives
As illustrated in Reference [70], partitioning directives are inserted in the source code as special comments in a preprocessing phase. Specifically, among the six types of partitioning directives described in Figure 17, five of them partition traces based on the control flow, and only \(\textrm {part}\langle \textrm {Val},\: {l},\: {x}=n\rangle\) introduces a partition guided by the value of a variable x at some point \({l}\). Although these partitioning directives have successfully handled a broad range of cases, there are still many cases that cannot be well coped with, and we would like to introduce a new partitioning directive to partition traces by environment properties (which are represented by abstract environment elements).
For example, to improve the precision of forward reachability analysis for the access control program in Figure 4, it is intuitive to partition traces by some environment properties that can be easily expressed by abstract environment elements in \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) (i.e., \({i1}\in [ {-\infty }{0}]\) and \({i1} \in [{1};{\infty }]\) at point \({l}_3\); \({apv}\in [{1}{\infty }]\wedge {i2}\in [{-\infty }{0}]\), \({apv}\in [{-\infty }{0}]\) and \({i2}\in [ {1}{\infty }]\) at point \({l}_5\)), and such properties (e.g., \({apv}\in [ {1}{\infty }]\wedge {i2}\in [{-\infty }{0}]\)) may not be expressed by directives of form \(\textrm {part}\langle \textrm {Val},\: {l},\: {x}=n\rangle\) when more than one variables are used in partitioning. Of course, the access control program can be equivalently transformed into a program with conditionals (by replacing ternary operators with conditionals), then the problem of partitioning guided by environment properties is transformed to partitioning based on the branch of conditionals. However, this is not always the case. For example, consider a simple program “\({l}_{1}: {z} := {x} - {y};\; {l}_{2}:\)” and suppose we are interested in whether the value of \({z}\) is positive or negative at point \({l}_2\), then it is of value to create partitions guided by \({x} \ge {y}\) and \({x} \lt {y}\) at point \({l}_1\). Such partitions can be expressed by abstract environment elements in the polyhedra/octagons domain, but not by the existing partitioning directives.
Therefore, here we propose a new partitioning directive of the form: \(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }\rangle\) (where \(\mbox{M}^{\sharp }\) is an abstract environment element in \(\mathcal {D}^{\sharp }_{\mathbb {M}}\)), which generates a new partition of traces such that \(\mbox{M}^{\sharp }\) is satisfied at point \({l}\). In practice, the trace partitioning introduced by a directive \(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }\rangle\) can be simply implemented by creating a new node, such that its partitioning token (i.e., the stack of partitioning directives) has this directive on the top, and the corresponding abstract environment element is the meet of \(\mbox{M}^{\sharp }\) and the standard forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) at point \({l}\).
(Access Control, Continued).
In Example 14, we have discussed the standard abstract forward reachability semantics of the access control program, in which the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) is the interval domain. Now, we can gain more precision by introducing five partitioning directives: \({d}_3: \textrm {part}\langle \textrm {Inv},\: {l}_3,\: {i1}\in [{-\infty }{0}]\rangle\), \({d}^{\prime }_3: \textrm {part}\langle \textrm {Inv},\: {l}_3,\: {i1}\in [{1}{\infty }]\rangle\), \({d}_5: \textrm {part}\langle \textrm {Inv},\: {l}_5,\: {apv}\in [{1}{\infty }]\wedge {i2}\in [{-\infty }{0}]\rangle\), \({d}^{\prime }_5: \textrm {part}\langle \textrm {Inv},\: {l}_5,\: {apv}\in [{\infty }{0}]\rangle ,\) and \({d}^{\prime \prime }_5: \textrm {part}\langle \textrm {Inv},\: {l}_5,\: {i2}\in [{1}{\infty }]\rangle\), and the corresponding partitioned forward reachability semantics is listed in Table 10
Table 10. Partitioned Forward Reachability Semantics for the Access Control Program
Compared with the standard forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) in Example 14, the partitioned forward reachability semantics is much more precise, revealing the relation between \({acs}\) and other variables, which is of significance in determining responsibility later.
Furthermore, the partitioned forward reachability semantics can be represented by a trace partitioning automaton in Figure 20. It is worth mentioning that, as what we have done in Figure 19, the partitions can be merged after the access check to \({acs}\) finishes at point \({l}_8\), such that all the partitioning directives pushed at point \({l}_3\) or \({l}_5\) can be popped from the partitioning tokens at point \({l}_8\).
Fig. 16. Trace partitioning automaton for the access control program.
6 User Specification of Behaviors and Cognizance
In Section 3.2, the responsibility is defined as an abstraction \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \mathcal {B}, \mathcal {T}}\), where \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\in \wp (\mathbb {S}^{\ast \infty })\) is the concrete maximal trace semantics, \(\mathcal {L}^{\mathsf {Max}}\in \wp (\wp (\mathbb {S}^{\ast \infty }))\) is a lattice of system behaviors (i.e., trace properties), \({\mathbb {C}}\in \mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty })\) is the cognizance function of a given observer, \(\mathcal {B}\in \mathcal {L}^{\mathsf {Max}}\) is the behavior whose responsibility is of interest, and \(\mathcal {T}\in \wp ([\![ \textrm {P}]\!] ^{\mathsf {Max}})\) is the set of valid traces to be analyzed. Among these parameters, the maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) is inherent in the given program \(\textrm {P}\), which can be soundly over-approximated by the abstract trace partitioning automata introduced in Section 5. Meanwhile, all the other parameters indicate the objective of responsibility analysis and can be specified only by users. However, it is difficult, if not impossible, to require users to explicitly specify system behaviors and the cognizance function in the concrete. Therefore, to implement the static responsibility analysis, the very first step is to specify \(\mathcal {L}^{\mathsf {Max}}\), \({\mathbb {C}}\), \(\mathcal {B}\), and \(\mathcal {T}\) in the abstract.
For the sake of simplicity, here it is assumed that we would like to analyze all the maximal traces of \(\textrm {P}\), thus \(\mathcal {T}= [\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and there is no need for the users to explicitly designate the traces to be analyzed. As for the behavior \(\mathcal {B}\) of interest, the lattice \(\mathcal {L}^{\mathsf {Max}}\) of behaviors and the cognizance function \({\mathbb {C}}\), this section discusses how to specify them with the abstract invariant domain \(\mathcal {D}^{\sharp }_{\mathbb {I}}= \langle \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}},\:\dot{\sqsubseteq }^{\sharp }_{\mathbb {M}}\rangle\) introduced in Section 4.1.3.
6.1 User Specification of Behaviors
6.1.1 The Abstract Behavior of Interest.
The behavior of interest is specified by an abstract invariant \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), which associates every program point with an abstract environment element. The corresponding behavior \(\mathcal {B}\) in the concrete is \([\![ \textrm {P}]\!] ^{\mathsf {Max}} \cap \gamma _{\mathbb {IV}}\circ \dot{\gamma }_{\mathbb {M}}(\mathcal {B}^{\sharp }) = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \forall \langle {l},\:\rho \rangle \in \sigma .\; \rho \in \gamma _{\mathbb {M}}(\mathcal {B}^{\sharp }( {l}))\rbrace\), i.e., the set of concrete valid maximal traces such that every state satisfies the abstract environment assigned by \(\mathcal {B}^{\sharp }\) at the corresponding program point.
In practice, the user can explicitly designate the chosen program points with some non-trivial abstract environments from \(\mathcal {D}^{\sharp }_{\mathbb {M}}\), while all other program points are implicitly associated with \(\top ^{\sharp }_{\mathbb {M}}\).
(Access Control, Continued).
Let us consider the access control program in Figure 4 again. There are a few behaviors that the user may be interested in: (1) If the user is interested in “the access to o fails,” like the abstract postcondition \(\mathsf {I}_\mathsf {post}^{\sharp }\) defined in Example 16, then the abstract behavior \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) can be defined such that \(\mathcal {B}^{\sharp }( {l}_8)\) is explicitly designated as “\({acs} \in [{-\infty };{0}]\),” while \(\mathcal {B}^{\sharp }( {l})\) is implicitly assigned to \(\top ^{\sharp }_{\mathbb {M}}\) for other program points \({l}\ne {l}_8\). (2) As we have discussed in Section 3, the responsibility for the complement behavior “the access to o succeeds” is different from the one for “the access to o fails.” Thus, if the user is interested in “the access to o succeeds” instead, then the abstract behavior shall be specified such that \(\mathcal {B}^{\sharp }( {l}_8)\) is “\({acs} \in [{1};{\infty }]\),” while \(\mathcal {B}^{\sharp }( {l})\) is \(\top ^{\sharp }_{\mathbb {M}}\) for other program points \({l}\ne {l}_8\). (3) Similarly, to analyze “the read and write access to o is granted” that requires the value of \({acs}\) is greater than or equal to 2 at point \({l}_8\), the corresponding abstract behavior \(\mathcal {B}^{\sharp }\) shall be specified such that \(\mathcal {B}^{\sharp }( {l}_8)\) is “\({acs} \in [{2};{\infty }]\),” while \(\mathcal {B}^{\sharp }( {l}) = \top ^{\sharp }_{\mathbb {M}}\) for \({l}\ne {l}_8\).
It is worth mentioning that, although in the above example there is only one program point that is assigned with non-trivial abstract environment elements, in general the user can express behaviors that are related to multiple program points. However, we have to admit that the expressiveness of abstract behaviors depends on the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\), and not every concrete behavior (i.e., a set of concrete traces) can be expressed by an abstract behavior. For instance, we cannot express the relation of variables by the interval domain, and it is impossible to express behaviors like “the value of \({x}\) is increasing along the execution” by the numerical invariance abstract domains.
In addition, the user specified behavior \(\mathcal {B}^{\sharp }\) is not directly used in the following backward accessibility analysis. Instead, as what we have done for \(\mathsf {I}_\mathsf {post}^{\sharp }\) in Example 16, the abstract behavior will be refined by the intersection with the abstract forward reachability semantics, which will be further illustrated in Section 7.
6.1.2 The Lattice of System Behaviors.
For the sake of conciseness, it is assumed that the user is interested in analyzing the responsibility of only one behavior, and the corresponding lattice of behaviors in the concrete consists of four elements: the top, the bottom, the behavior of interest, and the corresponding complement behavior. However, for an abstract behavior \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), its complement may not be expressible by the abstract invariant domain \(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), since most abstract environment domains (e.g., intervals, octagons, polyhedra) do not support complements. For instance, in general the complement of an interval (e.g., \({x}\in [{0};{9}]\)) is a disjunction of two intervals; the complement of a polyhedron is a disjunction of affine inequalities, which cannot be expressed by a polyhedron. Therefore, for any lattice of behaviors in the concrete, it may be impossible to construct the corresponding lattice of abstract behaviors, and we cannot require the user to specify such a lattice.
Fortunately, the abstract responsibility analysis introduced later in Section 7 does not directly use the lattice of abstract behaviors, and it is sufficient to provide only the abstract behavior \(\mathcal {B}^{\sharp }\) of interest to the analyzer. Nevertheless, to prove the soundness of abstract responsibility analysis for a given abstract behavior \(\mathcal {B}^{\sharp }\), the corresponding lattice \(\mathcal {L}^{\mathsf {Max}}\) of behaviors in the concrete can be easily built as in Figure 21.
Fig. 17. The lattice \( \mathcal {L}^{\mathsf {Max}} \) of behaviors in the concrete.
More precisely, the lattice \(\mathcal {L}^{\mathsf {Max}}\) of concrete behaviors consists of four elements: the top \(\top ^{\mathsf {Max}}\) is the maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the bottom \(\bot ^{\mathsf {Max}}\) is the empty set, the behavior \(\mathcal {B}= [\![ \textrm {P}]\!] ^{\mathsf {Max}} \cap \gamma _{\mathbb {IV}}\circ \dot{\gamma }_{\mathbb {M}}(\mathcal {B}^{\sharp }) = \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \forall \langle {l},\:\rho \rangle \in \sigma .\; \rho \in \gamma _{\mathbb {M}}(\mathcal {B}^{\sharp }( {l}))\rbrace\), and the complement behavior \(\lnot \mathcal {B}= [\![ \textrm {P}]\!] ^{\mathsf {Max}} \backslash \mathcal {B}= \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\mid \exists \langle {l},\:\rho \rangle \in \sigma .\; \rho \notin \gamma _{\mathbb {M}}(\mathcal {B}^{\sharp }( {l}))\rbrace\) is the set of valid maximal traces, in each of which there exists at least one state that does not satisfy the abstract environment assigned by \(\mathcal {B}^{\sharp }\).
(Access Control, Continued).
For the access control program, its maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) is given in example 1. If the behavior of interest is “the access to o fails” (i.e., \(\mathcal {B}^{\sharp }\) is specified such that \(\mathcal {B}^{\sharp }( {l}_8) = {acs} \in [{-\infty };{0}]\)” and \(\mathcal {B}^{\sharp }( {l}) = \top ^{\sharp }_{\mathbb {M}}\) for \({l}\ne {l}_8\)), then the corresponding concrete behavior \(\mathcal {B}= \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[7]} = \langle {l}_8,\:\rho \rangle \wedge \rho ( {acs}) \le 0\rbrace\), and the complement behavior \(\lnot \mathcal {B}= \lbrace \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Max}} \mid \exists \rho \in \mathbb {M}.\; {\sigma }_{[7]} = \langle {l}_8,\:\rho \rangle \wedge \rho ( {acs}) \gt 0\rbrace\). Together with the empty set, the four elements form the lattice of behaviors in the concrete.
6.2 User Specification of the Cognizance
In the concrete, the cognizance function \({\mathbb {C}}\in \mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty })\) of an observer essentially maps a trace σ to an equivalence class \({\mathbb {C}{(\sigma)}}\) of traces such that every trace in \({\mathbb {C}{(\sigma)}}\) is equivalent (or, say, indistinguishable) to σ according to the cognizance of that observer. Specially for an omniscient observer, every trace is distinguishable from other traces, thus the equivalence class for each trace is a singleton (i.e., \(\forall \sigma \in \mathbb {S}^{\ast \infty }.\; {\mathbb {C}}_{O} {}{\sigma } = \lbrace \sigma \rbrace\)). However, it is infeasible to require users to directly provide a cognizance function or an equivalence relation on concrete traces, hence the cognizance function needs to be specified in the abstract instead.
6.2.1 The Abstract Cognizance Function.
Formally, the abstract cognizance function \(\mathbb {C}^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\) is defined as a function mapping the program point to a set of cognizance directives \({d}_{c}\), each of which is an element of the numerical abstract domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\). It is important to note that, although both the abstract environment element \(\mbox{M}^{\sharp }\) and the cognizance directive \({d}_{c}\) are from the same abstract domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) (e.g., intervals, octagons, polyhedra), their meanings in the concrete are completely different: \(\mbox{M}^{\sharp }\) represents a set of concrete environments that satisfy a certain property, while \({d}_{c}\) essentially defines an equivalence relation on concrete environments, which is further used to define an equivalence relation on concrete traces.
To start with, we give several examples of the abstract cognizance functions and explain their concrete meanings in an informal but intuitive way, while its formal concretization back to the concrete cognizance function is defined later in this section.
(i) Consider an abstract cognizance function \({\mathbb {C}}^{\sharp}\) such that \(\mathbb {C}^{\sharp} { {l}} = \lbrace {x}\in [{-\infty };{\infty }]\rbrace\). When \({x}\in [{-\infty };{\infty }]\) is treated as an abstract environment \(\mbox{M}^{\sharp }\), then it represents a set of concrete environments, i.e., \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }) = \mathbb {M}\), which does not provide any non-trivial information. In contrary, if we take \({x}\in [{-\infty };{\infty }]\) as a cognizance directive, then it actually defines an equivalence relation on environments, such that two environments are equivalent even if their values of \({x}\) are different, as long as the values of any other variable (e.g., \({z}\)) are the same in those two environments. Thus, such an abstract cognizance function \({\mathbb {C}}^{\sharp}\) indicates that the observer does not know the value of \({x}\) at the program point \({l}\), but the value of any other variable.
(ii) For another abstract cognizance function such that \(\mathbb {C}^{\sharp} { {l}} = \lbrace {x}\in [{-\infty };{-1}], {x}\in [{0};{\infty }]\rbrace\), there are two cognizance directives assigned to point \({l}\). Take \({x}\in [{0};{\infty }]\) as an example, it does not mean the value of \({x}\) is positive or zero at point \({l}\). Instead, it means that any two environments ρ and \(\rho ^{\prime }\) at point \({l}\) are equivalent (or indistinguishable) if and only if the value of \({x}\) in both ρ and \(\rho ^{\prime }\) are positive or zero (e.g., \(\rho ( {x}) = 0\) and \(\rho ^{\prime }( {x}) = 5\)), and the values of any other variable are the same. Similarly, \({x}\in [{-\infty };{-1}]\), as a cognizance directive, means that two environments ρ and \(\rho ^{\prime }\) at \({l}\) are equivalent, as long as their values of \({x}\) are negative (e.g., \(\rho ( {x}) = -2\) and \(\rho ^{\prime }( {x}) = -5\)) and the values of any other variable are the same. Together, the abstract cognizance function \({\mathbb {C}}^{\sharp}\) indicates that the observer does not know the exact value of \({x}\) at point \({l}\), but only the sign of \({x}\) (i.e., positive or zero, or negative), as well as the exact value of other variables.
(iii) The numerical abstract domain used in previous two examples is the interval domain, and now we consider another example with octagon/polyhedron domains. Suppose the abstract cognizance function \({\mathbb {C}}^{\sharp}\) is specified such that \(\mathbb {C}^{\sharp} { {l}} = \lbrace {x}\le {y}, {y}\lt {x}\rbrace\), then the cognizance directive \({x}\le {y}\) (respectively, \({y}\lt {x}\)) means that two environments ρ and \(\rho ^{\prime }\) are equivalent if and only if \(\rho ( {x}) \le \rho ( {y})\) and \(\rho ^{\prime }( {x}) \le \rho ^{\prime }( {y})\) (respectively, \(\rho ( {y}) \lt \rho ( {x})\) and \(\rho ^{\prime }( {y}) \lt \rho ^{\prime }( {x})\)) hold, and the values of any other variable in ρ and \(\rho ^{\prime }\) are the same. That is to say, the observer does not know the exact value of \({x}\) and \({y}\) at point \({l}\), but the relation between \({x}\) and \({y}\), as well as the exact value of other variables.
In the following, we formalize the equivalence relations introduced by the abstract cognizance function and define the concretization from the abstract cognizance \(\mathbb {C}^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\) back to the corresponding concrete cognizance \({\mathbb {C}}\in \mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty })\).
Equivalence Relation on Environments. Suppose \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) is a numerical abstract domain (e.g., intervals, octagons, polyhedra). For any cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), let \(\textrm {vars}( {d}_{c})\) be the set of variables used in \({d}_{c}\). For instance, \(\textrm {vars}( {x}\in [{-\infty };{\infty }]) = \lbrace {x}\rbrace\), and \(\textrm {vars}( {x}\le {y}) = \lbrace {x}, {y}\rbrace\). Then, for every cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), we can define an equivalence relation \(\overset{ {d}_{c}}{\sim }\) on concrete environments as follows: \[\begin{equation*} \begin{array}{@{}rcl} \overset{ {d}_{c}}{\sim }&\in &\wp (\mathbb {M}\times \mathbb {M})\text{equivalence relation on environments}\\ \rho \overset{ {d}_{c}}{\sim }\rho ^{\prime }&\Leftrightarrow &\rho =\rho ^{\prime } \vee (\rho \in \gamma _{\mathbb {M}}( {d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}( {d}_{c})\wedge \forall {x}\in \mathbb {X}\backslash \textrm {vars}( {d}_{c}).\, \rho ( {x}) = \rho ^{\prime }( {x})).\end{array} \end{equation*}\]
That is to say, two environments are equivalent (indistinguishable) according to a cognizance directive \({d}_{c}\) if and only if either they are equal to each other, or both of them belong to \(\gamma _{\mathbb {M}}( {d}_{c})\) and the values of any variable not used in \({d}_{c}\) are the same.
For example, suppose the set of all variables in a program is \(\mathbb {X}=\lbrace {x}, {y}\rbrace\), and the cognizance directive \({d}_{c}\) is \({x}\in [{0};{\infty }]\) from the interval domain such that \(\textrm {vars}( {d}_{c})=\lbrace {x}\rbrace\). Let \([ {x}\mapsto {v}, {y}\mapsto {v}^{\prime }]\) be an environment such that the value of \({x}\) is \({v}\) and the value of \({y}\) is \({v}^{\prime }\). Then, we have \([ {x}\mapsto {0}, {y}\mapsto {1}] \overset{ {d}_{c}}{\sim } [ {x}\mapsto {5}, {y}\mapsto {1}]\), since the values of \({x}\) in both environments are positive or zero, and the values of \({y}\) are the same in those two environments. Besides, \([ {x}\mapsto {-1}, {y}\mapsto {1}] \overset{ {d}_{c}}{\not\sim } [ {x}\mapsto {5}, {y}\mapsto {1}]\) and \([ {x}\mapsto {-1}, {y}\mapsto {1}] \overset{ {d}_{c}}{\not\sim } [ {x}\mapsto {-2}, {y}\mapsto {1}]\), since \({x}\) is negative in at least one environment; and \([ {x}\mapsto {0}, {y}\mapsto {1}] \overset{ {d}_{c}}{\not\sim } [ {x}\mapsto {5}, {y}\mapsto {2}]\), because the values of \({y}\) in those two environments are different.
Specially, for the cognizance directive \(\bot ^{\sharp }_{\mathbb {M}}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), the set of used variables \(\textrm {vars}(\bot ^{\sharp }_{\mathbb {M}})\) is empty, thus two environments cannot be equivalent unless they are equal. Thus, the special cognizance directive \(\bot ^{\sharp }_{\mathbb {M}}\) indicates that every concrete environment is distinguishable from each other.
Equivalence Relation on Traces. Given an abstract cognizance function \(\mathbb {C}^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), an equivalence relation \(\overset{\mathbb {C}^{\sharp}}{\sim }\) on concrete traces can be defined as follows (where |σ| denotes the length of σ, and it is ∞ when the trace σ is infinite): \[\begin{equation*} \begin{array}{@{}rcl} \overset{\mathbb {C}^{\sharp}}{\sim }&\in &\wp (\mathbb {S}^{\ast \infty }\times \mathbb {S}^{\ast \infty })\text{equivalence relation on traces}\\ \sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }&\Leftrightarrow &|\sigma |=|\sigma ^{\prime }| \wedge \forall i \in [0, |\sigma |).\; ({\sigma }_{[i]} = \langle {l},\:\rho \rangle \wedge {\sigma ^{\prime }}_{[i]} = \langle {l}^{\prime },\:\rho ^{\prime }\rangle)\\ && \qquad \qquad \qquad \qquad \qquad \; \Rightarrow ( {l}= {l}^{\prime } \wedge (\exists {d}_{c}\in \mathbb {C}^{\sharp} { {l}}.\; \rho \overset{{d}_{c}}{\sim }\rho ^{\prime })).\end{array} \end{equation*}\]
That is to say, two concrete traces are equivalent (indistinguishable) according to the abstract cognizance \({\mathbb {C}}^{\sharp}\) if and only if they are of the same length and have the same control flow, and the environments at the same location are equivalent according to some cognizance directive assigned to that point.
For instance, suppose the set of all variables in a program is \(\mathbb {X}=\lbrace {x}, {y}\rbrace\), and the abstract cognizance function
is defined such that \(\mathbb {C}^{\sharp} { {l}_1} = \lbrace \bot ^{\sharp }_{\mathbb {M}}\rbrace\) and \(\mathbb {C}^{\sharp} { {l}_2} = \lbrace {x}\in [{0};{\infty }]\rbrace\). Then, a trace \(\langle {l}_1,\:[ {x}\mapsto {-1}, {y}\mapsto {1}]\rangle \rightarrow \langle {l}_2,\:[ {x}\mapsto {0}, {y}\mapsto {1}]\rangle\) is equivalent to another trace \(\langle {l}_1,\:[ {x}\mapsto {-1}, {y}\mapsto {1}]\rangle \rightarrow \langle {l}_2,\:[ {x}\mapsto {5}, {y}\mapsto {1}]\rangle\), because the two traces have the same control flow, the two environments at point \({l}_1\) are equal, and the two environments at point \({l}_2\) are equivalent according to the cognizance directive \({x}\in [{0};{\infty }]\).
Concretization to the Concrete Cognizance Function. Using the equivalence relation \(\overset{\mathbb {C}^{\sharp}}{\sim }\) introduced by the abstraction \({\mathbb {C}}^{\sharp}\), we can define the concretization function: \[\begin{equation*} \begin{array}{@{}rcl} \gamma _{\mathbb {C}}&\in &\left(\mathbb {L}\mapsto \wp \left(\mathcal {D}^{\sharp }_{\mathbb {M}}\right)\right)\mapsto \left(\mathbb {S}^{\ast \infty }\mapsto \wp (\mathbb {S}^{\ast \infty })\right)\text{cognizance concretization}\\ \gamma _{\mathbb {C}}(\mathbb {C}^{\sharp})&\triangleq &\lambda \sigma \in \mathbb {S}^{\ast \infty }.\; [\sigma ]_{\overset{\mathbb {C}^{\sharp}}{\sim }}\\ &=&\lambda \sigma \in \mathbb {S}^{\ast \infty }.\; \lbrace \sigma ^{\prime }\in \mathbb {S}^{\ast \infty }\mid \sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\rbrace .\end{array} \end{equation*}\]
According to the above definition, for any abstract cognizance function \({\mathbb {C}}^{\sharp}\), the corresponding concrete cognizance function maps a trace σ to its equivalence class \([\sigma ]_{\overset{\mathbb {C}^{\sharp}}{\sim }}\), i.e., the set of traces that are \(\overset{\mathbb {C}^{\sharp}}{\sim }\) equivalent to σ.
Here, we have to admit that, compared with the concrete cognizance function that could map a trace to an arbitrary set of traces, the expressiveness of our abstract cognizance function is restricted: Only traces with the same control flow can be specified as equivalent in the abstract, but it is expressive enough to cover many interesting cases. An alternative way to specify the abstract cognizance function is to use abstract relational invariants, which could express relational properties about two executions of a single program on different inputs [3, 4].
6.2.2 Validating Partitioning Directives with Cognizance.
As discussed in Section 5, the program’s trace semantics is soundly over-approximated by trace partitioning automata, which can be computed by the abstract forward (possible success) reachability analysis with trace partitioning. Hence, every valid maximal trace is represented by at least one (and possibly more than one) paths in the automaton, and every path in the automaton represents a set of concrete traces, which may include invalid concrete trace due to the over-approximation.
To implement the cognizance function \({\mathbb {C}}^{\sharp}\) in the abstract responsibility analysis, the key is to guarantee that: For any two concrete traces σ and \(\sigma ^{\prime }\) that are equivalent (indistinguishable) to each other according to \({\mathbb {C}}^{\sharp}\) (i.e., \(\sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\)), they must be represented by the same path in the trace partitioning automaton.
Since the structure of trace partitioning automata is decided by the partitioning directives, we need to make sure that during the execution of any two equivalent traces, every time when a partitioning directive \({d}_{p}\) is encountered, the two traces must belong to the same partition (i.e., both of them are in the partition generated by \({d}_{p}\), or neither of them are in the partition generated by \({d}_{p}\)). If such a property holds, then the partitioning directive \({d}_{p}\) is said to be valid with respect to the cognizance \({\mathbb {C}}^{\sharp}\) and will be used to generate trace partitioning automata; otherwise, it is invalid and will be either removed or revised before it is used in generating trace partitioning automata.
By the definition of \(\,\overset{\mathbb {C}^{\sharp}}{\sim }\), equivalent traces are assumed to have the same control flow. Thus, for all partitioning directives related with the control states (e.g., a partitioning directive \(\textrm {part}\langle \textrm {If},\: {l},\:b\rangle\) that partitions traces by the branch of a conditional), every two equivalent traces are ensured to belong to the same partition. That is to say, for any cognizance function, all the control-state-related partitioning directives are valid. Therefore, when implementing the cognizance function in the abstract responsibility analysis, we only need to check the validity of partitioning directives related with memory states (i.e., environments) that is of the form “\(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }\rangle\),” while the directive of the form “\(\textrm {part}\langle \textrm {Val},\: {l},\: {x}=n\rangle\)” can be treated as a special case of “\(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }\rangle\).”
In this section, we formalize the validity of a partitioning directive \({d}_{p}\) with respect to a given cognizance directive \({d}_{c}\) and propose a sound approach to check the validity in the abstract.
(1) The Definition of Validity of Partitioning Directives. As explained above, all the control-state-related partitioning directives in Figure 17 are always valid, and here we only need to consider the validity of partitioning directives that are related with environments. Intuitively, a partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) creates a partition at point \({l}\) such that the environment property \(\mbox{M}^{\sharp }_{p}\) holds, and this partition is valid if and only if it does not partition any equivalence class of environments into two separate parts. That is to say, every equivalence class of environments must be either a subset of \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) or completely disjoint from \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\).
A partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to a cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) if and only if (19) \[\begin{equation} \begin{array}{c} \forall \rho \in \mathbb {M}.\;[\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right)\;\vee \;[\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right) = \emptyset ,\end{array} \end{equation}\] where \([\rho ]_{\overset{{d}_{c}}{\sim }} = \lbrace \rho ^{\prime }\in \mathbb {M}\mid \rho \overset{{d}_{c}}{\sim }\rho ^{\prime }\rbrace\) and \(\rho \overset{{d}_{c}}{\sim }\rho ^{\prime }\Leftrightarrow \rho =\rho ^{\prime } \vee (\rho \in \gamma _{\mathbb {M}}({d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}({d}_{c})\wedge \forall {x}\in \mathbb {X}\backslash \textrm {vars}({d}_{c}).\, \rho ( {x}) = \rho ^{\prime }( {x}))\).
For example, for a cognizance directive \({d}_{c}= {x}\in [{0};{\infty }]\), the partitioning directives \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x}\in [{-1};{\infty }]\rangle\), \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x}\in [{-\infty };{-2}]\rangle ,\) and \(\textrm {part}\langle \textrm {Inv},\: {l},\: {y}\in [{1};{\infty }]\rangle\) are valid, since none of these partitioning directives would partition any equivalence class incurred by \(\overset{{d}_{c}}{\sim }\). Meanwhile, partitioning directives \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x}\in [{1};{\infty }]\rangle\) and \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x}\in [{-9};{9}]\rangle\) are invalid: For example, \([ {x}\mapsto {0}, {y}\mapsto {1}]\) is equivalent to \([ {x}\mapsto {5}, {y}\mapsto {1}]\) according to \(\overset{{d}_{c}}{\sim }\), but \([ {x}\mapsto {5}, {y}\mapsto {1}]\) belongs to the partition generated by \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x}\in [{1};{\infty }]\rangle\) while \([ {x}\mapsto {0}, {y}\mapsto {1}]\) does not belong to it.
In practice, it is difficult or even impossible to directly check if the condition (19) holds or not, since the number of equivalence classes (or, say, the size of quotient set of \(\mathbb {M}\) by the equivalence relation \(\overset{{d}_{c}}{\sim }\)) is huge, making the cost of directly checking the condition (19) prohibitive. In the following, we try to transfer (19) into equivalent forms, which are easier to check in practice.
By the definition of \(\overset{{d}_{c}}{\sim }\), it is trivial that: For every environment \(\rho \in \mathbb {M}\backslash \gamma _{\mathbb {M}}({d}_{c})\), its equivalence class \([\rho ]_{\overset{{d}_{c}}{\sim }}=\lbrace \rho \rbrace\). Since a singleton is either a subset of another set or completely disjoint from that set, the condition “\([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\;\vee \;[\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset\)” trivially holds for every partitioning directive \(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) where \(\mbox{M}^{\sharp }_{p}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\).
Therefore, the condition (19) is equivalent to the the following simplified one: (20) \[\begin{equation} \begin{array}{c} \forall \rho \in \gamma _{\mathbb {M}}({d}_{c}).\;[\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right)\;\vee \;[\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right) = \emptyset .\end{array} \end{equation}\]
Compared with checking the condition (19), the cost of checking the condition (20) is lower: Instead of checking the quotient set of \(\mathbb {M}\) by \(\overset{{d}_{c}}{\sim }\), now we need to check only the quotient set of \(\gamma _{\mathbb {M}}({d}_{c})\) by \(\overset{{d}_{c}}{\sim }\), whose size is reduced.
Further Refinement on the Definition. First, it is not hard to find that, for any abstract environment element \(\mbox{M}^{\sharp }_{p}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), we have: (21) \[\begin{equation} \begin{array}{c} \forall \rho \in \mathbb {M}.\; \left(\forall {x}\in \textrm {vars}\left(\mbox{M}^{\sharp }_{p}\right).\; \rho ( {x}) = \rho ^{\prime }( {x})\right) \Rightarrow \left(\rho \in \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right) \Leftrightarrow \rho ^{\prime }\in \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right)\right).\end{array} \end{equation}\]
The intuition is that, whether an environment belongs to \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) or not (or, say, whether an environment property \(\mbox{M}^{\sharp }_{p}\) holds or not) is not affected by the value of variables that are not used in \(\mbox{M}^{\sharp }_{p}\). For example, suppose \(\mbox{M}^{\sharp }_{p} = {x} \in [{0};{\infty }]\) (where trivial constraints like “\({y} \in [{-\infty };{\infty }]\)” are assumed to be omitted in the abstract environment element), then whether an environment belongs to \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) or not is solely decided by the value of \({x}\). Hence, if two environments have the same value of \({x}\) and may have different values of other variables, then both of them or neither of them belong to \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\).
Second, given a cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) and a partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) where \(\mbox{M}^{\sharp }_{p}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), we define a new equivalence relation \(\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\) on environments: \[\begin{equation*} \begin{array}{@{}rcl} \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}&\in &\wp (\mathbb {M}\times \mathbb {M})\text{equivalence relation on environments}\\ \rho \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\rho ^{\prime }&\Leftrightarrow &\rho =\rho ^{\prime } \vee (\rho \in \gamma _{\mathbb {M}}({d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}({d}_{c})\wedge {}\\ &&\qquad \qquad \forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}).\, \rho ( {x}) = \rho ^{\prime }( {x})).\end{array} \end{equation*}\]
It is obvious that the size of each equivalence class by \(\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\) is greater than \(\overset{{d}_{c}}{\sim }\): (22) \[\begin{equation} \begin{array}{c} \forall \rho \in \mathbb {M}.\; [\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}\end{array} \end{equation}\] where \([\rho ]_{\overset{{d}_{c}}{\sim }} = \lbrace \rho ^{\prime }\in \mathbb {M}\mid \rho \overset{{d}_{c}}{\sim }\rho ^{\prime }\rbrace\) and \([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} = \lbrace \rho ^{\prime }\in \mathbb {M}\mid \rho \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\rho ^{\prime }\rbrace\).
\(\forall \rho \in \mathbb {M}.\; \forall \rho ^{\prime }\in [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}.\;\exists \rho ^{\prime \prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}.\; \forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p}).\; \rho ^{\prime }( {x}) = \rho ^{\prime \prime }( {x}).\)
Last, using the Corollary 8 and (21), we can prove that the condition (20) is equivalent to the condition (23), and get the following lemma:
A partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to a cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) if and only if (23) \[\begin{equation} \begin{array}{c} \forall \rho \in \gamma _{\mathbb {M}}({d}_{c}).\;[\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right)\;\vee \;[\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \cap \gamma _{\mathbb {M}}\left(\mbox{M}^{\sharp }_{p}\right) = \emptyset ,\end{array} \end{equation}\] where \([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} = \lbrace \rho ^{\prime }\in \mathbb {M}\mid \rho \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\rho ^{\prime }\rbrace\) and \(\rho \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\rho ^{\prime }\Leftrightarrow \rho =\rho ^{\prime } \vee (\rho \in \gamma _{\mathbb {M}}({d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}({d}_{c})\wedge \forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}).\, \rho ( {x}) = \rho ^{\prime }( {x}))\).
Intuitively, compared with checking the condition (20), the cost of checking (23) is further reduced. Essentially, for both conditions, we need to partition the set of environments \(\gamma _{\mathbb {M}}({d}_{c})\) into equivalence classes and check if there exists any equivalence class that overlaps with \(\gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\). Since the definition of \(\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\) is looser than \(\overset{{d}_{c}}{\sim }\), the size of each equivalence class created by \(\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\) is larger, thus the number of equivalence classes that need to be checked is smaller.
(2) Checking the Validity of Partitioning Directives in the Abstract. Although we have formally defined the validity of a partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) with respect to a cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), it is impractical to directly use those definitions to check the validity of partitioning directives, since it requires to compare sets of environments in the concrete. The objective of this section is to propose a sound checking approach, which guarantees that if a partitioning directive is determined as valid in the abstract, then it is indeed valid in the concrete.
To begin with, we consider the abstract environment domains \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) that have a Galois connection with the concrete environment domain, i.e.,
. Such abstract domains include but are not limited to the interval domain and the octagon domain. In this case, we have: \(\alpha _{\mathbb {M}}([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}})\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \Leftrightarrow [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) and \(\alpha _{\mathbb {M}}([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}) \sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\Rightarrow [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset\). Therefore, we can infer a sufficient condition for (23) to hold:
(24) \[\begin{equation} \begin{array}{c} \forall \rho \in \gamma _{\mathbb {M}}({d}_{c}).\;\alpha _{\mathbb {M}}\left([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}\right)\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}\;\vee \;\alpha _{\mathbb {M}}\left([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}\right) \sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}.\end{array} \end{equation}\]
More generally, for abstract domains (e.g., the polyhedron domain) that do not have a corresponding abstraction function \(\alpha _{\mathbb {M}}\in \wp (\mathbb {M})\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\), we can use the following condition instead as a sufficient condition to check (23): (25) \[\begin{equation} \begin{array}{l} \forall \rho \in \gamma _{\mathbb {M}}({d}_{c}).\; \exists {d}_{c}^{\prime } \in \mathcal {D}^{\sharp }_{\mathbb {M}}.\; [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}({d}_{c}^{\prime }) \wedge \left({d}_{c}^{\prime } \sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}\;\vee \;{d}_{c}^{\prime } \sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\right).\end{array} \end{equation}\]
Now the question is: How to find \({d}_{c}^{\prime } \in \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}({d}_{c}^{\prime })\)? Suppose \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) is a classic numerical domain (including intervals, octagons, and polyhedra), \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \lbrace {x}_1, \ldots , {x}_n\rbrace\) that are denoted as \(\vec{ {x}}\). Then, for any environment \(\rho \in \gamma _{\mathbb {M}}({d}_{c})\), its equivalence class \([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}\) can be soundly over-approximated by \({d}_{c}^{\prime } = {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}(\vec{ {x}} = \vec{ {v}})\), where \(\vec{ {v}}\) is the values of \(\vec{ {x}}\) in ρ. Therefore, we can infer another sufficient condition for (23) to hold, which is more convenient to check.
A partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to a cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) if (26) \[\begin{equation} \begin{array}{c} \forall \vec{ {v}}\in \mathbb {V}^{n}.\; {d}_{c}^{\prime } = \left({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\vec{ {x}} = \vec{ {v}}\right) \wedge \left({d}_{c}^{\prime }\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}^{\prime }\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\right),\end{array} \end{equation}\] where \(\vec{ {x}} = \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \lbrace {x}_1, \ldots , {x}_n\rbrace\).
More specifically, \(\vec{ {x}} = \vec{ {v}}\) is expressed as “\({x}_1\in [{ {v}_1};{ {v}]_1}\wedge \ldots \wedge {x}_n\in [{ {v}_n};{ {v}]_n}\)” in the interval domain, and as “\({x}_1\le {v}_1\wedge - {x}_1\le - {v}_1\wedge \ldots \wedge {x}_n\le {v}_n\wedge - {x}_n\le - {v}_n\)” in the octagon/polyhedron domain.
However, directly checking the condition (26) is still costly, thus we discuss a few special cases that are common and easy to check in practice:
(S1) If \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c}) = \emptyset\) (or, say, \(\mbox{M}^{\sharp }_{p}\) and \({d}_{c}\) do not have commonly used variables, e.g., \(\mbox{M}^{\sharp }_{p}= {x}\le 1\) and \({d}_{c}= {y}\le 0\)): In this case, \(\vec{ {x}} = \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \textrm {vars}(\mbox{M}^{\sharp }_{p})\) includes all the variables used in \(\mbox{M}^{\sharp }_{p}\), hence we have \(\forall \vec{ {v}}\in \mathbb {V}^{n}.\; (\vec{ {x}} = \vec{ {v}}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}) \vee (\vec{ {x}} = \vec{ {v}}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}})\). Since \(({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\vec{ {x}} = \vec{ {v}}) \sqsubseteq ^{\sharp }_{\mathbb {M}}\vec{ {x}} = \vec{ {v}}\), condition (26) always holds. Thus, if \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c}) = \emptyset\), then the partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\).
(S2) If \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \emptyset\) (or, say, every variable used in \(\mbox{M}^{\sharp }_{p}\) is also used in \({d}_{c}\), e.g., \(\mbox{M}^{\sharp }_{p}= {x}\le 1\) and \({d}_{c}= {x}\le 0\wedge {y}\le 0\)): In this case, \(\vec{ {x}} = \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \emptyset\), hence \({d}_{c}^{\prime } = {d}_{c}\) in the condition (26). It is obvious that the condition (26) is equivalent to \({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\). Thus, when \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \emptyset\), the partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to the cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) if and only if \({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\) holds.
(S3) If \({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\) holds: Since \({d}_{c}^{\prime } = ({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\vec{ {x}} = \vec{ {v}}) \sqsubseteq ^{\sharp }_{\mathbb {M}}{d}_{c}\), we always have \({d}_{c}^{\prime }\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}^{\prime }\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\). Thus, if \({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\), then the partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to the cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\).
To sum up the lemma 5 and special cases (S1–S3), now we propose a sound approach to check if a partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to the cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) and formalize it as a function \(\textrm {isValid}_{{d}}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto (\mathcal {D}^{\sharp }_{\mathbb {M}}\mapsto \mathbb {B})\) such that \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) returns whether the partitioning directive is valid or not. Observe that \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) returns false in Case (S2), since the condition for Case (S3) is already checked and it is false.
bool \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) {
If (\(\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c}) = \emptyset\)) return true; // Case (S1)
If (\({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\)) return true; // Case (S3)
If (\(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \emptyset\)) return false; // Case (S2)
Check (26) and return the result. // Lemma 5
}
By the proof of Lemma 5 and the explanation of (S1–S3), we know that the above approach is sound. More precisely, if the function \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) returns true, then the partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) must be valid with respect to the cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) in the concrete (def. 2).
Special Case of the Interval Domain. In particular (but not necessary), the implementation of \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) can be further simplified if the abstract environment domain \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) is the interval domain. Since the interval domain cannot express the relation among variables and every element in the interval domain is simply a conjunction of interval constraints on a set of variables, for any \(\mbox{M}^{\sharp }_{p}, {d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\), the constraints in \(\mbox{M}^{\sharp }_{p}\) can be split into two parts: \(\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})}\) denotes the constraints on the variables in \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})\), and \(\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})}\) denotes the constraints on the variables in \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})\). When the set \({\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})}\) (respectively, \({\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})}\)) is empty, \(\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})}\) (respectively, \(\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})}\)) denotes \(\top ^{\sharp }_{\mathbb {M}}\). Then, condition (26) is equivalent to: \(\forall \vec{ {v}}\in \mathbb {V}^{n}.\; ({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} \wedge \vec{ {x}} = \vec{ {v}} \sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})}) \vee ({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} = \bot ^{\sharp }_{\mathbb {M}}\wedge \vec{ {x}} = \vec{ {v}} \sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})} = \bot ^{\sharp }_{\mathbb {M}})\).
Since \((\vec{ {x}} = \vec{ {v}} \sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})}) \vee (\vec{ {x}} = \vec{ {v}} \sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c})} = \bot ^{\sharp }_{\mathbb {M}})\) always hold in the above condition, the condition (26) is equivalent to: (27) \[\begin{equation} \begin{array}{c} {d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} = \bot ^{\sharp }_{\mathbb {M}},\end{array} \end{equation}\] and the implementation of \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) for the interval domain could be simplified into checking if the condition (27) holds.
For example, if \({d}_{c}= {x}\in [{0};{\infty }] \wedge {y}\in [{0};{\infty }]\) and \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p} = {y}\in [{-5};{5}] \wedge {z}\in [{-5};{5}]\rangle\), then \(\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} = {y}\in [{-5};{5}]\), since \({\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} = \lbrace {y}\rbrace\). It is not hard to see that \({d}_{c}\not\sqsubseteq ^{\sharp }_{\mathbb {M}} {y}\in [{-5};{5}]\) and \({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}} {y}\in [{-5};{5}] = {x}\in [{0};{\infty }] \wedge {y}\in [{0};{5}]\ne \bot ^{\sharp }_{\mathbb {M}}\), thus the condition (27) does not hold, and \({d}_{p}\) is invalid with respect to \({d}_{c}\).
(Checking the Validity of Partitioning Directives).
Here, we give some examples of checking the validity of partitioning directive \({d}_{p}\) with respect to some cognizance directive \({d}_{c}\) by the approach proposed in this section.
(i) \({d}_{c}= {x}\le -1\) and \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}= {y}\le 0\rangle\): \({d}_{c}\) indicates that the observer does not know the exact value of \({x}\) if it is negative, and \({d}_{p}\) would like to generate a partition such that the value of \({y}\) is less than 0. Since \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c}) = \emptyset\) (Case (S1)) holds, the partitioning directive \({d}_{p}\) is valid with respect to \({d}_{c}\).
(ii) \({d}_{c}= {x}\le -1\) and \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}= {x}\le 0\rangle\): \({d}_{c}\) indicates that the observer does not know the exact value of \({x}\) if it is negative, and \({d}_{p}\) intends to generate a partition such that the value of \({x}\) is less than 0. It is obvious that \({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}\), thus this is case (S3) and the partitioning directive \({d}_{p}\) is valid.
(iii) \({d}_{c}= {x}\le 0\) and \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}= {x}\le -1\rangle\): \({d}_{c}\) indicates that the observer does not know the exact value of \({x}\) if it is negative or zero, and \({d}_{p}\) intends to generate a partition such that the value of \({x}\) is negative. In this example, \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \emptyset\), and it is easy to see that \({d}_{c}\not\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}\) and \({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \ne \bot ^{\sharp }_{\mathbb {M}}\), thus this is case (S2) and the partitioning directive \({d}_{p}\) is invalid with respect to \({d}_{c}\).
(iv) \({d}_{c}= {x}\le {y}\) and \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}= {x}\le {z}\rangle\): \({d}_{c}\) indicates that the observer does not know the exact value of \({x}\) and \({y}\) when \({x}\le {y}\), but knows the relation between \({x}\) and \({y}\); and \({d}_{p}\) would like to generate a partition such that \({x}\le {z}\). It is not hard to see that none of (S1–S3) holds in this example, thus we need to directly check the condition (26), which is \(\forall {v}\in \mathbb {V}.\; {d}_{c}^{\prime } = ( {x}\le {y} \wedge {z} = {v}) \wedge ({d}_{c}^{\prime }\sqsubseteq ^{\sharp }_{\mathbb {M}} {x}\le {z}\vee {d}_{c}^{\prime }\sqcap ^{\sharp }_{\mathbb {M}} {x}\le {z} = \bot ^{\sharp }_{\mathbb {M}})\). Such a condition does not hold: for example, if \({v}= 0\), then \({d}_{c}^{\prime } = ( {x}\le {y} \wedge {z} = 0)\), hence we have \({d}_{c}\not\sqsubseteq ^{\sharp }_{\mathbb {M}} {x}\le {z}\) and \({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}} {x}\le {z}= ( {x}\le {y} \wedge {z} = 0 \wedge {x}\le 0) \ne \bot ^{\sharp }_{\mathbb {M}}\). Therefore, the partitioning directive \({d}_{p}\) is invalid with respect to \({d}_{c}\).
(v) \({d}_{c}= {x}\le {y}\wedge {y}\le {z}\) and \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}= {z} \lt {x} \wedge {w} \le 0\rangle\): In this example, \(\textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}) = \lbrace {w}\rbrace\), and none of (S1–S3) holds in this example, thus we need to directly check the condition (26), which is always true, because \(\forall {v}\in \mathbb {V}.\;( {x}\le {y}\wedge {y}\le {z} \wedge {w} = {v}) \sqcap ^{\sharp }_{\mathbb {M}}( {z} \lt {x} \wedge {w} \le 0) = \bot ^{\sharp }_{\mathbb {M}}\). Therefore, the partitioning directive \({d}_{p}\) is valid with respect to \({d}_{c}\).
(3) Checking the Validity of a Partition Function in the Abstract. Up to now, we have discussed how to check if a single partitioning directive is valid with respect to a cognizance directive. For a program, the user specifies an abstract cognizance function \(\mathbb {C}^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), and there are typically more than one partitioning directive of the form \(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\), hence we need to check the validity of all these partitioning directives with respect to the whole cognizance function. For the sake of clarity, here we rephrase the set of partitioning directives of the form \(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) as a partition function \(\mathbb {P}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), such that \(\forall {l}\in \mathbb {L}.\; \forall \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}).\;\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is a partitioning directive in the program.
Formally, here we define a function \(\textrm {isValid}_{\mathbb {P}}\) that checks if a partition function \(\mathbb {P}^{\sharp }\) is valid with respect to a cognizance function \({\mathbb {C}}^{\sharp}\): \[\begin{equation*} \begin{array}{@{}rcl} \textrm {isValid}_{\mathbb {P}}&\in &\left(\mathbb {L}\mapsto \wp \left(\mathcal {D}^{\sharp }_{\mathbb {M}}\right)\right)\mapsto \left(\left(\mathbb {L}\mapsto \wp \left(\mathcal {D}^{\sharp }_{\mathbb {M}}\right)\right)\mapsto \mathbb {B}\right)\text{Validity of Partition}\\ \textrm {isValid}_{\mathbb {P}}(\mathbb {C}^{\sharp}, \mathbb {P}^{\sharp }) &\triangleq & {\left\lbrace \begin{array}{ll}\text{true} &\text{if } \forall {l}\in \mathbb {L}.\; \forall {d}_{c}\in \mathbb {C}^{\sharp} { {l}}, \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}).\; \textrm {isValid}_{{d}}\left({d}_{c}, \mbox{M}^{\sharp }_{p}\right)\\ \text{false} &\text{otherwise}.\end{array}\right.} \end{array} \end{equation*}\]
That is to say, a partition function \(\mathbb {P}^{\sharp }\) is valid with respect to an abstract cognizance function \({\mathbb {C}}^{\sharp}\) if and only if, at each program point \({l}\), every partitioning directive specified by \(\mathbb {P}^{\sharp }\) is valid with respect to every cognizance directive assigned by \({\mathbb {C}}^{\sharp}\).
Recall that the partitioning directives are designed to create new partitions when constructing trace partitioning automata, and the sole purpose of checking if a partition function \(\mathbb {P}^{\sharp }\) is valid with respect to an abstract cognizance function \({\mathbb {C}}^{\sharp}\) is to ensure that any two indistinguishable traces would not be partitioned into different partitions, thus are always represented by the same path in the constructed trace partitioning automaton.
If the partition function \(\mathbb {P}^{\sharp }\) is valid with respect to the cognizance function \({\mathbb {C}}^{\sharp}\), then every two indistinguishable traces \(\sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\) must belong to the same partition created by \(\mathbb {P}^{\sharp }\) at every program point along the execution.
Formally, \(\forall \mathbb {C}^{\sharp},\mathbb {P}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}}).\; \textrm {isValid}_{\mathbb {P}}(\mathbb {C}^{\sharp}, \mathbb {P}^{\sharp }) \Rightarrow (\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\; \sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime } \Rightarrow (\forall i\in [0, |\sigma |).\; \exists {l}\in \mathbb {L}, \rho , \rho ^{\prime } \in \mathbb {M}.\; {\sigma }_{[i]} = \langle {l},\:\rho \rangle \wedge {\sigma ^{\prime }}_{[i]} = \langle {l},\:\rho ^{\prime }\rangle \wedge \forall \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}).\; \rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \Leftrightarrow \rho ^{\prime }\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})))\).
6.2.3 Revising Partitioning Directives to Be Valid.
In the previous sections, we have introduced the method to check the validity of partitioning directives (or, say, the partition function), while the approach of creating partitioning directives will be discussed in Section 7. Intuitively, we could create partitioning directives based on the information provided by the cognizance function, such that the created partitioning directives are always valid. For example, if the cognizance function \(\mathbb {C}^{\sharp} { {l}} = \lbrace {x} \lt 0, {x} \ge 0\rbrace\) indicates that the observer knows the sign of \({x}\) at point \({l}\), but not the exact value of \({x}\). It is intuitive to create two partitions according to the sign of \({x}\) at point \({l}\): \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x} \lt 0\rangle\) and \(\textrm {part}\langle \textrm {Inv},\: {l},\: {x} \ge 0\rangle\), both of which can be simply proved to be valid with respect to \({\mathbb {C}}^{\sharp}\). However, this is not always the case, and we may want to create partitioning directives based on some other criteria, which may bring us invalid partitioning directives. Thus, a missing part here is: What shall we do if a certain partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) (or \(\mbox{M}^{\sharp }_{p}\) for short) is found invalid with respect to a cognizance directive \({d}_{c}\) at point \({l}\) (i.e., \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p}) = \text{false}\))?
Obviously, we can simply discard the partitioning directive \({d}_{p}\), and the correspondingly constructed trace partitioning automaton is still guaranteed to be sound. However, this may incur the loss of precision in the forward reachability analysis, which further affects the result of abstract responsibility analysis.
Alternatively, we can retrieve the validity by revising \(\mbox{M}^{\sharp }_{p}\). By the definition of \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\), we know that \({d}_{c}\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \vee {d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} = \bot ^{\sharp }_{\mathbb {M}}\) does not hold. That is to say, \({d}_{c}\not\sqsubseteq ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p}\) and \({d}_{c}\sqcap ^{\sharp }_{\mathbb {M}}\mbox{M}^{\sharp }_{p} \ne \bot ^{\sharp }_{\mathbb {M}}\), thus there are two possible cases:
To sum up, in this section, we have discussed the user specification of system behaviors and cognizance in the abstract, proposed a sound approach to check if the partitioning directives are valid with respect to the user specified cognizance, and sketched some possible methods to retrieve the validity for invalid partitioning directives.
7 Abstract Responsibility Analysis
The concrete responsibility analysis \({\alpha_{R}}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \mathcal {B}, \mathcal {T}}\) proposed in Section 3.2 is undecidable, and an implementation of it has to abstract sets of finite or infinite traces involved in \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), \(\mathcal {L}^{\mathsf {Max}}\), \({\mathbb {C}}\), \(\mathcal {B}\), and \(\mathcal {T}\). Up to now, we have discussed the abstraction of maximal trace semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) by trace partitioning automata that are constructed by over-approximating forward reachability analysis (Section 4.2) with trace partitioning (Section 5), the abstraction of system behaviors \(\mathcal {B}\) by abstract invariants (Section 6.1), and the abstraction of cognizance \({\mathbb {C}}\) by abstract cognizance function (Section 6.2). Moreover, it is assumed that the lattice of behaviors \(\mathcal {L}^{\mathsf {Max}}\) consists of only \(\mathcal {B}\) and its complement (besides the top and bottom), and the set of traces to be analyzed \(\mathcal {T}\) is the whole maximal trace semantics, thus all the components in responsibility analysis have been abstracted.
In this section, we propose the framework of responsibility analysis in the abstract, which essentially consists of an iteration of forward (possible success) reachability analysis with trace partitioning and backward impossible failure accessibility analysis. In addition, this abstract responsibility analysis is proved to be sound.
7.1 The Framework of Abstract Responsibility Analysis
As shown in Figure 22, given a program \(\textrm {P}\) with the user-specified behavior of interest \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) and abstract cognizance \(\mathbb {C}^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), the abstract responsibility analysis can determine the responsible entities in \(\textrm {P}\) that are potentially responsible for \(\mathcal {B}^{\sharp }\) to the cognizance of \({\mathbb {C}}^{\sharp}\).
Fig. 18. Trace framework of abstract responsibility analysis.
More precisely, the abstract responsibility analysis starts with a forward reachability analysis \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\), which produces an over-approximation of the program’s reachability semantics. Then, after refining the behavior of interest \(\mathcal {B}^{\sharp }\) by the intersection with the computed reachability semantics, we perform in parallel both an under-approximating backward impossible failure accessibility analysis \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) and an over-approximating backward impossible failure accessibility analysis \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\), and the correspondingly computed accessibility semantics (or its complement) are transformed into partitioning directives of form “\({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\).” Further, using the partitioning directives that are valid with respect to \({\mathbb {C}}^{\sharp}\), a new round of forward reachability analysis is conducted, which computes a refined reachability semantics and a trace partitioning automaton. In such an automaton, nodes created by partitioning directives from the complement of \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) are marked as left bounds, while nodes created by partitioning directives from \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) are marked as right bounds. It follows that, along each path in the automaton, the responsible entities must be located after the left bounds (if any) and before the right bounds (if any). Thus, at this point we can determine responsible entities in the trace partitioning automaton and stop if we are satisfied with the results or the cost exceeds the pre-specified threshold. Otherwise, we start a new round of backward-forward analysis with the behavior \(\mathcal {B}^{\sharp }\) that is refined again by the new reachability semantics, which may improve the precision of responsibility analysis result.
It is not hard to see that most components in this framework of abstract responsibility analysis have been discussed in previous sections. In the rest of this section, we summarize these components and illustrate how they collaborate to determine responsibility in the abstract.
7.2 The Preprocessing Phase
The abstract responsibility analysis starts with a preprocessing phase, in which the user specifies the behavior of interest and the observer’s cognizance, and a preliminary forward reachability analysis is conducted to compute the reachability semantics.
The abstract behavior \(\mathcal {B}^{\sharp }\) and the abstract cognizance \({\mathbb {C}}^{\sharp}\) have been elaborated in Section 6, and the over-approximating forward reachability analysis \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) has been formalized in Section 4.2, thus here we reuse them and supplement with some practical tips that could facilitate the coming analysis phases.
For any program \(\textrm {P}\) to be analyzed, we insert a dummy initial program point \({l}_0\) followed by a dummy action that does not affect the program execution (e.g., \(\textrm {skip}\)) in front of \(\textrm {P}\), such that the variable initialization action at the beginning of program execution is explicitly mimicked by this dummy action. Therefore, when the dummy initial action is determined as responsible for a behavior \(\mathcal {B}^{\sharp }\), it means that whether \(\mathcal {B}^{\sharp }\) occurs or not may be decided by the variable initialization.
In addition, for the over-approximating forward reachability analysis \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\), the abstract precondition \(\mathsf {I}_\mathsf {pre}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) is always defined such that the abstract environment element for the dummy initial point is the top (i.e., \(\mathsf {I}_\mathsf {pre}^{\sharp }( {l}_0) = \top ^{\sharp }_{\mathbb {M}}\)) and it is the bottom for all other program points (i.e., \(\mathsf {I}_\mathsf {pre}^{\sharp }( {l}) = \bot ^{\sharp }_{\mathbb {M}}\) for \({l}\ne {l}_0\)). Moreover, the precision of this forward reachability analysis can be improved by trace partitioning, which is optional. Although until this step we have not obtained any partitioning directives that are related with memory states and of form “\(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\),” we can still conduct the trace partitioning by partitioning directives related with the control flow (e.g., \(\textrm {part}\langle \textrm {If},\: {l},\:b\rangle\) and \(\textrm {part}\langle \textrm {While},\: {l},\:n\rangle\)), which can be derived as in the preprocessing phase of Reference [70].
(Access Control, Continued).
For the access control program in Figure 4, we insert a dummy initial point \({l}_0\) as well as a dummy action before the point \({l}_1\), which has no affect on the result of forward reachability analysis in this phase. Suppose the user is interested in the behavior “the access to o fails,” then the user can specify the abstract behavior \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\mathcal {B}^{\sharp }( {l}_8) = {acs} \in [{-\infty };{0}]\), while \(\mathcal {B}^{\sharp }( {l}) = \top ^{\sharp }_{\mathbb {M}}\) for other program points \({l}\ne {l}_8\). Here, we consider two types of observers: an omniscient observer, whose abstract cognizance function \(\mathbb {C}_0^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\) is specified such that \(\mathbb {C}_0^{\sharp} { {l}} = \lbrace \bot ^{\sharp }_{\mathbb {M}}\rbrace\) for every program point \({l}\in \mathbb {L}\); and an observer that does not know the input of the 1st admin, and the corresponding abstract cognizance function \(\mathbb {C}^{\sharp} \in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\) is defined such that, if \({l}\in \lbrace {l}_0, {l}_1, {l}_2\rbrace\), then \(\mathbb {C}^{\sharp} { {l}} = \lbrace \bot ^{\sharp }_{\mathbb {M}}\rbrace\), otherwise \(\mathbb {C}^{\sharp} { {l}} = \lbrace {i1}\in [{-1};{2}]\rbrace\).
Since there is no conditional or while loop in the access control program, we do the forward reachability analysis without trace partitioning, and the corresponding forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) is listed in Table 11
| \({l}\) | \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) |
|---|---|
| \({l}_0\) | \(\top ^{\sharp }_{\mathbb {M}}\) |
| \({l}_1\) | \(\top ^{\sharp }_{\mathbb {M}}\) |
| \({l}_2\) | \({apv}\in [{1};{1}]\) |
| \({l}_3\) | \({apv}\in [{1};{1}]\wedge {i1}\in [{-1};{2}]\) |
| \({l}_4\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\) |
| \({l}_5\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\) |
| \({l}_6\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\) |
| \({l}_7\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\) |
| \({l}_8\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\wedge {acs}\in [{-2};{2}]\) |
Table 11. Abstract Forward Reachability Semantics for the Access Control Program
7.3 The Backward Analysis Phase
The objective of this backward analysis phase is to create partitioning directives of the form “\(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\)” that can either guarantee that the behavior \(\mathcal {B}^{\sharp }\) always hold or guarantee the existence of at least one execution trace that fails behavior \(\mathcal {B}^{\sharp }\).
7.3.1 Behavior Refinement with Reachability Semantics.
After completing a forward reachability analysis, the first step is to refine the behavior \(\mathcal {B}^{\sharp }\) of interest by the intersection with the computed reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\).
If \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) is computed without trace partitioning, then the intersection of \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) with \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) is simply the pointwise meet \(\sqcap ^{\sharp }_{\mathbb {M}}\) of abstract environments, and the refined behavior is \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\, \dot{\sqcap }^{\sharp }_{\mathbb {M}}\, \mathcal {B}^{\sharp }\). However, if the trace partitioning is involved in the forward reachability analysis, then \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\in \mathbb {L}_{{T}}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\triangleq \mathbb {L}\times {T}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) (where T is the set of partitioning tokens) has to be transformed into the form \(\mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) before its intersection with \(\mathcal {B}^{\sharp }\).
There are possibly several ways to do so: (1) A naive method is to apply to \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) the forget function \(\pi _{\tau }\), which is defined in the trace partitioning abstract domain (Section 5.1) to remove partitioning tokens from extended program points, such that abstract environments at the same point with different partitioning tokens are joined together. Formally, we construct \(\mathsf {I}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\forall {l}\in \mathbb {L}.\; \mathsf {I}^{\sharp }( {l}) = \sqcup ^{\sharp }_{\mathbb {M}}\lbrace \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{\langle {l},\:{t}\rangle }\mid {t}\in {T}\rbrace\), and the refined behavior would be \(\mathsf {I}^{\sharp }\,\dot{\sqcap }^{\sharp }_{\mathbb {M}}\, \mathcal {B}^{\sharp }\). (2) The naive method can be improved if we do the intersection with \(\mathcal {B}^{\sharp }\) before joining the abstract environments together. Formally, the refined behavior is \(\mathcal {B}^{\sharp }{}^{\prime } \in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that \(\mathcal {B}^{\sharp }{}^{\prime }( {l}) = \sqcup ^{\sharp }_{\mathbb {M}}\lbrace \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{\langle {l},\:{t}\rangle }\, \sqcap ^{\sharp }_{\mathbb {M}}\, \mathcal {B}( {l})\mid {t}\in {T}\rbrace\). (3) Another alternative method is to use multiple behaviors to represent the intersection of \(\mathcal {B}^{\sharp }\) with \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\). More specifically, \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) can be equivalently viewed as a trace partitioning automaton, thus for each path in this automaton we can do an intersection with \(\mathcal {B}^{\sharp }\) and construct a new behavior if the path is still valid (i.e., no node is attached with \(\bot ^{\sharp }_{\mathbb {M}}\)). This method is the most precise one for refining the behavior of interest, but the cost of introducing multiple behaviors to the following backward analysis is prohibitive, hence it is not adopted in this article.
(Access Control, Continued).
Following Example 22, the trace partitioning is not used in the forward reachability analysis, hence the abstract behavior \(\mathcal {B}^{\sharp }\) can be refined simply by the pointwise meet \(\dot{\sqcap }^{\sharp }_{\mathbb {M}}\) with \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) from Table 11. For the sake of conciseness, the refined behavior is still called \(\mathcal {B}^{\sharp }\), thus we have: \(\mathcal {B}^{\sharp }( {l}_8) = {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\wedge {acs}\in [{-2};{0}]\), and \(\mathcal {B}^{\sharp }( {l}) = \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) for program points \({l}\) other than \({l}_8\).
7.3.2 Under-approximating/Over-approximating Backward Impossible Failure Accessibility Analysis.
Using the under-approximating backward impossible failure accessibility analysis given in Section 4.3.2, we get \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{} \in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that, for every program point \({l}\), \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) is an under-approximation of the weakest sufficient precondition for \(\mathcal {B}^{\sharp }\). Since an under-approximation of the weakest sufficient precondition is still a sufficient condition, every concrete valid trace that begins from a state \(\langle {l},\:\rho \rangle\) such that \(\rho \in \gamma _{\mathbb {M}}(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}})\) must satisfy the behavior \(\mathcal {B}^{\sharp }\).
Similarly, using the over-approximating backward impossible failure accessibility analysis formalized in Section 4.3.3, we get \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {post}^{\sharp \prime }}{} \in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) such that, for every program point \({l}\), \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) over-approximates the weakest sufficient precondition for \(\mathcal {B}^{\sharp }\). Since an over-approximation of the weakest sufficient precondition is not necessarily a sufficient condition, \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) does not guarantee that the occurrence of behavior \(\mathcal {B}^{\sharp }\). However, it is guaranteed that, if all the concrete valid traces that begin from a state \(\langle {l},\:\rho \rangle\) have the behavior \(\mathcal {B}^{\sharp }\), then ρ must satisfy the environment property \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) (i.e., \(\rho \in \gamma _{\mathbb {M}}(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}})\)). That is to say, from a state \(\langle {l},\:\rho \rangle\) such that ρ does not satisfy \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) (i.e., \(\rho \not\in \gamma _{\mathbb {M}}(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}})\)), there must exist at least one concrete valid trace that fails the behavior \(\mathcal {B}^{\sharp }\).
To make use of the environments that do not satisfy \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\), we compute the complement of \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\), or even better, \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) (i.e., \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{} \dot{\sqcap }^{\sharp }_{\mathbb {M}}(\dot{\lnot }\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{})\)), such that invalid environments are excluded. Yet, most abstract environment domains do not directly support the complement operation, including the classic numerical domains (such as the interval, octagon, and polyhedron domain). For example, the complement of a polyhedron is a disjunction of affine inequalities. Nevertheless, similar to the disjunctive completion, we can define the complement of \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) as \(\dot{\lnot }\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), such that each abstract environment element in \(\dot{\lnot }\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) represents an affine inequality in the disjunction at the point \({l}\).
It is worth mentioning that the number of affine inequalities in the complement of some abstract environment element from \(\mathcal {D}^{\sharp }_{\mathbb {M}}\) may be large, especially for polyhedra. However, it is safe to remove part of these affine inequalities and keep only the heuristically selected ones, without any harm to the soundness of abstract responsibility analysis.
(Access Control, Continued).
Following Example 23, we conduct an under-approximating backward impossible failure accessibility analysis on \(\mathcal {B}^{\sharp }\), and the corresponding result \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) is listed in Table 12
| \({l}\) | \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) |
|---|---|
| \({l}_0\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_1\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_2\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_3\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_4\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_5\) | \(\mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\wedge \mathbf { {i2}\in [{-1};{0}]}\) |
| \({l}_6\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\) |
| \({l}_7\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\) |
| \({l}_8\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\wedge \mathbf { {acs}\in [{-2};{0}]}\) |
Table 12. Under-approximating Backward IF Accessibility Semantics for \( \mathcal {B}^{\sharp } \)
| \({l}\) | \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) |
|---|---|
| \({l}_0\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_1\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_2\) | \(\bot ^{\sharp }_{\mathbb {M}}\) |
| \({l}_3\) | \({apv}\in [{1};{1}]\wedge \mathbf { {i1}\in [{-1};{0}]}\) |
| \({l}_4\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\) |
| \({l}_5\) | \(\lbrace \mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\wedge { {i2}\in [{-1};{2}]}\), \(\mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\wedge \mathbf { {i2}\in [{-1};{0}]}\rbrace\) |
| \({l}_6\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\) |
| \({l}_7\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\) |
| \({l}_8\) | \({apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\wedge \mathbf { {acs}\in [{-2};{0}]}\) |
Table 13. Over-approximating Backward IF Accessibility Semantics for \( \mathcal {B}^{\sharp } \) with Disjunctive Completion
Furthermore, the complement of \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) is listed in Table 14
| \({l}\) | \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) |
|---|---|
| \({l}_0\) | \(\lbrace \top ^{\sharp }_{\mathbb {M}}\rbrace\) |
| \({l}_1\) | \(\lbrace \top ^{\sharp }_{\mathbb {M}}\rbrace\) |
| \({l}_2\) | \(\lbrace {apv}\in [{1};{1}]\rbrace\) |
| \({l}_3\) | \(\lbrace {apv}\in [{1};{1}]\wedge \mathbf { {i1}\in [{1};{2}]}\rbrace\) |
| \({l}_4\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\rbrace\) |
| \({l}_5\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\wedge \mathbf { {i2}\in [{1};{2}]}\rbrace\) |
| \({l}_6\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\rbrace\) |
| \({l}_7\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\rbrace\) |
| \({l}_8\) | \(\lbrace {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\wedge \mathbf { {acs}\in [{1};{2}]}\rbrace\) |
Table 14. The Complement of Over-approximating Backward IF Accessibility Semantics for \( \mathcal {B}^{\sharp } \)
7.3.3 Partitioning Directives Generation with Validity Check.
Using the under-approximating backward impossible failure accessibility semantics \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) and the complement of over-approximating backward impossible failure accessibility semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\), this step aims at constructing a partition function \(\mathbb {P}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), such that \(\forall {l}\in \mathbb {L}.\; \forall \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}).\;\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is a partitioning directive that is valid with respect to the specified cognizance function \({\mathbb {C}}^{\sharp}\) and will be used in the next round of forward reachability analysis. Sometimes, a partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is called as \(\mbox{M}^{\sharp }_{p}\) for short, when the program point \({l}\) is known from the context.
More specifically, here we design four types of partitioning directives that are based on the environments, and accordingly the partition function \(\mathbb {P}^{\sharp }\) can be split into four parts:
(1) Right-bound partitioning directives. For any point \({l}\), \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) is a right-bound partitioning directive, if it is not \(\bot ^{\sharp }_{\mathbb {M}}\) and is valid with respect to all cognizance directives assigned to \({l}\). Formally, we define the right-bound partition function \(\mathbb {P}_{R}^{\sharp }\): \[\begin{equation*} \begin{array}{@{}rcl} \mathbb {P}_{R}^{\sharp }&\in &\mathbb {L}\mapsto \wp \left(\mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{right-bound partition function}\\ \mathbb {P}_{R}^{\sharp }( {l})&\triangleq &\left\lbrace \mbox{M}^{\sharp }_{p}\mid \mbox{M}^{\sharp }_{p}= \mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}} \wedge \mbox{M}^{\sharp }_{p}\ne \bot ^{\sharp }_{\mathbb {M}}\wedge \forall {d}_{c}\in \mathbb {C}^{\sharp} { {l}}.\; \textrm {isValid}_{{d}}\left({d}_{c}, \mbox{M}^{\sharp }_{p}\right)\right\rbrace .\end{array} \end{equation*}\]
By the definition of \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\), the partitions generated by right-bound partitioning directives during the next forward reachability analysis would guarantee the occurrence of \(\mathcal {B}^{\sharp }\).
In addition, the time cost of forward reachability analysis with trace partitioning greatly depends on the number of created partitions, while typically \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) contains redundant elements in consecutive program points, thus adopting every element in \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) as partitioning directives may bring unnecessary burden to the forward reachability analysis without benefits in improving the precision. Therefore, in practice, we can keep the partitioning directives only for the program points of importance (e.g., the points immediately after external inputs) and discard the rest of them.
(2) Left-bound partitioning directives. Similar to the generation of right-bound partitioning directives from \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\), the left-bound partitioning directives are derived from the complement of \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) (i.e., \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\)). Specifically, for any point \({l}\), every element in \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}}\) is a left-bound partitioning directive if it is not \(\bot ^{\sharp }_{\mathbb {M}}\) and is valid with respect to all cognizance directives assigned to \({l}\). Formally, the left-bound partition function \(\mathbb {P}_{L}^{\sharp }\) is: \[\begin{equation*} \begin{array}{@{}rcl} \mathbb {P}_{L}^{\sharp }&\in &\mathbb {L}\mapsto \wp \left(\mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{left-bound partition function}\\ \mathbb {P}_{L}^{\sharp }( {l})&\triangleq &\left\lbrace \mbox{M}^{\sharp }_{p}\mid \mbox{M}^{\sharp }_{p}\in \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}} \wedge \mbox{M}^{\sharp }_{p}\ne \bot ^{\sharp }_{\mathbb {M}}{}\wedge {} \forall {d}_{c}\in \mathbb {C}^{\sharp} { {l}}.\; \textrm {isValid}_{{d}}\left({d}_{c}, \mbox{M}^{\sharp }_{p}\right)\right\rbrace .\end{array} \end{equation*}\]
By the definition of \(\mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\), we know that from every partition generated by the left-bound partitioning directive, there must exist at least one concrete valid trace that fails the behavior \(\mathcal {B}^{\sharp }\). Moreover, similar to the right-bound partitioning directives, it is of practical use to keep the left-bound partitioning directives only for selected program points and discard the rest.
(3) Dual-right-bound partitioning directives. Intuitively, the left-bound partitioning directives can determine the points from which there is still possibility to fail \(\mathcal {B}^{\sharp }\), and the right-bound partitioning directives are used to determine the points at which \(\mathcal {B}^{\sharp }\) is guaranteed and the responsibility analysis could stop. Besides these two types of partitioning directive, the responsibility analysis would benefit from another type of partitioning directive, which are used to determine the points at which the behavior \(\mathcal {B}^{\sharp }\) is guaranteed to fail and the responsibility analysis can also stop. Such partitioning directives are called dual-right-bound partitioning directives, which marks the finishing point for responsibility analysis on the traces failing \(\mathcal {B}^{\sharp }\); without such partitioning directives, the responsibility analysis may last much longer than necessary.
Theoretically, the dual-right-bound partitioning directives can be derived from backward impossible failure accessibility analyses for the complements of \(\mathcal {B}\), but the cost of doing so would be prohibitive and the analysis results overlaps with the left-bound partitioning directives. In practice, to mark the finishing point of responsibility analysis on the traces failing \(\mathcal {B}^{\sharp }\), we can simply use the complements of \(\mathcal {B}^{\sharp }\), or more precisely, \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{} \backslash \mathcal {B}^{\sharp }\). Specifically, for every point \({l}\) of interest where the original behavior (before the refinement) \(\mathcal {B}^{\sharp }( {l})\ne \top ^{\sharp }_{\mathbb {M}}\), we compute the complement of \(\mathcal {B}^{\sharp }( {l}),\) which is represented by the disjunctive completion (e.g., a disjunction of affine inequalities for polyhedral), do the meet with \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) for every element in the disjunction, and collect the valid ones in the dual-right-bound partition function \(\mathbb {P}_{\tilde{R}}^{\sharp }\). Usually, there are not many dual-right-bound partitioning directives, since the original behavior \(\mathcal {B}^{\sharp }\) is specified \(\top ^{\sharp }_{\mathbb {M}}\) at most program points. \[\begin{equation*} \begin{array}{@{}rcl} \mathbb {P}_{\tilde{R}}^{\sharp }&\in &\mathbb {L}\mapsto \wp \left(\mathcal {D}^{\sharp }_{\mathbb {M}}\right)\text{dual-right-bound partition function}\\ \mathbb {P}_{\tilde{R}}^{\sharp }( {l})&\triangleq &\left\lbrace \mbox{M}^{\sharp }_{p}\mid \mbox{M}^{\sharp }_{p}\in \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}} \backslash \mathcal {B}^{\sharp }( {l}) \wedge \mbox{M}^{\sharp }_{p}\ne \bot ^{\sharp }_{\mathbb {M}}{}\wedge {} \forall {d}_{c}\in \mathbb {C}^{\sharp} { {l}}.\; \textrm {isValid}_{{d}}\left({d}_{c}, \mbox{M}^{\sharp }_{p}\right)\right\rbrace .\end{array} \end{equation*}\]
(4) No-bound partitioning directives. To make sure that the trace partitioning automaton (or, say, the extended transition system in Reference [70]) constructed by the partitioning directives introduced above is a covering of the original transition system (i.e., every transition in the original transition system is simulated by at least one transition in the trace partitioning automaton), we introduce some complementary partitioning directives to ensure every reachable state is covered by at least one partition. Such partitioning directives are called no-bound partitioning directives, and we define a no-bound partition function \(\mathbb {P}_{o}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\).
Formally, it is required that: \(\forall {l}\in \mathbb {L}.\; \cup \lbrace \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \mid \mbox{M}^{\sharp }_{p}\in \mathbb {P}_{R}^{\sharp }( {l})\cup \mathbb {P}_{L}^{\sharp }( {l})\cup \mathbb {P}_{\tilde{R}}^{\sharp }( {l})\cup \mathbb {P}_{o}^{\sharp }( {l})\rbrace \supseteq \gamma _{\mathbb {M}}(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}})\), where \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\) over-approximates the set of all reachable concrete environments at point \({l}\). Ideally, the no-bound partitioning directives \(\mathbb {P}_{o}^{\sharp }( {l})\) can be computed by the subtraction of \(\mathbb {P}_{R}^{\sharp }( {l})\cup \mathbb {P}_{L}^{\sharp }( {l})\cup \mathbb {P}_{\tilde{R}}^{\sharp }( {l})\) from \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\). However, in some cases it may be difficult to do such a subtraction operation. If this happens, then it is always safe to define \(\mathbb {P}_{o}^{\sharp }( {l}) = \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}}\), or even, \(\mathbb {P}_{o}^{\sharp }( {l}) = \top ^{\sharp }_{\mathbb {M}}\), which are guaranteed to be valid with respect to any cognizance function.
Combining the above four types of partitioning directives together, we can get a partition function \(\mathbb {P}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\) such that \(\mathbb {P}^{\sharp }( {l}) \triangleq \mathbb {P}_{R}^{\sharp }( {l}) \cup \mathbb {P}_{L}^{\sharp }( {l}) \cup \mathbb {P}_{\tilde{R}}^{\sharp }( {l}) \cup \mathbb {P}_{o}^{\sharp }( {l})\). For every program point \({l}\), every partitioning directive in \(\mathbb {P}^{\sharp }( {l})\) is valid with respect to every cognizance directive \({d}_{c}\) in \(\mathbb {C}^{\sharp} { {l}}\), thus by the definition of \(\textrm {isValid}_{\mathbb {P}}\), the partition function \(\mathbb {P}^{\sharp }\) is valid with respect to the cognizance function
. Besides, it is assumed that \(\mathbb {P}^{\sharp }( {l}_0) = \emptyset\) for the dummy initial point \({l}_0\), such that the correspondingly constructed trace partitioning automaton has only one initial node.
(Access Control, Continued).
Using the backward analysis result \(\mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) and \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{}\) from Example 24, here we generate partitioning directives for two different cognizance functions that are specified in Example 22.
(1) Consider the omniscient cognizance function \(\mathbb {C}_0^{\sharp}\) such that \(\mathbb {C}_0^{\sharp} { {l}} = \lbrace \bot ^{\sharp }_{\mathbb {M}}\rbrace\) for every point \({l}\in \mathbb {L}\). In this case, every partitioning directive is trivially valid with respect to \(\mathbb {C}_0^{\sharp}\), and the corresponding partition function \(\mathbb {P}^{\sharp }\) is displayed in Table 15
| \({l}\) | \(\mathbb {P}_{R}^{\sharp }( {l})\) | \(\mathbb {P}_{L}^{\sharp }( {l})\) | \(\mathbb {P}_{\tilde{R}}^{\sharp }( {l})\) | \(\mathbb {P}_{o}^{\sharp }( {l})\) |
|---|---|---|---|---|
| \({l}_0\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_1\) | \(\emptyset\) | \(\lbrace \top ^{\sharp }_{\mathbb {M}}\rbrace\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_2\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_3\) | \(\emptyset\) | \(\lbrace {apv}\in [{1};{1}]\wedge \mathbf { {i1}\in [{1};{2}]}\rbrace\) | \(\emptyset\) | \(\lbrace {apv}\in [{1};{1}]\)\(\wedge \mathbf { {i1}\in [{-1};{0}]}\rbrace\) |
| \({l}_4\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_5\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge \mathbf { {i2}\in [{-1};{0}]}\rbrace\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge \mathbf { {i2}\in [{1};{2}]}\rbrace\) | \(\emptyset\) | \(\lbrace \mathbf { {apv}\in [{-1};{0}]}\)\(\wedge {i1}\in [{-1};{2}]\)\(\wedge \mathbf { {i2}\in [{-1};{2}]}\rbrace\) |
| \({l}_6\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_7\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\rbrace\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_8\) | \(\lbrace {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\)\(\wedge \mathbf { {acs}\in [{-2};{0}]}\rbrace\) | \(\lbrace {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\)\(\wedge \mathbf { {acs}\in [{1};{2}]}\rbrace\) | \(\mathbb {P}_{L}^{\sharp }( {l}_8)\) | \(\emptyset\) |
Table 15. The Partition Function for the Omnisicent Cognizance
Taking the point \({l}_5\) as an example, the forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}_5} = {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\wedge {i2}\in [{-1};{2}]\) is partitioned into three parts: the right-bound partitioning directives \(\mathbb {P}_{R}^{\sharp }( {l}_5) = \lbrace { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}] \wedge { {i2}\in [{-1};{0}]}\rbrace\) that guarantee “the access to o fails”; the left-bound partitioning directives \(\mathbb {P}_{L}^{\sharp }( {l}_5) = \lbrace { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}] \wedge { {i2}\in [{1};{2}]}\rbrace\), which ensures there exists at least one valid concrete trace such that “the access to o succeeds”; the no-bound partitioning directives \(\mathbb {P}_{o}^{\sharp }( {l}_5) = \lbrace { {apv}\in [{-1};{0}]}\) \(\wedge {i1}\in [{-1};{2}] \wedge { {i2}\in [{-1};{2}]}\rbrace\) are complementary to the two other types of partitioning directives such that every reachable environment at point \({l}_5\) is covered. Although \(\mathbb {P}_{o}^{\sharp }( {l}_5)\) actually guarantee “the access to o fails” in this very example, we cannot take advantage of this information, since typically the no-bound partitioning directives cannot guarantee anything.
(2) Consider a non-omniscient cognizance function \({\mathbb {C}}^{\sharp}\) such that, if \({l}\in \lbrace {l}_0, {l}_1, {l}_2\rbrace\), then \(\mathbb {C}^{\sharp} { {l}} = \lbrace \bot ^{\sharp }_{\mathbb {M}}\rbrace\), otherwise \(\mathbb {C}^{\sharp} { {l}} = \lbrace {i1}\in [{-1};{2}]\rbrace\). In this case, every partitioning directive from Table 15 needs to be checked with respect to the cognizance. Since the abstract environment domain is the interval domain, checking the validity of partitioning directives is quite easy by the condition (27), and we can find that only the partitioning directives at point \({l}_3\) are invalid. Take \(\mbox{M}^{\sharp }_{p}= {apv}\in [{1};{1}]\wedge { {i1}\in [{1};{2}]} \in \mathbb {P}_{L}^{\sharp }( {l}_3)\) as an example, the only cognizance directive at \({l}_3\) is \({d}_{c}= {i1}\in [{-1};{2}] \in \mathbb {C}^{\sharp} { {l}_3}\), thus \(\mbox{M}^{\sharp }_{p}|_{\textrm {vars}(\mbox{M}^{\sharp }_{p})\cap \textrm {vars}({d}_{c})} = {i1}\in [{1};{2}]\), and it is obvious the condition (27) does not hold. Similarly, the partitioning directive in \(\mathbb {P}_{o}^{\sharp }( {l}_3)\) is found invalid. Therefore, after removing the invalid partitioning directives at \({l}_3\), we get the partition function as in Table 16
| \({l}\) | \(\mathbb {P}_{R}^{\sharp }( {l})\) | \(\mathbb {P}_{L}^{\sharp }( {l})\) | \(\mathbb {P}_{\tilde{R}}^{\sharp }( {l})\) | \(\mathbb {P}_{o}^{\sharp }( {l})\) |
|---|---|---|---|---|
| \({l}_0\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_1\) | \(\emptyset\) | \(\lbrace \top ^{\sharp }_{\mathbb {M}}\rbrace\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_2\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_3\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_4\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_5\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge \mathbf { {i2}\in [{-1};{0}]}\rbrace\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge \mathbf { {i2}\in [{1};{2}]}\rbrace\) | \(\emptyset\) | \(\lbrace \mathbf { {apv}\in [{-1};{0}]}\)\(\wedge {i1}\in [{-1};{2}]\)\(\wedge \mathbf { {i2}\in [{-1};{2}]}\rbrace\) |
| \({l}_6\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_7\) | \(\mathbf { {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\) | \(\lbrace \mathbf { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\rbrace\) | \(\emptyset\) | \(\emptyset\) |
| \({l}_8\) | \(\lbrace {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\)\(\wedge \mathbf { {acs}\in [{-2};{0}]}\rbrace\) | \(\lbrace {apv}\in [{-1};{1}]\wedge {i1}\in [{-1};{2}]\)\(\wedge {i2}\in [{-1};{2}]\wedge {typ}\in [{1};{2}]\)\(\wedge \mathbf { {acs}\in [{1};{2}]}\rbrace\) | \(\mathbb {P}_{L}^{\sharp }( {l}_8)\) | \(\emptyset\) |
Table 16. The Partition Function for the Non-omniscient Cognizance
.7.4 The Forward Analysis Phase
The objective of this forward analysis phase is to construct a trace partitioning automaton with the partitioning directives from the last phase, mark left bounds and right bounds of responsibility in the automaton, and determine responsible entities.
(1) Trace Partitioning Automaton Generation. Using the partitioning directives from the backward analysis phase (i.e., \(\lbrace \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle \mid {l}\in \mathbb {L}\wedge \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l})\rbrace\)) and optionally the partitioning directives based on the control flow (e.g., \(\textrm {part}\langle \textrm {If},\: {l},\:b\rangle\)), we perform an over-approximating forward reachability analysis with trace partitioning (Section 5), compute the refined forward reachability semantics, and construct a trace partitioning automaton. Specially, the nodes generated by left-bound partitioning directives are marked as “left-bound nodes” in the automaton, the nodes generated by right-bound partitioning directives are marked as “right-bound nodes,” and the nodes generated by dual-right-bound partitioning directives are marked as “dual-right-bound nodes.”
Furthermore, after the forward reachability analysis with trace partitioning completes, we can improve the constructed automaton by propagating the right-bounds or dual-right-bounds: For any node in the automaton that is not marked as any bound, if all its successors are marked as right-bound nodes (respectively, dual-right-bound nodes), then we mark this node as a right-bound node (respectively, a dual-right-bound node) as well.
(2) Determining Responsible Entities. Now, we can determine the responsibility in the generated trace partitioning automaton. The intuition is: Every path in the automaton represents a set of concrete traces; if a path contains a dual-right-bound node, then the path does not have the behavior \(\mathcal {B}^{\sharp }\), hence there is no responsible entity along this path; otherwise, the responsible entities are the edges (i.e., actions), which are located after the left-bound nodes (if any) and before the right-bound nodes (if any) along the path. That is to say, for any path that does not contain a dual-right-bound node, all the actions between the rightmost left-bound node (if any) and the leftmost right-bound node (if any) are potentially responsible for the behavior \(\mathcal {B}^{\sharp }\). Specially, if there is neither a left-bound node nor a right-bound node along a certain path, then the analysis is not precise enough and every action along that path would be determined as potentially responsible.
Since only the actions with free choices can be possibly responsible for a behavior, we can further restrict the potentially responsible entities to the actions such as external inputs, random number generation, and variable initialization (which is mimicked as the dummy initial action).
In addition, we do not only find potentially responsible entities, but also get some hints on when these entities are actually responsible, and this is the so called “responsible under the condition.” Suppose an edge \(\langle {l},\:{t},\:\mbox{M}^{\sharp }\rangle \rightarrow \langle {l}^{\prime },\:{d}_{p}::{t},\:\mbox{M}^{\sharp \prime }\rangle\) in the automaton is found potentially responsible, it means that the action \({a}\) from \({l}\) to \({l}^{\prime }\) (which can be retrieved from the program source code) is potentially responsible under the condition that the partitioning token t holds at point \({l}\) and the action \({a}\) satisfies the partitioning directive \({d}_{p}\). For example, for the access control program in Figure 4, the edge \(\langle {l}_4,\:{t},\:\mbox{M}^{\sharp }\rangle \rightarrow \langle {l}_5,\:{d}_{p}::{t},\:\mbox{M}^{\sharp \prime }\rangle\) is determined responsible, where \({t}= {apv}\in [{1};{1}]\wedge { {i1}\in [{1};{2}]}\) and \({d}_{p}= { {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}] \wedge { {i2}\in [{-1};{0}]}\). Instead of claiming that the action \({i2} := [-1; 2]\) is responsible for “the access to o fails” in all executions, we state that \({i2} := [-1; 2]\) is responsible under the condition that: The partitioning token \({apv}\in [{1};{1}]\wedge { {i1}\in [{1};{2}]}\) holds at \({l}_4\), and the action \({i2} := [-1; 2]\) satisfies the new partitioning directive \({ {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}] \wedge { {i2}\in [{-1};{0}]}\). That is to say, the input from 2nd admin is responsible for the behavior “the access to o fails” if the input from 1st admin is positive and the input from 2nd admin is negative or zero, which is much more informative than simply claiming the input from 2nd admin is responsible.
(3) Termination or a New Round of Analysis. Up until this step, we have already successfully inferred some information about the responsible entities. If such an analysis result is satisfactory or the time and costs exceeds the prespecified threshold, then we could terminate the analyzer and return the found responsible entities to the user. Otherwise, if the precision of forward reachability semantics \(\mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{}\) is improved in the last forward analysis phase, then we could start a new round of backward accessibility analysis (Section 7.3) followed by the forward reachability analysis (Section 7.4) to seek for more precise responsibility analysis results.
Intuitively, in the new round of analysis, using the refined behavior of interest (possibly with the disjunctive completion), the backward impossible failure accessibility analysis is expected to be more precise, which creates more partitioning directives to construct a refined automaton and further improves the responsibility analysis result. The extreme case is that we create as many partitioning directives as possible and construct the most precise trace partitioning automaton, such that every path in the automaton represents a single concrete valid trace. From such a trace partitioning automaton, we can get exactly the same analysis result as the concrete responsibility analysis (Section 3), yet the time cost is in general prohibitive.
(Access Control, Continued).
Following Example 25, we conduct a forward reachability analysis with trace partitioning, construct the trace partitioning automaton, and determine responsible entities. Since the partition function varies for different cognizance functions, the corresponding constructed trace partitioning automata are different.
(1) First, consider the omniscient cognizance function
. In this case, we adopt the partitioning directives from the partition function in the Table 15, and the correspondingly constructed trace partitioning automaton is in Figure 23, in which various types of nodes are represented by different circles.
Fig. 19. Trace partitioning automaton for the omniscient cognizance.
Since there is at most one element in \(\mathbb {P}_{L}^{\sharp }( {l})\) for every program point \({l}\), we simply use the notation \({d}_{L( {l})}\) for short to refer the partitioning directive \(\textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }\rangle\), where \(\mbox{M}^{\sharp }\) is the only element in \(\mathbb {P}_{L}^{\sharp }( {l})\). For instance, \({d}_{L( {l}_3)}\) refers to the partitioning directive \(\textrm {part}\langle \textrm {Inv},\: {l},\: {apv}\in [{1};{1}]\wedge \mathbf { {i1}\in [{1};{2}]}\rangle\), where \({apv}\in [{1};{1}]\wedge \mathbf { {i1}\in [{1};{2}]} \in \mathbb {P}_{L}^{\sharp }( {l}_3)\). Similarly, we use the notations \({d}_{R( {l}})\), \({d}_{\tilde{R}( {l})}\) and \({d}_{o( {l})}\) to refer the partitioning directives from \(\mathbb {P}_{R}^{\sharp }( {l})\), \(\mathbb {P}_{\tilde{R}}^{\sharp }( {l})\), and \(\mathbb {P}_{o}^{\sharp }( {l})\). Besides, for the sake of conciseness, instead of explicitly drawing partitioning tokens inside the nodes of the automaton, we label some edges with a partitioning directive \({d}\,\) such that every node after the edge has the partitioning directive d pushed into its stack of directives (i.e., the partitioning token). For instance, for the node at point \({l}_3\) with double dashed circles in upper path of the automaton, its partitioning token is “\({d}_{L( {l}_3)}::{d}_{L( {l}_1)}\).”
Furthermore, the automaton in Figure 23 can be refined by removing the invalid node whose associated abstract environment element is \(\bot ^{\sharp }_{\mathbb {M}}\) (i.e., it is unreachable) and propagating right-bound nodes, and we get a simpler trace partitioning automaton as in Figure 24. For example, the node at point \({l}_5\) created by \({d}_{o( {l}_5)}\) in the upper path is invalid and can be removed; the node at point \({l}_6\) in the lower path has only one valid successor that is marked as a right-bound node, thus we mark the node at point \({l}_6\) also as a right-bound node, as well as its predecessors.
Fig. 20. The refined trace partitioning automaton for the omniscient cognizance.
From the above automaton, we can clearly see that there are three maximal paths from \({l}_0\) to \({l}_8\) in the automaton, which over-approximate all the concrete valid traces of the program.
For the upper path, the rightmost left-bound node is at \({l}_3\) and the leftmost right-bound node is at \({l}_5\), thus the responsible entities must be located between \({l}_3\) and \({l}_5\). Since the action “\({apv} := ( {i1} \le 0)\; ?\; -1 : {apv}\)” has no free choice, only the action “\({i2} := [-1; 2]\)” is determined responsible under the condition: \({apv}\in [{1};{1}]\wedge { {i1}\in [{1};{2}]}\) hold at point \({l}_4\), and the action “\({i2} := [-1; 2]\)” satisfies \({ {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\) \(\wedge { {i2}\in [{1};{2}]}\). It indicates that the input from 2nd admin is responsible if the input from 1st admin is positive and the input from 2nd admin is negative or zero.
For the path in the middle, the node at \({l}_8\) is marked as a dual-right-bound node, which means that every concrete trace represented by this path does not have the behavior “the access to o fails.” Thus, there is no responsible entity along this path.
For the lower path, the rightmost left-bound node is at \({l}_1\) and the leftmost right-bound node is at \({l}_3\). Since the action “\({apv} := 1\)” from \({l}_1\) to \({l}_2\) has no free choice, only the action \({i1} := [-1; 2]\) from \({l}_2\) to \({l}_3\) is determined responsible, under the condition that \({apv}\in [{1};{1}]\wedge { {i1}\in [{\text{}-1};{0}]}\) holds at point \({l}_3\). That is to say, the input from 1st admin is responsible if it is -1 or 0.
To sum up, for the omniscient cognizance in the access control program example, the abstract responsibility analysis finds that the input from 1st admin or 2nd admin is potentially responsible for “the access to o fails” under certain conditions, while other actions with free choice (e.g., the variable initialization and the input from system settings) are not responsible. This analysis result is almost as precise as the concrete responsibility analysis, thus there is no need to conduct a new round of analysis and we can terminate the analysis here.
(2) Second, consider the trace partitioning automaton constructed for the non-omniscient cognizance function \({\mathbb {C}}^{\sharp}\) such that the observer does not know the input of 1st admin (i.e., the observer cannot distinguish the value of \({i1}\) in the interval \([{-1};{2}]\)). In this case, we adopt the partitioning directives from the partition function defined in Table 16, and the correspondingly constructed trace partitioning automaton is in Figure 25, in which we represent various types of nodes by different circles as in Figure 23.
Fig. 21. The trace partitioning automaton for a non-omniscient cognizance.
Compared with the trace partitioning automaton for the omniscient cognizance, we do not have the partitioning directives at point \({l}_3\), while the partitioning directives at other points are still valid and preserved. After removing the invalid nodes and propagating right-bound nodes, the refined trace partitioning automaton is in Figure 26.
Fig. 22. The refined trace partitioning automaton for a non-omniscient cognizance.
Similar to the automaton in Figure 24, there are three maximal paths in the refined automaton for the non-omniscient cognizance, which over-approximate the concrete valid traces.
For the lower path, the node at \({l}_8\) is marked as a dual-right-bound node, which means that the behavior of interest does not hold, thus there is no responsible entity along the path.
In contrast, along both the upper path and the middle path, the rightmost left-bound node is at point \({l}_1\) and the leftmost right-bound node is at point \({l}_5\), thus the responsible entities must be located between \({l}_1\) and \({l}_5\). After filtering out the actions without free choices, we would determine both “\({i1} := [-1; 2]\)” and “\({i2} := [-1; 2]\)” potentially responsible for the behavior. More precisely, “\({i1} := [-1; 2]\)” is responsible under no condition, while “\({i2} := [-1; 2]\)” is responsible under the condition that the partitioning directive \({ {apv}\in [{1};{1}]}\wedge {i1}\in [{-1};{2}]\wedge { {i2}\in [{-1};{0}]}\) or \({ {apv}\in [{-1};{0}]}\wedge {i1}\in [{-1};{2}]\wedge { {i2}\in [{-1};{2}]}\) holds at point \({l}_5\).
To sum up, for the non-omniscient cognizance such that the observer does not know the input from 1st admin, the abstract responsibility analysis find both the input from 1st admin and the input from 2nd admin are potentially responsible for the behavior “the access to o fails” in every execution where the behavior occurs. Compared with the concrete responsibility analysis that determines only the input from 2nd admin responsible, this abstract analysis result is less precise, but it is still sound, since every entity that is responsible in the concrete is also found responsible in the abstract.
7.5 The Soundness of Abstract Responsibility Analysis
In this section, we prove that the abstract responsibility analysis introduced in Section 7.1 is sound with respect to the concrete responsibility analysis defined in Section 3.2.4.
Every entity that is responsible in the concrete must be found responsible in the abstract responsibility analysis.
Given a program \(\textrm {P}\) along with the user specified behavior of interest \(\mathcal {B}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}\) and cognizance function \(\mathbb {C}^{\sharp}\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}})\), the corresponding concrete behavior of interest \(\mathcal {B}\) and lattice of concrete behaviors \(\mathcal {L}^{\mathsf {Max}}\) are formalized in Section 6.1, as well as the concrete cognizance function \({\mathbb {C}}\) in Section 6.2. Suppose that the behavior \(\mathcal {B}\) holds in a valid concrete trace σ of \(\textrm {P}\), and a concrete transition \(\tau = \langle {l},\:\rho \rangle \xrightarrow {a}\langle {l}^{\prime },\:\rho ^{\prime }\rangle\) (in which \({a}\) may be omitted and can be retrieved from the source code) in σ is found responsible for \(\mathcal {B}\) by the Definition 2 of concrete responsibility analysis (i.e., the trace σ is splitted into \(\sigma = \sigma _{\mbox{H}}\tau \sigma _{\mbox{F}}\) such that \(\emptyset \subsetneq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau }\subseteq \mathcal {B}\wedge {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\not\subseteq \mathcal {B}\)), then we would like to prove that the action \({a}\) must be found responsible in the abstract responsibility analysis.
Since the trace partitioning automaton constructed in the abstract responsibility analysis is a covering of the concrete trace semantics of \(\textrm {P}\), every valid concrete trace is simulated by at least one path in the automaton. Let \(\sigma ^{\sharp }\) be a path in the trace partitioning automaton that simulates the concrete trace σ and \(\tau ^{\sharp }= \langle {l},\:{t},\:\mbox{M}^{\sharp }\rangle \xrightarrow {a} \langle {l}^{\prime },\:{t}^{\prime },\:\mbox{M}^{\sharp \prime }\rangle \in (\mathbb {L}_{{T}}\times \mathcal {D}^{\sharp }_{\mathbb {M}}) \times (\mathbb {L}_{{T}}\times \mathcal {D}^{\sharp }_{\mathbb {M}})\) be the edge on the path \(\sigma ^{\sharp }\) that represents the transition \(\tau\). Thus, we need to prove that \(\tau ^{\sharp }\) must be found responsible in the abstract responsibility analysis.
To start with, we prove that there is no dual-right-bound node along the abstract path \(\sigma ^{\sharp }\) by contradiction. Assume there is a dual-right-bound node at point \({l}_{\tilde{R}}\) on \(\sigma ^{\sharp }\), which is created by a dual-right-bound partitioning directive \(\textrm {part}\langle \textrm {Inv},\: {l}_{\tilde{R}},\:\mbox{M}^{\sharp }_{\tilde{R}}\rangle\). By the definition of dual-right-bound partition function, we know that \(\mbox{M}^{\sharp }_{\tilde{R}}\) guarantees the complement of \(\mathcal {B}^{\sharp }\) (i.e., \(\mbox{M}^{\sharp }_{\tilde{R}} \in \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}_{\tilde{R}}} \backslash \mathcal {B}^{\sharp }( {l}_{\tilde{R}})\)), thus all the concrete traces represented by \(\sigma ^{\sharp }\) must fail the behavior \(\mathcal {B}\) at point \({l}_{\tilde{R}}\). This contradicts with our assumption that σ is simulated by \(\sigma ^{\sharp }\) and the behavior \(\mathcal {B}\) holds in σ. Thus, along the path \(\sigma ^{\sharp }\), there is no dual-right-bound node, and all the edges between the rightmost left-bound-node (if any) and the leftmost right-bound-node are determined potentially responsible by the abstract responsibility analysis. Specially, if there is no left-bound-node or right-bound-node along \(\sigma ^{\sharp }\), every edge is determined potentially responsible, which obviously includes \(\tau ^{\sharp }\).
Furthermore, we prove that if there is a left-bound node along \(\sigma ^{\sharp }\), then \(\tau ^{\sharp }\) must be located after that node. Assume that there is a left-bound node along \(\sigma ^{\sharp }\), which is created by a left-bound partitioning directive \(\textrm {part}\langle \textrm {Inv},\: {l}_L,\:\mbox{M}^{\sharp }_L\rangle\), and a concrete state \({s}_L = \langle {l}_L,\:\rho _L\rangle\) on σ is represented by the left-bound node. By the definition of the left-bound partition function, the abstract environment \(\mbox{M}^{\sharp }_L\) is from the complement of the over-approximating backward impossible failure semantics for the behavior \(\mathcal {B}^{\sharp }\) (i.e., \(\mbox{M}^{\sharp }_L \in \mathcal {S}^{\sharp}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{\mathsf {I}_\mathsf {pre}^{\sharp }}{ {l}_L} \backslash \mathcal {\hat {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}_L}\)). That is to say, from every concrete state that is represented by the left-bound node, there must exist at least one valid concrete trace that fails the behavior \(\mathcal {B}\). If we split σ into \(\sigma ^{\prime }\) and \(\sigma ^{\prime \prime }\) such that \(\sigma ^{\prime }\) ends with \({s}_L\) while \(\sigma ^{\prime \prime }\) begins with \({s}_L\), then it is obvious that \(\sigma ^{\prime }\) cannot guarantee the occurrence of \(\mathcal {B}\), thus \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}},\sigma ^{\prime }} \not\subseteq \mathcal {B}\). Since \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}},\sigma ^{\prime }} \subseteq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}\), we have \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }} \not\subseteq \mathcal {B}\). As \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau }\subseteq \mathcal {B}\) and the observation function \({\mathbb {O}} {}{}{}\) is decreasing (Lemma 3), we find that \(\sigma _{\mbox{H}}\tau\) must be greater (longer) than \(\sigma ^{\prime }\). Therefore, the responsible transition \(\tau\) must be located after the state \({s}_L\), and accordingly the edge \(\tau ^{\sharp }\) must be located after the left-bound node.
Last, we prove that if there is a right-bound node along \(\sigma ^{\sharp }\), then \(\tau ^{\sharp }\) must be located before that node. Assume that there is a right-bound node along \(\sigma ^{\sharp }\), which is created by a right-bound partitioning directive \(\textrm {part}\langle \textrm {Inv},\: {l}_R,\:\mbox{M}^{\sharp }_R\rangle\), and a concrete state \({s}_R = \langle {l}_R,\:\rho _R\rangle\) on σ is represented by the right-bound node. By the definition of the right-bound partition function, the abstract environment \(\mbox{M}^{\sharp }_R\) is from the under-approximating backward impossible failure semantics for the behavior \(\mathcal {B}^{\sharp }\) (i.e., \(\mbox{M}^{\sharp }_R = \mathcal {\check {S}}^{\sharp}\mathop{\rightarrow}\limits_{if} [\![{\textrm {P}}]\!]{\mathcal {B}^{\sharp }}{ {l}_R}\)). That is to say, every concrete trace starting from the states represented by the right-bound node is guaranteed to have the behavior \(\mathcal {B}\). If we split σ into \(\sigma ^{\prime }\) and \(\sigma ^{\prime \prime }\) such that \(\sigma ^{\prime }\) ends with \({s}_R\) while \(\sigma ^{\prime \prime }\) begins with \({s}_R\), then it is easy to know \(\mathcal {B}\) holds in \(\sigma ^{\prime }\) (since \(\mathcal {B}\) holds in the whole trace σ), and every trace with the prefix \(\sigma ^{\prime }\) is guaranteed to have the behavior \(\mathcal {B}\). Hence, we get \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}},\sigma ^{\prime }} \subseteq \mathcal {B}\). Now we consider the traces that are equivalent to \(\sigma ^{\prime }\) according to the cognizance \({\mathbb {C}}^{\sharp}\). For any trace \(\sigma ^{\prime }_{e}\) such that \(\sigma ^{\prime }_{e}\overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\), the behavior \(\mathcal {B}\) must hold during the execution of \(\sigma ^{\prime }_{e}\) (since \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}\!, \mathcal {L}^{\mathsf {Max}}\!, {\mathbb {C}}, \sigma _{\mbox{H}}\tau }\subseteq \mathcal {B}\)). By Theorem 2, \(\sigma ^{\prime }_{e}\) must be represented by the same path as \(\sigma ^{\prime }\) in the automaton, thus the last state in \(\sigma ^{\prime }_{e}\) is also represented by the same right-bound node in the automaton. Thus, every trace with the prefix \(\sigma ^{\prime }_{e}\) is guaranteed to have the behavior \(\mathcal {B}\), which implies that \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}},\sigma ^{\prime }_{e}} \subseteq \mathcal {B}\). By the definition of \({\mathbb {O}} {}{}{}\), we get \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}\subseteq \mathcal {B}\). Since the observation function \({\mathbb {O}} {}{}{}\) is decreasing (Lemma 3) and \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\not\subseteq \mathcal {B}\), it is easy to see that \(\sigma ^{\prime }\) is strictly greater (longer) than \(\sigma _{\mbox{H}}\). Therefore, the responsible transition \(\tau\) must be located before the state \({s}_R\), and accordingly the edge \(\tau ^{\sharp }\) must be located before the right-bound node.
To sum up, we have proved that for every concrete trace σ with a responsible entity that is a transition \(\tau = \langle {l},\:\rho \rangle \xrightarrow {a}\langle {l}^{\prime },\:\rho ^{\prime }\rangle\), there exists an abstract path \(\sigma ^{\sharp }\) with an edge \(\tau ^{\sharp }= \langle {l},\:{t},\:\mbox{M}^{\sharp }\rangle \xrightarrow {a} \langle {l}^{\prime },\:{t}^{\prime },\:\mbox{M}^{\sharp \prime }\rangle\) in the corresponding trace partitioning automaton, and the edge \(\tau ^{\sharp }\) must be located after all the left-bound nodes (if any) and before all the right-bound nodes (if any) on the path \(\sigma ^{\sharp }\). Thus, by the abstract responsibility analysis designed in Section 7.1, the edge \(\tau ^{\sharp }\) must be determined responsible for \(\mathcal {B}^{\sharp }\).□
8 Related Work
Definition of Causality and Responsibility. Hume [38] is the first one to specify causation by counterfactual dependence [54]. The best-known counterfactual theory of causation is proposed by Lewis [51], which defines causation as a transitive closure of counterfactual dependencies. Halpern and Pearl [34, 35, 63] define actual causality based on SEM and extend counterfactual dependency to allow “contingent dependency.” Chockler and Halpern [13] define responsibility to have a quantitative measure of the relevance between causes and effects and define blame to consider the epistemic state of an agent. Their application of actual causality, responsibility, and blame is mainly on artificial intelligence.
Our definition of responsibility also adopts the idea of counterfactual dependence in the sense that, suppose an event \(\sigma _{\mbox{R}}\) is said to be responsible for behavior \(\mathcal {B}\) in the trace \(\sigma _{\mbox{H}}\sigma _{\mbox{R}}\), there must exist another event \(\sigma _{\mbox{R}}^{\prime }\) such that, if \(\sigma _{\mbox{R}}\) is replaced by \(\sigma _{\mbox{R}}^{\prime }\), then \(\mathcal {B}\) is not guaranteed (by Lemma 1).
A “naive” definition of causality [51, 52] based on counterfactual dependency could exclude non-decisive factors (e.g., the wind in this example) from the analysis result. This definition proposed by Lewis adopts an alternative world semantics and determines causality relations according to a criterion: An event e is a cause of the occurrence of another event \(e^{\prime }\) if and only if, were e not to occur, \(e^{\prime }\) would not happen. The testing of this condition hinges upon the availability of alternative worlds. For instance, in the conjunctive scenario of this forest fire example, we can infer that the forest would not be burnt down in an alternative world where the arsonist A does not drop a lit match, thus the arsonist A is causal for the forest fire; yet, in the alternative world where there is no wind, the forest would still be burnt down, hence the wind is not a cause of the forest fire. However, the counterfactual causality may be too strict in some circumstances such that no cause could be found. Taking the disjunctive scenario of forest fire as an example, in the alternative world where one arsonist A (respectively, B) does not drop a lit match, the forest would still have been burnt down due to the other arsonist B (respectively, A), hence neither of these two arsonists would be determined as the cause of forest fire. Thus, it may be inappropriate to directly adopt the idea of counterfactual dependency in the responsibility analysis.
Error Cause Localization. Classic program analysis techniques, e.g., dependency analysis [1, 12, 73] and program slicing [2, 46, 74, 75], are useful in detecting the code that may be relevant to errors, but fail to localize the cause of error.
In recent years, there are many papers [8, 32, 33, 42, 43, 65, 66, 67] on fault localization for counterexample traces, and most of them compare multiple traces produced by a model checker and build a heuristic metric to localize the point from which error traces separate from correct traces. Other related papers include error diagnosis by abductive/backward inference [27], tracking down bugs by dynamic invariant detection [36]. Actual causality is applied to explain counterexamples from model checker [10] and estimate the coverage of specification [14]. Besides, there are researches on analyzing causes of specific security issues; e.g., King et al. [45] employ a blame dependency graph to explain the source of information flow violation and generate a program slice as the error report.
Compared to the above techniques, this article succeeds to formally define the cause or responsibility, and the proposed responsibility analysis, which does not require a counterexample from the model checker, is sound, scalable, and generic to cope with various problems.
9 Conclusion
This article formally defines responsibility as an abstraction of trace semantics. Typically, the responsibility analysis consists of four steps: collect the trace semantics, build a lattice of system behaviors of interest, create an observation function for each observer, and apply the responsibility abstraction on analyzed traces. Compared to current dependency and causality analysis methods, the responsibility analysis is demonstrated to be more generic and precise in a few examples. In addition, a sound framework of abstract responsibility analysis is proposed, which is based on trace partitioning automata constructed by the iteration of over-approximating forward reachability analysis with trace partitioning and under-approximating/over-approximating backward impossible failure accessibility analysis. It is guaranteed that actions that are not found responsible in the abstract analysis are definitely not responsible in the concrete.
We hope this article has successfully demonstrated that the responsibility analysis constitutes a worthy avenue of research. In the future, there are a number of directions that deserve further exploration.
Analysis of Probabilistic Programs. The definition of responsibility proposed in this article can be extended to probabilistic programming languages such that the degree of responsibility of each responsible entity can be quantified, which is similar to the degree of blame designed to quantify actual causality [13]. More precisely, instead of identifying a single responsible entity for each specific trace as in (2), we can collect all the potentially responsible entities for the whole system and assign each of them with a probability of being responsible for the behavior of interest.
Generalization of Abstract Analysis. The framework of abstract responsibility analysis can be applied to new abstract domains other than the classic numeric domains discussed in this article, such that we can analyze the responsibility of more behaviors (which cannot be expressed by intervals, octagons, or polyhedra). The main challenges are expected to come from designing a sound under-approximating backward impossible failure accessibility analysis for the new abstract domain. In addition, we suggest specifying the abstract cognizance function by abstract relational invariants [3, 4] that can directly express relational properties about two executions of the program, such that we do not have the restrictions that two equivalent traces must be of the same length and have the same control flow.
Alternative Definitions of Responsibility. In the philosophy literature, there is a protracted controversy concerning the meaning of responsibility. Just like the law varies from one nation to another, there cannot exist a perfect universal rule of defining responsibility [28] that deals well with all scenarios. In our current definition (2), whether a transition \(\tau _{\mbox{R}}\) (or, say, the corresponding action \({a}_{\, \mbox{R}}\)) is responsible or not in the trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\) solely depends on its history \(\sigma _{\mbox{H}}\), while its future \(\sigma _{\mbox{F}}\) has no impact on deciding the responsibility. For instance, in the forest fire example, whether an arsonist A is responsible or not solely depends on if there is another arsonist that already dropped a lit match before A or not. This definition of responsibility is quite intuitive and works in many scenarios, but not necessarily all scenarios. In some scenarios, the future part \(\sigma _{\mbox{F}}\) may also need to be taken into account for determining responsibility. We wish to design a lattice of responsibility definitions, each of which adopts a distinct rule of defining responsibility, and for every specific scenario there is at least one definition from the lattice that can handle it well.
Acknowledgments
Any opinions, findings, and conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of the National Science Foundation.
APPENDIX
A Appended Proofs
A.1 Proof of Galois Isomorphism (1)

A.2 Proofs of Corollary 1 and 2
Corollary 1.Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, for any maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\), if a trace σ belongs to the prediction trace property that corresponds to \(\mathcal {T}\), then every valid trace greater than σ belongs to that prediction trace property too. I.e., \(\forall \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}.\;\forall \sigma ,\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}.\;(\sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\wedge \sigma \preceq \sigma ^{\prime })\Rightarrow \sigma ^{\prime }\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).
Proof by contradiction. We assume \(\exists \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}.\) \(\exists \sigma ,\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}.\) \(\sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\wedge \sigma \preceq \sigma ^{\prime }\wedge \sigma ^{\prime }\not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\). By the definition of prediction abstraction, \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\) \(=\lbrace \sigma \in {\mathtt {Pref}} {\mathcal {T}}\) \(\mid\) \(\forall \sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\) \(\sigma \preceq \sigma ^{\prime } \Rightarrow \sigma ^{\prime }\in \mathcal {T}\rbrace\). There are two possibilities for \(\sigma ^{\prime }\not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\):
(1) \(\sigma ^{\prime }\not\in {\mathtt {Pref}} {\mathcal {T}}\), hence every maximal trace greater than \(\sigma ^{\prime }\) does not belong to \(\mathcal {T}\);
(2) \(\exists \sigma ^{\prime \prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\; \sigma ^{\prime }\preceq \sigma ^{\prime \prime } \wedge \sigma ^{\prime \prime }\not\in \mathcal {T}\).
Both cases imply that there is a maximal trace \(\sigma ^{\prime \prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\) such that \(\sigma \preceq \sigma ^{\prime }\preceq \sigma ^{\prime \prime } \wedge \sigma ^{\prime \prime }\not\in \mathcal {T}\), which contradicts with the assumption of \(\sigma \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).□
Corollary 2. Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, for any maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\) and any valid prefix trace π that is not maximal, if every valid prefix trace \(\pi {s}\) that concatenates π with a new event \({s}\) belongs to the prediction trace property \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\), then π belongs to \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\) too. More formally, \(\forall \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}.\)\(\forall \pi \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\)\((\forall {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \Rightarrow \pi {s}\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}})\Rightarrow \pi \in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).
Prove by contradiction, and here we assume that \(\exists \mathcal {T}\in \mathcal {L}^{\mathsf {Max}}.\) \(\exists \pi \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\) \((\forall {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \Rightarrow \pi {s}\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}})\wedge \pi \not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\). According to the definition that \(\alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}=\lbrace \sigma \in {\mathtt {Pref}} {\mathcal {T}}\mid \forall \sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\) \(\sigma \preceq \sigma ^{\prime } \Rightarrow \sigma ^{\prime }\in \mathcal {T}\rbrace\), there are two possibilities to have \(\pi \not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\):
(1) \(\pi \not\in {\mathtt {Pref}} {\mathcal {T}}\). This implies that \(\forall {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \Rightarrow \pi {s}\not\in {\mathtt {Pref}} {\mathcal {T}}\), which further implies that \(\forall {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \Rightarrow \pi {s}\not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\). Since \(\pi \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \backslash\) \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), there must exist at least one \({s}\) such that \(\pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\wedge \pi {s}\not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).
(2) There is a maximal trace \(\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Max}}\) such that \(\pi \prec \sigma ^{\prime } \wedge \sigma ^{\prime }\not\in \mathcal {T}\). Take \({s}={\sigma ^{\prime }}_{[|\pi |]}\), then \(\pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\wedge\) \(\pi {s}\preceq \sigma ^{\prime } \wedge \sigma ^{\prime }\not\in \mathcal {T}\) holds, which implies \(\pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\wedge\) \(\pi {s}\not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).
Both two cases find that \(\exists {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \wedge \pi {s}\not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\), which contradicts with the assumption \(\forall {s}\in \mathbb {S}.\, \pi {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}} \Rightarrow \pi {s}\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\).□
A.3 Proof of Lemma 2 and Corollary 4
Lemma 2.Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, the inquiry function \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}}\) is decreasing on the inquired trace σ: The greater (longer) σ is, the stronger property it can guarantee. I.e., \(\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\;\sigma \preceq \sigma ^{\prime }\Rightarrow \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\supseteq \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\).
First, if σ is invalid (i.e., \(\sigma \not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\)), then every trace \(\sigma ^{\prime }\) that is greater than σ must also be invalid (i.e., \(\sigma ^{\prime }\not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\)), hence it is obvious that \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }=\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\) \(=\bot ^{\mathsf {Max}}\).
Second, if \(\sigma ^{\prime }\) is invalid (\(\sigma ^{\prime }\not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\)), then \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}=\bot ^{\mathsf {Max}}\), hence \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma } \supseteq \bot ^{\mathsf {Max}}=\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\).
Last, if both σ and \(\sigma ^{\prime }\) are valid(\(\sigma ,\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\)), then we have

To sum up the three cases above, we prove that \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}}\) is decreasing.□
Corollary 4. Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of behaviors, \(\forall \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\)\(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }=\underset{ {s}\in \mathbb {S}}{\bigcup \!\!\!\!\!{\cdot} }\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}=\underset{\sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}}{\bigcup \!\!\!\!\!{\cdot} }\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\).
First, it is easy to see that \(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid {s}\in \mathbb {S}\rbrace\) \(=(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace)\) \(\cup\!\!\!\!\cdot (\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace)\) \(=(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace) \cup\!\!\!\!\cdot\) \(\bot ^{\mathsf {Max}}= \cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace\).
Second, we prove \(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace\) \(=\) \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\) in two steps: (1) by Lemma 2, it is proved that \(\forall \sigma , \sigma {s}\in \mathbb {S}^{\ast \infty }.\;\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\supseteq \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\), thus \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\supseteq \cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace\). (2) assume \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\supsetneq\) \(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace\) \(=\) \(\mathcal {T}\). By the definition of \(\mathbb {I}\) in (2), we know that \(\sigma \not\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\) and \(\forall \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}.\) \(\sigma {s}\in \alpha_{\text {Pred}} {[\![ \textrm {P}]\!] ^{\mathsf {Max}}}{\mathcal {T}}\), which is impossible by Corollary 2. Thus, by contradiction, \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\) \(=\) \(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma {s}}\mid \sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\rbrace\).□
A.4 Proofs of Corollary 6, 7, and Lemma 3
Corollary 6.Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\) and lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors, for any observer with cognizance \({\mathbb {C}}\), if the corresponding observation function maps a trace σ to a maximal trace property \(\mathcal {T}\in \mathcal {L}^{\mathsf {Max}}\), then σ guarantees the satisfaction of property \(\mathcal {T}\) (i.e., every valid maximal trace that is greater than or equal to σ is guaranteed to have property \(\mathcal {T}\)).
Suppose \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\) \(=\mathcal {T}^{\prime }\). By Corollary 3, σ guarantees the property \(\mathcal {T}^{\prime }\), i.e., every valid maximal trace that is greater than or equal to σ belongs to \(\mathcal {T}^{\prime }\).
In addition, since the cognizance is extensive (i.e., \(\sigma \in {\mathbb {C}{(\sigma)}}\)), then from the definition of observation function in (4), we know that \(\mathcal {T}\) \(=\) \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\) \(=\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\mid \sigma ^{\prime }\in {\mathbb {C}{(\sigma)}}\rbrace\) \(\supseteq\) \(\mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma }\) \(=\) \(\mathcal {T}^{\prime }\). Therefore, every valid maximal trace that is greater than or equal to σ belongs to \(\mathcal {T}\). That is to say, σ guarantees the satisfaction of property \(\mathcal {T}\).□
Corollary 7. Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), the lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors and the cognizance function \({\mathbb {C}}\), we have: \(\forall \sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}.\)\({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\)\(=\underset{ {s}\in \mathbb {S}}{\bigcup \!\!\!\!\!{\cdot} }{\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma {s}}=\underset{\sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}}{\bigcup \!\!\!\!\!{\cdot} }{\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma {s}}\).
We start the proof from the right side:

In the above, the formula is split into three cases by the length of \(\sigma ^{\prime \prime }\). The first case:

The second case: If there is \({s}\in \mathbb {S}\) such that \(\varepsilon \in {\mathbb {C}}{ {s}}\), then \(\cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }\sigma ^{\prime \prime }}\) \(\mid \sigma ^{\prime }\in {\mathbb {C}{(\sigma)}}\wedge \sigma ^{\prime \prime }\in {\mathbb {C}}{ {s}}\wedge {s}\in \mathbb {S}\wedge |\sigma ^{\prime \prime }|=0\rbrace = \cup\!\!\!\!\cdot \lbrace \mathbb {I}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, \sigma ^{\prime }}\mid \sigma ^{\prime }\in {\mathbb {C}{(\sigma)}}\rbrace = {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\). Otherwise, it is an empty set.
The third case:

Joining the above three cases together, we have proved that
\(\underset{\sigma {s}\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}}{\bigcup \!\!\!\!\!{\cdot} }{\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma {s}}={\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\).□
Lemma 3. Given the semantics \([\![ \textrm {P}]\!] ^{\mathsf {Max}}\), lattice \(\mathcal {L}^{\mathsf {Max}}\) of system behaviors and cognizance function \({\mathbb {C}}\), the observation function \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}}\) is decreasing on the observed trace σ: The greater (longer) σ is, the stronger property it can observe. I.e., \(\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\;\sigma \preceq \sigma ^{\prime }\Rightarrow {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\supseteq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}\).
We only need to consider the case where \(\sigma \prec \sigma ^{\prime }\). First, if σ is invalid (i.e., \(\sigma \not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\)), then every trace \(\sigma ^{\prime }\) that is greater than σ must also be invalid (i.e., \(\sigma ^{\prime }\not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\)), hence we have \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }={\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}=\bot ^{\mathsf {Max}}\).
Second, if \(\sigma ^{\prime }\not\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\), then we have \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}=\bot ^{\mathsf {Max}}\). Hence, it is trivial to find \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\supseteq \bot ^{\mathsf {Max}}={\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}\).
Last, if \(\sigma ,\sigma ^{\prime }\in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\), then σ must be a valid non-maximal trace, i.e., \(\sigma \in [\![ \textrm {P}]\!] ^{\mathsf {Pref}}\backslash [\![ \textrm {P}]\!] ^{\mathsf {Max}}\). From Corollary 7, it is easy to see \(\forall {s}\in \mathbb {S}.\) \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\supseteq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma {s}}\). Since \(\sigma ^{\prime }\) is greater than σ(or, say, \(\sigma ^{\prime }\) is a prolongation of σ with states), then by the transitivity of \(\supseteq\), it is not hard to see that \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma }\supseteq {\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma ^{\prime }}\).□
A.5 Proof of Theorem 1
Theorem 1.If \(\tau _{\mbox{R}}\) is said to be responsible for a behavior \(\mathcal {B}\) in a valid trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\sigma _{\mbox{F}}\), then \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\) guarantees the occurrence of behavior \(\mathcal {B}\), and there must exist another valid prefix trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}^{\prime }\) such that the behavior \(\mathcal {B}\) is not guaranteed.
First, from the definition of responsibility, we know \({\mathbb {O}} {}{}{(\mathcal {S}^{\mathsf {MAX}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}}\) \(\subseteq \mathcal {B}\). By Corollary 6, \(\sigma _{\mbox{H}}\tau _{\mbox{R}}\) guarantees the satisfaction of \({\mathbb {O}} {}{}{(\mathcal {S}^{\mathsf {MAX}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}}\), which is at least as strong as \(\mathcal {B}\). Thus, the occurrence of behavior \(\mathcal {B}\) is guaranteed.
Second, we prove by contradiction. Assume that every valid trace \(\sigma _{\mbox{H}}\tau _{\mbox{R}}^{\prime }\) guarantees the occurrence of behavior \(\mathcal {B}\) (i.e., \(\forall \sigma _{\mbox{H}}\tau _{\mbox{R}}^{\prime }\in \mathcal {S}^{\mathsf {Pref}}.\) \({\mathbb {O}} {}{}{(\mathcal {S}^{\mathsf {MAX}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}\tau _{\mbox{R}}^{\prime }}\) \(\subseteq \mathcal {B}\)). By Corollary 7, we can prove that \({\mathbb {O}} {}{}{(\mathcal {S}^{\mathsf {MAX}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\) \(\subseteq \mathcal {B}\), which contradicts with the condition \({\mathbb {O}} {}{}{[\![ \textrm {P}]\!] ^{\mathsf {Max}}, \mathcal {L}^{\mathsf {Max}}, {\mathbb {C}}, \sigma _{\mbox{H}}}\not\subseteq \mathcal {B}\) for \(\tau _{\mbox{R}}\) to be responsible for the behavior \(\mathcal {B}\).□
A.6 Proof of Galois Connection (2)

A.7 Proof of the Soundness Condition (3)
The abstract function \(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\) obeys the following soundness condition (\(\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\)): \[\begin{equation*} \begin{array}{c} \forall \mathsf {I}^{\sharp }\in \mathbb {L}\mapsto \mathcal {D}^{\sharp }_{\mathbb {M}}.\;\mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}\circ \dot{\gamma }_{\mathbb {M}}(\mathsf {I}^{\sharp })\; \dot{\subseteq }\; \dot{\gamma }_{\mathbb {M}}\circ \mathrm {F}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}(\mathsf {I}^{\sharp }).\end{array} \end{equation*}\]
A.8 Proof of Galois Connection (5)

For any \(\mathsf {I}_\mathsf {pre}, \mathsf {I}_\mathsf {post}\in \mathbb {L}\mapsto \wp (\mathbb {M})\), we can prove that:

Thus, the forward (possible success) reachability semantics \(\mathcal {S}\mathop{\rightarrow}\limits_{ps} [\![{\textrm {P}}]\!]{}{}\) and the backward impossible failure accessibility semantics \(\mathcal {S}\mathop{\leftarrow}\limits_{if} [\![{\textrm {P}}]\!]{}{}\) form a Galois connection.□
A.9 Proof of Corollary 8, Lemma 4, and Theorem 2
Corollary 8.\(\forall \rho \in \mathbb {M}.\; \forall \rho ^{\prime }\in [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}.\;\exists \rho ^{\prime \prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}.\; \forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p}).\; \rho ^{\prime }( {x}) = \rho ^{\prime \prime }( {x}).\)
The key is to prove there exists an environment \(\rho ^{\prime \prime }\) in \([\rho ]_{\overset{{d}_{c}}{\sim }}\) that satisfies all the requirements. Here, we construct \(\rho ^{\prime \prime } = \rho [\,\forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\cup \textrm {vars}({d}_{c}).\; {x}\mapsto \rho ^{\prime }( {x})]\) such that (i) \(\forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\cup \textrm {vars}({d}_{c}).\; \rho ^{\prime }( {x}) = \rho ^{\prime \prime }( {x})\) and (ii) \(\forall {x}\in \mathbb {X}\backslash (\textrm {vars}(\mbox{M}^{\sharp }_{p})\cup \textrm {vars}({d}_{c})).\; \rho ( {x}) = \rho ^{\prime \prime }( {x})\). Thus, the constructed environment \(\rho ^{\prime \prime }\) satisfies the requirement \(\forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p}).\; \rho ^{\prime }( {x}) = \rho ^{\prime \prime }( {x})\).
Now, we only need to prove that \(\rho ^{\prime \prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}\). Since \(\rho ^{\prime }\in [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}\), by the definition of \(\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\), we know that there are two possible cases: The first case is \(\rho = \rho ^{\prime }\), then \(\rho ^{\prime \prime }\) is also equal to ρ, which makes \(\rho ^{\prime \prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}\) trivial; the second case is \(\rho \in \gamma _{\mathbb {M}}({d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}({d}_{c})\) and (iii) \(\forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}).\; \rho ( {x}) = \rho ^{\prime }( {x})\). Since \(\forall {x}\in \textrm {vars}({d}_{c}).\; \rho ^{\prime }( {x}) = \rho ^{\prime \prime }( {x})\), by (21) we can prove that \(\rho ^{\prime \prime }\in \gamma _{\mathbb {M}}({d}_{c})\) holds. Moreover, combining (i) and (iii) together, we get \(\forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}).\; \rho ( {x}) = \rho ^{\prime \prime }( {x})\), which further implies that \(\forall {x}\in \mathbb {X}\backslash \textrm {vars}({d}_{c}).\; \rho ( {x}) = \rho ^{\prime \prime }( {x})\). By the definition of \(\overset{{d}_{c}}{\sim }\), we have proved that \(\rho ^{\prime \prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}\).□
Lemma 4. A partitioning directive \({d}_{p}= \textrm {part}\langle \textrm {Inv},\: {l},\:\mbox{M}^{\sharp }_{p}\rangle\) is valid with respect to a cognizance directive \({d}_{c}\in \mathcal {D}^{\sharp }_{\mathbb {M}}\) if and only if \[\begin{equation*} \begin{array}{c} \forall \rho \in \gamma _{\mathbb {M}}({d}_{c}).\;[\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\;\vee \;[\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset ,\end{array} \end{equation*}\] where \([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} = \lbrace \rho ^{\prime }\in \mathbb {M}\mid \rho \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\rho ^{\prime }\rbrace\) and \(\rho \sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}\rho ^{\prime }\Leftrightarrow \rho =\rho ^{\prime } \vee (\rho \in \gamma _{\mathbb {M}}({d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}({d}_{c})\wedge \forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p})\backslash \textrm {vars}({d}_{c}).\, \rho ( {x}) = \rho ^{\prime }( {x}))\).
To prove that the condition (20) is equivalent to the condition (23), we first need to show that: \(\forall {d}_{c}, \mbox{M}^{\sharp }_{p}\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\; \forall \rho \in \mathbb {M}.\; [\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \Leftrightarrow [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\). The proof of this statement from right to left is trivial, since \([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}\) (22). Here, we consider the opposite direction: \([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \Rightarrow [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\). By Corollary (8), we have \(\forall \rho ^{\prime }\in [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}}.\;\exists \rho ^{\prime \prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}.\; \forall {x}\in \textrm {vars}(\mbox{M}^{\sharp }_{p}).\; \rho ^{\prime }( {x}) = \rho ^{\prime \prime }( {x})\). Since the assumption \([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) implies that \(\rho ^{\prime \prime } \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\), then by (21), we prove that \(\rho ^{\prime } \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\), which implies that \([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\).
Similarly, we can prove that \([\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset \Leftrightarrow [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset\).
Together, we have proved that \(\forall {d}_{c}, \mbox{M}^{\sharp }_{p}\in \mathcal {D}^{\sharp }_{\mathbb {M}}.\; \forall \rho \in \mathbb {M}.\; ([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \vee [\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset) \Leftrightarrow ([\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \vee [\rho ]_{\sim _{{\mbox{M}^{\sharp }_{p}}\backslash {{d}_{c}}}} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset)\).□
Theorem 2. If the partition function \(\mathbb {P}^{\sharp }\) is valid with respect to the cognizance function \({\mathbb {C}}^{\sharp}\), then every two indistinguishable traces \(\sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\) must belong to the same partition created by \(\mathbb {P}^{\sharp }\) at every program point along the execution.
Formally, \(\forall \mathbb {C}^{\sharp},\mathbb {P}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}}).\; \textrm {isValid}_{\mathbb {P}}(\mathbb {C}^{\sharp}, \mathbb {P}^{\sharp }) \Rightarrow (\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\; \sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime } \Rightarrow (\forall i\in [0, |\sigma |).\; \exists {l}\in \mathbb {L}, \rho , \rho ^{\prime } \in \mathbb {M}.\; {\sigma }_{[i]} = \langle {l},\:\rho \rangle \wedge {\sigma ^{\prime }}_{[i]} = \langle {l},\:\rho ^{\prime }\rangle \wedge \forall \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}).\; \rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \Leftrightarrow \rho ^{\prime }\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})))\).
The contraposition of this theorem states that, suppose \(\mathbb {P}^{\sharp }\) is valid with respect to \({\mathbb {C}}^{\sharp}\), if two traces do not belong to the same partition created by \(\mathbb {P}^{\sharp }\) at some program point along the execution, then these two traces cannot be equivalent according to \({\mathbb {C}}^{\sharp}\). More formally, \(\forall \mathbb {C}^{\sharp},\mathbb {P}^{\sharp }\in \mathbb {L}\mapsto \wp (\mathcal {D}^{\sharp }_{\mathbb {M}}).\; \textrm {isValid}_{\mathbb {P}}(\mathbb {C}^{\sharp}, \mathbb {P}^{\sharp }) \Rightarrow (\forall \sigma ,\sigma ^{\prime }\in \mathbb {S}^{\ast \infty }.\; (\exists i\in [0, |\sigma |), {l}\in \mathbb {L}, \rho , \rho ^{\prime } \in \mathbb {M}, \mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}).\; {\sigma }_{[i]} = \langle {l},\:\rho \rangle \wedge {\sigma ^{\prime }}_{[i]} = \langle {l},\:\rho ^{\prime }\rangle \wedge \rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \wedge \rho ^{\prime }\not\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}))\Rightarrow \sigma \overset{\mathbb {C}^{\sharp}}{\not\sim }\sigma ^{\prime })\).
Here, we prove by contradiction. Assume that there exist two traces \(\sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\) such that they do not belong to the same partition at some location i, i.e., \(\mbox{M}^{\sharp }_{p}\in \mathbb {P}^{\sharp }( {l}) \wedge {\sigma }_{[i]} = \langle {l},\:\rho \rangle \wedge {\sigma ^{\prime }}_{[i]} = \langle {l},\:\rho ^{\prime }\rangle \wedge \rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \wedge \rho ^{\prime }\not\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\).
Since \(\sigma \overset{\mathbb {C}^{\sharp}}{\sim }\sigma ^{\prime }\), there must exist some \({d}_{c}\in \mathbb {C}^{\sharp} { {l}}\) such that \(\rho \overset{{d}_{c}}{\sim }\rho ^{\prime }\). By the definition of \(\overset{{d}_{c}}{\sim }\), there are two possible cases:
(1) \(\rho = \rho ^{\prime }\). In this case, it is impossible to have \(\rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \wedge \rho ^{\prime }\not\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\), which simply introduces a contradiction.
(2) \(\rho \in \gamma _{\mathbb {M}}({d}_{c})\wedge \rho ^{\prime }\in \gamma _{\mathbb {M}}({d}_{c})\wedge \forall {x}\in \mathbb {X}\backslash \textrm {vars}({d}_{c}).\, \rho ( {x}) = \rho ^{\prime }( {x})\). Since \(\textrm {isValid}_{\mathbb {P}}(\mathbb {C}^{\sharp}, \mathbb {P}^{\sharp })\) is true, we know \(\textrm {isValid}_{{d}}({d}_{c}, \mbox{M}^{\sharp }_{p})\) must hold, which further implies \([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\;\vee \;[\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) = \emptyset\) (19). By the assumption \(\rho \in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) and the fact that \(\rho \in [\rho ]_{\overset{{d}_{c}}{\sim }}\), we know \([\rho ]_{\overset{{d}_{c}}{\sim }} \cap \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p}) \ne \emptyset\), thus \([\rho ]_{\overset{{d}_{c}}{\sim }} \subseteq \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\) must hold. Since \(\rho \overset{{d}_{c}}{\sim }\rho ^{\prime }\), we have \(\rho ^{\prime }\in [\rho ]_{\overset{{d}_{c}}{\sim }}\), thus \(\rho ^{\prime }\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\), which contradicts with the assumption \(\rho ^{\prime }\not\in \gamma _{\mathbb {M}}(\mbox{M}^{\sharp }_{p})\).□
- [1] . 1999. A core calculus of dependency. In POPL. ACM, 147–160.Google Scholar
- [2] . 1990. Dynamic Program Slicing. In PLDI. ACM, 246–256.Google Scholar
- [3] . 2017. A relational logic for higher-order programs. Proc. ACM Program. Lang. 1, ICFP (2017), 21:1–21:29.Google Scholar
Digital Library
- [4] . 2019. A relational logic for higher-order programs. J. Funct. Program. 29 (2019), e16.
DOI: https://doi.org/10.1017/S0956796819000145Google ScholarCross Ref
- [5] . 2008. The Parma Polyhedra Library: Toward a complete set of numerical abstractions for the analysis and verification of hardware and software systems. Sci. Comput. Program. 72, 1-2 (2008), 3–21.
DOI: https://doi.org/10.1016/j.scico.2007.08.001Google ScholarDigital Library
- [6] . 2002. Possibly not closed convex polyhedra and the Parma Polyhedra Library. In Static Analysis, 9th International Symposium, SAS 2002, Madrid, Spain, September 17–20, 2002, Proceedings(
Lecture Notes in Computer Science , Vol. 2477), and (Eds.). Springer, 213–229.DOI: https://doi.org/10.1007/3-540-45789-5_17Google ScholarCross Ref
- [7] . 2014. Backward analysis via over-approximate abstraction and under-approximate subtraction. In Static Analysis - 21st International Symposium, SAS 2014, Munich, Germany, September 11–13, 2014. Proceedings(
Lecture Notes in Computer Science , Vol. 8723), and (Eds.). Springer, 34–50.DOI: https://doi.org/10.1007/978-3-319-10936-7_3Google ScholarCross Ref
- [8] . 2003. From symptom to cause: Localizing errors in counterexample traces. In POPL. ACM, 97–105.Google Scholar
- [9] . 2015. Symbolic causality checking using bounded model checking. In Model Checking Software - 22nd International Symposium, SPIN 2015, Stellenbosch, South Africa, August 24–26, 2015, Proceedings(
Lecture Notes in Computer Science , Vol. 9232), and (Eds.). Springer, 203–221.DOI: https://doi.org/10.1007/978-3-319-23404-5_14Google ScholarDigital Library
- [10] . 2012. Explaining counterexamples using causality. Form. Meth. Syst. Des. 40, 1 (2012), 20–40.Google Scholar
Digital Library
- [11] . 2016. Incorporating knowledge into structural equation models using auxiliary variables. In IJCAI. IJCAI/AAAI Press, 3577–3583.Google Scholar
- [12] . 2011. Provenance as dependency analysis. Math. Struct. Comput. Sci. 21, 6 (2011), 1301–1337.Google Scholar
Digital Library
- [13] . 2004. Responsibility and blame: A structural-model approach. J. Artif. Intell. Res. 22 (2004), 93–115.Google Scholar
Cross Ref
- [14] . 2008. What causes a system to satisfy a specification? ACM Trans. Comput. Log. 9, 3 (2008), 20:1–20:26.Google Scholar
Digital Library
- [15] . 2015. Structural Equation Models, from Paths to Networks. Springer.Google Scholar
- [16] . 2008. Hyperproperties. In CSF. IEEE Computer Society, 51–65.
DOI: https://doi.org/10.1109/CSF.2008.7Google Scholar - [17] . 2019. Abstract semantic dependency. In Static Analysis - 26th International Symposium, SAS 2019, Porto, Portugal, October 8–11, 2019, Proceedings(
Lecture Notes in Computer Science , Vol. 11822), (Ed.). Springer, 389–410.DOI: https://doi.org/10.1007/978-3-030-32304-2_19Google ScholarDigital Library
- [18] . 2021. Principles of Abstract Interpretation. The MIT Press.Google Scholar
- [19] . 1976. Static determination of dynamic properties of programs. In Proceedings of the Second International Symposium on Programming. Dunod, Paris, France, 106–130.Google Scholar
- [20] . 1977. Abstract Interpretation: A unified lattice model for static analysis of programs by construction or approximation of fixpoints. In POPL. ACM, 238–252.Google Scholar
- [21] . 1979. Systematic design of program analysis frameworks. In POPL. ACM Press, 269–282.Google Scholar
- [22] . 2005. The ASTREÉ analyzer. In Programming Languages and Systems, 14th European Symposium on Programming,ESOP 2005, Held as Part of the Joint European Conferences on Theory and Practice of Software, ETAPS 2005, Edinburgh, UK, April 4–8, 2005, Proceedings(
Lecture Notes in Computer Science , Vol. 3444), (Ed.). Springer, 21–30.DOI: https://doi.org/10.1007/978-3-540-31987-0_3Google ScholarDigital Library
- [23] . 2009. Why does Astrée scale up? Form. Meth. Syst. Des. 35, 3 (2009), 229–264.
DOI: https://doi.org/10.1007/s10703-009-0089-6Google ScholarDigital Library
- [24] . 1978. Automatic discovery of linear restraints among variables of a program. In Conference Record of the Fifth Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages. ACM Press, New York, NY, 84–97.Google Scholar
Digital Library
- [25] . 2019. Responsibility analysis by abstract interpretation. In Static Analysis - 26th International Symposium, SAS 2019, Porto, Portugal, October 8–11, 2019, Proceedings(
Lecture Notes in Computer Science , Vol. 11822), (Ed.). Springer, 368–388.DOI: https://doi.org/10.1007/978-3-030-32304-2_18Google ScholarDigital Library
- [26] . 2019. Responsibility analysis by abstract interpretation. Retrieved from http://arxiv.org/abs/1907.08251.Google Scholar
- [27] . 2012. Automated error diagnosis using abductive inference. In PLDI. ACM, 181–192.Google Scholar
- [28] . 1976. Harré on causation. Philos. Sci. 43, 4 (
Dec. 1976), 560–569.Google ScholarCross Ref
- [29] . 2018. Practical accountability of secret processes. In USENIX Security Symposium. USENIX Association, 657–674.Google Scholar
- [30] . 2018. Abstract non-interference: A unifying framework for weakening information-flow. ACM Trans. Priv. Secur. 21, 2 (2018), 9:1–9:31.Google Scholar
Digital Library
- [31] . 1982. Security policies and security models. In IEEE Symposium on Security and Privacy. IEEE Computer Society, 11–20.Google Scholar
- [32] . 2007. Automated fault localization for C programs. Electr. Notes Theor. Comput. Sci. 174, 4 (2007), 95–111.Google Scholar
Digital Library
- [33] . 2006. Error explanation with distance metrics. Int. J. Softw. Tools Technol. Transf. 8, 3 (2006), 229–247.Google Scholar
Cross Ref
- [34] . 2001. Causes and explanations: A structural-model approach: Part 1: Causes. In UAI. Morgan Kaufmann, 194–202.Google Scholar
- [35] . 2005. Causes and explanations: A structural-model approach. Part I: Causes. Brit. J. Philos. Sci. 56, 4 (2005), 843–887.Google Scholar
Cross Ref
- [36] . 2002. Tracking down software bugs using automatic anomaly detection. In ICSE. ACM, 291–301.Google Scholar
- [37] . 2019. Outside the Box: Abstraction-Based Monitoring of Neural Networks. arXiv preprint arXiv:1911.09032 (2019).Google Scholar
- [38] . 1748. An Enquiry Concerning Human Understanding. A. Millar, London. Retrieved from http://www.davidhume.org/texts/ehu.html.Google Scholar
- [39] . 2009. Towards a theory of accountability and audit. In ESORICS(
Lecture Notes in Computer Science , Vol. 5789). Springer, 152–167.Google Scholar - [40] . 2009. The Interproc Analyzer. Retrieved from http://pop-art.inrialpes.fr/interproc/interprocweb.cgi.Google Scholar
- [41] . 2009. Apron: A library of numerical abstract domains for static analysis. In Computer-aided Verification, 21st International Conference, CAV 2009, Grenoble, France, June 26–July 2, 2009. Proceedings(
Lecture Notes in Computer Science , Vol. 5643), and (Eds.). Springer, 661–667.DOI: https://doi.org/10.1007/978-3-642-02658-4_52Google ScholarDigital Library
- [42] . 2002. Fate and free will in error traces. In TACAS(
Lecture Notes in Computer Science , Vol. 2280). Springer, 445–459.Google Scholar - [43] . 2011. Cause clue clauses: Error localization using maximum satisfiability. In PLDI. ACM, 437–446.Google Scholar
- [44] . 2018. An iterative approach to precondition inference using constrained Horn clauses. Theor. Pract. Log. Program. 18, 3–4 (2018), 553–570.
DOI: https://doi.org/10.1017/S1471068418000091Google ScholarCross Ref
- [45] . 2008. Effective blame for information-flow violations. In SIGSOFT FSE. ACM, 250–260.Google Scholar
- [46] . 1998. Dynamic program slicing methods. Inf. Softw. Technol. 40, 11–12 (1998), 647–659.Google Scholar
Cross Ref
- [47] . 2011. From probabilistic counterexamples via causality to fault trees. In Computer Safety, Reliability, and Security - 30th International Conference, SAFECOMP 2011, Naples, Italy, September 19–22, 2011. Proceedings(
Lecture Notes in Computer Science , Vol. 6894), , , and (Eds.). Springer, 71–84.DOI: https://doi.org/10.1007/978-3-642-24270-0_6Google ScholarCross Ref
- [48] . 2009. Program Dependencies. Springer London, 125–142.
DOI: https://doi.org/10.1007/978-1-84882-240-5_6Google Scholar - [49] . 2013. Causality checking for complex system models. In Verification, Model Checking, and Abstract Interpretation, 14th International Conference, VMCAI 2013, Rome, Italy, January 20–22, 2013. Proceedings(
Lecture Notes in Computer Science , Vol. 7737), , , and (Eds.). Springer, 248–267.DOI: https://doi.org/10.1007/978-3-642-35873-9_16Google ScholarDigital Library
- [50] . 2007. Backward Analysis for Inferring Quantified Preconditions. Tr-2007-12-01, Tel Aviv University.Google Scholar
- [51] . 1973. Causation. J. Philos. 70, 17 (1973), 556–567.Google Scholar
Cross Ref
- [52] . 2013. Counterfactuals. John Wiley & Sons.Google Scholar
- [53] . 2005. Trace partitioning in abstract interpretation-based static analyzers. In ESOP(
Lecture Notes in Computer Science , Vol. 3444). Springer, 5–20.Google Scholar - [54] . 2017. Counterfactual theories of causation. In the Stanford Encyclopedia of Philosophy (winter 2017 ed.), (Ed.). Metaphysics Research Lab, Stanford University.Google Scholar
- [55] . 2012. The Banal Static Analyzer Prototype. Retrieved from https://www-apr.lip6.fr/mine/banal/.Google Scholar
- [56] . 2001. A new numerical abstract domain based on difference-bound matrices. In Programs as Data Objects, Second Symposium, PADO 2001, Aarhus, Denmark, May 21–23, 2001, Proceedings(
Lecture Notes in Computer Science , Vol. 2053), and (Eds.). Springer, 155–172.DOI: https://doi.org/10.1007/3-540-44978-7_10Google ScholarCross Ref
- [57] . 2001. The octagon abstract domain. In Proceedings of the Eighth Working Conference on Reverse Engineering, WCRE’01, Stuttgart, Germany, October 2–5, 2001, , , and (Eds.). IEEE Computer Society, 310.
DOI: https://doi.org/10.1109/WCRE.2001.957836Google ScholarCross Ref
- [58] . 2006. The octagon abstract domain. High. Order Symb. Comput. 19, 1 (2006), 31–100.
DOI: https://doi.org/10.1007/s10990-006-8609-1Google ScholarDigital Library
- [59] . 2006. Symbolic methods to enhance the precision of numerical abstract domains. In Verification, Model Checking, and Abstract Interpretation, 7th International Conference, VMCAI 2006, Charleston, SC, USA, January 8–10, 2006, Proceedings(
Lecture Notes in Computer Science , Vol. 3855), and (Eds.). Springer, 348–363.DOI: https://doi.org/10.1007/11609773_23Google ScholarCross Ref
- [60] . 2012. Inferring sufficient conditions with backward polyhedral under-approximations. Electron. Notes Theor. Comput. Sci. 287 (2012), 89–100.
DOI: https://doi.org/10.1016/j.entcs.2012.09.009Google ScholarDigital Library
- [61] . 2014. Backward under-approximations in numeric abstract domains to automatically infer sufficient program conditions. Sci. Comput. Program. 93 (2014), 154–182.
DOI: https://doi.org/10.1016/j.scico.2013.09.014Google ScholarDigital Library
- [62] . 2010. Robust and Generic Abstract Domain for Static Program Analyses: The Polyhedral Case. Ph.D. Dissertation. Paris, ENMP.Google Scholar
- [63] . 2013. Causality: Models, Reasoning and Inference (2nd ed.). Cambridge University Press.Google Scholar
- [64] . 2005. Interprocedural analysis for privileged code placement and tainted variable detection. In ECOOP(
Lecture Notes in Computer Science , Vol. 3586). Springer, 362–386.Google Scholar - [65] . 2009. Darwin: An approach for debugging evolving programs. In ESEC/SIGSOFT FSE. ACM, 33–42.Google Scholar
- [66] . 2004. Minimal assignments for bounded model checking. In TACAS(
Lecture Notes in Computer Science , Vol. 2988). Springer, 31–45.Google Scholar - [67] . 2003. Fault localization with nearest neighbor queries. In ASE. IEEE Computer Society, 30–39.Google Scholar
- [68] . 1948. Relations binaires, fermetures, correspondances de Galois. Bulletin de la S.M.F., Tome 76 (1948), 114–155.Google Scholar
- [69] . 2005. Understanding the origin of alarms in Astrée. In SAS(
Lecture Notes in Computer Science , Vol. 3672). Springer, 303–319.Google Scholar - [70] . 2007. The trace partitioning abstract domain. ACM Trans. Program. Lang. Syst. 29, 5 (2007), 26.Google Scholar
Digital Library
- [71] . 2020. Introduction to Static Analysis. The MIT Press.Google Scholar
- [72] . 1955. A lattice-theoretical fixpoint theorem and its applications. Pacif. J. Math. 5, 2 (1955), 285–309.Google Scholar
Cross Ref
- [73] . 2018. An abstract interpretation framework for input data usage. In ESOP(
Lecture Notes in Computer Science , Vol. 10801). Springer, 683–710.Google Scholar - [74] . 1981. Program slicing. In ICSE. IEEE Computer Society, 439–449.Google Scholar
Digital Library
- [75] . 1984. Program slicing. IEEE Trans. Softw. Eng. 10, 4 (1984), 352–357.Google Scholar
Digital Library
- [76] . 2008. Information accountability. Commun. ACM 51, 6 (2008), 82–87.Google Scholar
Digital Library
Index Terms
The Systematic Design of Responsibility Analysis by Abstract Interpretation
Recommendations
Responsibility Analysis by Abstract Interpretation
Static AnalysisAbstractGiven a behavior of interest in the program, statically determining the corresponding responsible entity is a task of critical importance, especially in program security. Classical static analysis techniques (e.g. dependency analysis, taint ...
Complementation in abstract interpretation
Reduced product of abstract domains is a rather well-known operation for domain composition in abstract interpretation. In this article, we study its inverse operation, introducing a notion of domain complementation in abstract interpretation. ...


































Comments