of Software Engineering/European Software Foundations Conference, Zurich, Sep 97 Engineering
Subtypes for Specications John Rushby Science Laboratory Computer International SRI Menlo Park, CA J. Rushby FSE97: Subtypes for Specications 1
Formal methods contribute useful mental frameworks, and systematic methods to the design, notations, But the primary benet from specically formal methods is they allow certain questions about a design to be that These symbolic calculations can be used for debugging and exploration as well as post-hoc verication design Comparable to the way computational uid dynamics is used the design of airplanes and jet engines in Formal Methods and Calculation documentation, and analysis of computer systems by symbolic calculation answered formal deduction, model checking) (e.g., J. Rushby FSE97: Subtypes for Specications 2
Tools are not the most important thing about formal methods Specication languages should be designed so that they ecient calculation (i.e., deduction) support Specication languages can also be designed to exploit the calculations provided by tools ecient Corollaries They are the only important thing Just like any other engineering calculations, it's tools that make formal calculations feasible and useful in practice E.g., based on higher-order logic, not set theory The topic of another talk... E.g., to better detect errors in specications The topic of this talk J. Rushby FSE97: Subtypes for Specications 3
Must be examined by proving challenge theorems, and inspection \execution," Can avoid inconsistencies using denitional styles of that guarantee \conservative extension" specication But these are often restrictive or inappropriate constructive) (too So a worthwhile goal is to increase the expressiveness and of the part of the specication language for convenience Errors in Formal Specications Most formal specications are full of errors A specication may fail to say what is intended A specication may fail to say anything at all Because it is inconsistent which we can guarantee conservative extension J. Rushby FSE97: Subtypes for Specications 4
Type systems for programming languages guarantee that errors will not occur during execution certain We should expect the type system for a specication also to guarantee absence of certain kinds of errors language Type systems for programming languages are traditionally to those for which type correctness is trivially restricted But specication languages should be used in environments powerful theorem proving is available, so suppose where Deduction Exploiting Increase the Power of Typechecking To E.g., inconsistency decidable typechecking could use theorem proving... J. Rushby FSE97: Subtypes for Specications 5
Subtypes can allow more concise and more precise specications But how do we characterize those integers that are also naturals? But this is not tightly bound to the subtype: reduces the for automation, and may allow inconsistencies opportunity Subtypes When types are interpreted as sets of values There is a natural association of subtype with subset E.g., natural is a subtype of integer Could add an axiom AXIOM 8(n: nat): n 0 nat_ax: J. Rushby FSE97: Subtypes for Specications 6
Are those where a characterizing predicate is tightly bound subtype denitions to Predicate Subtypes For example (in the notation of PVS) nat: TYPE = f i: int i 0 g Then we can write nat_prop: LEMMA 8(i, j: nat): i+j i ^ i+j j the prover can easily establish this result because the And information is recorded with the type for i and j necessary This is concise and ecient Now let's see where error detection comes in J. Rushby FSE97: Subtypes for Specications 7
Generate a proof obligation called a type correctness (TCC) to do this condition Specications are not considered typechecked until their have been discharged TCCs Nonemptiness Proof Obligations for Predicate Subtypes Subtypes may be empty, so a constant declaration c: nat introduce an inconsistency unless we ensure that its Would is nonempty type c_tcc1: OBLIGATION 9(x: nat): TRUE J. Rushby FSE97: Subtypes for Specications 8
Predicates are functions of return type bool, written as bool = i 0 nat?(i:int): Some PVS Notation The examples use the notation of PVS A verication system freely available from SRI Specication language is a simply-typed higher-order logic Augmented with dependent types and predicate subtypes Sets and predicates are equivalent in higher-order logic Regarded as a predicate, membership is written nat?(x) Regarded as a set, it is written x 2 nat? A predicate in parentheses denotes the corresponding subtype (nat?) is the same type as nat given earlier PVS has theory-level parameterization setof[nat] is the type of sets of natural numbers J. Rushby FSE97: Subtypes for Specications 9
We can specify the minimum a set axiomatically as a value two properties satisfying ^ 8(n: nat): n 2 s min(s) n An Example: The Minimum of a Set of Naturals It is a member of the given set It is no greater than any other member In PVS, this is min(s: setof[nat]): nat simple_ax: AXIOM 8(s:setof[nat]): min(s) 2 s Unfortunately, this specication is inconsistent J. Rushby FSE97: Subtypes for Specications 10
The problem is that the argument s to min could be an set empty But the rst conjunct to simple ax asserts that min(s) is a of this set member The Inconsistency J. Rushby FSE97: Subtypes for Specications 11
Using predicate subtypes, it is natural to factor the rst into the return type for min conjunct In higher-order logic, functions are just constants of \higher" so PVS forces us to prove that the corresponding type type, not empty is OBLIGATION 9(x: [s: setof[nat]! (s)]): TRUE min_tcc1: Detecting the Error With Predicate Subtypes min(s: setof[nat]): (s) (Observe that this is a dependent type) A (total) function type is nonempty if either Its range type is nonempty, or Both its domain and range types are empty Here, domain type is nonempty, but the range type may be So the TCC is false, and the inconsistency is revealed J. Rushby FSE97: Subtypes for Specications 12
the TCC becomes And OBLIGATION 9(x: [s: (nonempty?[nat])! (s)]): TRUE min_tcc: The second conjunct of the dening axiom can also be into the type factored Fixing the Specication Must either weaken properties of the value returned by min Or restrict its argument to be a nonempty set The predicate that tests for nonemptiness is nonempty?[nat] So the revised signature is (nonempty?[nat])): (s) min(s: Which is true and provable min(s: (nonempty?[nat])): f x: (s) 8(n: (s)): x n g J. Rushby FSE97: Subtypes for Specications 13
It might then seem natural to dene a max function dually (nonempty?[nat])): f x: (s) 8(n: (s)): x n g max(s: This generates the following TCC OBLIGATION max_tcc1:! fx: (s) 8(n: (s)): x ng ]): TRUE To which we can apply the following PVS proof commands + "(s:(nonempty?[nat])): (inst The PVS prover command grind does simplication using procedures and rewriting decision Extending the Example: from Minimum to Maximum 9(x1: [s: (nonempty?[nat]) choose( fx: (s) 8(n: (s)): x ng )") (grind :if-match nil) (rewrite "forall_not") J. Rushby FSE97: Subtypes for Specications 14
These proof steps produce the following goal x!1 0 [-1] Not true! We are alerted to the inconsistency in our specication By moving what was formerly specied by an axiom into the of the range type, we are using PVS's predicate specication Another Error is Revealed by Predicate Subtypes [-2] s!1(x!1) ------- f1g 9(x: (s!1)): 8(n: (s!1)): x n is asking us to prove that any nonempty set of natural Which has a largest member numbers to mechanize generation of proof-obligations for subtyping axiom satisfaction problem the J. Rushby FSE97: Subtypes for Specications 15
Which is true, and can be proved by appealing to the of the naturals well-foundedness (9(y:(p)): (8(x:(p)): (NOT x < y)))) Why Doesn't Minimum Have the Same Problem? The corresponding proof goal for min is [-1] x!1 0 [-2] s!1(x!1) ------- f1g 9(x: (s!1)): 8(n: (s!1)): x n well_founded?(<): bool = (8p: (9y: p(y)) wf_nat: AXIOM well_founded?( (i, j: nat): i < j) This is stated in the built-in \prelude" library of PVS J. Rushby FSE97: Subtypes for Specications 16
Now we see the importance of well-foundedness, can write a specication for min over any well-founded order generic Notice that the constraint on < is stated as a predicate will be required to prove that any actual subtype we The following nonemptiness TCC is generated OBLIGATION min_tcc1:! fx: (s) 8(i: (s)): x < i _ x = ig]): TRUE A Generic Specication for Minimum minspec[t: TYPE, <: (well_founded?[t])]: THEORY BEGIN min((s: (nonempty?[t]))): f x: (s) 8(i: (s)): x < i _ x = i g END minspec parameter satises the conditions for well-foundedness 9(x1: [s: (nonempty?[t]) J. Rushby FSE97: Subtypes for Specications 17
We can discharge the TCC by exhibiting the \choice choose function" Although this discharges the main goal, choose requires its to be nonempty (we'll see why later) so we get a argument f1g 8(s: (nonempty?[t])): Discharging the TCC from the Generic Specication (INST + "(s:(nonempty?[t])): choose(fx: (s) 8(i: (s)): x<i _ x=ig)") subsidiary TCC proof obligation from the instantiation min_tcc1 (TCC): ------- nonempty?[(s)](fx: (s) 8(i: (s)): x < i _ x = ig) J. Rushby FSE97: Subtypes for Specications 18
The subsidiary goal looks as though it should follow by so we introduce this fact as follows well-foundedness, And obtain the following proof goal s!1(x!1) [-1] y!1 = i!1 f3g is not true in general! Which And Another Error is Revealed by Predicate Subtyping (typepred "<") (grind :if-match nil) ------- i!1 < y!1 f1g y!1 < i!1 f2g We realize that well-foundedness is not enough Need trichotomy as well Must revise specication to require that < is a well-ordering J. Rushby FSE97: Subtypes for Specications 19
epsilon(p) returns a value satisfying p if there are any, some value of type T otherwise Automating Proofs With Predicate Subtypes We have already seen choice functions a couple of times The standard one is Hilbert's " function epsilons [T: NONEMPTY_TYPE]: THEORY BEGIN p: VAR setof[t] epsilon(p): T epsilon_ax: AXIOM (9x: x 2 p) epsilon(p) 2 p END epsilons Notice the type T is required to be nonempty J. Rushby FSE97: Subtypes for Specications 20
If p is constrained to be nonempty, can give the following specialization epsilon alt is similar to the built-in choose, but if we use it in proof of min TCC1, we get an additional subgoal the f1g 8(s: (nonempty?[t])): 8(i: (s)): _ epsilon_alt[(s)](fx: (s) 8(i: (s)): x<i _ x=ig) = i Another Choice Function choice [T: TYPE]: THEORY p: VAR (nonempty?[t]) epsilon_alt(p): T epsilon_alt_ax: AXIOM epsilon_alt(p) 2 p END choice ------- epsilon_alt[(s)](fx: (s) 8(i: (s)): x<i _ x=ig) < i J. Rushby FSE97: Subtypes for Specications 21
The extra subgoal is asking us to prove that the value of alt satises the predicate supplied as its argument epsilon It did so because its specication is VAR (nonempty?[t]) p: Which records in its type the fact that choose(p) satises p It is quite hard for a prover to locate and instantiate stated in general axioms (unless they have special properties Making Information Available in the Types Follows from epsilon alt ax but has quite complicated proof How did choose avoid this? choose(p): (p) such as rewrite rules), but predicate subtypes bind forms to types, so the prover can locate them easily properties J. Rushby FSE97: Subtypes for Specications 22
Suppose we introduce a new subtype for even integers TYPE = fi:int 9(j:int): i=2jg even: And a function half with signature [ even! int ] half: And then pose the conjecture LEMMA 8(i: int): half(i+i+2) = i+1 even_prop: The argument i+i+2 to half has type int, but is required to even be However, int is a supertype of even, so we can generate a to check that the value satises the predicate for even TCC PVS provides \type judgments" that allow closure properties the sum of two evens is even) to be stated and proved (e.g., Another Proof Obligation for Predicate Subtypes even_prop_tcc1: OBLIGATION 8(i:int): 9(j: int): i+i+2 = 2j once and for all J. Rushby FSE97: Subtypes for Specications 23
Given a name, the phone book should return the set of numbers associated with that name phone There should also be functions for adding, changing, and phone numbers deleting Here is the beginning of a suitable specication phone_numbers: TYPE names, Enforcing Invariants with Predicate Subtypes Consider a specication for a city phone book phone_book: TYPE = [names! setof[phone_numbers]] B: VAR phone_book n: VAR names p: VAR phone_numbers add_number(b, n, p): phone_book = B WITH [(n) := B(n)[fpg]... J. Rushby FSE97: Subtypes for Specications 24
Suppose that dierent names are required to have disjoint of phone numbers sets Introduce unused number predicate and modify add number as follows And how do we know the the modied add number function it? preserves Adding an Invariant unused_number(b, p): bool = 8(n: names): NOT p 2 B(n) add_number(b, n, p): phone_book = IF unused_number(b, p) THEN B WITH [(n) := B(n)[fpg] ELSE B ENDIF But where is the disjointness property stated explicitly? J. Rushby FSE97: Subtypes for Specications 25
Simply change the type for phone book as follows TYPE = phone_book: f B: [ names! setof[phone_numbers]] Furthermore, typechecking add number generates the TCC following 8(r, m: names): r 6= m Making the Invariant Explicit with a Predicate Subtype 8(n, m: names): n 6= m disjoint?(b(n), B(m)) g This makes the invariant explicit add_number_tcc1: OBLIGATION 8(B, n, p): unused_number(b, p) disjoint?(b WITH [(n) := B(n)[fpg](r), B WITH [(n) := B(n)[fpg](m)) Which requires us to prove that it really is invariant J. Rushby FSE97: Subtypes for Specications 26
For example, division can be typed as follows real: TYPE = f r: real r 6= 0 g nonzero Then typechecking prop: LEMMA 8 (x, y: real): div Generates the following proof obligation OBLIGATION 8 (x, y: real): div_prop_tcc1: Notice that the context of the subtype occurrence (under a reading) appears in the TCC left-to-right Predicate Subtypes and Partial Functions partial functions become total when their domains are Many more precisely specied /: [real, nonzero real! real] x 6= y (x - y)/(y - x) = -1 x 6= y (y - x) 6= 0 Discharged automatically by the PVS decision procedures J. Rushby FSE97: Subtypes for Specications 27
This function is undened if j > i The subp \Challenge" Consider the function subp on the integers dened by subp(i; j) = if i = j then 0 else subp(i; j + 1) + 1 endif When j i; subp(i; j) = i? j Often cited as demonstrating the need for partial functions But is easily handled using dependent predicate subtypes (j:int j i)): RECURSIVE int = subp((i:int), IF i = j THEN 0 ELSE subp(i, j+1) + 1 ENDIF MEASURE i-j subp_val: LEMMA 8 (i,j: int): ji subp(i,j) = i-j J. Rushby FSE97: Subtypes for Specications 28
The subp \Challenge" (continued) Specication generates the following TCCs % Subtype TCC generated (line 6) for i - j subp_tcc1: OBLIGATION 8(i: int), (j: int j i): i-j 0 % Subtype TCC generated (line 5) for j + 1 subp_tcc2: OBLIGATION 8(i: int), (j: int j i): NOT i = j j+1 i % Termination TCC generated (line 5) for subp subp_tcc3: OBLIGATION 8(i: int), (j: int j i): NOT i = j i - (j+1) < i-j All three proved automatically by PVS decision procedures J. Rushby FSE97: Subtypes for Specications 29
It often contributes clarity and precision to a specication if are identied as injections, surjections, etc. functions But how to ensure a purported surjection really has the property? Predicate subtypes! The surjections are a subtype of the associated with the following predicate functions So that alt: (surjective?[even, int]) = (e: even): e/2 half Generates the following proof obligation OBLIGATION half_alt_tcc2: Higher-Order Predicate Subtypes function props[dom, rng: TYPE]: THEORY surjective?(f): bool = 8 (r: rng): 9 (d: dom): f(d) = r surjective?[even, int](lambda (e: even): e / 2) J. Rushby FSE97: Subtypes for Specications 30
Higher-Order Predicate Subtypes (continued) The proof command (grind :if-match nil) reduces this to half_alt_tcc2 : f-1g integer_pred(y!1) ------- f1g (9(x: even): x / 2 = y!1) Which is easily discharged J. Rushby FSE97: Subtypes for Specications 31
The datatype invariants of VDM have some similarity to subtypes (e.g., proof obligations in typechecking) predicate But are part of VDM's mechanisms for specifying operations terms of pre- and post-conditions on a state, rather than in And Z/Eves does \domain checking" for Z (and has found thereby in every specication checked) aws Predicate subtypes are fully supported as part of a logic only by Nuprl and PVS (as far as I know) specication PVS separates the algorithmic elements from those that TCCs require Languages with Predicate Subtypes part of the type system for its logic ACL2 has predicate \guards" on appl'ns of partial functions In Nuprl, all typechecking requires theorem proving J. Rushby FSE97: Subtypes for Specications 32
Some treatments of programming languages use \structural" to account for Object-Oriented features subtypes Intuition is dierent to \subtypes as subsets": value of allowed anywhere one of the parent type is subtype Thus adding elds to a record creates a subtype: function operates on \points" should also operate on \colored that Extension to function types leads to normal or covariant on range types subtyping Other Approaches to Subtyping points" [ nat! nat] is a subtype of [ nat! int] But contravariant subtyping on domain types [ int! nat] is a subtype of [ nat! nat] J. Rushby FSE97: Subtypes for Specications 33
Interesting research challenge to combine structural with subtyping (contravariance complicates equality) predicate PVS does extend subtyping covariantly over range types of functions However, PVS also provides type \conversions" that can restrict, or (less automatically) expand the automatically E.g., allow setof[int] to be provided where setof[nat] is (and vice-versa) expected Combinations And over the positive parameters to abstract data types E.g., list[nat] is a subtype of list of list[int] But requires equality on domain types domain of a function J. Rushby FSE97: Subtypes for Specications 34
Via earlier Ehdm system, where Friedrich von Henke them from ANNA adopted I nd them the most useful innovation I have seen in language design specication But not everybody agrees: Lamport and Paulson make a for untyped specication languages (when used by hand) case Conclusion Predicate subtypes in PVS due to Sam Owre and N. Shankar Formal semantics available on the PVS web site Many users exploit them very eectively I hope to have persuaded you of their value, too J. Rushby FSE97: Subtypes for Specications 35
Browse general papers and technical reports at http://www.csl.sri.com/fm.html Detailed Information about PVS is available from http://www.csl.sri.com/pvs.html http://www.csl.sri.com/pvs/examples gets you to a of tutorials and their supporting specication directory To Learn More About PVS tse95.html is a good overview of PVS pvs-bib.html links to a bibliography with over 140 entries les You can get PVS from ftp://ftp.csl.sri.com/pub/pvs Allegro Lisp for SunOS, Solaris, IBM AIX, or Linux Need 64M memory, 100M swap space, Sparc 20 or better (Best is 64MB 200 MHz P6, costs under $3,000 in USA) J. Rushby FSE97: Subtypes for Specications 36