Mutation Testing with Hyperproperties

We present a new method for model-based mutation-driven test case generation. Mutants are generated by making small syntactical modifications to the model or source code of the system under test. A test case kills a mutant if the behavior of the mutant deviates from the original system when running the test. In this work, we use hyperproperties-which allow to express relations between multiple executions-to formalize different notions of killing for both deterministic as well as non-deterministic models. The resulting hyperproperties are universal in the sense that they apply to arbitrary reactive models and mutants. Moreover, an off-the-shelf model checking tool for hyperproperties can be used to generate test cases. We evaluate our approach on a number of models expressed in two different modeling languages by generating tests using a state-of-the-art mutation testing tool.


Introduction
Mutations-small syntactic modifications of programs that mimic typical programming errors-are used to assess the quality of existing test suites. A test kills a mutated program (or mutant), obtained by applying a mutation operator to a program, if its outcome for the mutant deviates from the outcome for the unmodified program. The percentage of mutants killed by a given test suite serves as a metric for test quality. The approach is based on two assumptions: (a) the competent programmer hypothesis [11], which states that implementations are typically close-to-correct, and (b) the coupling effect [26], which states that a test suites ability to detect simple errors (and mutations) is indicative of its ability to detect complex errors.
In the context of model-based testing, mutations are also used to design tests. Modelbased test case generation is the process of deriving tests from a reference model (which is assumed to be free of faults) in such a way that they reveal any non-conformance of the reference model and its mutants, i.e., kill the mutants. The tests detect potential errors (modeled by mutation operators) of implementations, treated as a black box in this setting, that conform to a mutant instead of the reference model. A test strongly kills a mutant if it triggers an observable difference in behavior [11], and weakly kills a mutant if the deviation is merely in a difference in traversed program states [21].
The aim of our work is to automatically construct tests that strongly kill mutants derived from a reference model. To this end, we present two main contributions: (1) A formalization of mutation killing in terms of hyperproperties [14], a formalism to relate multiple execution traces of a program which has recently gained popularity due to its ability to express security properties such as non-interference and observational determinism. Notably, our formalization also takes into account potential non-determinism, which significantly complicates killing of mutants due to the unpredictability of the test outcome. (2) An approach that enables the automated construction of tests by means of model checking the proposed hyperproperties on a model that aggregates the reference model and a mutant of it. To circumvent limitations of currently available model checking tools for hyperproperties, we present a transformation that enables the control of non-determinism via additional program inputs. We evaluate our approach using a state-of-the-art model checker on a number of models expressed in two different modeling languages.
Running example. We illustrate the main concepts of our work in Figure 1. Figure 1a shows the SMV [24] model of a beverage machine, which non-deterministically serves coff (coffee) or tea after input req (request), assuming that there is still enough wtr (water) in the tank. Water can be refilled with input fill. The symbol ε represents absence of input and output, respectively. The code in Figure 1a includes the variable mut (initialized non-deterministically in line 1), which enables the activation of a mutation in line 7. The mutant refills 1 unit of water only, whereas the original model fills 2 units. Figure 1b states a hyperproperty over the inputs and outputs of the model formalizing that the mutant can be killed definitely (i.e., independently of non-deterministic choices). The execution shown in Figure 1c is a witness for this claim: the test requests two drinks after filling the tank. For the mutant, the second request will necessarily fail, as indicated in Figure 1d, which shows all possible output sequences for the given test.
Outline. Section 2 introduces our system model and HyperLTL. Section 3 explains the notions of potential and definite killing of mutants, which are then formalized in terms of hyperproperties for deterministic and non-deterministic models in Section 4. Section 5 introduces a transformation to control non-determinism in models, and Section 6 describes our experimental results. Related work is discussed in Section 7.
denote Y with v set to and ⊥, respectively. We assume that the initial conditions-and transition relation predicate are defined in a logic that includes standard Boolean operators ¬, ∧, ∨, →, and ↔. We omit further details, as as our results do not depend on a specific formalism. We write X, O |= α and I, O, X, X |= δ to denote that α and δ evaluate to true under an evaluation of inputs I, outputs O, states X, and successor states X . We assume that every STS has a distinct output O ε , representing absence of output.
A state X with output O such that X, O |= α are an initial state and initial output. A state X has a transition with input I to its successor state X with output O iff I, O, X, X |= δ, denoted by X I,O − − → X . A trace of S is a sequence of tuples of concrete inputs, outputs, and states We require that every state has at least one successor, therefore all traces of S are infinite. We denote by T (S) the set of all traces of S. Given a trace p = (I 0 , O 0 , X 0 ), (I 1 , O 1 , X 1 ), . . . , we write p[j] for S is deterministic iff there is a unique pair of an initial state and initial output and for each state X and input I, there is at most one state X with output O, such that X In the following, we presume the existence of sets of atomic propositions AP = {AP I ∪ AP O ∪ AP X } (intentionally kept abstract) 1 serving as labels that characterize inputs, outputs, and states (or properties thereof).
For a trace p = (I 0 , O 0 , X 0 ), ( Example 1. Figure 1a shows the formalization of a beverage machine in SMV [24]. In Figure 1b, we use atomic propositions to enumerate the possible values of in and out. This SMV model closely corresponds to an STS: the initial condition predicate α and transition relation δ are formalized using integer arithmetic as follows: The trace p = (ε, ε, 2), (req, ε, 2), (req, coff, 1), (ε, tea, 0), . . . is one possible execution of the system (for brevity, variable names are omitted

HyperLTL
In the following, we provide an overview of the HyperLTL, a logic for hyperproperties, sufficient for understanding the formalization in Section 4. For details, we refer the reader to [13]. HyperLTL is defined over atomic proposition traces (see Section 2.1) of a fixed STS S = I, O, X , α, δ as defined in Section 2.1.
Syntax. Let AP be a set of atomic propositions and let π be a trace variable from a set V of trace variables. Formulas of HyperLTL are defined by the following grammar: ψ ::= ∃π.ψ | ∀π.ψ | ϕ ϕ ::= a π | ¬ϕ | ϕ ∨ ϕ | ϕ | ϕ Uϕ Connectives ∃ and ∀ are universal and existential trace quantifiers, read as "along some traces" and "along all traces". In our setting, atomic propositions a ∈ AP express facts about states or the presence of inputs and outputs. Each atomic proposition is sub-scripted with a trace variable to indicate the trace it is associated with. The Boolean connectives ∧, →, and ↔ are defined in terms of ¬ and ∨ as usual. Furthermore, we use the standard temporal operators eventually ♦ϕ def = true Uϕ, and always ϕ def = ¬♦¬ϕ.
Semantics Π |= S ψ states that ψ is valid for a given mapping Π : V → APTr(S) of trace variables to atomic proposition traces. Let Π [π → p] be as Π except that π is mapped to p. We use Π [i, ∞] to denote the trace assignment Π (π) = Π(π) [i, ∞] for all π. The validity of a formula is defined as follows: and for all 0 ≤ j < i we have Π [j, ∞] |= S ϕ 1 We write |= S ψ if Π |= S ψ holds and Π is empty. We call q ∈ T (S) a π-witness of a formula ∃π.ψ, if Π [π → p] |= S ψ and AP(q) = p.

Killing mutants
In this section, we introduce mutants, tests, and the notions of potential and definite killing. We discuss how to represent an STS and its corresponding mutant as a single STS, which can then be model checked to determine killability.

Mutants
Mutants are variations of a model S obtained by applying small modifications to the syntactic representation of S. A mutant of an STS S = I, O, X , α, δ (the original model) is an STS S m = I, O, X , α m , δ m with equal sets of input, output, and state variables as S but a deviating initial predicate and/or transition relation. We assume that S m is equally input-enabled as S, that is T (S m )| I = T (S)| I , i.e., the mutant and model accept the same sequences of inputs. In practice, this can easily be achieved by using self-loops with empty output to ignore unspecified inputs. We use standard mutation operators, such as disabling transitions, replacing operators, etc. Due to space limitations and the fact that mutation operators are not the primary focus of this work, we do not list them here, but refer to Appendix A and [5].
We combine an original model represented by S and a mutant S m into a conditional mutant S c(m) , in order to perform mutation analysis via model checking the combined model. The conditional mutant is defined as , where mut is a fresh Boolean variable used to distinguish states of the original and the mutated STS.
Suppose S m replaces a sub-formula δ 0 of δ by δ m 0 , then the transition relation predicate of the conditional mutant δ c(m) is obtained by replacing δ 0 in δ by (mut ∧ δ m 0 ) ∨ (¬mut ∧ δ 0 ). We fix the value of mut in transitions by conjoining δ with mut ↔ mut . The initial conditions predicate of the conditional mutant is defined similarly. Consequently, for a trace is non-deterministic, since mut is chosen non-deterministically in the initial state. However, we only refer to S c(m) as "non-deterministic" if either S or S m is non-deterministic, as mut is typically fixed in the hypertproperties in Section 4. Example 1 and Figure 1a show a conditional mutant as an STS and in SMV.

Killing
Killing a mutant amounts to finding inputs for which the mutant produces outputs that deviate from the original model. In a reactive, model-based setting, killing has been formalized using conformance relations [28], for example in [4,15], where an implementation conforms to its specification if all its input/output sequences are part of/allowed by the specification. In model-based testing, the model takes the role of the specification and is assumed to be correct by design. The implementation is treated as black box, and therefore mutants of the specification serve as its proxy. Tests (i.e., input/output sequences) that demonstrate non-conformance between the model and its mutant can be used to check whether the implementation adheres to the specification or contains the bug reflected in the mutant. The execution of a test on a system under test fails if the sequence of inputs of the test triggers a sequence of outputs that deviates from those predicted by the test. Formally, tests are defined as follows: Definition 1 (Test). A test t of length n for S comprises inputs t| I and outputs t| O of length n, such that there exists a trace p ∈ T (S) with p| I [0, n] = t| I and For non-deterministic models, in which a single sequence of inputs can trigger different sequences of outputs, we consider two different notions of killing. We say that a mutant can be potentially killed if there exist inputs for which the mutant's outputs deviate from the original model given an appropriate choice of non-deterministic initial states and transitions. In practice, executing a test that potentially kills a mutant on a faulty implementation that exhibits non-determinism (e.g., a multi-threaded program) may fail to demonstrate non-conformance (unless the non-determinism can be controlled). A mutant can be definitely killed if there exists a sequence of inputs for which the behaviors of the mutant and the original model deviate independently of how non-determinism is resolved. Note potential and definite killability are orthogonal to the folklore notions of weak and strong killing, which capture different degrees of observability. Formally, we define potential and definite killability as follows: Note that definite killability is stronger than potential killabilty, though for deterministic systems, the two notions coincide. Proposition 1. If S m is definitely killable then S m is potentially killable. If S m is deterministic then: S m is potentially killable iff S m is definitely killable.
The following example shows a definitely killable mutant, a mutant that is only potentially killable, and an equivalent mutant. Figure 1a, is definitely killable, since we can force the system into a state in which both possible outputs of the original system (coff, tea) differ from the only possible output of the mutant (ε).

Example 2. The mutant in
Consider a mutant that introduces non-determinism by replacing line 7 with the code if(in=fill):(mut ? {1,2} : 2), indicating that the machine is filled with either 1 or 2 units of water. This mutant is potentially but not definitely killable, as only one of the non-deterministic choices leads to a deviation of the outputs.
Finally, consider a mutant that replaces line 4 with if(in=req&wtr>0):(mut ? coff : {coff,tea}) and removes the mut branch of line 7, yielding a machine that always creates coffee. Every implementation of this mutant is also correct with respect to the original model. Hence, we consider the mutant equivalent, even though the original model, unlike the mutant, can output tea.
In this section, we provide a formalization of potential and definite killability in terms of HyperLTL, assert the correctness of our formalization with respect to Section 3, and explain how tests can be extracted by model checking the HyperLTL properties. All HyperLTL formulas depend on inputs and outputs of the model, but are model-agnostic otherwise. The idea of all presented formulas is to discriminate between traces of the original model ( ¬mut π ) and traces of the mutant ( mut π ). Furthermore, we quantify over pairs (π, π ) of traces with globally equal inputs ( i∈AP I i π ↔ i π ) and express that such pairs will eventually have different outputs (♦ o∈AP O ¬(o π ↔ o π )).

Deterministic Case
To express killability (potential and definite) of a deterministic model and mutant, we need to find a trace of the model (∃π) such that the trace of the mutant with the same inputs (∃π ) eventually diverges in outputs, formalized by φ 1 as follows: Proposition 2. For a deterministic model S and mutant S m it holds that If t is a π-witness for S c(m) |= φ 1 (I, O), then t[0, n]| I∪O kills S m (for some n ∈ N).

Non-deterministic Case
For potential killability of non-deterministic models and mutants, 2 we need to find a trace of the mutant (∃π) such that all traces of the model with the same inputs (∀π ) eventually diverge in outputs, expressed in φ 2 : Proposition 3. For non-deterministic S and S m , it holds that If s is a π-witness for S c(m) |= φ 2 (I, O), then for any trace t ∈ T (S) with t| I = s| I , t[0, n]| I∪O potentially kills S m (for some n ∈ N).
To express definite killability, we need to find a sequence of inputs of the model (∃π) and compare all non-deterministic outcomes of the model (∀π ) to all non-deterministic outcomes of the mutant (∀π ) for these inputs, as formalized by φ 3 : In Figure 1b, we present an instance of φ 3 for our running example. To generate tests, we use model checking to verify whether the conditional mutant satisfies the appropriate HyperLTL formula presented above and obtain test cases as finite prefixes of witnesses for satisfaction.

Non-deterministic models in practice
As stated above, checking the validity of the hyperproperties in Section 4 for a given model and mutant enables test-case generation. To the best of our knowledge, MCHY-PER [17] is the only currently available HyperLTL model checker. Unfortunately, MC-HYPER is unable to model check formulas with alternating quantifiers. 3 Therefore, we are currently limited to checking φ 1 (I, O) for deterministic models, since witnesses of φ 1 may not satisfy φ 2 in the presence of non-determinism.
To remedy this issue, we propose a transformation that makes non-determinism controllable by means of additional inputs and yields a deterministic STS. The transformed model over-approximates killability in the sense that the resulting test cases only kill the original mutant if non-determinism can also be controlled in the system under test. However, if equivalence can be established for the transformed model, then the original non-deterministic mutant is also equivalent.

Controlling non-determinism in STS
The essential idea of our transformation is to introduce a fresh input variable that enables the control of non-deterministic choices in the conditional mutant S c(m) . The new input is used carefully to ensure that choices are consistent for the model and the mutant encoded in S c(m) . W.l.o.g., we introduce an input variable nd with a domain sufficiently large to encode the non-deterministic choices in α c(m) and δ c(m) , and write nd(X, O) to denote a value of nd that uniquely corresponds to state X with output O. Moreover, we add a fresh Boolean variable x τ to X used to encode a fresh initial state.
Non-deterministic initial conditions: Let X be an arbitrary, fixed state. The unique fresh initial state is X τ def = X[x τ ], which, together with an empty output, we enforce by the new initial conditions predicate: We add the conjunct ¬ψ(X τ ) → ¬x τ to D(δ c(m) ), in order to force x τ evaluating to ⊥ in all states other than X τ . In addition, we add transitions from X τ to all pairs of initial states/outputs in α c(m) . To this end, we first partition the pairs in α c(m) into pairs shared by and exclusive to the model and the mutant: For each (O, X + ) ∈ J ∩ ∪J mut ∪J orig , we add the following conjunct to D(δ c(m) ): In addition, for inputs nd(O, X) without corresponding target state in the model or mutant, we add conjuncts to D(δ c(m) ) that represent self loops with empty outputs: Non-deterministic transitions: Analogously to initial states, for each state/input pair, we partition the successors into successors shared or exclusive to model or mutant: For each pair (X + , I) that causes non-determinism and each (X + , I, O j , X +j ) ∈ T ∩ (X+,I) ∪ T mut (X+,I) ∪ T orig (X+,I) , we add the following conjunct to D(δ c(m) ): Finally, we add conjuncts representing self loops with empty output for inputs that have no corresponding transition in the model or mutant: The proposed transformation has the following properties: For Item 3 (which is a direct consequence of Item 2), assume that the original nondeterministic mutant is not equivalent (i.e., potentially killable). Then D(S c(m) ) |= φ 1 (I, O), and the corresponding witness yields a test which kills the mutant assuming non-determinism can be controlled in the system under test. Killability purported by φ 1 , however, could be an artifact of the transformation: determinization potentially deprives the model of its ability to match the output of the mutant by deliberately choosing a certain non-deterministic transition. In Example 2, we present an equivalent mutant which is killable after the transformation, since we will detect the deviating output tea of the model and ε of the mutant. Therefore, our transformation merely allows us to provide a lower bound for the number of equivalent non-deterministic mutants.

Controlling non-determinism in modeling languages
The exhaustive enumeration of states (J) and transitions (T ) outlined in Section 5.1 is purely theoretical and infeasible in practice. However, an analogous result can often be achieved by modifying the syntactic constructs of the underlying modeling language that introduce non-determinism. . . x n }, as provided by SMV [24], can readily be converted into a caseswitch construct over nd. More generally, explicit non-deterministic assignments x := to state variables x [25] can be controlled by assigning the value of nd to x. -Non-deterministic schedulers. Non-determinism introduced by concurrency can be controlled by introducing input variables that control the scheduler (as proposed in [22] for bounded context switches).
In case non-determinism arises through variables under-specified in transition relations, these variable values can be made inputs as suggested by Section 5.1. In general, however, identifying under-specified variables automatically is non-trivial. Similarly, the STS representation of the beverage machine, given in Example 1, can be transformed by replacing the first two rules by the following two rules:

Experiments
In this section, we present an experimental evaluation of the presented methods. We start by presenting the deployed tool-chain. Thereafter, we present a validation of our method on one case study with another model-based mutation testing tool. Finally, we present quantitative results on a broad range of generic models. Figure 2 shows the toolchain that we use to produce test suites for models encoded in the modeling languages Verilog and SMV. Verilog models are deterministic while SMV models can be non-deterministic. Variable annotation. As a first step, we annotate variables as inputs and outputs. These annotations were added manually for Verilog, and heuristically for SMV (partitioning variables into outputs and inputs). Mutation and transformation. We produce conditional mutants via a mutation engine. For Verilog, we implemented our own mutation engine into the open source Verilog compiler VL2MV [12]. We use standard mutation operators, replacing arithmetic operators, Boolean relations, Boolean connectives, constants, and assignment operators. The list of mutation operators used for Verilog can be found in Appendix A. For SMV models, we use the NuSeen SMV framework [5,6], which includes a mutation engine for SMV models. The mutation operators used by NuSeen are documented in [5]. We implemented the transformation presented in Section 5 into NuSeen and applied it to conditional mutants. Translation. The resulting conditional mutants from both modeling formalisms are translated into AIGER circuits [9]. AIGER circuits are essentially a compact representation for finite models. The formalism is widely used by model checkers. For the translation of Verilog models, VL2MV and the ABC model checker are used. For the translation of SMV models, NuSMV is used. Test suite creation. We obtain a test suite, by model checking ¬φ 1 (I, O) on conditional mutants. Tests are obtained as counterexamples, which are finite prefixes of π-witnesses to φ 1 (I, O). In case we can not find a counter-example, and use a complete model checking method, the mutant is provably equivalent.

Toolchain
Case study test suite evaluation We compare the test suite created with our method for a case study, with the model-based mutation testing tool MoMuT [2,15]. The case study is a timed version of a model of a car alarm system (CAS), which was used in the model-based test case generation literature before [4,3,15].
To this end, we created a test suite for a SMV formulation of the model. We evaluated its strength and correctness on an Action System (the native modeling formalism of MoMuT) formulation of the model. MoMuT evaluated our test suite by computing its mutation score -the ratio of killed-to the total number of-mutants-with respect to Action System mutations, which are described in [15].
This procedure evaluates our test suite in two ways. Firstly, it shows that the tests are well formed, since MoMuT does not reject them. Secondly, it shows that the test suite is able to kill mutants of a different modeling formalism than the one it was created from, which suggests that the test suite is also able to detect faults in implementations.
We created a test suite consisting of 61 tests, mapped it to the test format accepted by MoMuT. MoMuT then measured the mutation score of our translated test suite on the Action System model, using Action System mutants. The measured mutation score is 91% on 439 Action System mutants. In comparison, the test suite achieves a mutation score of 61% on 3057 SMV mutants. Further characteristics of the resulting test suite are presented in the following paragraphs.
Quantitative Experiments All experiments presented in this section were run in parallel on a machine with an Intel(R) Xeon(R) CPU at 2.00GHz, 60 cores, and 252GB RAM. We used 16 Verilog models which are presented in [17], as well as models from opencores.org. Furthermore, we used 76 SMV models that were also used in [5]. Finally, we used the SMV formalism of CAS. All models are available in [1]. Verilog and SMV experiments were run using property driven reachability based model checking with a time limit of 1 hour. Property driven reachability based model checking did not perform well for CAS, for which we therefore switched to bounded model checking with a depth limit of 100.
Characteristics of models. Table 1 present characteristics of the models. For Verilog and SMV, we present average (µ), standard deviation (σ), minimum (Min), and maximum (Max) measures per model of the set of models. For some measurements, we additionally present average (Avg.) or maximum (Max) number over the set of mutants per model. We report the size of the circuits in terms of the number of inputs (#Input), outputs (#Output), state (#State) variables as well as And gates (#Gates), which corresponds to the size of the transition relation of the model. Moreover, the row "Avg. ∆ # Gates" shows the average size difference (in % of # Gates) of the conditional mutant and the original model, where the average is over all mutants. The last row of the table shows the number of the mutants that are generated for the models.
We can observe that our method is able to handle models of respectable size, reaching thousands of gates. Furthermore, ∆# Gates of the conditional mutants is relatively low. Conditional mutants allow us to compactly encode the original and mutated model in one model. Hyperproperties enable us to refer to and juxtapose traces from the original and mutated model, respectively. Classical temporal logic does not enable the comparison of different traces. Therefore, mutation analysis by model checking classical temporal logic necessitates strictly separating traces of the original and the mutated model, resulting in a quadratic blowup in the size of the input to the classical modelchecker, compared to the size of the input to the hyperproperty model-checker. Model checking results. Table 2 summarizes the quantitative results of our experiments. The quantitative metrics we use for evaluating our test generation approach are the mutation score (i.e. percentage of killed mutants) and the percentage of equivalent mutants, the number of generated tests, the amount of time required for generating them and the average length of the test cases. Furthermore, we show the number of times the resource limit was reached. For Verilog and SMV this was exclusively the 1 hour timeout. For CAS this was exclusively the depth limit 100. Finally, we show the total test suite creation time, including times when reaching the resource limit. The reported time assumes sequential test suite creation time. However, since mutants are model checked independently, the process can easily be parallelized, which drastically reduces the total time needed to create a test suite for a model. The times of the Verilog benchmark suite are dominated by two instances of the secure hashing algorithm (SHA), which are inherently hard cases for model checking.
We can see that the test suite creation times are in the realm of a few hours, which collapses to minutes when model checking instances in parallel. However, the timing measures really say more about the underlying model checking methods than our proposed technique of mutation testing via hyperporperties. Furthermore, we want to stress that our method is agnostic to which variant of model checking (e.g. property driven reachability, or bounded model checking) is used. As discussed above, for CAS switching from one method to the other made a big difference.
The mutation scores average is around 60% for all models. It is interesting to notice that the scores of the Verilog and SMV models are similar on average, although we use a different mutation scheme for the types of models. Again, the mutation score says more about the mutation scheme than our proposed technique. Notice that we can only claim to report the mutation score, because, besides CAS, we used a complete model checking method (property driven reachability). That is, in case, for example, 60% of the mutants were killed and no timeouts occurred, then 40% of the mutants are provably equivalent. In contrast, incomplete methods for mutation analysis can only ever report lower bounds of the mutation score. Furthermore, as discussed above, the 61.7% of CAS translate to 91% mutation score on a different set of mutants. This indicates that failure detection capability of the produced test suites is well, which ultimately can only be measured by deploying the test cases on real systems.

Related Work
A number of test case generation techniques are based on model checking; a survey is provided in [18]. Many of these techniques (such as [29,27,20]) differ in abstraction levels and/or coverage goals from our approach. Model checking based mutation testing using trap properties is presented in [19]. Trap properties are conditions that, if satisfied, indicate a killed mutant. In contrast, our approach directly targets the input / output behavior of the model and does not require to formulate model specific trap properties.
Mutation based test case generation via module checking is proposed in [10]. The theoretical framework of this work is similar to ours, but builds on module checking instead of hyperproperties. Moreover, no experimental evaluation is given in this work.
The authors of [4] present mutation killing using SMT solving. In this work, the model, as well as killing conditions, are encoded into a SMT formula and solved using specialized algorithms. Similarly, the MuAlloy [30] framework enables model-based mutation testing for Alloy models using SAT solving. In this work, the model, as well as killing conditions, are encoded into a SAT formula and solved using the Alloy framework. In contrast to these approaches, we encode only the killing conditions into a formula. This allows us to directly use model checking techniques, in contrast to SAT or SMT solving. Therefore, our approach is more flexible and more likely to be applicable in other domains. We demonstrate this by producing test cases for models encoded in two different modeling languages.
Symbolic methods for weak mutation coverage are proposed in [8] and [7]. The former work describes the use of dynamic symbolic execution for weakly killing mutants. The latter work describes a sound and incomplete method for detecting equivalent weak mutants. The considered coverage criterion in both works is weak mutation, which, unlike the strong mutation coverage criterion considered in this work, can be encoded as a classic safety property. However, both methods could be used in conjunction with our method. Dynamic symbolic execution could be used to first weakly kill mutants and thereafter strongly kill them via hyperproperty model checking. Equivalent weak mutants can be detected with the methods of [7] to prune the candidate space of potentially strongly killable mutants for hyperpropery model checking.
A unified framework for defining multiple coverage criteria, including weak mutation and hyperproperties such as unique-cause MCDC, is proposed in [23] . While strong mutation is not expressible in this framework, applying hyperproperty model checking to the proposed framework is interesting future work.

Conclusion
Our formalization of mutation testing in terms of hyperproperties enables the automated model-based generation of tests using an off-the-shelf model checker. In particular, we study killing of mutants in the presence of non-determinism, where test-case generation is enabled by a transformation that makes non-determinism in models explicit and controllable. We evaluated our approach on publicly available SMV and Verilog models, and will extend our evaluation to more modeling languages and models in future work.
Proof. Assume that S m is potentially killable, which implies that there is a trace q ∈ T (S m ), such that there is no trace p ∈ T (S) with q| I∪O = p| I∪O . Any trace assignment that maps π to p satisfies φ 2 (I, O), since either the antecedent is violated by a trace q ∈ T (S m ) assigned to π with different inputs, or the consequent is violated by a trace q ∈ T (S m ) assigned to π with inputs I and outputs that can only be different to p| O .
Conversely, assume S c(m) |= φ 2 (I, O). Let p be a π-witness and q be a π -witness for which the antecedent is satisfied, which is in fact satisfiable, since S m is equally input-enabled. Then, from Lemma 1, we get p| I∪O∪X ∈ T (S), q| I∪O∪X ∈ T (S m ), and q| I = p| I . Since Π[π → p, π → q] satisfies the antecedent and the whole formula, the trace assignment also satisfies the consequent, i.e. q| O = p| O (Lemma 1). Since q was chosen arbitrary (besides satisfying the antecedent), we can conclude p| I∪O / ∈ T (S m )| I∪O , i.e. S m is potentially killable.
The existence of the potentially killing test can be shown analogously as in the proof of Proposition 6.