• Aucun résultat trouvé

Core extraction and non-example generation : debugging and understanding logical models

N/A
N/A
Protected

Academic year: 2021

Partager "Core extraction and non-example generation : debugging and understanding logical models"

Copied!
132
0
0

Texte intégral

(1)

Core Extraction and Non-Example Generation:

Debugging and Understanding Logical Models

by

Robert Morrison Seater

Submitted to the Department of Electrical Engineering and Computer

Science

in partial fulfillment of the requirements for the degree of

Masters of Science in Computer Science and Engineering

at the

MASSACHUSETTS INSTITUTE OF TECHNOLOGY

November 2004

@

Massachusetts Institute of Technology 2004. All rights reserved.

A u th or ... ... ...

Department of Electrical Engineering and Computer Science

November 30, 2004

C ertified by ...

.. ...-.

Daniel N. Jackson

Associate Professor

Thesis Supervisor

Accepted by ...

. ... ...

- .-.

.

.

Arthur C. Smith

Chairman, Department Committee on Graduate Students

MASSACHUSETS INSTMi OF TECHNOLOGY

(2)
(3)

Core Extraction and Non-Example Generation: Debugging

and Understanding Logical Models

by

Robert Morrison Seater

Submitted to the Department of Electrical Engineering and Computer Science on November 30, 2004, in partial fulfillment of the

requirements for the degree of

Masters of Science in Computer Science and Engineering

Abstract

Declarative models, in which conjunction and negation are freely used, are a pow-erful tool for software specification and verification. Unfortunately, tool support for developing and debugging such models is limited. The challenges to developing such tools are twofold: technical information must be extracted from the model, then that information must be presented to the user in way that is both meaningful and manageable. This document introduces two such techniques to help fill the gap.

Non-example generation allows the user to ask for the role of a particular subformula in a

model. A formula's role is explained in terms of how the set of satisfying solutions to the model would change were that subformula removed or altered. Core extraction helps detect and localize unintentional overconstraint, in which real counterexamples are masked by bugs in the model. It leverages recent advances in SAT solvers to identify irrelevant portions of an unsatisfiable model. Experiences are reported from applying these two techniques to a variety of existing models.

Thesis Supervisor: Daniel N. Jackson Title: Associate Professor

(4)
(5)

Acknowledgments

This research was supported by grant 0086154 (Design Conformant Software) from the ITR program of the National Science Foundation, by grant 6895566 (Safety

Mechanisms for Medical Software) from the ITR program of the National Science

Foundation, and by the High Dependability Computing Program from NASA Ames cooperative agreement NCC-2-1298.

The core extraction portion of this thesis (Chapter 3) is isomorphic to a paper co-authored with Ilya Shlyakhter, along with Manu Sridharan, Daniel Jackson, and Mana Taghdiri [19]. In addition, the author is grateful for the insight and feedback given by his advisor Dr. Daniel Jackson and colleagues Gregory Dennis, Emina Torlak, Derek Rayside, Dr. Robert Miller, and Dr. Michael Ernst.

This work was completed while the author was a member of the Software Design Group (SDG), a research group at the Computer Science and Artificial Intelligence Labratory (CSAIL) at the Massachusetts Institute of Technology (MIT).

(6)
(7)

Contents

1 Declarative Modeling: Benefits and Drawbacks 21

1.0.1 Benefits of Declarative Modeling ... 22

1.0.2 Under- and Over-constraint . . . . 24

1.0.3 Writing and Analyzing Declarative Models . . . . 26

1.1 The Alloy Language . . . . 27

1.2 Errors: Modeling Bugs vs. System Faults . . . . 27

2 Non-Example Generation: Explaining Subformulae 29 2.1 Motivating Non-Examples . . . . 30

2.1.1 Windows and Rain . . . . 30

2.1.2 Counterfactual Reasoning? . . . . 32

2.1.3 Events vs. Policies . . . . 36

2.1.4 What is the Role of a Formula? . . . . 37

2.2 Formalization and Representation: Conjunction Diagrams . . . 39

2.2.1 Deletion (and Sabotage) Formalized . . . . 39

2.2.2 Conjunction Diagrams . . . . 40

2.2.3 Representing Sabotage . . . . 42

2.2.4 Theorem s . . . . 43

2.3 Propositional Logic Examples . . . . 46

2.3.1 Trivial Examples . . . . 46

2.3.2 CNF Example . . . . 48

2.3.3 Using Expansion to Explore a Model . . . . 50

(8)

2.4 Handling Rich Logics . . . . 52

2.4.1 Non-Boolean Values . . . . 53

2.4.2 Defined Names and Other Syntactic Sugars . . . . 54

2.5 Alloy Examples . . . . 57

2.5.1 Ceilings and Floors . . . . 58

2.5.2 Sequence Library . . . . 64

2.5.3 The Firewire Network Protocol . . . . 66

2.6 Expansion and Refinement . . . . 80

2.7 Related Work . . . . 80

2.7.1 Understanding Counterexamples with explain . . . . 80

2.7.2 Mutation Testing . . . . 81

2.7.3 Logic Programming: Prolog . . . . 82

2.7.4 Near Miss Learning . . . . 84

3 Core Extraction: Identifying Overconstraint 87 3.1 Introduction . . . . 88

3.2 A Toy Example . . . . 90

3.3 The Core Extraction Algorithm . . . . 95

3.3.1 Constraint Language . . . . 96 3.3.2 Translation . . . . 96 3.3.3 Mapping Back . . . . 98 3.3.4 Complications . . . . 99 3.4 Experience . . . . 99 3.4.1 Common Mistakes . . . . 100

3.4.2 Locating Known Overconstraints . . . . 102

3.4.3 Blunders Discovered . . . . 105

3.4.4 Performance . . . . 106

3.5 Related work . . . . 107

3.6 Conclusions . . . . 108

(9)

B Proofs 121

B.1 Deletion and Sabotage are Sufficient to Compute Correctness . 121

B.2 Disjoint Entries . . . . 123

(10)
(11)

List of Figures

2-1 An Alloy model of the relation between the weather, the status of your

bedroom window, and whether or not you get wet. . . . . 31

2-2 There are only 6 pairs of entries in a conjunction diagram which are not always disjoint. . . . . 45

2-3 An Alloy model written by Daniel Jackson about Paul Simon's song "One Man's Ceiling Is Another Man's Floor". . . . . 58

2-4 A counterexample to the claim that one man's floor is another man's ceiling . . . . 59

2-5 The role of the PaulSimon constraint . . . . 60

2-6 A counterexample to the claim that the Geometry constraint is suffi-cient to force each man's floor to be some man's ceiling . . . . 61

2-7 The role of the Geometry constraint . . . . 62

2-8 The role of the presence of the NoSharing constraint . . . . 63

2-9 A simplified version of Alloy's sequence module . . . . 65

2-10 The role of part of the add predicate in the sequence module. An arc labeled next [seqO] from node widget1 to node widgetO means that, in the sequence [seqO], widget1 immediately preceeds widgetO. . . . 67

2-11 In state SO, the system is initialized and the nodes are waiting. Each link has a message queue which is initially empty. Node0 has only one incoming link, and thus it has only one incoming link which has not been classified as a parentLink. In state Si, Node0 becomes active and sends a request to Node1, declaring its willingness to be a child. . 71

(12)

2-12 In state S2, Node2 acknowledges NodeO's request, indicating that Node2 is willing to be NodeO's parent. NodeO thus declares that its outgoing link is a parentLink, making it a leaf in the tree being constructed. In state S3, Node2 becomes active and notices that it how has only one outgoing link which is not marked as being a parentLink. It thus sends a request to Nodel, indicating its willingness to be a parent. . . 72

2-13 In state S4, Nodel acknowledges Node2's request, indicating its

willing-ness to be a child. Node2 sees that only one of its incoming links is not a parentLink, so it sends a request to Nodel that the other incoming link be made a parentLink. In state S5, Node1 activates and sees that it can only be a leaf node. . . . . 73

2-14 In state S6, all of Node2's incoming links are parentLinks, and those choices have been validated by its neighbors. Node2 thus declares itself to be the root, and the algorithm terminates . . . . . 74

2-15 One state from a trace in PCD from the entire constraint describing

of the stutter operation . . . . 75 2-16 PCD from the conjunction diagram for the role of the latter half of

the constraint s' .op = Stutter => SameState (s, s') . . . . 76 2-17 The formula n in s .active in the specification for the Elect operator

is crucial to disallowing the case where an inactive node is elected as the root. Shown, are states S5 and S6 (the final two states) of one such trace. This trace would appear in the PCD entry of the conjunction diagram . . . . 79

3-1 A toy Alloy model describing the behavior of a web cache . . . . 91

3-2 The corrected version of the web cache Alloy model, taking into account the information provided by core extraction . . . . 94

(13)

3-3 A Roadmap to Core Extraction. (1) A model is created in any

con-straint language which is reducible to SAT in a structure preserving fashion. (2) During translation to CNF, each clause generated is anno-tated with the AST node from which the clause was produced. (3) A

SAT solver (used as a black box) determines that the model is

unsat-isfiable and extracts an unsatunsat-isfiable core (a subset of the CNF clauses which is also unsatisfiable). (4) The core is mapped back to the orig-inal model by marking (as "relevant") any part of the AST indicated

by the annotation of any clause in the CNF core. The analysis is now

complete. The remaining steps concern guarantees made to the user about what the markings on the AST mean; they are not actually ex-ecuted during normal use of the tool. (5) The user is guaranteed that changing the unmarked (non-relevant) portions of the AST will leave the model unsatisfiable. (6) Specifically, the CNF corresponding to

the altered AST will be a superset of the unsatisfiable core previously extracted, and thus will itself be unsatisfiable. . . . . 109

3-4 Translation of AST to CNF, and mapping back of unsatisfiable core. The AST is for the (trivially unsatisfiable) Alloy formula of the form "(some p) && (no p) && ...". To each node, a sequence of Boolean variables (bi through b6) is allocated to represent the node's value. From each inner node, translation produces a set of clauses relating the node's Boolean variables to its childrens' Boolean variables. The highlighted clauses form an unsatisfiable core, which is mapped back to the highlighted AST nodes. . . . . 110

(14)
(15)

List of Tables

2.1 A generic conjunction diagram with column formulae Coll and Col2

2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12

and row formulae Row1 and Row2 . . . . . . . . . . .

The generic conjunction diagram for deletion . . . . . The conjunction diagram for sabotage . . . .

The conjunction diagram for deletion and sabotage .

The role of the final clause of a CNF formula . . . . .

The role of B in A V B . . . . The role of B in A A B . . . .

Our intuition for the role of a CNF clause . . . .

Our intuition for the role of a term in a CNF clause . The role of a redundant CNF clause . . . . The role of a term in a redundant CNF clause . . . .

The role of -,Wif eLate in the dinner example . . . .

41 . . . . . 41 . . . . . 43 . . . . . 43 . . . . . 44 . . . . . 46 . . . . . 47 . . . . . 48 . . . . . 49 . . . . . 49 . . . . . 50 . . . . . 51

(16)
(17)

Introduction

Suppose you are a software developer and have formulated an important aspect of your program as a logical model. Now you want to make sure that your model is saying what you think it is saying and that you are correctly interpreting the results it gives you.

Consider this excerpt from an Alloy model which is discussed in depth later on.

pred Geometry O{no m: Man I m.floor = m.ceiling}

What role does this constraint play in the model? Is it necessary? What would have happened if it had been written it incorrectly? Is it allowing solutions which ought to be eliminated? Is it eliminating solutions that ought to be allowed?

The answers to these questions could probably be deduced through careful reason-ing but (a) it would be a lot of work, and (b) there would always remain a lreason-ingerreason-ing doubt that you missed something. Such concerns beg for automated tool support. We present two such tools to help the user answer these questions.

Explaining Roles

When looking at a logical model, it is natural to ask what role some particular constraint plays in that model. But what sort of an animal is the role of a subformula? Logicians and philosophers have addressed this issue in a number of ways that involve extending the logic to include special constructs. In Chapter 2, we propose

non-example generation as an appealing, lightweight alternative. This technique explains

(18)

were absent or altered. We introduce conjunction diagrams as a notation to present such information.

Determining the effect of deleting a suformula T is not as simple as removing T and re-analyzing the model. Suppose, after removing T, your checker produces a new solution. Was it a solution before you removed T? Are the old solution still solutions? What you really want to know is what new solutions were added and what old solutions have been inhibited. A more sophisticated approach is required, and we introduce non-example generation as one such approach.

Overconstraint

Logical models are susceptible to unintentional overconstraint in which real coun-terexamples are masked by bugs in the model. In Chapter 3, we introduce Core

extraction, a new analysis that mitigates this problem in the presence of a checker

which translated the model to CNF. It exploits a recently developed facility of SAT solvers to deduce an unsatisfiable subset of a CNF which is often much smaller than the clause set as a whole. This unsatisfiable "core" is mapped back into the syntax of the original model, showing the user irrelevant fragments of the model. This in-formation can be a great help in discovering and localizing overconstraint, sometimes pinpointing it immediately. The construction of the mapping between the model and an equivalent CNF is given for a generalized modeling language, along with a proof of the soundness of the claim that the marked portions of the model are irrelevant. Experiences in applying core extraction to a variety of existing models are discussed.

Summary

Chapter 1 provides background and puts the remaining chapters in context. We introduce declarative modeling and discuss its benefits and drawbacks.

Chapter 2 introduces non-example generation, a technique which explains the role of a subformula by computing solutions it is responsible for allowing or disallowing. We begin by motivating our approach as a lightweight alternative to counterfactual

(19)

reasoning, formalize it, and introduce conjunction diagrams as a convenient notation. We expand the technique to account for quantifiers and named predicates, then use it to examine and explain several Alloy models.

Chapter 3 introduces core extraction, a technique for detecting unintentional over-constraint by showing the user unused portion of the model. We introduce the tech-nique in the context of a general constraint language, and discuss its implementation. We prove the correctness of the algorithm, and report on our experience in applying to several Alloy models.

(20)
(21)

Chapter 1

Declarative Modeling: Benefits

and Drawbacks

"There is nothing so annoying as a good example!"

Mark Twain

Roughly speaking, there are two ways to model a transition system 1 2. In the operational idiom, transitions are expressed using assignment statements, either with

the control flow of a conventional imperative program (as in Promela, the language of the Spin model checker [16]), or using a variant of Dijkstra's guarded commands (as in Murphi [11] and SMV [7]). In the declarative idiom, transitions are expressed with constraints, either on whole executions, or, more often, on individual steps. This idea is rooted in the early work on program verification; the operation specifications of the declarative languages VDM, Larch and Z are essentially the pre- and post-conditions of Hoare triples.

For readers unfamiliar with these idioms, it may help to think of an operational specification as one that gives a recipe for constructing new states from old ones, and a declarative specification as one that gives a fact that can be observed about the

'This introduction is largely lifted from Daniel Jackson's description of declarative modeling, as given in [19]. It has been altered to suite this document, but it retains much of his content, organization, and elements of his style.

2

A transition system is a model which specifies states and actions which cause the system to

(22)

relationship between old and new states. An operational modeler asks "How would I make X happen?"; a declarative modeler asks "How would I recognize that X has happened?".

The advantage of the operational idiom is its executability. A simulation, either random or guided by inputs from the user, can give useful feedback to a designer. In model checking, the ability to generate a state's successor in a single computational step makes it possible to explore the reachable state space by depth-first search (as in Spin [7]). In contrast, declarative models have been viewed as not executable, and less amenable to automatic analysis in general, since even generating successors requires search. Recently, however, we have developed an analysis based on SAT that allows both simulation and systematic exploration of declarative models [22]. A common form of analysis that we perform is similar to bounded model checking [4]: the SAT solver is used to find traces that violate specified properties. In fact, earlier symbolic methods could also handle models with declarative elements. The earliest versions

of SMV, for example, provided a construct for expressing transitions implicitly. Its

analysis, being symbolic, was not hindered by the inability to generate successors of a state constructively.

The advantage of the declarative idiom is its expressibility. For some kinds of problem, especially the control-intensive aspects of a system, the operational idiom can be more natural and direct. But in many cases, especially for software systems, the declarative idiom is more flexible, more natural, and sometimes, surprisingly, more amenable to analysis. In many contexts, it is more natural and concise to use a declarative description; often one need only to describe the rules of the game and what it means to have won, and not ever think about what moves will be needed (and which must be avoided) in order to win.

1.0.1

Benefits of Declarative Modeling

Partial Descriptions. The declarative idiom better supports partial descriptions.

Sometimes, only one operation is of interest. In a study of a name server [27], for example, only the lookup operation was modeled and analyzed, since the operations

(23)

for storing and distributing name records were straightforward. An explicit invariant on the structure of the name database took the place of the operations that in an operational model would define the reachable states implicitly. Even if the lookup operation were not written declaratively, the need to account for the invariant in

generating initial states makes the description essentially declarative.

Underspecification. The need to constrain a model's behavior only loosely arises

in many ways. It arises when implementation issues are to be postponed or ignored; analysis of a cache protocol, for example, can establish its correctness irrespective of the eviction policy. It arises when analyzing a family of systems: an analysis can check that a collection of design or style rules implies certain desirable properties, and thus that any system built in conformance with the rules will have those properties too. And it arises when accounting for an unpredictable environment: checking a railway signaling protocol, for example, for all possible train motions. In these cases, a declarative description is often succinct and natural, where an operational idiom would, in contrast, require an explicit enumeration of possibilities. Cache eviction, for example, might be specified by saying that the resulting cache, viewed as a set of address/value pairs, is a subset of the original cache. The motion of trains on a network might be specified by saying that the new track segment occupied by a train is either its old one, or one connected to it.

Analyzing Specifications. Specifications can be used not only as yardsticks of

analysis, but also as subjects in their own right. It is easy to make mistakes writing specifications, so it helps to analyze their properties directly: to check that one fol-lows from another, for example, or to generate executions over which specifications differ. If the model and specification are written in the same declarative language, 'masking' is possible. If the model M fails to have properties P and Q, we might want to know whether the problems are correlated. By checking the conjunction of P and M against Q, we can find out whether fixing M so that it satisfies P would also fix M with respect to Q. A declarative analyzer also helps refactoring; any fragment of a model or specification can be compared to a candidate replacement by conjecturing the equivalence of the two.

(24)

Non-Operational Problems. Some problems are simply not operational in nature,

and demand a logical rather than a programmatic description. Alloy has been used, for example, to check the soundness of a refinement rule: this involved modeling state machines and their trace semantics, and checking that the rule related only machines with appropriately related semantics. Many subjects are well described in a rule-based manner: ontology models, security policies, and software architectural styles, for example.

Topology Constraints. Sometimes one particular aspect of a system has a

declar-ative flavor. For example, many distributed algorithms are designed to work only if the network's topology takes some form, such as a ring or tree. A declarative model can be constructed that constrains the network appropriately, but does not limit it to a single topology. The analysis will then account for all executions over all acceptable topologies (for a network of some bounded size). The Firewire example described in Sections 2.5.3 and 3.4 exploits this benefit.

Avoiding Initialization. In some systems, normal operation is preceded by an

initialization phase in which the system is configured. An operational description of such a system will suffer from traces that are made longer than necessary by their initialization prefixes. A declarative description can bypass the initialization phase with an invariant that captures its possible results, thus shortening the traces. The result is not only simpler description, uncluttered by the details of initialization, but also more efficient analysis, since a bounded model checking analysis can use a lower bound on trace length and still reach all states.

1.0.2

Under- and Over-constraint

"Example is the school of mankind, and [we] will learn at no other"

Edmund Burke

The very mechanisms that give declarative modeling its power - conjunction and negation - also bring a curse. Any modeler faces the dual risks of underconstraint and overconstraint. In a declarative setting, underconstraint turns out to be easy to

(25)

notice and correct, while overconstraint is both difficult to recognize and dangerous when it goes undetected.

Underconstraint An underconstrained model does not eliminate all the situa-tions which the user intended to eliminate. The consequence of underconstraint is the discovery of bogus or absurd counterexamples. When the user encounters such a counterexample, it is obvious that the model is underconstrained and usually straight-forward to add a constraint to the model to eliminate the extraneous solution. Fur-thermore, if the user does not discover the underconstraint there is no harm done: If a valid counterexample is generated despite the underconstraint, the user still has found a fault in the system. If there are no counterexamples despite the underconstraint, then the user has inadvertently proven a stronger claim than intended.

Overconstraint It is unfortunately easy to write a model that has fewer behaviors than intended. An overconstrained model does not allow some or all behaviors that the user intended to investigate. A check of a safety property may then pass only because the offending behavior has been accidentally ruled out (probably along with many other behaviors). In the extreme, an overconstrained model may have no so-lutions at all. As a result, there will be no counterexamples to any assertion! Such situations are easily detected simply by analyzing the model - effectively a liveness check'. The much more worrisome case is when the model is satisfiable, but bugs in the constraints have accidentally eliminated those cases which violate the asser-tion. The analyzer will (correctly) report that there are no counterexamples to the model the user actually wrote, and the user will (erroneously) interpret this to mean that there are no counterexamples to the model she intended to write; unlike with underconstraint, undetected overconstrained is a serious problem.

The risk can be mitigated by working carefully. One can exploit the ability to build and analyze a model incrementally, adding as few (and as weak) constraints as possible to establish the required safety properties. One can simulate the model

3

1f your analyzer can only check an asserted property, then one can perform a liveness check by

(26)

extensively, adding conditions to force execution of interesting cases. And of course one can formulate and check liveness properties, at least ruling out the most egregious overconstraints, such as those that lead to deadlock.

None of these approaches, however, counter the risk of overconstraint that is relevant to a particular safety property. The worst overconstraints are not the ones that rule out most behaviors, since they are usually easy to detect, but the ones that rule out exactly those behaviors that would violate the safety property. Since the purpose of checking a safety property is precisely to find behaviors that violate it, we are hardly likely to be able to formulate a liveness constraint to ensure that those behaviors are possible! And of course a liveness check can itself be confounded by an overconstraint that rules out those traces that would be counterexamples to the liveness check itself. A property-specific detection of overconstraint is thus required, and core extraction, introduced in Chapter 3, is exactly such an analysis.

1.0.3

Writing and Analyzing Declarative Models

Let's consider what the world looks like from the eyes of a modeler developing a declarative description about a subject system. The modeler begins with an empty set of constraints, allowing all possible worlds and behaviors. Each constraint added to the model eliminates some class of situations, and a complete model reduces the

set of possibilities to a meaningful subset. Typically, the model eliminates those which cannot occur in the subject system. That set of solutions is searched for a solution which violates a user-defined property - thus finding solutions which should not occur in the subject system. Solutions are reported to the user as counterexamples

- situations which are possible but undesirable.

For example, one could write a model M with constraints that restrict the world to those cases where trains obey traffic signals. One might then write a safety property

P which states that trains never collide. Solutions to the equation M A -,P are

counterexamples to the claim that traffic signals are sufficient to prevent collision. In order to enumerate all the worlds satisfying the model, it is necessary to bound the size of the universe. Such a bound is known as the scope of the model. The

(27)

implication is that counterexamples are sound but not complete (although they are "complete up to scope"). The role of model checking is to find bugs, not to prove properties, and the assumption is that many bugs can be revealed by small examples [2]. However, by giving up the ability to prove a property for any bound (such as a theorem prover does), the search process is made completely automatic.

Each new conjunct serves to eliminate some set of solutions, but a subformula of one of those conjuncts may actually relax the model and increase the number of solutions. For example, a top-level constraint of the form "A or B" excludes solutions but the subformula "B" within that constraint allows solutions. In Chapter 2, we introduce non-example generation, which explains the role played by a subformula of a model by classifying it as either relaxing or restraining, and by computing solutions it is responsible for including or excluding.

1.1

The Alloy Language

In developing the process of non-example generation, we will start with symbolic logic and build up to more sophisticated logical languages, such as first order logic, relational logic, and eventually the Alloy modeling language [9, 21, 8] . The techniques described in this paper are not particular to the Alloy language. Rather, they are particular to logical, declarative modeling languages of which Alloy is an example.

1.2

Errors: Modeling Bugs vs. System Faults

One of the chief benefits of writing a model about a piece of software or other system is the discovery of faults in that system. This goal is reflected in the division of a model into a description of the system and a property (which typically asserts the absence of a particular class of faults). Of course, the model may iself contain errors. Bugs are a risk of any language, although certain kinds of bugs (such as overconstraint) are especially problematic for declarative models. It is important to distinguish bugs in the model from faults in the system being modeled. The techniques in this thesis

(28)

help the user resolve the tension and interaction between these two types of errors.

Chapter 2: non-example generation

Whether or not there are solutions to the model, we wish to understand the role that particular portions of the system play in preventing (or failing to prevent) faults. By understanding the role that a constraint actually plays, and contrasting it to the role we think it should play, we not only discover bugs in the model, but we also gain insight into why there are or no faults in the system.

Chapter 3: core extraction

The absence of counterexamples indicates that either there are no faults in the system or that bugs in the model are masking all of the system's faults. Unintentional overconstraint can often be found by identifying which parts of the model played a role in making it unsatisfiable (and which were irrelevant).

(29)

Chapter 2

Non-Example Generation:

Explaining Subformulae

"Give me a fruitful error anytime,

full of seeds, bursting with its own corrections." Vilfredo Pareto

When looking at a logical model, it is natural to ask what role some particular constraint plays in that model. But what sort of an animal is the role of a subformula? In this chapter we discuss some of the ways logicians and philosophers have addressed this issue, and we propose non-example generation as a lightweight alternative. This technique explains the role of a formula by calculating what would happen differently if that formula were absent or altered.

This chapter begins by motivating non-example generation as a lightweight al-ternative to counterfactual reasoning for explaining models. Conjunction diagrams

are introduced as an effective notation both for presenting non-example information to the user and for proving handy properties about the technique. Equipped with a good notation, the technique can be extended beyond propositional logic to include first order logics, relational logics, and logics with declarations and named predicates. Non-example generation is applied to several existing models and experiences are reported.

(30)

2.1

Motivating Non-Examples

"A life spent making mistakes is not only more honorable,

but more useful than a life spent doing nothing."

George Bernard Shaw

One often wishes to know what would be the case if the world were slightly different than the way it currently is. When asked to explain a phenomenon, a common answer is to describe how that phenomenon would have differed had the world been slightly different. Understanding a situation means understanding the influence that small changes to the initial conditions of that situation have on its the outcome. Let's consider an example.

2.1.1

Windows and Rain

One morning, you notice that you left your bedroom window open overnight. Ex-plaining to your child why this is a problem, you say something along the lines of "Had it rained, then I would have gotten wet.". One can also present the situation the other way around: having woken up, you notice that it rained last night. You explain why it is a good thing your window was closed by saying "Had I left the window open, then I would have gotten wet.". This example is deceptively simple. Figure 2-1 shows a formalization of it in the Alloy language.

The model begins by defining the set State and 8 subsets. The following fact ensures that opposite pairs of those subsets partition the set of states. E.g. every state is either in Rain or Sunny but not both. The Physics constraint describes the conditions under which you get wet. If the window is broken, then you get wet whenever it rains. If the window is intact, then you get wet whenever it rains while the window is open. The Diligent constraint ensures that you close the window whenever it rains.

At the end of the model, we ask to analyzer to show us an example of the system. We also check the StayDry assertion, which states that you're always dry if the window is intact. No such cases are found, and the assertion passes.

(31)

module rain sig State {}

sig Rain, Sunny, Wet, Dry, Open, Closed, Broken, Intact in State {} /* In any given state, the weather is either rainy or sunny, the

* window is either open or closed, the window is either broken or

* intact, and you are either wet or dry. */ fact Partitions {

//the weather outside

Rain + Sunny = State

no Rain & Sunny //your bedroom window

Open + Closed = State

no Open & Closed

Intact + Broken = State

no Intact & Broken //your status

Wet + Dry = State

no Wet & Dry

}

/* If the window is intact, you get wet when the window is open and it

* rain. If the window is broken, you get wet when it rains. */ fact Physics {

all S: State I S in Intact =>

(S in Rain and S in Open <=> S in Wet) all

S:

State

I

S in Broken =>

(S in Rain <=> S in Wet)

}

/* You always close the window when it rains. */

fact Diligent {all S: State I S in Raining => S in Closed}

pred example() {}

run example for exactly 1 State expect 1

assert StayDry {all S: State

I

S in Intact => S in Dry} check StayDry for exactly 1 State expect 0

Figure 2-1: An Alloy model of the relation between the weather, the status of your bedroom window, and whether or not you get wet.

(32)

Intuitively, the Diligence policy has something to do with why we manage to stay dry as long as the window is intact. How can we ask the model to verify and elaborate on that intuition?

2.1.2

Counterfactual Reasoning?

"If I had only known, I would have been a locksmith."

Albert Einstein

At first, this looks like a task for counterfactual reasoning. Counterfactual reason-ing asks how the world would be different if some variable had taken on a different value. For example, we might counterfactually inquire "What would have happened had the window been left open last night?" and expect an answer along the lines of "I would have gotten wet.". Philosophers and logicians have worked on formal-izing counterfactual reasoning in a number of ways. However, we will see that each solution either produces undesirable results or requires significant extensions to the logic in which the model is written. The task at hand is to answer questions about propositional logic, so requiring the user to rewrite her model in a different logic is unacceptable.

Adding to the World

Consider a model M from which you can draw some conclusion C. If we add a new

fact N, stating our counterfactual supposition, we can draw some new conclusion Cil.

MFC

(M A N) I- C'

Unfortunately, this approach tends to produce one of two useless results for C': 'Astute readers may object to the use of the proof symbol I- when we are talking about model checkers whose finite limitations prevent them from producing proofs. For the purposes of this discussion, imagine that our analyzer can examine infinitely many possible worlds. The finite bound put on a model is an issue of analysis not of semantics; the model is written as if the world were arbitrarily large (or even infinite), and the bound is only enforced when we actually analyze the model. In principle, conclusions can be proven from models. In practice our method of analysis does not consitute proof.

(33)

1. Contradiction: Suppose the new constraint N contradicts the previous model M. For example, N might be "It rained last night and I left the window open."?

This constraint contradicts the Diligent constraint already in M, so the new model, M A N, is inconsistent. We would conclude that there are no possible worlds in which it rains and the window is open.

2. Odd Causality: Even in the case where N does not contradict M, C' may be a very odd conclusion. If we instead added the weaker constraint N = "I

left the window open last night.", then analysis of the model M A N will tell us that it could not have rained. We have learned that opening our window prevents rain!

Entailment vs. Causality

In the second case, had we instead added the constraint "It rained last night", then the analyzer would tell us that we couldn't have opened the window. While this is not quite what we want (since we were hoping to learn that we might have gotten wet), it is at least consistent with our intuition about causality. Why does asking about changing the state of the window ("What if I had left the window open?") produce an unintuitive result yet asking about changing the state of the weather ("What if it had rained?") produce a sensivle result? Where does the asymmetry come from.

The problem is that Diligent is written in propositional logic, and thus uses

logi-cal implication not causal implication. In Diligent, we wrote that (Rain -> Closed).

From that formula, the law of the contrapositive lets us conclude that (,Closed

-,Rain). However, the law of the contrapositive does not apply to causal implication;

the formula (Rain causes Closed) does not imply that (,Closed causes ,Rain). Unfortunately, without adding a "causes" operator to the language, we cannot accurately represent causality, as discussed by Avi Sion [40] and John Stuart Mill [34].

(34)

Changing the World

To avoid producing the contradictions we saw in Section 2.1.2 when we added con-straints to the model, we might consider instead changing part of the model. In this approach, an old fact N in replaced with a new fact N', thus producing a new

(hopefully meaningful) conclusion C'.

M _ C

M[N +- N'] I C'

The complication here is that you cannot just change part of the state without vio-lating constraints in the model. As before, we cannot force the window to be open when it it raining without violating the Diligent constraint.

We are faced with a serious dilemma: Changing part of the world requires one of two approaches:

1. Constraint Violation One solution is to allow constraints to be violated if

neces-sary. Unfortunately, we will end up with situations which violate fundamental aspects of the model. For example, we might generate the situation in which it is sunny and I close the window, yet I get wet (violates Physics). That is hardly an explanation of how the model works!

2. Variable Alteration The other solution is to update other variables until all constraints are satisfied. However, there may be several different ways to change the world, all of which satisfy the constraints. Offhand, it is unclear which one to choose.

Fixing Constraint Violation: Laws vs. Policies

One might try to avoid the problems with constraint violation by classifying facts into "fundamental laws", such as Physics, versus "preferred policies", such as Diligent. When making a counterfactual inquiry, one only allows policies to be violated. In our simple model, such a distinction would indeed avoid the problem - the diligence constraint may be violated but the physics constraint may not.

(35)

Such a distinction would require that the user annotate the model. Besides being

extra work for the user, it might not even be feasible - the user is asking about the model in order to understand it better and may not feel qualified to make such distinctions.

Furthermore, imposing such a distinction limits the questions one can ask - why not allow the user to ask why a funamental law is necessary? For example, what roles

does the Physics constraint play in our toy model?

Even worse, this solution does not always avoid our previous dilemma. If our supposition violates a fundamental law then we will have to either change the value of some of the other variables or accept that one of the fundamental law is violated. We are back where we started.

Fixing Variable Alteration: Closest Possible World

Since constraint violation seemes irreparable, let's look at how variable alteration can be improved. David Lewis [31] developed an approach to change the world to satisfy all the constraints, but to do so in a deterministic and sensible manner. In order to determine what would have happened if some event E had occurred, consider the closest possible world in which E holds. In this manner, we only consider worlds in which all the constraints are satisfied, but use a distance metric do decide which other variables should be changed. See Section 2.7.4 for his exact words on the matter.

In our simple example, this seems to work. Given that last night we observed the state

Rain, Closed, Intact, Dry

we ask "What if the window had been open?". By the Closest Possible World defini-tion, we want the state which is closest to the state

Rain, Open, Intact, Dry

but which satisfies the model. If we use a simple bit-comparison metric (the distance between two states is the number of variables on which those states differ), then

(36)

closest such state is

Rain, Open, Intact, Wet

which is exactly what we want to see; if we had left the window open in the rain, then we would have gotten wet.

The chief objections to this approach are the oddities which develop in very de-tailed models. The traditional example of an unintuitive result is the so called Nixon

Paradox, originally pointed by Kit Fine in 1975 [12]: "What would have happened

if Nixon had pushed the button to launch nuclear weapons at Russia?". We expect an answer along the lines of "Russia would have retaliated, reducing both nations to radioactive ash.". However, if we look at the closest possible world to our own in which nixon pushed the button, we instead conclude "There would have been an electrical failure so that the button did nothing, after which Nixon would have come to his senses.".

Problems such as the Nixon Paradox arise when the model becomes very detailed and models unlikely events and corner cases. The model analyzer has no notion of probability and so it will happily make rare events occur if doing so will produce a solution which has a shorter distance. To correct this shortcoming, the model needs a notion of probability - when selecting the "closest possible world" the possibilities need to be weighted by likelihood as well as similarity. Extending traditional logic to include such a notion is an interesting avenue, but it is not the task at hand.

2.1.3

Events vs. Policies

So far, the only ways we've seen to do counterfactual reasoning involve making non-trivial additions to our logic. In fact, there is a solution to this problem which does not involve counterfactual reasoning and all the complexities that go along with it. Rather than asking the role of a bit of the state (e.g. whether or not the window was open), consider asking about the role a constraint plays (e.g. the diligence policy).

What you really want to know is not the role of closing the window on that one occasion, but the role of the constraint which makes you always close the window in

(37)

such situations. Instead of "If I left the window open, then ..." you would say "If

I were not diligent, then ..."; we will examine explaining the policy that lead to the action, not the action itself. In order do do this, we will need to develop a notion of the role of a constraint. In fact, the formalism we develop will not only let us ask for the role of a constraint, but also about the role of an arbitrary subformula of a constraint.

2.1.4

What is the Role of a Formula?

What kind of an animal is the role of a formula? I appeal to the intuition of what a human would say to another human to explain such a thing; its role is what it allows or what is disallows, or how it interacts with another part of the model. For now, we will focus on non-example generation, which addresses the first view. Core extraction, described in Chapter 3, addresses the second.

Note that this approach lends itself to a model-theoretic view of the world rather than a logical view of the world. That is, it looks at enumerating the solutions (within some bound) and looking at how that set changes, rather than using syntactic manipulations to produce a proof.

Naive Role Computation

The naive approach is to just check the StayDry assertion once with Diligent present and once with it absent. This might get us what we want, if we get either of the following results:

(a) if neither check finds any counterexamples, then we know that Diligent is redundant; we stay dry either way.

(b) if the first check passes but the second finds a counterexample, then we have

an example of a circumstance where Diligent is necessary to ensure StayDry. The role of Diligent is to eliminate that case (and others like it).

As the model stands, we expect the second result. However, we might not be so fortunate; consider the situation in which the window is broken. In that case, there's

(38)

nothing you can do to stay dry if it happens to rain, be you diligent or not. The two possible results of the naive approach are the following:

(a) if both checks return the same counterexample (e.g. where the window is bro-ken), you now know one case where Diligent is irrelevant since you will get wet anyway. However, you don't know if there are cases where Diligent does matter.

(b) if both checks return different counterexamples, you have learned even less.

Perhaps each counterexample is actually a solution to both checks, or perhaps not.

What we really want is to solve for a counterexample which is only valid because Diligent was not enforced. We want an assignment which is not a solution to the model with Diligent enforced, but which is a solution when it is removed. This can be expressed as a solution to

-M A (M - D)

where M is the model, and (M - D) is the model with the Diligent constraint

removed. Solutions to this formula are cases which are disallowed by the presence of Diligent. We now get the desired solution <Intact, Open, Raining, Wet>. We term this approach non-example generation, since we are generating assignments which are almost solutions to the model, but not quite. In particular, we gener-ate assignments which would be solutions except that they fail to satisfy the target subformulae.

In the next section, we will formalize this notion of role in terms of non-examples, develop a convenient notation (conjunction diagrams), and prove some handy lemmas. Later, we will extend the technique beyond propositional logic.

(39)

2.2

Formalization and Representation:

Conjunction Diagrams

"In a few minutes a computer can make a mistake

so great that it would have taken many men many months to equal it."

Unknown

In the last section, we concluded that to determine the role of the presence of T in M, we should examine solutions to the formula M A -,(M - T); such solutions

satisfy the original model but not the altered model, thus indicating what has been

disallowed by including T in the model. First, we need to formalize what it means

to delete a subformula from a model. Then we will look at other formulae which produce useful information for the user.

2.2.1

Deletion (and Sabotage) Formalized

We need to be precise when we say "delete the subformula T from the model M", denoted (M - T). Here is what it shall mean:

" M is the simple AST of the user's model model. A simple AST is one in which

all logical operations have been desugared into -,, binary A, and binary V.

* T is a node in M, at the root of the target subformula. We assume that T is

not the root of M and that T's parent node is not a negation (although T itself may be a negation). To ask about the role of a subformula which is directly negated, one must instead ask the role of the negation plus that subformulae.

A well formed tree results when the subtree rooted at T is removed from the AST

M, except that the old parent of T will now be either a unary A or a unary V. That

node is interpreted using the following semantics, making (M - T) a simple AST:

unary and A (x) = x unary or V (x) = x

(40)

Constant Replacement

It will be convenient to talk about deletion in terms of replacing T with a Boolean constant. To that end, we prove the following result:

Theorem 1:

(M - T) is either equivalent to M[T <- True] (the formula obtained by replacing

T with the constant True), or it is equivalent to M[T <- False] (the formula obtained

by replacing T with the constant False). Proof:

Since M is simple and we have discounted the case were T's parent is a negation

(,), we know that T's parent is either an A or an V. If T's parent is an A, then (M - T) - M[T <- True]. If T's parent is an V, then (M - T) = M[T <- False].

This property of deletion leads us to define the complementary notion of sabotage, which will prove useful later on when we define a notion of correctness (Setion 2.2.4).

Definition:

Let C be the constant for which (M - T) = M[T <- C]. The result of sabotaging

T within M, denoted (M ~ T), is M[T <- -,C].

One way of thinking about sabotage is as follows: Where deleting T from M leaves the rest of M as intact as possible, sabotaging T in M simplifies the rest of M as much as possible, to the extend that altering T can. For example,

(AAB)-B = AATrue =-A

(AAB)~B _ AAFalse =-False

Sabotaging a subformula produces the maximum possible effect that the subformula could have on the entire model.

2.2.2

Conjunction Diagrams

It is now clear exactly what we mean when we write M A ,(M - T). It will also prove

fruitful to consider the other 3 possible combinations of negating and conjoining those two formulae: -M A (M - T), M A (M - T), and ,M A -,(M - T). A convenient

(41)

form for representing these combinations is a conjunction diagram. Definition:

A conjunction diagram is a table constructed from two sets of logical formulae:

one set is written as labels on the columns of a table and the other as labels on the rows. An entry in the table contains a formula (the conjunction of the row and column formulae) and/or a set of assignments (solutions to that formula).

Table 2.1: A generic conjunction diagram with column formulae Coll and C012 and row formulae Row, and Row2

A

Col1

Col2

Row1 Col1 A Row1 0012 A Row1

Row2 Col1 A Row2 Col2 A Row2

In our case, the row formulae will be always be M and -,M. When we draw the conjunction diagram for deletion, the column formulae are (M - T) and -,(M - T).

Later we will add additional column formulae.

Table 2.2: The generic conjunction diagram for deletion

A

(M - T) (M - T)

M PIA PCA

Presence Irrelevant to Allowing Presence Crucial to Allowing

MA(M-T) M A -,(M - T)

,M PCD PID

Presence Crucial to Disallowing Presence Irrelevant to Disallowing ,-M A (M - T) -,M A -,(M - T)

Conjunction diagrams are both useful for performing proofs and for presenting the information to the user. However, it is probably unreasonable to expect to teach the user the precise semantics of conjunction diagrams just to be able to answer simple questions. To that end, each entry is also given a name which indicates the meaning to the user of the solutions in that cell.

* M A (M - T) produces solutions to the original model, M, which are still

solu-tions if T is deleted. We abbreviate this category of solusolu-tions PIA, pronounced

(42)

" Al A -(M - T) produces solutions to the original model, M, which cease to

be solutions if T is deleted. We abbreviate this category of solutions PCA, pronounced "Presence Crucial to Allowing".

* -1M A (M - T) produces assignments which are not solutions of the original

model, M, but which become solutions if T is deleted. We abbreviate this category of solutions PCD, pronounced "Presence Crucial to Disallowing".

* ,M A -(M - T) produces assignments which are not solutions of the original

model, M, and are still not solutions if T is deleted. We abbreviate this category of solutions PID, pronounced "Presence Irrelevant to Disallowing".

Each cell of the conjunction diagram contails all solutions satisfying the equation written there. To avoid an overwhelming amount of data, when displaying a conjunc-tion diagram to the user, only one (arbitrarily chosen) soluconjunc-tion is shown in each cell. As we will see in Section 2.5, one solution is often enough to learn interesting things about a model.

Observation: Each possible assignment to variables of M appears somewhere in the conjunction diagram for deletion; for any assignment A,

A E PIAU PCAu PCDU PID

2.2.3

Representing Sabotage

We construct an analogous conjunction diagram for sabotage by setting the column formulae to (M ~ T) and -,(M ~ T). The interpretation of solutions in the con-junction diagram for sabotage are similar to that of deletion. However, instead of referring to the role of T's presence (failure to delete), they refer to the role of T's

integrity 2 (failure to sabotage).

Sabotage represents the maximum extent to which the target formula can influence the structure of the model as a whole. This information is far less valuable to the

2

(43)

Table 2.3: The conjunction diagram for sabotage

A

(M

~

T) -,(M T)

M IIA ICA

Integrity Irrelevant to Allowing Integrity Crucial to Allowing

MA(M~T) M A -,(M T)

ICD IID

Integrity Crucial to Disallowing Integrity Irrelevant to Disallowing

,M A (M ~ T) ,-M A ,(M ~ T)

user than is deletion; its real value comes from combining it with information about deletion to compute a notion of correctness (see Section 2.2.4. To that end, it will prove convenient to display the two tables together.

Table 2.4: The conjunction diagram for deletion and sabotage

A

(M-T) -,(M-T) (M~T) -,(M~T)

M PIA PCA IIA ICA

MA(M-T) MA-,(M -T) MA(M~T) MA-,(M~T)

,M PCD PID ICD IID

-,M A(M -T) -,MA -,(M -T) -,M A(M~,T) -,M A-,(M~T)

2.2.4

Theorems

"An expert is a person who has made all the mistakes that can be made in a very narrow field."

Niels Bohr

One can consider other mutations of T, besides replacing it with True or False, and construct comparable conjunction diagrams for them 3. However, it turns out that the 8 formulae represented in the conjunction diagram for deletion and sabotage are sufficient to compute (or bound) the effect of making an arbitrary change to T.

Definition:

Let CIA, pronounced "correctness irrelevant to allowing", denote the set of all assignments which are solutions to M and which remain solutions regardless of how

3

The column formulae will be M[T <- T'] (M with T mutated) and -(M[T <- T']) (the negation of that formula)

Figure

Table  2.1:  A  generic  conjunction  diagram  with  column  formulae  Coll  and  C012  and row  formulae  Row,  and  Row 2
Table  2.3:  The  conjunction  diagram  for  sabotage
Table  2.5:  The  role  of  the  final  clause  of  a  CNF  formula
Figure  2-2:  There  are  only  6  pairs  of entries  in  a  conjunction  diagram  which  are  not always  disjoint.
+7

Références

Documents relatifs

Our goal is to generate a trivariate parameterization with respects to a given solid model defined by its boundary triangle mesh or boundary (possibly trimmed) spline surfaces..

Through non-parametric statistical methods, we thus compare a model directly built on the extreme events and a model reconstructed from estimations of the trends of the location

When evaluating core assets modeling methods, two important dimensions can be identified: specification, which refers to the collection of aids required for specifying both

The comparison of the models has revealed the correlation that regions exhibiting high magnetic field values in the Earth’s core correspond to depressions in the core-mantle

Similarly to the acyclic orientation tests, we compared the execution time of the scheduling heuristic with the execution time of the scheduling ILP using 200 random operation graphs

Clinic for Cardiovascular Surgery, Cardiovascular Center, University Hospital Zu¨rich, Ra¨mistrasse 100, 8091, Zu¨rich, Switzerland.. *

We analyzed the main security models for the analysis of Diffie–Hellman protocols in the public key setting, the CK and eCK models, and provided secure and efficient designs of

This table presents the active weighted durations for various fractions of the portfolio invested for the replication with the use of derivatives but without