home *** CD-ROM | disk | FTP | other *** search
/ ftp.pasteur.org/FAQ/ / ftp-pasteur-org-FAQ.zip / FAQ / larch-faq < prev    next >
Encoding:
Internet Message Format  |  2002-01-03  |  199.3 KB

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!newsfeed.stanford.edu!newsfeed.berkeley.edu!ucberkeley!hammer.uoregon.edu!logbridge.uoregon.edu!newsrelay.iastate.edu!news.iastate.edu!leavens
  2. From: leavens@cs.iastate.edu (Gary T. Leavens)
  3. Newsgroups: comp.specification.larch,comp.answers,news.answers
  4. Subject: Larch Frequently Asked Questions (comp.specification.larch FAQ)
  5. Supersedes: <larch-faq-1-1007417763@cs.iastate.edu>
  6. Followup-To: comp.specification.larch
  7. Date: 2 Jan 2002 22:16:11 GMT
  8. Organization: Department of Computer Science, Iowa State University
  9. Lines: 4199
  10. Approved: news-answers-request@MIT.EDU
  11. Distribution: world
  12. Expires: 02/06/02 16:16:03
  13. Message-ID: <larch-faq-1-1010009763@cs.iastate.edu>
  14. Reply-To: leavens@cs.iastate.edu (Gary T. Leavens)
  15. NNTP-Posting-Host: larch.cs.iastate.edu
  16. Summary: Background on the Larch family of languages,
  17.          including references to where more information can be found.
  18. Keywords: Larch, LSL, LP, BISL, specification, FAQ
  19. X-Content-Currency: This FAQ changes regularly.  When a saved or printed copy
  20.    is over 6 months old, obtain a new one as described in the introduction.
  21. Xref: senator-bedfellow.mit.edu comp.specification.larch:792 comp.answers:48388 news.answers:222170
  22.  
  23. Posted-By: auto-faq 3.2.1.4
  24. Archive-name: larch-faq
  25. Posting-Frequency: monthly
  26. Version: 1.116
  27. URL: http://www.cs.iastate.edu/~leavens/larch-faq.html
  28. Copyright: (c) 1995, 1996, 1997 Gary T. Leavens
  29. Maintainer: Gary T. Leavens and Matt Markland
  30.  
  31. This FAQ is copyright (C) 1997 Gary T. Leavens.
  32.  
  33. Permission is granted for you to make copies of this FAQ for educational and
  34. scholarly purposes, and for commercial use in specifying software, but the
  35. copies may not be sold or otherwise used for direct commercial advantage;
  36. permission is also granted to make this document available for file
  37. transfers from machines offering unrestricted anonymous file transfer access
  38. on the Internet; these permissions are granted provided that this copyright
  39. and permission notice is preserved on all copies. All other rights reserved.
  40.  
  41. ----------------------------------------------------------------------------
  42.  
  43. Larch Frequently Asked Questions
  44.  
  45. $Revision: 1.116 $
  46.  
  47. 18 July 2001
  48.  
  49. by Gary T. Leavens
  50.  
  51.   ------------------------------------------------------------------------
  52.  
  53. Table of Contents
  54.  
  55.    * Introduction
  56.    * Acknowledgements
  57.    * 1. Larch and the Larch Family of Languages
  58.         o 1.1 What is Larch? What is the Larch family of specification
  59.           languages?
  60.         o 1.2 Why does Larch have two tiers?
  61.         o 1.3 What is the difference between LSL and a Larch BISL?
  62.         o 1.4 How does Larch compare to other specification languages?
  63.              + 1.4.1 How does Larch compare to VDM-SL?
  64.              + 1.4.2 How does Larch compare to Z?
  65.              + 1.4.3 How does Larch compare to COLD-K?
  66.         o 1.5 What is the history of the Larch project?
  67.         o 1.6 What is the origin of the name Larch?
  68.         o 1.7 Where can I get more information on Larch and Larch languages?
  69.         o 1.8 Is there an object-oriented extension to Larch?
  70.         o 1.9 What is the use of formal specification and formal methods?
  71.    * 2. The Larch Shared Language (LSL)
  72.         o 2.1 What is the Larch Shared Language (LSL)?
  73.         o 2.2 Where can I find information on-line about LSL?
  74.         o 2.3 Where can I get a checker for LSL?
  75.         o 2.4 Do you have a good makefile to use with the LSL checker?
  76.         o 2.5 What is a sort?
  77.         o 2.6 What is the purpose of an LSL trait? What is a trait used for?
  78.         o 2.7 What are the sections of an LSL trait?
  79.         o 2.8 What is the difference between assumes and includes?
  80.         o 2.9 How and when should I use a partitioned by clause?
  81.         o 2.10 How and when should I use a generated by clause?
  82.         o 2.11 When should I use an implies section?
  83.         o 2.12 How and when should I use a converts clause?
  84.         o 2.13 How and when should I use an exempting clause?
  85.              + 2.13.1 Does exempting some term make it undefined?
  86.              + 2.13.2 How can I exempt only terms that satisfy some
  87.                condition?
  88.         o 2.14 What is the meaning of an LSL specification?
  89.         o 2.15 How does LSL handle undefined terms?
  90.         o 2.16 Is there support for partial specifications in LSL?
  91.              + 2.16.1 Can I specify a partial function in LSL?
  92.              + 2.16.2 Do I have to specify everything completely in LSL?
  93.         o 2.17 Can I define operators using recursion?
  94.         o 2.18 What pitfalls are there for LSL specifiers?
  95.         o 2.19 Can you give me some tips for specifying things with LSL?
  96.         o 2.20 How do I know when my trait is abstract enough?
  97.         o 2.21 Is there a way to write a trait that will guarantee
  98.           consistency?
  99.         o 2.22 Do I have to write all the traits I am going to use from
  100.           scratch?
  101.         o 2.23 Where can I find handbooks of LSL traits?
  102.         o 2.24 How do I write logical quantifiers within an LSL term?
  103.         o 2.25 Where can I find LaTeX or TeX macros for LSL?
  104.         o 2.26 How do I write some of those funny symbols in the Handbook in
  105.           my trait?
  106.         o 2.27 Is there a literate programming tool for use with LSL?
  107.         o 2.28 Is there a tool for converting LSL to hypertext for the web?
  108.    * 3. The Larch Prover (LP)
  109.         o 3.1 What is the Larch Prover (LP)?
  110.         o 3.2 What kind of examples have already been treated by LP?
  111.         o 3.3 How does LP compare with other theorem provers?
  112.         o 3.4 Where can I get an implementation of LP?
  113.         o 3.5 Is there a command reference or list of LP commands?
  114.         o 3.6 Can I change the erase character in LP?
  115.         o 3.7 How do I interrupt LP?
  116.         o 3.8 Do I need to use LSL if I use LP?
  117.         o 3.9 Do I need to use LP if I use LSL?
  118.         o 3.10 How do I use LP to check my LSL traits?
  119.         o 3.11 What is the use of each kind of file generated by the LSL
  120.           checker?
  121.         o 3.12 If LP stops working on my input is it all correct?
  122.         o 3.13 How do I find out where I am in my proof?
  123.         o 3.14 What proof techniques does LP attempt automatically?
  124.         o 3.15 Can you give me some tips on proving things with LP?
  125.         o 3.16 What pitfalls are there for LP users?
  126.         o 3.17 How do I prove that my theory is consistent with LP?
  127.         o 3.18 How can I backtrack if I made a mistake in my proof?
  128.         o 3.19 How do I prove something like 0 <= 2 in LP?
  129.         o 3.20 How can I develop a proof that I can replay later?
  130.         o 3.21 Do I have to reprove everything in an included trait?
  131.         o 3.22 Does LP use assertions in the implies section of an included
  132.           trait?
  133.    * 4. Behavioral Interface Specification Languages (BISLs)
  134.         o 4.1 What is a behavioral interface specification language (BISL)?
  135.         o 4.2 Where can I get a BISL for my favorite programming language?
  136.         o 4.3 Do I need to write an LSL trait to specify something in a
  137.           BISL?
  138.         o 4.4 What is an abstract value?
  139.         o 4.5 What do mutable and immutable mean?
  140.         o 4.6 If I specify an ADT in a BISL do I prove it is the same as the
  141.           trait?
  142.         o 4.7 What does requires mean?
  143.         o 4.8 What does ensures mean?
  144.         o 4.9 What does modifies mean?
  145.         o 4.10 What does trashes mean?
  146.         o 4.11 What does claims mean?
  147.         o 4.12 What is the meaning of a specification written in a BISL?
  148.         o 4.13 How do I specify something that is finite or partial?
  149.         o 4.14 How do I specify errors or error-checking?
  150.         o 4.15 How do I specify that all the values of a type satisfy some
  151.           property?
  152.         o 4.16 What pitfalls are there for BISL specifiers?
  153.         o 4.17 Can you give me some tips for specifying things in a BISL?
  154.    * Bibliography
  155.    * Footnotes
  156.  
  157.   ------------------------------------------------------------------------
  158.  
  159. Introduction
  160.  
  161. This document is a list of frequently asked questions (FAQ) and their
  162. answers for the Larch family of specification languages. It is intended to
  163. be useful to those who are new to Larch, especially to students and others
  164. trying to understand and apply Larch. However, there is some material that
  165. is also intended for experts in other formal methods who would like to learn
  166. more about Larch. If you find something that seems too technical, please
  167. skip a bit, perhaps to another question.
  168.  
  169. We are looking for more contributions of questions and answers, as well as
  170. corrections and additions to the answers given. Please send e-mail to us at
  171. larch-faq@cs-DOT-iastate-DOT-edu (after changing each "-DOT-" to "."). We
  172. will welcome and acknowledge any help you may give.
  173.  
  174. Bibliographic references are described at the end of this document (see
  175. section Bibliography). They look like "[Wing83]", which give the names of up
  176. to 3 authors, and an abbreviated year of publication.
  177.  
  178. This FAQ is accessible on the WWW in the following URL.
  179.  
  180.    http://www.cs.iastate.edu/~leavens/larch-faq.html
  181.  
  182. HTML, plain text, postscript, and GNU info format versions are also
  183. available by anonymous ftp at the following URLs.
  184.  
  185.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.html
  186.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.txt.gz
  187.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.ps.gz
  188.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.info.tar.gz
  189.  
  190. <larch-faq@cs-DOT-iastate-DOT-edu>
  191.  
  192.  
  193. This FAQ is provided as is without any express or implied warranties. While
  194. every effort has been taken to ensure the accuracy of its information, the
  195. author and maintainers assume no responsibility for errors or omissions, or
  196. for damages resulting from the use of the information contained herein.
  197.  
  198. Acknowledgements
  199.  
  200. This work was partially funded by (US) National Science Foundation, under
  201. grant CCR-9503168.
  202.  
  203. Thanks to Matt Markland who provided the initial impetus for getting this
  204. FAQ started, who helped make up the initial list of questions.
  205.  
  206. Many thanks to John Guttag, Jim Horning, Jeannette Wing, and Steve Garland
  207. for creating the Larch approach and its tools, and for their patient
  208. teaching of its ideas through their writing, personal contact, and many
  209. e-mail messages.
  210.  
  211. Thanks to Perry Alexander, Al Baker, Pieter Bekaert, Eric Eide, John
  212. Fitzgerald, Jim Horning, Ursula Martin, Bertrand Meyer, Clyde Ruby, and
  213. Jeannette Wing for general comments, updates, and corrections to this FAQ.
  214. Thanks to Steve Garland and Jim Horning for help with answers. Thanks to
  215. Pierre Lescanne, Kishore Dhara, Teo Rus, Narayanan Sridhar, and
  216. Sathiyanarayanan Vijayaraghavan for suggesting questions.
  217.  
  218. 1. Larch and the Larch Family of Languages
  219.  
  220. In this chapter, we discuss global questions about Larch.
  221.  
  222.    * What is Larch?
  223.    * Why does Larch have two tiers?
  224.    * What is the difference between LSL and a Larch BISL?
  225.    * How does Larch compare to other specification languages?
  226.    * What is the history of the Larch project?
  227.    * What is the origin of the name Larch?
  228.    * Where can I get more information on Larch and Larch languages?
  229.    * Is there an object-oriented extension to Larch?
  230.    * What is the use of formal specification and formal methods?
  231.  
  232. 1.1 What is Larch? What is the Larch family of specification languages?
  233.  
  234. Larch [Guttag-Horning93] may be thought of as an approach to formal
  235. specification of program modules. This approach is an extension of Hoare's
  236. ideas for program specification [Hoare69] [Hoare72a]. Its distinguishing
  237. feature is that it uses two "tiers" (or layers) [Wing83]. The top tier is a
  238. behavioral interface specification language (BISL), tailored to a specific
  239. programming language. Such BISLs typically use pre- and postcondition
  240. specifications to specify software modules. The bottom tier is the Larch
  241. Shared Language (LSL, see [Guttag-Horning93], Chapter 4), which is used to
  242. describe the mathematical vocabulary used in the pre- and postcondition
  243. specifications. The idea is LSL specifies a domain model, some mathematical
  244. vocabulary, and the BISL specifies both the interface and the behavior of
  245. program modules. See section 1.2 Why does Larch have two tiers?, for more of
  246. the reasons for this separation.
  247.  
  248. The Larch family of specification languages [Guttag-Horning-Wing85b]
  249. consists of all the BISLs that use LSL for specification of mathematical
  250. vocabulary. Published BISLs with easily accessible references include:
  251.  
  252.    * Larch/CLU [Wing83] [Wing87], for CLU,
  253.    * Larch/Ada [Guaspari-Marceau-Polak90] [ORA94], for Ada,
  254.    * LCL [Guttag-Horning93] Chapter 5 and [Tan94] [Evans00], for ANSI C,
  255.    * LM3 [Guttag-Horning93] Chapter 6 and [Jones91] [Jones93], for Modula-3,
  256.    * Larch/Smalltalk [Cheon-Leavens94] [Cheon-Leavens94b], for Smalltalk-80,
  257.    * Larch/C++ [Leavens97] [Leavens96b], for C++, and
  258.    * Larch/ML [Wing-Rollins-Zaremski93], for Standard ML,
  259.    * VSPEC [Baraona-Penix-Alexander95] [Baraona-Alexander96]
  260.      [Baraona-Alexander-Wilsey96], for VHDL.
  261.  
  262. There are also some BISLs whose documentation is not as easy to come by:
  263. Larch/Generic [Chen89], GCIL (which stands for Generic Concurrent Interface
  264. specification Language [Lerner91]), and Larch/CORBA (a BISL for CORBA IDL
  265. [Sivaprasad95]).
  266.  
  267. Typically, each BISL uses the declaration syntax of the programming language
  268. for which it is tailored (e.g., C for LCL, Modula-3 for LM3), and adds
  269. annotations to specify behavior. These annotations typically consist of pre-
  270. and postconditions (often using the keywords requires and ensures), some way
  271. to state a frame axiom (often using the keyword modifies), and some way to
  272. indicate what LSL traits are used to provide the mathematical vocabulary.
  273. See section 4. Behavioral Interface Specification Languages (BISLs), for
  274. more details.
  275.  
  276. 1.2 Why does Larch have two tiers?
  277.  
  278. The two "tiers" used in the Larch family of specification languages are LSL,
  279. which is called the bottom tier, and a behavioral interface specification
  280. language (a BISL), which is called the top tier.
  281.  
  282. This specification of program modules using two "tiers" is a deliberate
  283. design decision (see [Wing83] and [Guttag-Horning93], Chapter 3). It is
  284. similar to the way that VDM [Jones90] [ISO-VDM96] [Fitzgerald-Larsen98] is
  285. typically used (one specifies a model and some auxiliary functions, in a way
  286. similar to LSL, and then one uses that vocabulary to specify the operations
  287. that are to be implemented in some programming language.) However, VDM does
  288. not have a family of BISLs that are tailored to specific programming
  289. languages. Only the Larch family, and the RESOLVE family [Edwards-etal94],
  290. have specification languages tailored to specific programming languages.
  291. (See section 1.4 How does Larch compare to other specification languages?,
  292. for more comparisons.)
  293.  
  294. What are the advantages of using the Larch two-tiered approach?
  295.  
  296.    * Having different BISLs tailored to each programming language allows
  297.      each BISL to specify all the details of a program module's interface
  298.      (how to call it) and behavior (what it does). If one has a generic
  299.      interface specification language, such as VDM-SL [Jones90] [ISO-VDM96]
  300.      [Fitzgerald-Larsen98], then one cannot specify all interface details.
  301.    * The division into two tiers allows the language used for each tier to
  302.      be more carefully designed and expressive. For example, although it is
  303.      possible to deal with finiteness, partiality, exceptional behavior,
  304.      aliasing, mutation, and side-effects in mathematics, dealing with such
  305.      issues requires using more apparatus than just mathematical functions.
  306.      (One might use, for example, the techniques of denotational semantics
  307.      [Schmidt86].) Since such additional apparatus does not fit well with an
  308.      algebraic style of specification, these issues are thus typically
  309.      ignored in LSL specifications. By ignoring these issues, LSL
  310.      specifiations can deal with potentially infinite, pure values, and
  311.      total functions, in a stateless setting. On the other hand, while pre-
  312.      and postcondition specifications are good for the specification of
  313.      finiteness, partiality, exceptions, aliasing, mutation, and
  314.      side-effects, they are not well adapted to the specification of
  315.      mathematical vocabulary. Thus each tier uses techniques that are most
  316.      appropriate to its particular task.
  317.    * The division into two tiers allows the underlying logic to be
  318.      classical. That is, because one is not specifying recursive programs in
  319.      LSL, there is no need for a specialized logic that deals with partial
  320.      functions; instead, LSL can use total functions and classical logic
  321.      [Leavens-Wing97].
  322.    * The domain models described in LSL can be shared among many different
  323.      BISLs, so the effort that goes into constructing such models is not
  324.      limited to just one BISL [Wing83].
  325.  
  326. One could imagine using some other language besides LSL for the bottom tier
  327. and still getting these advantages. This is done, for example, in RESOLVE
  328. [Edwards-etal94]. Chalin [Chalin95] has suggested that Z [Hayes93]
  329. [Spivey92] could also serve for the bottom tier, but one would probably want
  330. to use a subset of Z without state and the specification of side-effects for
  331. that.
  332.  
  333. The major disadvantage of the tailoring of each BISL to a specific
  334. programming language is that each BISL has its own syntax and semantics, and
  335. thus requires its own tool support, manuals, etc.
  336.  
  337. (Parts of the following paragraph are adapted from a personal communication
  338. from Horning of November 29, 1996.)
  339.  
  340. Something that might seem to be a disadvantage of the Larch approach is that
  341. one sometimes finds oneself writing out a very similar specifications in
  342. both LSL and a BISL. Isn't that a waste of effort? It may seem like that,
  343. but one has to realize that one is doing two different things, and thus the
  344. two similar specifications cannot really be the same. What may happen is
  345. that one writes similar declarations on the two levels, with parallel sets
  346. of operators and procedures. For example, one might specify LSL operators
  347. empty, push, pop, top for stacks, and then specify in a BISL procedures
  348. Empty, Push, Pop, and Top. While the BISL procedure specification will use
  349. the LSL operators in their pre- and postconditions, there will probably be
  350. significant differences in their signatures. For example, the procedure Push
  351. may have a side-effect, rather than returning a new stack value as would the
  352. push operator in the trait. If you find yourself repeating the axioms from
  353. an LSL trait in a BISL specificaton, then you're probably making a mistake.
  354.  
  355. It is also difficult to extract a simple mathematical vocabulary (like the
  356. total functions of LSL) from a BISL specification. This is because the
  357. semantics of program modules tends to be complex, Thus a BISL specification
  358. is not an appropriate vehicle for the specification of mathematical
  359. vocabulary.
  360.  
  361. See section 1.3 What is the difference between LSL and a Larch BISL?, for
  362. more discussion on this point.
  363.  
  364. 1.3 What is the difference between LSL and a Larch BISL?
  365.  
  366. The main difference between LSL and a Larch BISL is that in LSL one
  367. specifies mathematical theories of the operators that are used in the pre-
  368. and postcondition specifications of a Larch BISL. Thus LSL is used to
  369. specify mathematical models and auxiliary functions, and the a Larch BISL is
  370. used to specify program modules that are to be implemented in some
  371. particular programming language.
  372.  
  373. The following summary, provided by Horning (private communication, October
  374. 1995), contrasts LSL and a Larch BISL.
  375.  
  376.   A BISL specifies (not LSL)        LSL specifies (not a BISL)
  377.   ---------------------------       ---------------------------
  378.   State                             Theory definition
  379.     storage allocation              Theory operations
  380.     aliasing, side-effects            inclusion, assumption,
  381.   Control                              implication, parameterization
  382.     errors, exception handling,     Operator definitions
  383.     partiality, pre-conditions,     Facilities for libraries, reuse
  384.     concurrency
  385.   Programming language constructs
  386.     type system, parameter modes,
  387.     special syntax and notations
  388.   Implementation
  389.     (no LSL operators are
  390.      implemented)
  391.  
  392. Horning's summary is that a BISL handles "all the messy, boring stuff",
  393. while LSL handles "all the subtle, hard stuff", and thus the features in the
  394. two tiers do not overlap much. However, that summary is from the
  395. point-of-view of a designer of LSL. From the point of view of a user of a
  396. Larch BISL, the BISL is where you specify what is to be implemented, and LSL
  397. is where you do "domain modeling".
  398.  
  399. See [Lamport89] [Guttag-Horning93], Chapter 3, for more about the role of
  400. interface specification, and the separation into two tiers.
  401.  
  402. 1.4 How does Larch compare to other specification languages?
  403.  
  404. First, a more precise comparison is needed, because Larch is not a single
  405. language, but a family of languages (see above). Another problem with this
  406. comparison is that Larch has two tiers, but VDM-SL [Jones90] [ISO-VDM96]
  407. [Fitzgerald-Larsen98], Z [Hayes93] [Spivey92], and COLD-K [Feijs-Jonkers92]
  408. are all integrated languages, which mix aspects of both of the tiers of the
  409. Larch family. Thus we will compare some aspects of VDM-SL and Z to LSL and
  410. other aspects to BISLs in the Larch family (such as LCL or LM3
  411. [Guttag-Horning93], Chapters 5 and 6).
  412.  
  413. (The comparisons below tend to be a bit technical; if you are not familiar
  414. with specification and verification, you might want to skip to another
  415. question.)
  416.  
  417. An excellent resource for comparison of LSL to other algebraic specification
  418. languages is [Mosses96]. Also a comparison of Larch with RESOLVE
  419. [Edwards-etal94] is found in [Sitaraman-Welch-Harms93].
  420.  
  421.    * How does Larch compare to VDM-SL?
  422.    * How does Larch compare to Z?
  423.    * How does Larch compare to COLD-K?
  424.  
  425. 1.4.1 How does Larch compare to VDM-SL?
  426.  
  427. By VDM, one means, of course, the specification language VDM-SL [Jones90]
  428. [ISO-VDM96] [Fitzgerald-Larsen98]. In comparison with LSL, in VDM-SL one can
  429. specify mathematical values (models) using constructs similar to those in
  430. denotational semantics and typed, functional programming languages. That is,
  431. one can declare types of records, tagged unions, sets, maps and so on, and
  432. one can specify mathematical functions on such values, either in a
  433. functional style, or by the use of pre- and postcondition specifications.
  434. For example, one might write the following in VDM-SL to define a phone book.
  435.  
  436.   -- This is a VDM-SL model and auxiliary function specification
  437.  
  438.   PhoneBook = map Id to (Info | HIDDEN)
  439.   Info :: number : seq of Digit
  440.           address : Address
  441.  
  442.   listed : PhoneBook * Id -> bool
  443.   listed(pb, id) == id in set dom pb
  444.  
  445. The above example uses the interchange syntax of VDM-SL [ISO-VDM96] is used.
  446. In this syntax, for example, * is an approximation to the mathematical
  447. notation for a cross product; see Section 10 of [ISO-VDM96] for details. The
  448. type PhoneBook is a map to a tagged union type. The type Info is a record
  449. type. The auxiliary function listed is given in a mathematical form, similar
  450. to LSL.
  451.  
  452. In LSL one can use standard traits (for example, those in Guttag and
  453. Horning's handbook [Guttag-Horning93], Appendix A) and the LSL shorthands
  454. tuple and union (see Section 4.8 of [Guttag-Horning93]) to translate VDM-SL
  455. specifications of mathematical values into LSL. For example, the following
  456. is an approximation to the above VDM-SL specification.
  457.  
  458. % This is LSL
  459.  
  460. PhoneBookTrait : trait
  461.   includes Sequence(Digit, Number),
  462.            FiniteMap(PhoneBook, Id, InfoOrHIDDEN)
  463.   Info tuple of number : Number, address : Address
  464.   InfoOrHidden union of left : Info, right : HIDDEN
  465.   introduces
  466.     listed : PhoneBook, Id -> Bool
  467.   asserts
  468.     \forall pb: PhoneBook, id: Id
  469.       listed(pb, id) = defined(pb, id);
  470.  
  471. However, VDM-SL does not have the equivalent of LSL's equational
  472. specification constructs, and thus it is more difficult in VDM-SL to specify
  473. a mathematical vocabulary at the same level of abstraction. That is, there
  474. is no provision for algebraic specification in VDM-SL.
  475.  
  476. Because VDM-SL has a component that is like a programming language, and
  477. because it allows recursive definitions, the logic used in VDM-SL is a
  478. three-valued logic instead of the classical, two-valued logic of LSL. This
  479. may make reasoning about VDM-SL specifications relatively more difficult
  480. than reasoning about LSL specifications.
  481.  
  482. In comparison to Larch family BISLs, the first thing to note is that VDM-SL
  483. is not a BISL itself, as it is not tailored to the specification of
  484. interfaces for some particular programming language. This is evident in the
  485. following example, which continues the above VDM-SL phonebook specification.
  486.  
  487.   -- The following is a VDM-SL operation specification
  488.  
  489.   LOOKUP(pb: PhoneBook, id: Id) i: Info
  490.     pre listed(pb, id)
  491.    post i = pb(id)
  492.  
  493. In the above VDM-SL specification, it is evident that one can define some
  494. generic interface information (parameters, information about their abstract
  495. values, etc.). The pre- and postcondition format of such specifications has
  496. been adopted by most Larch family BISLs. Framing for procedure
  497. specifications in VDM-SL is done by declaring external variables, and noting
  498. which are readable and writable by a procedure; these two classes of
  499. variables are respectively defined by external declarations (in LCL and
  500. Larch/C++), and by the modifies clause. Because VDM-SL is generic, it
  501. cannot, by itself, specify language-specific interface details, such as
  502. pointers, exception handling, etc. However, an advantage of VDM-SL is that
  503. it has better tool support than most BISLs in the Larch family.
  504.  
  505. 1.4.2 How does Larch compare to Z?
  506.  
  507. Like VDM-SL, Z [Hayes93] [Spivey92] (pronounced "zed") is a specification
  508. language that allows both the specification of mathematical values and
  509. program modules.
  510.  
  511. Like LSL, Z allows the definition of mathematical operators equationally
  512. (see [Spivey92], section 3.2.2). A Z schema is roughly comparable to an LSL
  513. trait. The main difference between Z and LSL is that in Z specifications can
  514. include state variables. That is, a Z schema can specify variables, or a
  515. procedure with side effects on such variables. In this respect a Z schema
  516. can act much like a Larch family BISL, since, unlike LSL, it is not
  517. restricted to the specification of mathematical constants and mathematical
  518. functions.
  519.  
  520. By concentrating on the features of Z that do not involve state variables,
  521. one can more closely compare Z and LSL. We do this for the next several
  522. paragraphs below.
  523.  
  524. The Z schema calculus (see [Spivey92], section 3.8) allows one to apply to
  525. schemas: most logical connectives, quantification, name hiding, and
  526. pipelining. (One can also use sequential composition between schemas that
  527. specify side-effects.) The schema calculus is thus more expressive than the
  528. LSL mechanisms: includes and assumes. However, in LSL one can effectively
  529. conjoin traits by including them all to make a new trait.
  530.  
  531. It is possible in Z to write schemas that describe constants and
  532. mathematical functions only. However, many purely mathematical Z schemas
  533. describe something more like an instance of an LSL tuple. This is done in Z
  534. by giving several variable declarations. For example, consider the following
  535. Z schema (in which Z stands for the integers).
  536.  
  537.   --Z_rational----------------------------------
  538.   | num, den: Z
  539.   ---------------------------------------------
  540.  
  541. The above is semantically similar to the LSL trait LSL_rational given below.
  542.  
  543. LSL_rational: trait
  544.   includes Integer
  545.   introduces
  546.     num: -> Int
  547.     den: -> Int
  548.  
  549. However, in Z usage, the schema Z_rational is likely to be useful, whereas
  550. in LSL one would typically write a trait such as the following, which
  551. specifies a type (called a sort in LSL) of rational numbers.
  552.  
  553. LSL_rational_sort: trait
  554.   includes Integer
  555.   rational tuple of num: Int, den: Int
  556.  
  557. The above is semantically similar to a Z schema that defines rational as the
  558. Cartesian product of Z and Z, and specifies the constructors and observers
  559. of the LSL shorthand (see [Guttag-Horning93], Figure 4.10). This is a
  560. difference in usage, not in expressiveness, however.
  561.  
  562. Z and LSL both have comparable built-in notations for describing abstract
  563. values. Z has basic types (the integers, booleans, etc.) and more type
  564. constructors (sets, Cartesian products, schemas, and free types). A "free
  565. type" in Z (see [Spivey92], Section 3.10) is similar to an LSL union type,
  566. but Z allows direct recursion. Z also has a mathematical tool-kit (see
  567. [Spivey92], Chapter 4) which specifies: relations, partial and total
  568. functions, sequences, and bags, and a large number of operation symbols and
  569. mathematical functions defined on these types. This tool-kit is roughly
  570. comparable to Guttag and Horning's handbook (see [Guttag-Horning93],
  571. Appendix A), although it tends to make heavier use of symbols (like "+")
  572. instead of named functions (like "plus"). (This use of symbols in Z has been
  573. found to be a problem with the understandability of Z specifications
  574. [Finney96]. However, the readability of Z is improved by the standard
  575. conventions for mixing informal commentary with the formal notation.)
  576.  
  577. LSL and Z both use classical logic, and the underspecification approach to
  578. the specification of partiality, in contrast to VDM-SL. Z does not have any
  579. way of stating the equivalent of an LSL partitioned by or generated by
  580. clause.
  581.  
  582. See [Baumeister96] for an extended Z example (the birthday book of
  583. [Spivey92]) worked in LSL.
  584.  
  585. Compared to a Larch family BISL, Z, like VDM-SL is generic, and thus is not
  586. able to specify the interface details of a particular programming language.
  587.  
  588. An interesting semantic difference between Z and a typical Larch-family BISL
  589. (and VDM-SL) is that Z does not have true preconditions (see [Jackson95],
  590. Sections 7.2 and 8.1); instead, Z has guards (enabling conditions, which are
  591. somewhat like the when clauses of GCIL [Lerner91]). Thus Z may be a better
  592. match to the task of defining finite state machines; the use of enabling
  593. conditions also (as Jackson points out) allows different views of
  594. specifications to be combined. Aside from the Larch BISLs like GCIL that
  595. have support for concurrency, most Larch family BISLs have preconditions
  596. which are "disclaimers". Because of this difference, and the Z schema
  597. calculus, it is much easier to combine Z specifications than it is to
  598. combine specifications in a Larch BISL.
  599.  
  600. A related point of usage difference is the frequency of the use of
  601. invariants in Z (Spivey calls these "constraints"; see [Spivey92], section
  602. 3.2.2). Because in Z one often specifies schemas with state variables, it
  603. makes sense to constrain such variables in various ways. In Z, a common
  604. idiom is to conjoin two schemas, in which case the invariants of each apply
  605. in the conjoined schema. A typical Larch family BISL has no provision for
  606. such conjunction, although object-oriented BISLs (such as Larch/C++) do get
  607. some mileage out of conjunction when subtypes are specified.
  608.  
  609. Because Z does not distinguish operation specifications from auxiliary
  610. function specifications, it does not have a separation into tiers. So in Z
  611. one can use operations previously specified to specify other operations.
  612.  
  613. 1.4.3 How does Larch compare to COLD-K?
  614.  
  615. Like Larch, COLD-K [Feijs-Jonkers92] makes more of a separation into
  616. mathematical and interface specifications, although all are part of the same
  617. language. The part of COLD-K comparable to LSL is its algebraic
  618. specifications (see [Feijs-Jonkers92], Chapters 2 and 3). In contrast to
  619. LSL, COLD-K does not use classical logic, and can specify partial functions.
  620. All COLD-K types have an "undefined" element, except the type of the
  621. Booleans. The logic in COLD-K has a definedness predicate that allows one to
  622. specify that some term must be undefined, for example; such a specification
  623. is not directly supported by LSL. A feature of COLD-K not found in LSL is
  624. the ability to hide names (see [Feijs-Jonkers92], Section 3.3); that is to
  625. only export certain names from a COLD-K scheme. Both COLD-K and LSL have
  626. mechanisms for importing and renaming.
  627.  
  628. Compared to a Larch family BISL, COLD-K is often more expressive, because it
  629. uses dynamic logic as its fundamental semantics (see [Feijs-Jonkers92],
  630. Section 5.9). In COLD-K one can also write algorithmic descriptions, and can
  631. mix algebraic, algorithmic, and dynamic logic specifications. COLD-K has
  632. relatively more sophisticated mechanisms for framing (see [Feijs-Jonkers92],
  633. p. 126, and [Jonkers91]) than most Larch family BISLs (see section 4.9 What
  634. does modifies mean?). All of this would seem to make COLD-K both more
  635. expressive and difficult to learn than a typical Larch family BISL.
  636.  
  637. 1.5 What is the history of the Larch project?
  638.  
  639. (The following is adapted from a posting of Horning to the larch-interest
  640. mailing list on June 19, 1995, which was itself condensed from the preface
  641. of [Guttag-Horning93].)
  642.  
  643. This project has been a long time in the growing. The seed was planted by
  644. Steve Zilles on October 3, 1973. During a programming language workshop
  645. organized by Barbara Liskov, he presented three simple equations relating
  646. operations on sets, and argued that anything that could reasonably be called
  647. a set would satisfy these axioms, and that anything that satisfied these
  648. axioms could reasonably be called a set. John Guttag refined this idea. In
  649. his 1975 Ph.D. thesis (University of Toronto), he showed that all computable
  650. functions over an abstract data type could be defined algebraically using
  651. equations of a simple form. He also considered the question of when such a
  652. specification constituted an adequate definition.
  653.  
  654. As early as 1974, Guttag and Horning realized that a purely algebraic
  655. approach to specification was unlikely to be practical. At that time, they
  656. proposed a combination of algebraic and operational specifications which
  657. they referred to as "dyadic specification." Working with Wing, by 1980 they
  658. had evolved the essence of the two-tiered approach to specification; the
  659. term "two-tiered" was introduced by Wing in her dissertation [Wing83]. A
  660. description of an early version of the Larch Shared Language was published
  661. in 1983. The first reasonably comprehensive description of Larch was
  662. published in 1985 [Guttag-Horning-Wing85a].
  663.  
  664. In the spring of 1990, software tools supporting Larch were becoming
  665. available, and people began using them to check and reason about
  666. specifications. To make information on Larch more widely available, it was
  667. decided to write a book [Guttag-Horning93].
  668.  
  669. The First International Workshop on Larch, organized by Ursula Martin and
  670. Jeannette Wing, was held in Dedham, Massachusetts, July 13-15, 1992
  671. [Martin-Wing93].
  672.  
  673. 1.6 What is the origin of the name Larch?
  674.  
  675. According to Jim Horning (personal communication, January 20, 1998) and John
  676. Guttag (personal communication, March 28 1998): "The name was not selected
  677. at PARC (hence from the Sunset Western Garden Book), but at MIT. The project
  678. had been known informally there as `Bicycle'." One day Mike Dertouzos
  679. [director of the MIT Laboratory for Computer Science] and John were talking
  680. on the phone. According to Jim, Mike asked John to "think up a new name
  681. quick, because he could just imagine what Senator Proxmire would say if he
  682. noticed that DARPA was sponsoring `a bicycle project' at MIT." John was, he
  683. says, "looking at a larch tree at" his "parent's house" and came up with
  684. "Larch". He also says "I did grow up in Larchmont, and I'm sure that
  685. influenced my choice of name." Jim adds, "It was only later that Butler
  686. Lampson suggested that we could use it for the specification of very `larch'
  687. programs."
  688.  
  689. The "Larch" is the common name of a species of fir tree. The cover of
  690. [Guttag-Horning93] has a picture of Larch trees on it. For more pictures of
  691. Larch trees, see the following URL.
  692.  
  693.   http://www.cs.iastate.edu/~leavens/larch-pics.html
  694.  
  695. GIF format pictures of the Larch logo, can be found at the following URLs.
  696.  
  697.   http://www.sds.lcs.mit.edu/spd/larch/pictures/larch.gif
  698.   http://www.sds.lcs.mit.edu/spd/larch/pictures/trees.gif
  699.  
  700. 1.7 Where can I get more information on Larch and Larch languages?
  701.  
  702. A good place to start is the Guttag and Horning's book [Guttag-Horning93].
  703. (This book is sometimes called "the silver book" by Larchers.) Consider it
  704. required reading. If you find that all tough going, you might want to start
  705. with Liskov and Guttag's book [Liskov-Guttag86], which explains the
  706. background and motivates the ideas behind abstraction and specification.
  707. (See section 1.9 What is the use of formal specification and formal
  708. methods?, for more background.)
  709.  
  710. You might also want to read the introductory article about the family
  711. [Guttag-Horning-Wing85b], although it is now somewhat dated. You might
  712. (especially if you are an academic) want to also read some of the
  713. proceedings of the First International Workshop on Larch [Martin-Wing93],
  714. which contains several papers about Larch.
  715.  
  716. The usenet newsgroup `comp.specification.larch' is devoted to Larch. You
  717. might also want to read the newsgroup `comp.specification.misc' for more
  718. general discussions.
  719.  
  720. There was a mailing list, called "larch-interest," for Larch. However, it
  721. has been discontinued, now that the usenet newsgroup is available. The
  722. archives of this list are available from the following URL.
  723.  
  724.   http://www.research.digital.com/SRC/larch/larch-interest.archive.html
  725.  
  726. Other on-line resources can be found through the global home page for Larch
  727. at the following URL.
  728.  
  729.   http://www.sds.lcs.mit.edu/spd/larch/index.html
  730.  
  731. Other resources are SRC's Larch home page
  732.  
  733.   http://www.research.digital.com/SRC/larch/larch-home.html
  734.  
  735. and Horning's page.
  736.  
  737.   http://www.star-lab.com/horning/larch.html
  738.  
  739. This frequently asked questions list (FAQ) is accessible on the world-wide
  740. web in:
  741.  
  742.    http://www.cs.iastate.edu/~leavens/larch-faq.html
  743.  
  744. HTML, plain text, postscript, and GNU info format versions are also
  745. available by anonymous ftp at the following URLs.
  746.  
  747.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.html
  748.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.txt.gz
  749.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.ps.gz
  750.    ftp://ftp.cs.iastate.edu/pub/larch/larch-faq.info.tar.gz
  751.  
  752. 1.8 Is there an object-oriented extension to Larch?
  753.  
  754. This question might mean one of several other more precise questions. These
  755. questions are discussed below.
  756.  
  757. One question is: is there a Larch-style BISL for some particular
  758. object-oriented (OO) programming language? Yes, there are Larch-style BISLs
  759. for Modula-3 (see [Guttag-Horning93], chapter 6, and [Jones91]),
  760. Smalltalk-80 (see [Cheon-Leavens94]), and C++ (see [Leavens97]
  761. [Leavens96b]).
  762.  
  763. Another question is: does LSL have extensions that support object-oriented
  764. specification? No, there are none in particular. One could imagine
  765. extensions of LSL with some notion of subsorting, as in OBJ
  766. [Futatsugi-etal85] [Goguen-etal87], but as yet this has not been done.
  767.  
  768. 1.9 What is the use of formal specification and formal methods?
  769.  
  770. There are endless debates about the use of formal specification and formal
  771. methods. For recent discussions see [Saiedian-etal96]. The following
  772. discussion may help you enter the debate in a reasonable fashion.
  773.  
  774. First, be sure you know what formal methods are, and what they are good for
  775. [Liskov-Guttag86] [Wing90]. Roughly speaking, formal methods encompass
  776. formalized software design processes, formal specifications, formal
  777. derivation of implementations, and formal verification. You might also want
  778. to look at the following URL for more recent work on formal methods.
  779.  
  780.     http://www.comlab.ox.ac.uk/archive/formal-methods.html
  781.  
  782. Formal verification of implementations that were not designed with
  783. verification in mind is impossible in general. Formal verification has been
  784. critiqued as too difficult to justify and manage [DeMillo-Lipton79].
  785. Programs can also only be verified relative to some abstract machine
  786. [Fetzer88]. However, these problems haven't stopped people from trying to
  787. use formal verification to gain an added level of confidence (or to help
  788. find bugs [Garland-Guttag-Horning90] [Tan94]) in software that is very
  789. critical (in terms of safety or business factors). Of course, you can still
  790. use formal methods without doing formal verification.
  791.  
  792. Several advocates of formal methods have tried to explain formal methods by
  793. debunking the "myths" that surround them [Hall90] [Bowen-Hinchey95]. Bowen
  794. and Hinchey have also given some advice in the form of "commandments" for
  795. good use of formal methods [Bowen-Hinchey95b].
  796.  
  797. Of the various kinds of formal methods, formal specification (that's where
  798. Larch comes in), seem to be the most useful. At a fundamental level, some
  799. specification is needed for any abstraction (otherwise there is no
  800. abstraction [Liskov-Guttag86]). A specification is useful as a contract
  801. between the implementor and a client of an abstraction (such as a procedure
  802. or a data type). This contract lays out the responsibilities and obligations
  803. of both parties, and allows division of labor (and a division of blame when
  804. something goes wrong). However, such a specification need not be formal; the
  805. main reason for preferring formal specification over informal specification
  806. is that formal specification can help prevent the ambiguity and
  807. unintentional imprecision which plague informal specification.
  808.  
  809. There are, however, some disadvantages to using formal specifications. One
  810. shouldn't take the search for precision to an extreme and try to formalize
  811. everything, as this will probably cost much time and effort. (Instead, try
  812. to formalize just the critical aspects of the system.) Another disadvantage
  813. is that a formal specification can itself contain errors and
  814. inconsistencies, which can lead to the specification becoming meaningless.
  815. The use of formality by itself also does not lead to well-structured and
  816. readable specifications; that is a job that humans have to do.
  817.  
  818. Although you can use the Larch languages and tools without subscribing to
  819. any particular view on the utility of formal methods, there is an emerging
  820. view of this question in the Larch community. This view is that formal
  821. specification and formal methods are most useful as aids to debugging
  822. designs [Garland-Guttag-Horning90] [Tan94]. The basic idea is that one
  823. writes (what one thinks is) redundant information into specifications, and
  824. this information is compared with the rest of the specification. Often the
  825. supposedly redundant information does not match, and trying to check that it
  826. does brings out design or conceptual errors. Thus formal methods play a role
  827. complementary to prototyping, in that they allow one to analyze certain
  828. properties of a design to see if there are lurking inconsistencies or
  829. problems.
  830.  
  831. Much of what has been said above seems logical, but experimentation would be
  832. helpful to understand what is really true and to help quantify the costs and
  833. benefits of formal methods.
  834.  
  835. One last answer to the question: some people find writing formal
  836. specifications (and even proofs) fun. No one knows why.
  837.  
  838. 2. The Larch Shared Language (LSL)
  839.  
  840. In this chapter, we discuss questions about the Larch Shared Language (LSL).
  841.  
  842.    * What is the Larch Shared Language (LSL)?
  843.    * Where can I find information on-line about LSL?
  844.    * Where can I get a checker for LSL?
  845.    * Do you have a good makefile to use with the LSL checker?
  846.    * What is a sort?
  847.    * What is the purpose of an LSL trait? What is a trait used for?
  848.    * What are the sections of an LSL trait?
  849.    * What is the difference between assumes and includes?
  850.    * How and when should I use a partitioned by clause?
  851.    * How and when should I use a generated by clause?
  852.    * When should I use an implies section?
  853.    * How and when should I use a converts clause?
  854.    * How and when should I use an exempting clause?
  855.    * What is the meaning of an LSL specification?
  856.    * How does LSL handle undefined terms?
  857.    * Is there support for partial specifications in LSL?
  858.    * Can I define operators using recursion?
  859.    * What pitfalls are there for LSL specifiers?
  860.    * Can you give me some tips for specifying things with LSL?
  861.    * How do I know when my trait is abstract enough?
  862.    * Is there a way to write a trait that will guarantee consistency?
  863.    * Do I have to write all the traits I am going to use from scratch?
  864.    * Where can I find handbooks of LSL traits?
  865.    * How do I write logical quantifiers within an LSL term?
  866.    * Where can I find LaTeX or TeX macros for LSL?
  867.    * How do I write some of those funny symbols in the Handbook in my trait?
  868.    * Is there a literate programming tool for use with LSL?
  869.    * Is there a tool for converting LSL to hypertext for the web?
  870.  
  871. 2.1 What is the Larch Shared Language (LSL)?
  872.  
  873. The Larch Shared Language (LSL) (see [Guttag-Horning93], Chapter 4, and
  874. [Guttag-Horning-Modet90]) is a language for specifying mathematical
  875. theories. LSL is a kind of equational algebraic specification language
  876. [Guttag75] [Guttag-Horning78] [Goguen-Thatcher-Wagner78] [Ehrig-Mahr85]
  877. [Futatsugi-etal85] [Mosses96] [Loeckx-Ehrich-Wolf96]. That is,
  878. specifications in LSL mainly consist of first-order equations between terms.
  879. The semantics of LSL is based on classical, multisorted first-order
  880. equational logic (see section 2.14 What is the meaning of an LSL
  881. specification?). However, LSL does have two second-order constructs, which
  882. allow you to specify rules of data type induction and certain kinds of
  883. deduction rules (see section 2.10 How and when should I use a generated by
  884. clause?, and see section 2.9 How and when should I use a partitioned by
  885. clause?).
  886.  
  887. Unlike a programming language, LSL is a purely declarative, mathematical
  888. formalism. In LSL there are no side-effects, algorithms, etc. (see section
  889. 2.18 What pitfalls are there for LSL specifiers?). Instead of specifying
  890. computation, in LSL one specifies mathematical operators and their theories.
  891. These operators are used in Larch behavioral interface specification
  892. languages as their mathematical vocabulary (see section 1.1 What is Larch?
  893. What is the Larch family of specification languages?).
  894.  
  895. An unusual feature of LSL is that it provides ways to add checkable
  896. redundancy to specifications (see section 2.11 When should I use an implies
  897. section?). See section 1.4 How does Larch compare to other specification
  898. languages?, for more detailed comparisons of LSL and related specification
  899. languages.
  900.  
  901. See Chapter 4 of [Guttag-Horning93], and the rest of this chapter, for more
  902. information.
  903.  
  904. 2.2 Where can I find information on-line about LSL?
  905.  
  906. Besides this FAQ, the best place to look is probably your own computer
  907. system. You should have a manual page for the LSL checker, if it's installed
  908. on your system. Try the Unix command man lsl to see it.
  909.  
  910. You should also look for a directory (such as `/usr/larch/LSL') where the
  911. installation of LSL is found. In that directory, you will find a
  912. subdirectory `Doc', where there is some documentation on the checker. See
  913. section 2.3 Where can I get a checker for LSL?, if you don't have the LSL
  914. checker installed on your system.
  915.  
  916. There is no official reference manual for the latest version of LSL (3.1)
  917. on-line. The defining document for LSL version 2.3 [Guttag-Horning-Modet90]
  918. is available from the URL
  919.  
  920.   ftp://ftp.digital.com/pub/DEC/SRC/research-reports/SRC-058.ps.gz
  921.  
  922. 2.3 Where can I get a checker for LSL?
  923.  
  924. You can get the MIT releases of the LSL checker using the world-wide web,
  925. starting at the following URL.
  926.  
  927.   http://www.sds.lcs.mit.edu/spd/larch/lsl.html
  928.  
  929. You can also get the MIT release by anonymous ftp from the following URL.
  930.  
  931.   ftp://ftp.sds.lcs.mit.edu/pub/Larch/LSL/
  932.  
  933. At Iowa State, the Larch/C++ group has made available later beta releases of
  934. the LSL checker that fix problems with its profligate use of space. You can
  935. get the sources for Unix and Windows 95 executables from the following URL.
  936.  
  937.   ftp://ftp.cs.iastate.edu/pub/larch/
  938.  
  939. You might also be interested in the Larch Development Environment (LDE),
  940. from Cheng's group at Michigan State University. This environment integrates
  941. tools that support LSL, LP, LCL, and Larch/C++. It runs under SunOS and
  942. Solaris. You can get it from the following URL.
  943.  
  944.   ftp://ftp.cps.msu.edu/pub/serg/tools/LDE/
  945.  
  946. 2.4 Do you have a good makefile to use with the LSL checker?
  947.  
  948. The following makefile shows one way to use the Unix command make to help
  949. check LSL traits. It relies on properties of the Bourne shell under Unix and
  950. standard Unix make, so it would have to be adjusted to work on other
  951. systems. (Also, if you cut and paste this makefile, be sure to change the
  952. leading blanks to tab characters on the rule lines.)
  953.  
  954. SHELL = /bin/sh
  955. LSL = lsl
  956. LSLFLAGS =
  957.  
  958. .SUFFIXES: .lsl .lsl-ckd .lp
  959. .lsl.lsl-ckd:
  960.         $(LSL) $(LSLFLAGS) $< 2>&1 | tee $
  961. .lsl.lp:
  962.         $(LSL) -lp $(LSLFLAGS) $<
  963.  
  964. checkalltraits:
  965.         $(LSL) $(LSLFLAGS) *.lsl
  966.  
  967. clean:
  968.         rm -f *.lsl-ckd *.lpfrz
  969. cleanall: clean
  970.         rm -f *.lpscr *.lp *.lplog
  971.  
  972. If you use the emacs text editor, you can then check your traits by using
  973. M-x compile (and responding with something like checkalltraits and a
  974. return). When you do this, you can then use C-x ` (which is an alias for M-x
  975. next-error) to edit the LSL trait with the next error message (if you're
  976. using a version of the LSL checker version 3.1beta5 or later). Emacs will
  977. put the cursor on the appropriate line for you automatically.
  978.  
  979. See section 3.10 How do I use LP to check my LSL traits?, for more
  980. information on how to use LP to check the implications in LSL traits.
  981.  
  982. 2.5 What is a sort?
  983.  
  984. The "sorts" in an LSL trait correspond to the types in a programming
  985. language. They are names for sets of values.
  986.  
  987. This usage is historical (it seems to come from [Goguen-Thatcher-Wagner78]),
  988. and arises from the desire to avoid the word "type", which is heavily
  989. overused. However, it does have some practical benefit, in that in the
  990. context of a BISL, one can say that a type comes from a programming
  991. language, but a sort comes from LSL.
  992.  
  993. Unlike some other specification languages (e.g., OBJ [Futatsugi-etal85]
  994. [Goguen-etal87]), in LSL there is no requirement that all sort names be
  995. declared. For example, in the following trait, a sort Answer is used.
  996.  
  997. AnswerTrait: trait
  998.   introduces
  999.     yes, no, maybe: -> Answer
  1000.  
  1001. In summary, LSL sorts are declared by being mentioned in the signatures of
  1002. operators.
  1003.  
  1004. 2.6 What is the purpose of an LSL trait? What is a trait used for?
  1005.  
  1006. An LSL trait is used to describe a mathematical theory. This could be used
  1007. by a mathematician to simply formalize a theory, but more commonly the
  1008. theory specified is intended to be used as the mathematical vocabulary for
  1009. some BISL. Another common use is as a way of specifying input to the Larch
  1010. Prover (LP).
  1011.  
  1012. When used as mathematical vocabulary for some behavioral interface
  1013. specification, one can identify some other common uses. Quite often one
  1014. wants to specify the abstract values of some data type. (See section 4.4
  1015. What is an abstract value?.) Examples include the Integer, Set, Queue, and
  1016. String traits in Guttag and Horning's handbook [Guttag-Horning93a]. Another
  1017. common use is to specify some function on abstract values, in order to ease
  1018. the specification of some procedure.
  1019.  
  1020. One might also write a trait in order to:
  1021.  
  1022.    * specialize some existing trait by renaming some sorts or by
  1023.      instantiating some parameterized sorts,
  1024.    * change vocabulary by renaming some operators of some existing trait,
  1025.    * state implications, for the benefit of readers, to help debug a
  1026.      specification [Garland-Guttag-Horning90], or as input to LP,
  1027.    * add additional operators to some existing trait, as a convenience in
  1028.      specifying some interface or as a way of introducing a name for some
  1029.      idea that is an important concept in an interface specification, or
  1030.    * combine several existing traits, to make it easier to use them in an
  1031.      interface specification.
  1032.  
  1033. 2.7 What are the sections of an LSL trait?
  1034.  
  1035. The sections of an LSL trait are determined by the LSL grammar
  1036. [Guttag-Horning-Modet90]. (See section 2.3 Where can I get a checker for
  1037. LSL?, for a more recent grammar, which is found in the file `Doc/lsl3_1.y',
  1038. for version 3.1, and `Doc/lsl3_2.y', for version 3.2.)
  1039.  
  1040. As a rough guide, one can have the following sections, in the following
  1041. order.
  1042.  
  1043.    * a context section, consisting of: the several assumes clauses, several
  1044.      includes clauses, and several shorthand declarations (enumeration,
  1045.      tuple, or union), all of which are optional,
  1046.    * several introduces sections (typically zero or one), in which the
  1047.      signatures of operators are declared,
  1048.    * several asserts sections (typically zero or one), in which various
  1049.      properties of operators are specified, and
  1050.    * and an optional implies section, in which intended consequences of the
  1051.      preceding are specified. The parts of this section are intended to be
  1052.      redundant. LP can be used to debug a specification by checking that
  1053.      they really follow from the rest of the trait (see [Guttag-Horning93],
  1054.      Chapter 7).
  1055.  
  1056. A good general introduction is found in [Guttag-Horning93], Chapter 4. See
  1057. section 2.8 What is the difference between assumes and includes?, for more
  1058. on the purposes of the assumes and includes clauses.
  1059.  
  1060. 2.8 What is the difference between assumes and includes?
  1061.  
  1062. One way to think of this is that includes requests textual inclusion of the
  1063. named traits, but assumes only says that all traits that include the trait
  1064. being specified must include some trait or traits that makes the assumptions
  1065. true. Hence includes is like #include in C or C++, but assumes is quite
  1066. different.
  1067.  
  1068. A common reason to use assumes instead of includes is when you want to
  1069. specify a trait with a sort parameter, and when you also need some operators
  1070. to be defined on your sort parameters. For example, Guttag and Horning's
  1071. handbook trait Sequence (see [Guttag-Horning93], page 174), starts as
  1072. follows
  1073.  
  1074. Sequence(E, C): trait
  1075.   assumes StrictPartialOrder(>, E)
  1076.  
  1077. The assumes clause is used to specify that the sort parameter E must have an
  1078. operator > that makes it a strict partial order. One way to view such
  1079. assumptions is that they specify what is needed about the theory of a sort
  1080. parameter in order to sort check, and make sense of the operators that apply
  1081. to the sort parameter [Goguen84] [Goguen86].
  1082.  
  1083. One can also use assumes to state assumptions about operators that are trait
  1084. parameters. For example, Guttag and Horning's handbook trait Sequence (see
  1085. [Guttag-Horning93], page 175), starts as follows.
  1086.  
  1087. PriorityQueue (>: E,E -> Bool, E, C): trait
  1088.   assumes TotalOrder(E for T)
  1089.  
  1090. The assumes clause is used to specify that the parameter >:E,E -> Bool must
  1091. make E into a total order.
  1092.  
  1093. Another reason to use an assumes clause instead of an includes clause is to
  1094. state that a trait is not self-contained, but is intended to be included in
  1095. some context in which some other trait has been included. For example,
  1096. Guttag and Horning's handbook trait IntegerPredicates (see
  1097. [Guttag-Horning93], page 164), starts as follows.
  1098.  
  1099. IntegerPredicates (Int): trait
  1100.   assumes Integer
  1101.  
  1102. The assumes clause is used to specify that this trait has to be used in a
  1103. trait that has included (the theory of) the trait Integer.
  1104.  
  1105. See [Guttag-Horning93], Section 4.6, for more details.
  1106.  
  1107. 2.9 How and when should I use a partitioned by clause?
  1108.  
  1109. You should use a partitioned by clause to identify (i.e., make equivalent)
  1110. some terms that would otherwise be distinct in an LSL trait's theory. A
  1111. classic example is in the specification of sets, which includes the
  1112. following partitioned by clause (see [Guttag-Horning93], page 166).
  1113.  
  1114.   C partitioned by \in
  1115.  
  1116. In this example, C is the sort for sets, and \in is the membership operator
  1117. on sets. This means that two sets, s1 and s2, are distinct (i.e., not equal)
  1118. if there is some element e such that member(e, s1) is not equal to member(e,
  1119. s2). Another way to look at this is that, you can prove that two sets are
  1120. equal by showing that they have the exactly the same members. (The sets
  1121. insert(1, insert(2, {})) and insert(2, insert(1, {})) are thus equal.) This
  1122. property is what distinguishes a set from a list, because it says that order
  1123. does not matter in a set.
  1124.  
  1125. The reason there is a separate clause in LSL for this is because of the
  1126. implicit quantifiers involved. The partitioned by clause in the example
  1127. above is more powerful than the following (see [Wing95], Section 5.1).
  1128.  
  1129.   \forall e: E, s1, s2: Set
  1130.      ((e \in s1) = (e \in s2)) => s1 = s2
  1131.  
  1132. The reason is that the above code would allow you to conclude that {1,2} =
  1133. {2,3}, because both have 2 as a member. (That is, one can let e be 2, and
  1134. then the left hand side of the implication holds.) Historically, LSL did not
  1135. have a way to write quantifiers inside its formulas, and so the partioned by
  1136. clause was necessary. With LSL version 3.1, however, one could write the
  1137. following equivalent to the above partitioned by clause for Set. (See
  1138. section 2.24 How do I write logical quantifiers within an LSL term?, for the
  1139. meaning of \A.)
  1140.  
  1141.   \forall e: E, s1, s2: Set
  1142.      (\A e (e \in s1) = (e \in s2)) => s1 = s2
  1143.  
  1144. However, the above formula will be harder to work with in LP than the
  1145. equivalent partitioned by clause. This is because LP has special provision
  1146. for using partitioned by clauses. Another reason to prefer the partitioned
  1147. by clause is that it conveys intent more clearly than a general logical
  1148. formula like the above. Thus it there are still good reasons to use a
  1149. partitioned by clause in LSL.
  1150.  
  1151. See section 4.2 in Guttag and Horning's book [Guttag-Horning93] for more
  1152. details.
  1153.  
  1154. 2.10 How and when should I use a generated by clause?
  1155.  
  1156. You should use a generated by clause to specify that there can be no
  1157. abstract values beside the ones that you are describing for a given sort.
  1158. This is quite common for specifications of the abstract values of data
  1159. types, but will not usually be the case for the abstract values of sort
  1160. parameters (such as E in Queue[E]). A generated by clause can also be
  1161. thought of as excluding "junk" (i.e., nonstandard values) from a type
  1162. [Goguen-Thatcher-Wagner78]. For example, in the trait AnswerTrait (see
  1163. section 2.5 What is a sort?), nothing in the specification prevents there
  1164. being other elements of the sort Answer besides yes, no, and maybe. That is,
  1165. if x has sort Answer, then the formula
  1166.  
  1167.     x = yes \/ x = no \/ x = maybe
  1168.  
  1169. is not necessarily true; in other words, it's not valid. However, in the
  1170. following trait the above formula is valid, because of the generated by
  1171. clause. (This is stated in the trait's implies section.)
  1172.  
  1173. AnswerTrait2: trait
  1174.   includes AnswerTrait
  1175.   asserts
  1176.     Answer generated by yes, no, maybe
  1177.     equations
  1178.       yes \neq no;
  1179.       yes \neq maybe;
  1180.       no \neq maybe;
  1181.   implies
  1182.     \forall x: Answer
  1183.       x = yes \/ x = no \/ x = maybe;
  1184.  
  1185. Yet another reason to use a generated by clause is to assert a rule of data
  1186. type induction. This view is particularly helpful in LP, because it allows
  1187. one to divide up a proof into cases, and to use induction. For example, when
  1188. proving some property P(x) holds for all x of sort Answer, the generated by
  1189. clause of the trait AnswerTrait2 allows one to proceed by cases; that is, it
  1190. suffices to prove P(yes), P(no), and P(maybe).
  1191.  
  1192. A more typical induction example can be had by considering Guttag and
  1193. Horning's handbook trait Set (see [Guttag-Horning93], page 167). In this
  1194. trait, C is the sort for sets. It has the following generated by clause (by
  1195. virtue of including the trait SetBasics, see [Guttag-Horning93], page 166).
  1196.  
  1197.     C generated by {}, insert
  1198.  
  1199. This clause says that the only abstract values of sort C, are those that can
  1200. be formed from (finite) combinations of the operators {} and insert. For
  1201. example, insert(x, insert(y, {})) is a set. This rules out, for example,
  1202. infinite sets, and sets that are nonstandard. It does not say that each such
  1203. term denotes a distinct set, and indeed some terms fall in the same
  1204. equivalence class (see section 2.9 How and when should I use a partitioned
  1205. by clause?). It also does not mean that other operators that form sets
  1206. cannot be defined; for example, in the trait Set one can write {x} \U {y}.
  1207. What it does say is that every other way to build a set, like this one, has
  1208. to be equivalent to some use of {} and insert.
  1209.  
  1210. Let us consider a sample proof by structural induction in the trait Set. One
  1211. of the implications in this trait is that
  1212.  
  1213.   \forall s: C
  1214.     size(s) >= 0
  1215.  
  1216. To prove this, one must prove that it holds for all sets s. Since, by the
  1217. generated by clause, all sets can be formed from {} and insert, it suffices
  1218. to prove two cases. For the base case, one must prove the following trivial
  1219. result.
  1220.  
  1221.     size({}) >= 0
  1222.  
  1223. For the inductive case, one gets to assume that
  1224.  
  1225.     size(y) >= 0
  1226.  
  1227. and then one must prove the following.
  1228.  
  1229.   \forall s: C, e: E
  1230.     size(insert(e, y)) >= 0
  1231.  
  1232. This follows fairly easily; we leave the details to the reader.
  1233.  
  1234. See section 4.2 in Guttag and Horning's book [Guttag-Horning93] for more
  1235. details on the generated by clause.
  1236.  
  1237. One situation where one usually does not want to use a generated by clause
  1238. is when specifying the theory of a sort parameter. For example, in the trait
  1239. Set (see [Guttag-Horning93], page 167), there is no generated by clause
  1240. describing the elements E of the set. The reason not to use a generated by
  1241. clause for such sort parameters is to make the assumptions on such
  1242. parameters as weak as possible. Thus, unless one has to do induction over
  1243. the elements of a sort parameter, one would not need to know that they are
  1244. generated.
  1245.  
  1246. 2.11 When should I use an implies section?
  1247.  
  1248. You should usually use an implies section in a trait, even though it adds
  1249. nothing to the theory of a trait, and is completely redundant. The reasons
  1250. for doing so are as follows.
  1251.  
  1252.    * You probably have something interesting to highlight about the theory
  1253.      of a trait, to bring to the attention of the reader. This includes
  1254.      important examples that help illustrate how to use the operators.
  1255.    * You probably have found more than one way to specify something in your
  1256.      trait. Putting both of them in the asserts section runs the risk of
  1257.      making your theory inconsistent (if they are not really equivalent).
  1258.      Leaving one of them out loses information, and prevents possible
  1259.      debugging and consistency checking that could otherwise be done (for
  1260.      example, using LP; see [Guttag-Horning93], Chapter 7).
  1261.  
  1262. Redundancy is a good thing for debugging and consistency checking; after
  1263. all, one needs two pieces of information to do any checking.
  1264.  
  1265. A motto that mathematicians live by is the following. (You do realize that
  1266. writing an LSL trait is doing math, don't you?)
  1267.  
  1268.      Few axioms, many theorems.
  1269.  
  1270. For LSL, this motto means that you should try to make your asserts section
  1271. as small and as elegant as possible, and to push off any redundancy into the
  1272. implies section.
  1273.  
  1274. An important piece of redundant information you can provide for a reader in
  1275. the implies section is a converts clause. You should also consider using a
  1276. converts clause for each operator you have introduced in the trait. See
  1277. section 2.12 How and when should I use a converts clause?.
  1278.  
  1279. Writing a good implies section for a trait is something that takes some
  1280. practice. It helps to get a feel for what can be checked with LP first (see
  1281. [Guttag-Horning93], Chapter 7). It also helps to look at some good examples;
  1282. for example, take a look at the traits in Guttag and Horning's handbook (see
  1283. [Guttag-Horning93], Appendix A); most of these have an implies section, and
  1284. some are quite extensive.
  1285.  
  1286. One general hint about writing implies clauses comes from the fact there are
  1287. an infinite number of theorems that follow from every LSL specification.
  1288. (One infinite set of theorems concerns the built-in sort Bool.) Since there
  1289. are an infinite number of theorems, you can't possibly list all of them.
  1290. Focus on the ones that you think are interesting, especially those that will
  1291. help the reader understand what your specification is about, and those that
  1292. will help you debug your specification.
  1293.  
  1294. See Section 4.5 in Guttag and Horning's book [Guttag-Horning93] for more
  1295. details.
  1296.  
  1297. 2.12 How and when should I use a converts clause?
  1298.  
  1299. A converts clause goes in the implies section of a trait. It is a way to
  1300. make redundant claims about the completeness of the specification of various
  1301. operators in a trait.
  1302.  
  1303. You should consider stating a converts clause for each non-constant operator
  1304. you introduce in a trait. If you list an operator in a converts clause, you
  1305. would be saying that the operator is uniquely defined "relative to the other
  1306. operators in a trait" (see [Guttag-Horning93], p. 142, [Leavens-Wing97],
  1307. Section B.1). Of course, this would not be true for every operator you might
  1308. define. This means that if you state that an operator is converted in the
  1309. implies section of a trait, then you are claiming that there is no ambiguity
  1310. in the definition of that operator, once the other operators of the trait
  1311. are fixed.
  1312.  
  1313. As an example of a converts clause, consider the following trait.
  1314.  
  1315. ConvertsExample: trait
  1316.   includes Integer
  1317.   introduces
  1318.     unknown, hmm, known: Int -> Int
  1319.   asserts \forall i: Int
  1320.     hmm(i) == unknown(i);
  1321.     known(i) = i + 1;
  1322.   implies
  1323.     converts
  1324.       known: Int -> Int,
  1325.       hmm: Int -> Int
  1326.  
  1327. In this trait, the converts clause claims that both known and hmm are
  1328. converted. It should be clear that known is converted, because it is
  1329. uniquely-defined for all integers. What may be a bit puzzling is that hmm is
  1330. also converted. The reason is that once the interpretation of the other
  1331. operators in the trait are fixed, in particular once the interpretation of
  1332. unknown is fixed, then hmm is uniquely-defined. It would not be correct to
  1333. claim that both hmm and unknown are converted; since they are defined in
  1334. terms of each other, they would not be uniquely defined relative to the
  1335. other operators of the trait.(1)
  1336.  
  1337. See Section 4.5 and pages 142-144 in Guttag and Horning's book
  1338. [Guttag-Horning93] for more details.
  1339.  
  1340. Often one wants to say that some operator is uniquely-defined, but not for
  1341. some arguments. This can be done using an exempting clause, which is a
  1342. subclause of a converts clause. See section 2.13 How and when should I use
  1343. an exempting clause?, for more discussion.
  1344.  
  1345. 2.13 How and when should I use an exempting clause?
  1346.  
  1347. An exempting clause is a subclause of a converts clause. (See section 2.12
  1348. How and when should I use a converts clause?.) You should use an exempting
  1349. clause when you want to claim that some operator is uniquely-defined,
  1350. "relative to the other operators in a trait" ([Guttag-Horning93], p. 142),
  1351. except for some special cases.
  1352.  
  1353. A very simple example is the trait List (see [Guttag-Horning93], p. 173),
  1354. where the converts includes the following.
  1355.  
  1356.     converts head
  1357.       exempting head(empty)
  1358.  
  1359. This just says that head is well-defined, except for taking the head of an
  1360. empty list.
  1361.  
  1362. A slightly more complicated exempts clause is illustrated by the following
  1363. classic example. Suppose one specifies a division operator on the natural
  1364. numbers. In such a trait (see [Guttag-Horning93], p. 201), one could use the
  1365. following trait outline.
  1366.  
  1367. Natural (N): trait
  1368.   introduces
  1369.     0: -> N
  1370.     div: N, N -> N
  1371.     % ...
  1372.   asserts
  1373.     % ...
  1374.   implies
  1375.     converts div: N, N -> N
  1376.       exempting \forall x: N
  1377.          div(x, 0)
  1378.  
  1379. The converts clause in this example claims that div is uniquely-defined,
  1380. relative to the other operators in a trait, except that division by 0 is not
  1381. defined. Without the exempting subclause, the converts clause would not be
  1382. correct.
  1383.  
  1384. See the following subsections and page 44 of [Guttag-Horning93] for more
  1385. information.
  1386.  
  1387.    * Does exempting some term make it undefined?
  1388.    * How can I exempt only terms that satisfy some condition?
  1389.  
  1390. 2.13.1 Does exempting some term make it undefined?
  1391.  
  1392. No, exempting a term does not make it undefined. An exempting clause merely
  1393. takes away the claim that it is defined (see [Guttag-Horning93], page 44).
  1394. For example, in the trait List (see [Guttag-Horning93], p. 173), writing the
  1395. following does not make head(empty) undefined.
  1396.  
  1397.     converts head
  1398.       exempting head(empty)
  1399.  
  1400. If anything, it is the lack of an axiom defining the value of head(empty)
  1401. that makes it "undefined". However, you would certainly want to use an
  1402. exempting clause in situations where you have a term that is intended to be
  1403. "undefined".
  1404.  
  1405. The concept of "undefinedness" is a tricky one for LSL. In a technical
  1406. sense, nothing is undefined in LSL, because each constant and variable
  1407. symbol has a value, and each non-constant operator is a total function (see
  1408. [Guttag-Horning93], p. 9, and [Leavens-Wing97], Appendix A). It would be
  1409. more accurate to say that in the trait List, the term head(empty) is
  1410. "underspecified". This means it has a value, but the trait doesn't specify
  1411. what that value is. See section 2.16 Is there support for partial
  1412. specifications in LSL?, for more discussion on this point.
  1413.  
  1414. 2.13.2 How can I exempt only terms that satisfy some condition?
  1415.  
  1416. With LSL (through version 3.1) the exempting subclause of a converts clause
  1417. is not based on semantics, instead it is based on syntax. You can only
  1418. exempt terms having particular forms; these forms allow the arguments to an
  1419. operator to be either ground terms (as in head(empty)), or universally
  1420. quantified variables or both (as in div(x, 0)).
  1421.  
  1422. If you want to exempt all terms for which one argument is positive, or has a
  1423. size larger than 3, then you are out of luck. All you can do is to state
  1424. your conversion claim informally in a comment (as you can't use a converts
  1425. clause naming the operator in question). If you want to rewrite your trait,
  1426. you could, for example, change the appropriate argument's sort to be the
  1427. natural numbers instead of the integers, or define a new sort for which your
  1428. operator is completely-defined.
  1429.  
  1430. See Section B.2 of [Leavens-Wing97] for a proposed extension to LSL that
  1431. would solve this problem.
  1432.  
  1433. 2.14 What is the meaning of an LSL specification?
  1434.  
  1435. An LSL trait denotes a theory, which is a collection of true formulas (of
  1436. sort Bool). This theory contains "the trait's assertions, the conventional
  1437. axioms of first-order logic, everything that follows from them, and nothing
  1438. else" (see [Guttag-Horning93], p. 37). For a brief introduction to these
  1439. ideas, see Chapter 2 of [Guttag-Horning93]; for general background on
  1440. equational logic, see [Ehrig-Mahr85] or [Loeckx-Ehrich-Wolf96].
  1441.  
  1442. Another way to look at the meaning of an LSL trait is the set of models it
  1443. denotes. An algebraic model of a trait has a set for each sort, and a total
  1444. function for each operator. In addition, it must satisfy the axioms of
  1445. first-order logic and the axioms of the trait. A model satisfies an
  1446. equational axiom if it assigns the same value to both sides of the equation.
  1447. (See [Ehrig-Mahr85], Chapter 1, or [Loeckx-Ehrich-Wolf96], Chapter 5, for
  1448. more details.)
  1449.  
  1450. In contrast to some other specification languages, the semantics of LSL is
  1451. loose (see [Guttag-Horning93], p. 37). That is, there may be several models
  1452. of a specification that have observably distinct behavior. For example,
  1453. consider the trait ChoiceSet in Guttag and Horning's handbook (see
  1454. [Guttag-Horning93], p. 176). There are many models of this trait with
  1455. different behavior; for example, it might be that in one model choose({2} \U
  1456. {3}) = 2, and in some other model choose({2} \U {3}) = 3. The specification
  1457. won't allow you to prove either of these things, of course, because whatever
  1458. is provable from the specification is true in all models.
  1459.  
  1460. 2.15 How does LSL handle undefined terms?
  1461.  
  1462. The following answer is adapted from a posting to `comp.specification.larch'
  1463. by Horning (July 19, 1995) in response to a question by Leavens (July 18,
  1464. 1995).
  1465.  
  1466.      The trouble starts with your question: there are no "undefined
  1467.      terms" in LSL. LSL is a language of total functions. There are no
  1468.      partial functions associated with operators, although there may be
  1469.      underspecified operators (i.e., operators bound to functions with
  1470.      different values in different models). The possibility of
  1471.      underspecification is intentional; it is important that models of
  1472.      traits do not have to be isomorphic.
  1473.  
  1474. Another way to say this is that in an algebraic model of a trait (see
  1475. section 2.14 What is the meaning of an LSL specification?), each term
  1476. denotes an equivalence class, which can be thought of as its definition in
  1477. that algebra. In other algebras, the same term may be in a nonisomorphic
  1478. equivalence class, if the term is underspecified.
  1479.  
  1480. To make this clearer, consider the following trait.
  1481.  
  1482. QTrait : trait
  1483.   includes Integer
  1484.   Q union of theBool: Bool, theInt: Int
  1485.   introduces
  1486.     isPositive: Q -> Bool
  1487.   asserts
  1488.     \forall q: Q
  1489.       isPositive(q) == q.theInt > 0 /\ (tag(q) = theInt);
  1490.   implies
  1491.     \forall q: Q, b: Bool
  1492.       isPositive(q) == (tag(q) = theInt) /\ q.theInt > 0;
  1493.       isPositive(q) == if (tag(q) = theInt)
  1494.                        then q.theInt > 0 else false;
  1495.       isPositive(theBool(b)) == false;
  1496.     converts isPositive: Q -> Bool
  1497.  
  1498. In this trait, the question is whether the assertion that defines isPositive
  1499. is written correctly. In particular, is isPositive(theBool(true))
  1500. "undefined" or an error? This is clarified in the implies section of the
  1501. trait, which claims that the order of conjuncts in the definition of
  1502. isPositive does not matter, that the definition using if is equivalent, that
  1503. the meaning of isPositive(theBool(true)) is false, and that isPositive is
  1504. converted (see section 2.12 How and when should I use a converts clause?).
  1505.  
  1506. The trait QTrait says that q.theInt is always of sort Int. However, it
  1507. places no constraint on what integer it is, unless tag(q) = theInt. So in
  1508. the definition and the first implication, both operands of /\ are always
  1509. defined (i.e., always mean either true or false, since Bool is generated by
  1510. true and false), even though we may not always know which. So the definition
  1511. is fine, and the implications are all provable.
  1512.  
  1513. The fact that you don't have to use if, and that all the classical laws of
  1514. logic (like conjunction being symmetric) apply is a big advantage of the
  1515. total function interpretation of LSL. See section 2.16.1 Can I specify a
  1516. partial function in LSL? for more discussion.
  1517.  
  1518. 2.16 Is there support for partial specifications in LSL?
  1519.  
  1520. There are two ways one might understand this question. These are dealt with
  1521. below.
  1522.  
  1523.    * Can I specify a partial function in LSL?
  1524.    * Do I have to specify everything completely in LSL?
  1525.  
  1526. 2.16.1 Can I specify a partial function in LSL?
  1527.  
  1528. Technically, no; all functions specified in LSL are total (see section 2.14
  1529. What is the meaning of an LSL specification?). Thus every operator specified
  1530. in LSL takes on some value for every combination of arguments. What you can
  1531. do is to underspecify such an operator, by not specifying what its value is
  1532. on all arguments. For example, the operator head in the handbook trait List
  1533. (see [Guttag-Horning93], p. 173) is underspecified in this sense, because no
  1534. value is specified for head(empty). It is a synonym to say that head is
  1535. weakly-specified.
  1536.  
  1537. One reason LSL takes this approach to dealing with partial functions is that
  1538. it makes the logic used in LSL classical. One doesn't have to worry about
  1539. non-classical logics, and "bottom" elements of types infecting a term
  1540. [Gries-Schneider95]. Another reason is that when LSL is used with a BISL,
  1541. the precondition of a procedure specification can protect the operators used
  1542. in the postcondition from any undefined arguments [Leavens-Wing97].
  1543.  
  1544. (If you want to develop a theory of partial functions, however, you can do
  1545. that in LSL. For example, you can specify a type with a constant bottom,
  1546. that, for you, represents "undefined". You will just have to manipulate your
  1547. partial functions with LSL operators that are total functions.)
  1548.  
  1549. 2.16.2 Do I have to specify everything completely in LSL?
  1550.  
  1551. No, you don't have to specify everything completely in LSL. It's a good
  1552. idea, in fact, to only specify the aspects that are important for what you
  1553. are doing. For example, if you want to reason about graph data structures,
  1554. it's best to not (at first, anyway) try to specify the theory of graphs in
  1555. great detail. Put in what you want, and go with that. (This won't hurt
  1556. anything, because whatever you need to prove you'll be forced to add
  1557. eventually.)
  1558.  
  1559. Anything you can specify in LSL, you can do incompletely. (There are no
  1560. "theory police" that will check your traits for completeness.) To
  1561. incompletely specify a sort, for example, nodes in a graph, just use it's
  1562. name in operations and don't say anything more about it. If you need to have
  1563. some operators that manipulate nodes, then write their signatures into the
  1564. introduces section, but don't write any axioms for them. If you need to know
  1565. some properties of these operators, you can write enough axioms in the
  1566. asserts section to prove them (perhaps making some of the properties
  1567. theorems in the implies section).
  1568.  
  1569. The time to worry about the completeness of your theory is when you are
  1570. having trouble proving some of the things you want to prove about it, or if
  1571. you are preparing it for reuse by others. (On the other hand, a less
  1572. complete theory is often more general, so when trying to generalize a trait
  1573. for others to use, sometimes it helps to relax some of the properties you
  1574. have been working with.)
  1575.  
  1576. 2.17 Can I define operators using recursion?
  1577.  
  1578. Yes, you can define operators recursively. A good, and safe, way to do this
  1579. is to use structural induction (e.g., on the generators of a sort). For
  1580. example, look at how count is defined in the handbook trait BagBasics (see
  1581. [Guttag-Horning93], p. 168). In this trait, the sort C of bags is generated
  1582. by the operators {} and insert. There is one axiom that specifies count when
  1583. its second argument is the empty bag, and one that specifies count when its
  1584. argument is constructed using insert. There are many other examples in the
  1585. Guttag and Horning's handbook (see [Guttag-Horning93], Appendix A), for
  1586. example the many specifications of operator size (Section A.5), the
  1587. specification of the operators head and tail in the trait Queue (p. 171),
  1588. the specification of flatten in the trait ListStructureOps (p. 183), and the
  1589. specification of operator + in the trait Positive (p. 202). See section 2.19
  1590. Can you give me some tips for specifying things with LSL?, for more details
  1591. on structural induction.
  1592.  
  1593. This kind of recursive specification is so common that if you are familiar
  1594. with functional programming (especially in a language like Haskell or ML),
  1595. then it's quite helpful to think that way when writing LSL traits.
  1596.  
  1597. There is one thing to be careful of, however. Unless you use structural
  1598. induction, you might specify an inconsistent trait. The following example
  1599. (from David Schmidt, personal communication), illustrates the problem. This
  1600. trait includes the Integer trait of Guttag and Horning's handbook (see
  1601. [Guttag-Horning93], p. 163).
  1602.  
  1603. BadRecTrait: trait
  1604.   includes Integer
  1605.   introduces
  1606.     f: Int -> Int
  1607.   asserts
  1608.     \forall i: Int
  1609.       f(i) == f(i) + 1;
  1610.  
  1611. It's easy to prove that this trait is inconsistent; subtract f(i) from both
  1612. sides of the defining equation for f, and you obtain 0 = 1. As a heuristic
  1613. for avoiding this kind of mistake, avoid recursive specifications that don't
  1614. "make progress" when regarded as programs.
  1615.  
  1616. It's also possible to fall into a pit when recursively defining a partial
  1617. function. The following is a silly example, but illustrates the problem.
  1618.  
  1619. BadZeroTrait: trait
  1620.   includes Integer, MinMax(Int)
  1621.   introduces
  1622.     zero: Int -> Int
  1623.   asserts
  1624.     \forall k: Int
  1625.       zero(k) == if k = 0 then 0 else min(k, zero(k-1));
  1626.  
  1627. This is silly, the idea being to define a constant function that returns
  1628. zero for any nonnegative integer. Still, it looks harmless. However, what
  1629. does the specification say about zero(-1). It's easy to see that it's less
  1630. than -1, and less than -2, and indeed less than any integer. But the Integer
  1631. trait in Guttag and Horning's handbook (see [Guttag-Horning93], p. 163) does
  1632. not allow there to be such an integer; so this trait is inconsistent. To
  1633. solve this problem, you could change the axiom defining zero to indicate the
  1634. intended domain, as follows.
  1635.  
  1636.      \forall k: Int
  1637.       (k >= 0) => zero(k) = (if k = 0 then 0 else min(k, zero(k-1)));
  1638.  
  1639. This revised axiom would allow zero(-1) to have any value. Another cure for
  1640. this kind of example would be to specify the domain of zero as the natural
  1641. numbers. (Of course, for this particular example, a nonrecursive definition
  1642. is also preferable.)
  1643.  
  1644. See section 2.18 What pitfalls are there for LSL specifiers?, for another
  1645. thing to watch for when making a recursive definition.
  1646.  
  1647. 2.18 What pitfalls are there for LSL specifiers?
  1648.  
  1649. According to Guaspari (posting to the larch-interest mailing list, on March
  1650. 8, 1995), "the commonest `purely mathematical' mistakes" in trait
  1651. definitions occur when one uses structural induction "over constructors that
  1652. don't freely generate a sort". To understand this, consider his example,
  1653. which includes the handbook trait Set (see [Guttag-Horning93], page 167).
  1654.  
  1655. GuasparisExample: trait
  1656.   includes Integer, Set(Int, Set[Int])
  1657.  
  1658.   introduces
  1659.     select: Set[Int] -> Int
  1660.  
  1661.   asserts
  1662.     \forall s: Set[Int], e: Int
  1663.       select(insert(e, s)) == e;
  1664.  
  1665.   implies
  1666.     equations
  1667.       insert(1, {2}) == insert(2, {1});
  1668.       select(insert(1, {2})) == select(insert(2, {1}));
  1669.       1 == 2;  % ouch!
  1670.  
  1671. In the above example, the problem with the definition of select is that it's
  1672. not well-defined with respect to the equivalence classes of the sort
  1673. Set[Int]. The problem is highlighted in the implies section of the trait.
  1674. The first implication is a reminder that the order of insertion in a set
  1675. doesn't matter; that is, insert(1, {2}) and insert(2, {1}) are equivalent
  1676. sets because they have the same members. In the jargon, insert(1, {2}) and
  1677. insert(2, {1}) are members of the same equivalence class. The second
  1678. implication is a reminder that an operator, such as select must give the
  1679. same result on equal arguments; in the jargon, a function must "respect" the
  1680. equivalence classes. But the definition of select does not respect the
  1681. equivalence classes, because if one applies the definition to both sides of
  1682. the second implication, one concludes that 1 = 2.
  1683.  
  1684. One way to fix the above definition is shown by the trait ChoiceSet in
  1685. Guttag and Horning's handbook (see [Guttag-Horning93], page 176). Another
  1686. way that would work in this example (because integers are ordered) would be
  1687. to define an operator minimum on the sort Set[Int], and to use that to
  1688. define select as follows.
  1689.  
  1690. GuasparisExampleCorrected: trait
  1691.   includes Integer, Set(Int, Set[Int]), MinMax(Int)
  1692.  
  1693.   introduces
  1694.     select: Set[Int] -> Int
  1695.     minimum: Set[Int] -> Int
  1696.  
  1697.   asserts
  1698.     \forall s: Set[Int], e, e1, e2: Int
  1699.       minimum(insert(e, {})) == e;
  1700.       minimum(insert(e1, insert(e2, s)))
  1701.         == min(e1, minimum(insert(e2, s)));
  1702.       select(insert(e, s)) == minimum(insert(e, s));
  1703.  
  1704.   implies
  1705.     \forall s: Set[Int], e1, e2: Int
  1706.       minimum(insert(e1, insert(e2, s)))
  1707.         == minimum(insert(e2, insert(e1, s)));
  1708.       select(insert(1, {2})) == 1;
  1709.       select(insert(2, {1})) == 1;
  1710.  
  1711. To show that minimum is well-defined, one has to prove that it gives the
  1712. same answer for all terms in the same equivalence class. The first
  1713. implication is this trait does not prove this in general, but does help in
  1714. debugging the trait.
  1715.  
  1716. To explain the difference that having a "freely-generated" sort makes,
  1717. compare the trait GuasparisExample above to the handbook trait Stack (see
  1718. [Guttag-Horning93], page 170). In that trait, top is defined using the
  1719. following equation.
  1720.  
  1721.   \forall e: E, stk: C
  1722.     top(push(e, stk)) == e;
  1723.  
  1724. Why doesn't this definition have the same problem as the definition of
  1725. select? Because it respects the equivalence classes of the sort C (stacks).
  1726. Why? Because there is no partitioned by clause for Stack, all equivalence
  1727. classes of stacks have a canonical representative. The canonical
  1728. representative is a term built using just the operators noted in the
  1729. generated by clause for Stack: empty and push; it is canonical because there
  1730. is only one way to use just these generators to produce a value in each
  1731. equivalence class. The sort of stacks is called freely generated because of
  1732. this property. (The sort for sets is not freely generated, because there is
  1733. more than one term built using the generators that represents the value
  1734. {1,2}.) Since a term of the form push(e, stk) is a canonical representative
  1735. of its equivalence class, the specification of top automatically respects
  1736. the equivalence classes.
  1737.  
  1738. A more involved example is the definition of the set membership operator
  1739. (\in) for sets (see [Guttag-Horning93], p. 166 and p. 224). Since sets are
  1740. not freely generated, it takes work to prove that the specification of \in
  1741. is well-defined. You might want to convince yourself of that as an exercise.
  1742.  
  1743. In summary, to avoid this first pitfall, remember the following mantra when
  1744. defining operators over a sort with a partitioned by clause or an
  1745. interesting notion of equality.
  1746.  
  1747.      Is it well-defined?
  1748.  
  1749. As a help in avoiding this problem, you can use a generated freely by clause
  1750. in the most recent versions of LSL. The use of a generated freely by clause
  1751. makes it clear that the reader does not have to be concerned about
  1752. ill-defined structural inductions.
  1753.  
  1754. Another pitfall in LSL is to assert that all values of some freely-generated
  1755. type satisfy some nontrivial property. An example is the trait given below.
  1756.  
  1757. BadRational: trait
  1758.   includes Integer
  1759.   Rational tuple of num: Int, den: Int
  1760.   asserts
  1761.     \forall r: Rational
  1762.        r.den > 0;
  1763.   implies
  1764.     equations
  1765.       ([3, -4]).den > 0;
  1766.       (-4) > 0;          % oops!
  1767.  
  1768. In this trait, the implications highlight the consequences of this
  1769. specification pitfall: an inconsistent theory. The reason the above trait is
  1770. inconsistent is that it says that all integers are positive. This is because
  1771. for all integers i and j, one can form a tuple of sort rational by writing
  1772. [i, j]. This kind of inconsistency arises whenever one has a freely
  1773. generated sort, such as LSL tuples, and tries to add constraints as
  1774. properties. There are several ways out of this particular pit. The most
  1775. straightforward is to use a different sort for the denominators of rationals
  1776. (e.g., the positive numbers, as in [Guttag-Horning93], page 207). Another
  1777. way is to specify the sort Rational without using a tuple, but using your
  1778. own constructor, such as mkRat; this allows the sort to be not freely
  1779. generated. The only problem with that approach is that one either has to
  1780. make arbitrary or difficult decisions (such as the value of mkRat(3, 0)), or
  1781. one has to be satisfied with an underspecified constructor. Another way to
  1782. avoid this is to use a parameterized trait; for example, we could have
  1783. parameterized BadRational by the sort Int, and instead of including the
  1784. trait Integer, used an assumes clause to specify the property desired of the
  1785. denominator's sort. In some cases, one can postpone asserting such
  1786. properties until one reaches the interface specification; this is because in
  1787. a BISL one can impose such properties on variables, not on entire sorts.
  1788.  
  1789. To avoid this pit, think of the following mantra.
  1790.  
  1791.      Is this property defining a sort, or imposing some constraint on
  1792.      another sort?
  1793.  
  1794. (If the answer is that it's imposing a constraint on another sort, watch out
  1795. for the pit!)
  1796.  
  1797. A pitfall that some novices fall into is forgetting that LSL is a purely
  1798. mathematical notation, that has no concept of state or side effects. For
  1799. example, the following are surely incorrect signatures in LSL.
  1800.  
  1801. BadSig: trait
  1802.   includes Integer
  1803.   introduces
  1804.    currentTime: -> Seconds
  1805.    random: -> Int
  1806.  
  1807. If you think random is a good signature for a random number generator,
  1808. you've fallen into the pit. The operator random is an (underspecified)
  1809. constant; that is, random stands for some particular integer, always the
  1810. same one no matter how many times it is mentioned in an assertion. The
  1811. operator currentTime illustrates how mathematical notation is "timeless": it
  1812. is also a constant.
  1813.  
  1814. How could you specify a notion like a clock in LSL? What you have to do is,
  1815. instead of specifying the concept of "the current time", specify the concept
  1816. of a clock. For example consider the following trait.
  1817.  
  1818. ClockTrait: trait
  1819.   assumes TotalOrder(Seconds for T)
  1820.   introduces
  1821.     newClock: Seconds -> Clock
  1822.     tick: Clock -> Clock
  1823.     currentTime: Clock -> Seconds
  1824.   asserts
  1825.     Clock generated by newClock, tick
  1826.     \forall sec: Seconds, c: Clock
  1827.       currentTime(newClock(sec)) == sec;
  1828.       currentTime(tick(c)) > currentTime(c);
  1829.   implies
  1830.     \forall sec: Seconds, c: Clock
  1831.       currentTime(tick(tick(c))) > currentTime(c);
  1832.  
  1833. Note that a clock doesn't change state in LSL, however, because each clock
  1834. is also timeless, the tick operator produces a new Clock value. Tricks like
  1835. this are fundamental to semantics (see, for example, [Schmidt86]). As an
  1836. exercise, you might want to specify a random number generator along the same
  1837. lines.
  1838.  
  1839. To avoid this pit remember the following mantra when you are writing the
  1840. signatures of operators in LSL.
  1841.  
  1842.      Does this operator have any hidden parameters?
  1843.  
  1844. There are no hidden parameters, or global variables, in LSL.
  1845.  
  1846. A logical pitfall that one can fall prey of in LSL is failing to understand
  1847. that the quantifiers on an equation in LSL are outside the equation as a
  1848. whole. Usually this problem can be detected when there is a free variable
  1849. that appears only on the right-hand side of an equation. (This assumes that
  1850. you use the typical convention of having the right-hand side of an equation
  1851. be the "result" of the left-hand side.) For example, consider the following
  1852. (from [Wing95], p. 13).
  1853.  
  1854. BadSubsetTrait: trait
  1855.   includes SetBasics(Set[E] for C)
  1856.   introduces
  1857.     __ \subseteq __: Set[E], Set[E] -> Bool
  1858.   asserts
  1859.     \forall e: E, s1, s2: Set[E]
  1860.       s1 \subseteq s2 == (e \in s1 => e \in s2);
  1861.   implies
  1862.     \forall e: E, s1, s2: Set[E]
  1863.       (e \in s1 /\ e \in s2) => s1 \subseteq s2;
  1864.  
  1865. The implication highlights the problem: if two sets have any single element
  1866. in common, then they are considered subsets of each other by the above
  1867. trait. This trait could be corrected in LSL by writing the quantifier inside
  1868. the defining equation. (See section 2.24 How do I write logical quantifiers
  1869. within an LSL term?, for the meaning of \A.)
  1870.  
  1871.     \forall e: E, s1, s2: Set[E]
  1872.       s1 \subseteq s2 == \A e (e \in s1 => e \in s2);
  1873.  
  1874. This is different, because the right-hand side must hold for all e, not just
  1875. some arbitrary e.
  1876.  
  1877. To avoid this pit remember the following mantra whenever you use a variable
  1878. on only one side of an equation.
  1879.  
  1880.      Is it okay if this variable has a single, arbitrary value?
  1881.  
  1882. See Wing's paper "Hints to Specifiers" [Wing95] for more tips and general
  1883. advice.
  1884.  
  1885. 2.19 Can you give me some tips for specifying things with LSL?
  1886.  
  1887. Yes indeed, we can give you some tips.
  1888.  
  1889. The first tip helps you write down an algebraic specification of a sort that
  1890. is intended to be used as an abstract data type (see [Guttag-Horning78],
  1891. Section 3.4, and [Guttag-Horning93], Section 4.9). The idea is to divide the
  1892. set of operators of your sort into generators and observers. A constructor
  1893. returns your sort, while an observer takes your sort in at least one
  1894. argument and returns some more primitive sort (such as Bool). The tip
  1895. (quoted from [Guttag-Horning93], p. 54) is to:
  1896.  
  1897.      Write an equation defining the result of applying each observer to
  1898.      each generator.
  1899.  
  1900. For example, consider the following trait.
  1901.  
  1902. ResponseSigTrait: trait
  1903.   introduces
  1904.     yes, no, maybe: -> Response
  1905.     optimistic, pessimistic: Response -> Bool
  1906.   asserts
  1907.     Response generated by yes, no, maybe
  1908.     Response partitioned by optimistic, pessimistic
  1909.  
  1910. In this trait, the generators are yes, no, and maybe; the observers are
  1911. optimistic and pessimistic. What equations would you write?
  1912.  
  1913. According to the tip, you would write equations with left-hand sides as in
  1914. the following trait. (The tip doesn't tell you what to put in the right hand
  1915. sides.)
  1916.  
  1917. ResponseTrait: trait
  1918.   includes ResponseSigTrait
  1919.  
  1920.   asserts
  1921.     equations
  1922.       optimistic(yes) == true;
  1923.       optimistic(no) == false;
  1924.       optimistic(maybe) == true;
  1925.       pessimistic(yes) == false;
  1926.       pessimistic(no) == true;
  1927.       pessimistic(maybe) == true;
  1928.  
  1929.   implies
  1930.     \forall r: Response
  1931.       yes ~= no;
  1932.       yes ~= maybe;
  1933.       no ~= maybe;
  1934.       optimistic(r) == r = yes \/ r = maybe;
  1935.       pessimistic(r) == r = no \/ r = maybe;
  1936.  
  1937. (Defining the operators optimistic and pessimistic as in the last two
  1938. equations in the implies section of the above trait is not wrong, but
  1939. doesn't follow the tip. That kind of definition can be considered a
  1940. shorthand notation for writing down the equations in the asserts section.)
  1941.  
  1942. As in the above example, you can specify that some set of generators is
  1943. complete by listing them in a generated by clause. If you have other
  1944. generators, what Guttag and Horning call extensions, then they can be
  1945. defined in much the same way as the observers are defined. As an exercise,
  1946. try defining the operator introduced in the following trait.
  1947.  
  1948. ResponseTraitExercise: trait
  1949.   includes ResponseTrait
  1950.   introduces
  1951.     negate: Response -> Response
  1952.  
  1953. Here are some other general tips for LSL.
  1954.  
  1955.    * Try to find a trait that you can reuse before starting to write your
  1956.      own trait. Familiarity with Guttag and Horning's handbook
  1957.      ([Guttag-Horning93], Appendix A) is very helpful. See section 2.23
  1958.      Where can I find handbooks of LSL traits? for other handbooks of
  1959.      traits.
  1960.    * Break your trait into small pieces. While it's not necessary to do so,
  1961.      your traits will be more reusable and more easily understood if they
  1962.      are small and focus on a tightly-related set of operators. One
  1963.      suggestion is to try to organize your trait as either an ADT (defining
  1964.      a sort such as sets, queues, integers, etc.), or as a mixin. A mixin
  1965.      trait defines a few operators, or a few properties on operators.
  1966.      Examples of mixin traits include all of those in Sections A.10 to A.14
  1967.      of [Guttag-Horning93] (such as Associative, Symmetric, TotalOrder, and
  1968.      MinMax). A mixin trait typically does not have a generated by or
  1969.      partitioned by clause (although the latter sometimes are implied by
  1970.      such traits), whereas an ADT trait typically will have at least a
  1971.      generated by clause.
  1972.    * When writing assertions, think about properties instead of algorithms.
  1973.      Since LSL specifications are not executed, you don't have to worry
  1974.      about efficiency; instead worry about clarity and correctness. For
  1975.      example, when specifying a sort operator, the following is a perfectly
  1976.      good idea, even though the implicit algorithm (generate and test) is
  1977.      terribly inefficient.
  1978.  
  1979.        \forall l1,l2: List[OrderedItem]
  1980.          sort(l1) = l2 ==  permutation(l1, l2) /\ ordered(l2);
  1981.  
  1982.    * State implications in your traits, and use LP to debug your traits.
  1983.      Even if you don't have time to do a lot of this, the mere act of
  1984.      thinking about whether what you have written really does imply what you
  1985.      think it should will have a beneficial effect on your traits.
  1986.    * When you use a negative number in a trait, always put parentheses
  1987.      around it. For example, the term -1 < 0 does not parse in LSL unless
  1988.      you put parentheses around the -1.
  1989.  
  1990. See Wing's paper "Hints to Specifiers" [Wing95] for several more tips and
  1991. general advice.
  1992.  
  1993. You can also find other tips by looking for the "mottos" and "mantras" in
  1994. this chapter. See section 2.18 What pitfalls are there for LSL specifiers?,
  1995. for tips on what to avoid.
  1996.  
  1997. 2.20 How do I know when my trait is abstract enough?
  1998.  
  1999. This is a good question, although there's no hard-and-fast answer to it. To
  2000. help you in deciding whether a specification is sufficiently abstract, we'll
  2001. give you a checklist, and an example of what not to do.
  2002.  
  2003.    * Are you using an overly-specific representation?
  2004.    * Are you specifying an algorithm for an operator instead of its
  2005.      properties?
  2006.    * Are you working with an overly-specific sort of data instead of a sort
  2007.      parameter and some assumed properties?
  2008.    * Are you specifying any unnecessary sizes or other constants?
  2009.  
  2010. To illustrate this checklist, we'll give a really awful example of a
  2011. specification that isn't abstract enough. It illustrates every fault in the
  2012. above list. (Of course, you'd never write anything this bad.)
  2013.  
  2014. NonAbstractSet: trait
  2015.   includes Integer
  2016.  
  2017.   SmallSet tuple of firstDef, secondDef, thirdDef: Bool,
  2018.                     first, second, third: Int
  2019.  
  2020.   introduces
  2021.     {}: -> SmallSet
  2022.     insert: Int, SmallSet -> SmallSet
  2023.     __ \in __: Int, SmallSet -> Bool
  2024.     size: SmallSet -> Int
  2025.  
  2026.   asserts
  2027.     \forall i,i1,i2,i3: Int, s: SmallSet, b1,b2,b3: Bool
  2028.       {} == [false, false, false, 0, 0, 0];
  2029.  
  2030.       insert(i, s)
  2031.          == if ~s.firstDef
  2032.                  then set_first(set_firstDef(s, true), i)
  2033.             else if ~s.secondDef
  2034.                  then set_second(set_secondDef(s, true), i)
  2035.             else if ~s.thirdDef
  2036.                  then set_third(set_thirdDef(s, true), i)
  2037.             else s;
  2038.  
  2039.       i \in s == if s.firstDef /\ i = s.first
  2040.                     then true
  2041.                  else if s.secondDef /\ i = s.second
  2042.                       then true
  2043.                  else if s.thirdDef /\ i = s.third
  2044.                       then true
  2045.                  else false;
  2046.  
  2047.       size(s) == if ~s.firstDef then 0
  2048.                  else if ~s.secondDef then 1
  2049.                  else if ~s.thirdDef then 2
  2050.                  else 3;
  2051.  
  2052. Comparing this specification with the one in Guttag and Horning's handbook
  2053. ([Guttag-Horning93], pp. 166-167) reveals a lot about how to write more
  2054. abstract specifications. Notice that the trait NonAbstractSet represents the
  2055. sort SmallSet as a tuple. This is akin to a "design decision" and makes the
  2056. specification less abstract. Another problem is the specification of
  2057. algorithms for the observers insert, \in, and size. These could be made more
  2058. abstract, even without changing the definition of the sort SmallSet. For
  2059. example, using the idea of generators and observers (see section 2.19 Can
  2060. you give me some tips for specifying things with LSL?), one could specify
  2061. \in as follows.
  2062.  
  2063.     i \in {} == false;
  2064.     size(s) < 3 => (i \in insert(i, s) = true);
  2065.  
  2066. The above trait also defines sets of integers, even though it doesn't
  2067. particularly depend on the properties of integers. It would be more abstract
  2068. to specify sets of elements. Finally the trait only works for sets of three
  2069. elements. Unless there is some good reason for this (for example, modeling
  2070. some particular implementation), you should avoid such arbitrary limits in
  2071. LSL. They can easily be imposed at the interface level.
  2072.  
  2073. Look at traits in the LSL handbook for examples of how to do things right.
  2074. You may find that a trait can be too abstract to make it easily understood;
  2075. that's fine, you don't have to try to define the ultimate theory of whatever
  2076. you're working with.
  2077.  
  2078. See [Wing95], section 4.1 for a more extended discussion on the above ideas.
  2079. You might want to look at [Liskov-Guttag86] for more background on the
  2080. general idea of abstraction in specification. See also [Jones90] for the
  2081. related idea of "implementation bias".
  2082.  
  2083. 2.21 Is there a way to write a trait that will guarantee consistency?
  2084.  
  2085. The question of how to write a trait that will guarantee consistency is
  2086. important for two reasons.
  2087.  
  2088.    * If you use all of LSL, which includes first-order logic, consistency is
  2089.      undecidable.
  2090.    * If your trait is inconsistent, then for most purposes the theory you
  2091.      are specifying is worthless, because everything will be provable (even
  2092.      equations such as true == false).
  2093.  
  2094. You can trade off ease of expression vs. ease of proving consistency as
  2095. follows (quoted from Garland's posting to `comp.specification.larch', June
  2096. 26, 1996).
  2097.  
  2098.      If you are willing to sacrifice ease of proving consistency, you
  2099.      can axiomatize your theories in first-order logic, where
  2100.      consistency is undecidable.
  2101.  
  2102.      If you are willing to sacrifice ease of expression, you can
  2103.      achieve consistency as do Boyer and Moore
  2104.      [Boyer-Moore79][Boyer-Moore88] with their "principle of
  2105.      definition"; that is, you can axiomatize your theories in
  2106.      primitive recursive arithmetic rather than in first-order logic.
  2107.  
  2108.      If you are willing to settle for some sort of middle ground, and
  2109.      you are willing to wait, a future release of the LSL Checker may
  2110.      provide some help. I've been thinking about how to enhance the
  2111.      checker to provide warnings about potentially inconsistent
  2112.      constructions, basically by using a less restrictive version of
  2113.      Boyer-Moore principle of definition to classify constructs as safe
  2114.      or unsafe.
  2115.  
  2116.      Part of my envisioned project for having LSL issue warnings about
  2117.      potential inconsistencies involves generating proof obligations
  2118.      for LP that can be used to establish consistency when it is in
  2119.      doubt.
  2120.  
  2121. So you can understand this tradeoff better, and so you can be aware of when
  2122. to worry about consistency, we will explain Boyer and Moore's shell
  2123. principle and definition principle and how they apply to LSL.
  2124.  
  2125. Boyer and Moore's shell principle (see [Boyer-Moore88] Section 2.3 and
  2126. [Boyer-Moore79] Section III.E) is a way of introducing new tuple-like sorts;
  2127. one would follow it literally in LSL by only using tuple of to construct
  2128. sorts. This prevents inconsistency, because it prevents the operators that
  2129. construct the new sorts from changing the theory of existing sorts. (That
  2130. is, the new theory is a conservative extension of the existing theory; see,
  2131. for example, Section 6.12 of [Ehrig-Mahr85].)
  2132.  
  2133. Although following the shell principle literally seems far too restrictive
  2134. in practice for LSL, one can try to use its ideas to define new sorts in a
  2135. disciplined way to help prevent inconsistency. This is done by divide the
  2136. set of operators of your sort into generators and observers and specifying
  2137. the result of applying each observer to each generator, as described above
  2138. (see section 2.19 Can you give me some tips for specifying things with
  2139. LSL?). For an example, see the handbook trait SetBasics (in
  2140. [Guttag-Horning93], page 166). However, it's not clear whether following
  2141. this discipline guarantees that your theory will be consistent.
  2142.  
  2143. Boyer and Moore's definition principle (see [Boyer-Moore88] Section 2.6) is
  2144. a way of defining auxiliary functions (operators in a trait that are not
  2145. generators and that are not the primitive observers used in defining a
  2146. sort). The definition principle does not allow one to underspecify a
  2147. function; its value must be defined in all of its declared domain.
  2148. Furthermore, recursion is only allowed if one can prove that the recursion
  2149. is terminating. For LSL this means that a definition of operator f satisfies
  2150. the definition principle if it satisfies the following conditions.
  2151.  
  2152.    * There is just one equation that defines the operator f, and it has the
  2153.      following form, where x1, ..., xn are distinct logical variables,
  2154.      called the "formals", and body is an LSL term, called the "body".
  2155.  
  2156.      f(x1, ..., xn) == body
  2157.  
  2158.    * The only free variables in body are the formals, x1, ..., xn.
  2159.    * If the definition is recursive, then the recursion must be proved to
  2160.      terminate.
  2161.  
  2162. See section 2.17 Can I define operators using recursion?, for how a
  2163. nonterminating recursive definition can cause inconsistency.
  2164.  
  2165. For examples of what may happen when some of the other conditions of the
  2166. definition principle are violated, consider the following trait.
  2167.  
  2168. BadDefinitionsTrait: trait
  2169.   includes Integer
  2170.   introduces
  2171.     moreThanOneAxiom: Int -> Bool
  2172.     freeVarsInBody: Int -> Int
  2173.   asserts
  2174.     \forall i, k: Int
  2175.       moreThanOneAxiom(i) == i >= 0;
  2176.       moreThanOneAxiom(i) == i <= 0;
  2177.       freeVarsInBody(i) == k + i;
  2178.   implies
  2179.     equations
  2180.       true == false;
  2181.       3 == 2;
  2182.  
  2183. The two axioms for the operator moreThanOneAxiom makes the theory
  2184. inconsistent; to see this, consider the following calculation.
  2185.  
  2186.     true
  2187.   = {by the trait Integer}
  2188.     4 >= 0
  2189.   = {by the first axiom}
  2190.     moreThanOneAxiom(4)
  2191.   = {by the second axiom}
  2192.     4 <= 0
  2193.   = {by the trait Integer}
  2194.     false
  2195.  
  2196. See section 2.18 What pitfalls are there for LSL specifiers?, for the trait
  2197. BadRational that illustrates a more subtle way to fall into this kind of
  2198. inconsistency.
  2199.  
  2200. In the trait BadDefinitionsTrait above, the axiom for freeVarsInBody also
  2201. makes the theory inconsistent. This can be seen as follows.
  2202.  
  2203.     3
  2204.   = {by the trait Integer}
  2205.     3 + 0
  2206.   = {by the axiom for freeVarsInBody, with k = 3}
  2207.     freeVarsInBody(0)
  2208.   = {by the axiom for freeVarsInBody, with k = 2}
  2209.     2 + 0
  2210.   = {by the trait Integer}
  2211.     2
  2212.  
  2213. See section 2.18 What pitfalls are there for LSL specifiers?, for the trait
  2214. BadSig that illustrates another way to fall into this kind of inconsistency.
  2215.  
  2216. Because Boyer and Moore's definition principle is quite restrictive, it
  2217. should be emphasized that the definition principle does not have to be used
  2218. in LSL, and is not even necessary for making consistent definitions. For
  2219. example, it seems perfectly reasonable to specify an auxiliary operator by
  2220. using several equations, one for each generator of an argument sort (see
  2221. section 2.19 Can you give me some tips for specifying things with LSL?),
  2222. instead of using just one equation and if then else. The definition
  2223. principle requires that all the variables in the defining equation be
  2224. distinct, but this seems only to prevent underspecification, not
  2225. inconsistency. (See section 2.16.2 Do I have to specify everything
  2226. completely in LSL?, for a discussion of underspecification.) The definition
  2227. principle also prohibits mutual recursion.
  2228.  
  2229. Remember that it's a tradeoff: if you use the definition principle, you are
  2230. guaranteed to make consistent auxiliary function definitions, but it may be
  2231. harder to specify what you want, and your specifications may be less clear
  2232. than they would be otherwise.
  2233.  
  2234. See section 3.17 How do I prove that my theory is consistent with LP?, for
  2235. how to use LP to help prove that a trait is consistent. This would be useful
  2236. if the trait violates either Boyer and Moore's shell principle or the
  2237. definition principle.
  2238.  
  2239. 2.22 Do I have to write all the traits I am going to use from scratch?
  2240.  
  2241. No, you don't have to write all the traits you are going to use from
  2242. scratch. You should certainly try to use Guttag and Horning's LSL handbook
  2243. traits ([Guttag-Horning93], Appendix A), which are freely available. Others
  2244. have also made other handbooks available. See section 2.23 Where can I find
  2245. handbooks of LSL traits?, for details on how to get these handbooks.
  2246.  
  2247. The whole idea of LSL is to enable reuse of traits, so you should
  2248. familiarize yourself with the relevant handbooks before starting to write
  2249. new traits.
  2250.  
  2251. 2.23 Where can I find handbooks of LSL traits?
  2252.  
  2253. The most commonly-used handbook of LSL traits is Guttag and Horning's
  2254. handbook ([Guttag-Horning93], Appendix A). This can be obtained by anonymous
  2255. ftp with the LSL checker (see section 2.3 Where can I get a checker for
  2256. LSL?). A hypertext version is on-line in
  2257.  
  2258.   http://www.research.digital.com/SRC/larch/toc.html
  2259.  
  2260. A general resource for all known handbooks that are publically available is
  2261. found on the world-wide web, at the following URL.
  2262.  
  2263.   http://www.cs.iastate.edu/~leavens/Handbooks.html
  2264.  
  2265. Besides a pointer to Guttag and Horning's handbooks, other handbooks found
  2266. there include handbooks of: mathematical traits, calendar traits, Larch/C++
  2267. traits. There is also a handbook of "SPECS traits", which allows one to
  2268. specify in a style similar to VDM-SL. The LSL input for these handbooks can
  2269. be obtained from the world-wide web page given above, or by anonymous ftp
  2270. from the following URL.
  2271.  
  2272.   ftp://ftp.cs.iastate.edu/pub/larch/
  2273.  
  2274. 2.24 How do I write logical quantifiers within an LSL term?
  2275.  
  2276. In LSL 3.1, you can write a universal quantifier within an LSL term by using
  2277. \A, and an existential quantifier using \E. As an example, consider the
  2278. following trait (from Leavens's Math handbook).
  2279.  
  2280. DenseOrder(T) : trait
  2281.   includes PartialOrder
  2282.   asserts
  2283.     \forall x,y,z: T
  2284.       (x < y) => (\E z (x < z /\ z < y));
  2285.   implies
  2286.     \forall x,y,z,t,u: T
  2287.       (x < y) => \E z \E t (x < z /\ z < t /\ t < y);
  2288.       (x < y) => \E z \E t \E u (x < z /\ z < t /\ t < u /\ u < y);
  2289.  
  2290. Note that the variables used in quantifiers are declared before the term.
  2291. The variable z used in the asserts section is existentially quantified, and
  2292. not universally quantified as might appear from its declaration.
  2293.  
  2294. 2.25 Where can I find LaTeX or TeX macros for LSL?
  2295.  
  2296. You can get a LaTeX style file, `larch.sty', and a macro file defining a
  2297. bunch of mathematical symbols, `larchmath.tex', by anonymous ftp from the
  2298. following URL.
  2299.  
  2300.   ftp://ftp.cs.iastate.edu/pub/larch/tex
  2301.  
  2302. These files were originally designed by Lamport, and revised by Horning.
  2303.  
  2304. The documentation for `larch.sty' says that it is to be used with LaTeX
  2305. 2.09. However, it can be used with LaTeX2e. To do so, put the following
  2306. lines at the start of your LaTeX input.
  2307.  
  2308. \documentclass{article}
  2309. \usepackage{larch}
  2310.  
  2311. Many published Larch papers and documents have formatting produced by these
  2312. TeX macros. However, it's not clear that the use of special symbols is a
  2313. good thing. Some of us prefer to let readers see the way the input is typed
  2314. (e.g., \in), because we think that non-mathematicians find it easier to
  2315. understand words instead of arbitrary symbols. There is some experimental
  2316. evidence for this [Finney96], so you might want to think about who your
  2317. audience is before you go to a great effort to print fancy symbols in your
  2318. specifications.
  2319.  
  2320. See section 2.26 How do I write some of those funny symbols in the Handbook
  2321. in my trait?.
  2322.  
  2323. 2.26 How do I write some of those funny symbols in the Handbook in my trait?
  2324.  
  2325. The ISO Latin codes for all of the "funny symbols" used in Guttag and
  2326. Horning's handbook are found on page 224 of [Guttag-Horning93]. Type the
  2327. characters on the right hand side when using LSL. If you are reading the
  2328. handbook in print form, you might want to tape a copy of that page to your
  2329. wall.
  2330.  
  2331. See section 2.25 Where can I find LaTeX or TeX macros for LSL?, for details
  2332. on how to get your specification to print out like the handbook.
  2333.  
  2334. 2.27 Is there a literate programming tool for use with LSL?
  2335.  
  2336. Yes, there actually is a version of "spiderweb" specialized for use with
  2337. LSL. If you are really a fan of such fancy systems, you can find it by using
  2338. the literate programming library's URL.
  2339.  
  2340.   http://www.desy.de/user/projects/LitProg.html
  2341.  
  2342. (If you don't know what literate programming is, you can find out there as
  2343. well.)
  2344.  
  2345. However, we have found that using the "noweb" system is much easier for most
  2346. people, and nearly as good. You can get noweb from the literate programming
  2347. library (see above), or directly from the following URL.
  2348.  
  2349.   http://www.eecs.harvard.edu/~nr/noweb/intro.html
  2350.  
  2351. Even easier, it's possible to use the trait modularization facilities of LSL
  2352. (includes, and assumes) to use virtually the same style as a literate
  2353. programming system would support.
  2354.  
  2355. 2.28 Is there a tool for converting LSL to hypertext for the web?
  2356.  
  2357. Yes, Penix's "lsl2html" tool converts an LSL input file to HTML, so it can
  2358. be browsed over the net. It can be found at the following URL.
  2359.  
  2360.   http://www.ece.uc.edu/~kbse/lsl2html/
  2361.  
  2362. Unfortunately, Penix's tool has a few problems that have never been fixed.
  2363. Instead, you might want to use Leavens's tool "lcpp2html", which is
  2364. available from the following URL.
  2365.  
  2366.   http://www.cs.iastate.edu/~leavens/lcpp2html.html
  2367.  
  2368. To use this like "lsl2html" invoke it as follows.
  2369.  
  2370.   lcpp2html -P -I *.lsl
  2371.  
  2372. 3. The Larch Prover (LP)
  2373.  
  2374. In this chapter, we discuss questions about the larch prover (LP).
  2375.  
  2376.    * What is the Larch Prover (LP)?
  2377.    * What kind of examples have already been treated by LP?
  2378.    * How does LP compare with other theorem provers?
  2379.    * Where can I get an implementation of LP?
  2380.    * Is there a command reference or list of LP commands?
  2381.    * Can I change the erase character in LP?
  2382.    * How do I interrupt LP?
  2383.    * Do I need to use LSL if I use LP?
  2384.    * Do I need to use LP if I use LSL?
  2385.    * How do I use LP to check my LSL traits?
  2386.    * What is the use of each kind of file generated by the LSL checker?
  2387.    * If LP stops working on my input is it all correct?
  2388.    * How do I find out where I am in my proof?
  2389.    * What proof techniques does LP attempt automatically?
  2390.    * Can you give me some tips on proving things with LP?
  2391.    * What pitfalls are there for LP users?
  2392.    * How do I prove that my theory is consistent with LP?
  2393.    * How can I backtrack if I made a mistake in my proof?
  2394.    * How do I prove something like 0 <= 2 in LP?
  2395.    * How can I develop a proof that I can replay later?
  2396.    * Do I have to reprove everything in an included trait?
  2397.    * Does LP use assertions in the implies section of an included trait?
  2398.  
  2399. 3.1 What is the Larch Prover (LP)?
  2400.  
  2401. The Larch Prover (LP) [Garland-Guttag95] is a program that helps check and
  2402. debug proofs. It is not geared toward proving conjectures automatically, but
  2403. rather toward automating the tedious parts of proofs. It automates
  2404. equational rewriting (proofs by normalization), but does not (by default)
  2405. automatically try other proof techniques.
  2406.  
  2407. Although LP is a general proof assistant, its main uses in the context of
  2408. Larch are to:
  2409.  
  2410.    * aid the debugging of specifications (i.e., theories), by helping
  2411.      develop redundant conjectures and their proofs, and
  2412.    * checking old proofs in the context of changed theories, to see if the
  2413.      proof is still valid.
  2414.  
  2415. The philosophy behind LP is "based on the assumption that initial attempts
  2416. to state conjectures correctly, and then to prove them, usually fail"
  2417. ([Garland-Guttag91], page 1). Because of this, LP does not (by default)
  2418. automatically attempt steps in a proof that are difficult (i.e.,
  2419. speculative, or mathematically interesting). Thus LP does not appear to be a
  2420. "smart" assistant in finding proofs; it will not suddenly try a complex
  2421. induction by itself. This prevents LP from spending lots of computer time on
  2422. conjectures that are not true, and helps make LP predictable. LP can be
  2423. thought of more as a "faithful" and "exacting" assistant. This is
  2424. appropriate in the debugging stage of a proof, where the steps you should
  2425. follow in interacting with LP are as follows.
  2426.  
  2427.    * LP applies equational rewriting to your conjecture, and either tells
  2428.      you that it's true, or presents you with a subgoal that, if proved,
  2429.      will lead to the proof of your conjecture.
  2430.    * If you have something left to prove, then ask yourself: "why do I think
  2431.      this is true?"
  2432.    * If you don't think the current subgoal is true, then you can change
  2433.      your conjecture (for example, by strengthening the hypothesis) or your
  2434.      theory, and start over.
  2435.    * If you think the current subgoal is true, but think you've started the
  2436.      proof out the wrong way, then you can backtrack in the proof (by using
  2437.      the cancel command).
  2438.    * If you think the current subgoal is true, then tell LP to carry out a
  2439.      step in the proof that corresponds to your reason. (For example, if you
  2440.      believe that the subgoal is true because it's true in each of several
  2441.      cases, use the resume by cases command.)
  2442.    * LP will then carry out the corresponding proof step for you, and this
  2443.      process starts over.
  2444.  
  2445. Think of using LP as a game whose prize is certainty about why your
  2446. conjecture is true, or at least knowledge about what's wrong with your
  2447. theory or conjecture. The main tactical knowledge you need to play the game
  2448. well is the correspondence between reasons and proof techniques (see section
  2449. 3.15 Can you give me some tips on proving things with LP?). Also needed for
  2450. good play is the ability to always question the consistency of your theory
  2451. and the truth of your conjectures.
  2452.  
  2453. The interaction described above is fine for developing conjectures and their
  2454. proofs, but LP also has features for replaying proofs, so that you don't
  2455. have to interact with it when checking old proofs in slightly modified
  2456. settings. See section 3.20 How can I develop a proof that I can replay
  2457. later?
  2458.  
  2459. See [Guttag-Horning93], Chapter 7, and [Garland-Guttag95] for more
  2460. information. See section 3.2 What kind of examples have already been treated
  2461. by LP?, for more discussion about the uses of LP.
  2462.  
  2463. 3.2 What kind of examples have already been treated by LP?
  2464.  
  2465. The original reason LP was built to help debug formal specifications (see
  2466. [Garland-Guttag-Horning90] and Chapter 7 of [Guttag-Horning93]). It has,
  2467. however, also been used for several other purposes, including the following
  2468. (reported in messages to the larch-interest mailing list, February 7 and
  2469. July 23, 1994).
  2470.  
  2471.    * Formal verification of circuits and general reasoning about hardware
  2472.      designs (including proofs of invariants, properties, refinement, and
  2473.      equivalence between implementations and specifications, see, for
  2474.      example, [Saxe-etal92] [Staunstrup-Garland-Guttag89]
  2475.      [Staunstrup-Garland-Guttag92]),
  2476.    * Reasoning about various mathematical theories, such as relational
  2477.      arithmetic and algebra [Martin-Lai92].
  2478.    * Verifying sequential programs (such as compilers) or properties of such
  2479.      programs.
  2480.    * Verification of concurrent programs (such as a distributed multiuser
  2481.      service) or properties of concurrent algorithms [Luchangco-etal94]
  2482.      [Soegaard-Anderson-etal93] and communication protocols [Chetali98].
  2483.  
  2484. Several other papers about uses of LP appear in [Martin-Wing93].
  2485.  
  2486. 3.3 How does LP compare with other theorem provers?
  2487.  
  2488. The basic difference between LP and other theorem provers is that LP does
  2489. not automatically attempt complex (i.e., interesting or speculative) proof
  2490. steps. LP also has no way to write general proof strategies or tactics (as
  2491. can be done in PVS, LCF, and other theorem provers). An additional
  2492. convenience is that there are tools for supporting the translation of LSL
  2493. specifications into LP's input format.
  2494.  
  2495. Compared with PVS [Owre-etal95], LP has a less sophisticated user interface,
  2496. and less automation. For example, PVS allows one to reorder what lemmas
  2497. should be proved more easily. PVS also has decision procedures for ground
  2498. linear arithmetic, and possibly better integration of arithmetic with
  2499. rewriting. The language used by PVS also has a more sophisticated type
  2500. system than does that of LSL (or LP), as it uses predicate subtyping and
  2501. dependent types. PVS also provides a strategy language for expressing proof
  2502. strategies, although it seems that users typically do not write their own
  2503. strategies. PVS also has various syntactic and semantic features, such as
  2504. support for tables and various kinds of model checking that are not
  2505. available in LP. On the other hand, LP is more portable (runs on more kinds
  2506. of computers), and because its interface does not rely on emacs, it requires
  2507. less set-up. Furthermore, as a teaching aid, a less automatic user interface
  2508. and a simpler type system have benefits in making students think more.
  2509.  
  2510. The Boyer-Moore theorem prover, NQTHM [Boyer-Moore79] [Boyer-Moore88] is
  2511. also more agressive than LP in trying to actively search for proofs. Its
  2512. successor, ACL2 is described as "industrial strength" [Kaufmann-Moore97].
  2513.  
  2514. A major difference between LP and HOL [Gordon-Melham93], Isabelle
  2515. [Paulson94], and PVS is that LP does not use a higher-order logic, which the
  2516. others do. Isabelle also has extensive support for term rewriting.
  2517.  
  2518. [[[Should also compare to OTTER, and RRL. Contributions are welcome
  2519. here...]]]
  2520.  
  2521. 3.4 Where can I get an implementation of LP?
  2522.  
  2523. Currently, LP only runs on Unix machines. You can get an implementation of
  2524. LP using the world-wide web, starting at the following URL.
  2525.  
  2526.   http://www.sds.lcs.mit.edu/spd/larch/LP/news/distribution.html
  2527.  
  2528. You can also get an implementation by anonymous ftp from the following URL.
  2529.  
  2530.   ftp://ftp.sds.lcs.mit.edu/pub/Larch/LP/
  2531.  
  2532. See section 2.3 Where can I get a checker for LSL?, for information about
  2533. getting a checker for LSL (that translates LSL traits into LP's input
  2534. format), and also for information on the Larch Development Environment
  2535. (LDE), that supports LSL, LP, LCL, and Larch/C++.
  2536.  
  2537. 3.5 Is there a command reference or list of LP commands?
  2538.  
  2539. Yes, there is a summary of LP's commands in the section titled "Command
  2540. Summary" of [Garland-Guttag95]. For ease of reference, you can find this at
  2541. the following URL.
  2542.  
  2543.   http://www.sds.lcs.mit.edu/spd/larch/LP/commands/commands.html
  2544.  
  2545. (You might want to print this out and paste it on your wall.)
  2546.  
  2547. Within an LP process, you can see this by issuing the command help commands.
  2548. Use help display to see help on the command display. Use display ? to see
  2549. the arguments you can pass to the command display.
  2550.  
  2551. 3.6 Can I change the erase character in LP?
  2552.  
  2553. According to Garland (posting on the larch-interest mailing list, July 14,
  2554. 1995), the erase (or rubout) character used by LP cannot be changed easily.
  2555. The reason is that "LP is written in CLU, and LP's line editing features are
  2556. provided by the CLU runtime environment. This environment hard-wires the
  2557. delete key [DEL] as the rubout character."
  2558.  
  2559. You can erase the current line in LP by typing a C-u (control-U). You can
  2560. redisplay the current line by typing C-r. See [Garland-Guttag91], page 7 for
  2561. more details.
  2562.  
  2563. See section 3.20 How can I develop a proof that I can replay later?, for a
  2564. way to avoid tedium and much direct interaction with LP.
  2565.  
  2566. If you use emacs, there is a way to get completely around this problem.
  2567. Simply start emacs, and type M-x shell, and then run LP from within the Unix
  2568. shell that appears. Besides allowing arbitrary editing, this trick allows
  2569. you to scroll backwards to view output.
  2570.  
  2571. 3.7 How do I interrupt LP?
  2572.  
  2573. If you are running LP under Unix, the Unix "quit" character (usually C-g,
  2574. that's control-g) will interrupt LP's execution.
  2575.  
  2576. See section 3.6 Can I change the erase character in LP?, for other
  2577. characters that aid in editing interactive input to LP. See section 3.20 How
  2578. can I develop a proof that I can replay later?, for a way to avoid tedium
  2579. and much direct interaction with LP.
  2580.  
  2581. 3.8 Do I need to use LSL if I use LP?
  2582.  
  2583. No, you do not need to use LSL if you use LP. LP has its own input format
  2584. (although it is very similar to LSL's input format). So, many users of LP
  2585. simply bypass LSL, and use LP exclusively. On the other hand, using LSL as
  2586. an input format to LP has the following advantages.
  2587.  
  2588.    * The LSL checker automatically generates proof management commands
  2589.      (scripting and logging) for LP, and helps organize theories and
  2590.      conjectures into files. See section 3.10 How do I use LP to check my
  2591.      LSL traits?.
  2592.    * Your theories and conjectures are accessible to a wider audience if
  2593.      they are stated in LSL format rather than in LP input format.
  2594.  
  2595. 3.9 Do I need to use LP if I use LSL?
  2596.  
  2597. No, you don't have to use LP if you use LSL. However, it's very helpful to
  2598. use LP with LSL, because it aids in debugging LSL traits. The idea is that
  2599. you state redundant properties of the theory you are specifying in the
  2600. implies section of your LSL trait (see section 2.11 When should I use an
  2601. implies section?), and then use LP to check that those really do follow from
  2602. the trait. See section 3.10 How do I use LP to check my LSL traits?, and
  2603. Chapter 7 of [Guttag-Horning93], for how to do this.
  2604.  
  2605. 3.10 How do I use LP to check my LSL traits?
  2606.  
  2607. There are three main things to check about an LSL trait (see
  2608. [Guttag-Horning93], Chapter 7).
  2609.  
  2610.    * Is the trait consistent?
  2611.    * Do the trait's assumptions (if any) hold?
  2612.    * Do the traits implications hold?
  2613.  
  2614. The first kind of check is vital, because you can prove anything in an
  2615. inconsistent theory. See section 3.17 How do I prove that my theory is
  2616. consistent with LP?, and Section 7.6 of [Guttag-Horning93], for more
  2617. information on how to do this.
  2618.  
  2619. The use of an assumes clause in a trait specifies assumptions about the
  2620. context in which that trait is used (see section 2.8 What is the difference
  2621. between assumes and includes?); if your trait has included other traits with
  2622. assumes clauses, then these assumptions must be checked (see page 124-125 of
  2623. [Guttag-Horning93]). However, checking such assumptions is similar to the
  2624. checking that happens when checking a trait's implications, which is the
  2625. focus of this section.
  2626.  
  2627. Here are the top-level steps in using LP to check the implications written
  2628. in the implies section of your trait. Let us suppose your trait is called
  2629. Foo, and is in a file named `Foo.lsl'.
  2630.  
  2631.    * To produce LP input from your trait, you would use the `-lp' switch
  2632.      with the LSL checker as follows.
  2633.  
  2634.        lsl -lp Foo.lsl
  2635.  
  2636.      This produces the following files: `Foo_Axioms.lp', `Foo_Checks.lp',
  2637.      and `Foo_Theorems.lp'.
  2638.    * Start LP. The suggested name for this command is lp, but on many
  2639.      systems it is called LP.
  2640.  
  2641.        lp
  2642.  
  2643.    * LP will prompt you for input with a prompt that looks like `LP1: '.
  2644.      When you see this prompt, type the following.
  2645.  
  2646.        execute Foo_Checks
  2647.  
  2648.    * LP will read in your input and attempt the first (rewriting) steps of
  2649.      the proofs of your conjectures. Often it will suspend each proof
  2650.      waiting for your input. See section 3.1 What is the Larch Prover (LP)?,
  2651.      for the steps to follow in debugging your trait by trying to prove the
  2652.      conjectures in its implies section. See section 3.15 Can you give me
  2653.      some tips on proving things with LP? for tips on how to go about a
  2654.      proof.
  2655.  
  2656. See section 3.20 How can I develop a proof that I can replay later?, for an
  2657. alternative to using LP interactively.
  2658.  
  2659. See section 3.15 Can you give me some tips on proving things with LP? and
  2660. Sections 7.4-7.5 of [Guttag-Horning93], for more information on checking
  2661. implications with LP.
  2662.  
  2663. 3.11 What is the use of each kind of file generated by the LSL checker?
  2664.  
  2665. The LSL checker, when used with the `-lp' switch on a file named `Foo.lsl',
  2666. in general produces three files: `Foo_Axioms.lp', `Foo_Checks.lp', and
  2667. `Foo_Theorems.lp'. Each of these files is in LP input format, hence the
  2668. suffix `.lp'.
  2669.  
  2670. The file `Foo_Axioms.lp' contains a translation of the trait in `Foo.lsl',
  2671. minus the implies section. It is "executed" by LP when LP is executing the
  2672. translation of some other LSL trait that includes Foo.
  2673.  
  2674. The file `Foo_Checks.lp' contains a translation of the implications in
  2675. `Foo.lsl', along with checks of assumptions. As an LP command file, it
  2676. starts logging and scripting to the appropriate files (`Foo.lplog' and
  2677. `Foo.lpscr'), executes the `Foo_Axioms.lp' file, and then attempts proofs
  2678. for each of the checks. This is the main file you execute when using LP.
  2679.  
  2680. The file `Foo_Theorems.lp' contains a translation of the implications in
  2681. `Foo.lsl', stated as axioms. It is used automatically when it is safe to do
  2682. so in the LP input generated by the LSL checker.
  2683.  
  2684. All of these files are text files, so viewing them with an editor, or
  2685. printing them out, is a good way to solidify your understanding. (See also
  2686. page 128 of [Guttag-Horning93].)
  2687.  
  2688. 3.12 If LP stops working on my input is it all correct?
  2689.  
  2690. No, if LP stops working, it may just mean that it wants more guidance from
  2691. you. The way to tell if all outstanding conjectures have been proved is to
  2692. use the qed command [Garland-Guttag95]. If you see the following, then you
  2693. are done.
  2694.  
  2695.   All conjectures have been proved.
  2696.  
  2697. However, if you see something like the following, then you are not done.
  2698.  
  2699.   Still attempting to prove level 2 lemma FooTheorem.2
  2700.  
  2701. See section 3.13 How do I find out where I am in my proof?, for a way to
  2702. find out what has to be done to finish your proof.
  2703.  
  2704. 3.13 How do I find out where I am in my proof?
  2705.  
  2706. When LP stops reading input from your file (for example, the `_Checks.lp'
  2707. file for an LSL trait), the first thing you should do is to get your
  2708. bearings. The commands described here also are helpful if you are using LP
  2709. interactively, because it's easy to forget what you are trying to do.
  2710.  
  2711. To find your bearings, the following commands are helpful (see the section
  2712. titled "Sample Proofs: how to guide a proof" in [Garland-Guttag95]).
  2713.  
  2714. To find out ...                  Use the command
  2715. ---------------------------------------------------
  2716. What is left to be proved?       display conjectures
  2717. What is the status of my proof?  display proof-status
  2718. How did I get here?              history
  2719. What axioms can I use?           display
  2720. What are the current hypotheses? display *Hyp
  2721. What are the induction rules?    display induction-rules
  2722. What are the deduction rules?    display deduction-rules
  2723.  
  2724. The commands display conjectures and display seem to be the most useful.
  2725. When you use display conjectures, LP shows where it stopped in your proofs.
  2726. There may be several lemmas listed below the first "conjecture". The last of
  2727. these (the one with the greatest "level" number) is the one you can work on
  2728. first.
  2729.  
  2730. See section 3.15 Can you give me some tips on proving things with LP?, for
  2731. tips on how to proceed with your proof, once you've found your bearings.
  2732.  
  2733. 3.14 What proof techniques does LP attempt automatically?
  2734.  
  2735. By default, LP automatically uses only the following forward inference
  2736. techniques.
  2737.  
  2738.    * normalization, and
  2739.    * application of deduction rules (that are not inactive).
  2740.  
  2741. See section 3.15 Can you give me some tips on proving things with LP?, and
  2742. Sections 7.4-7.5 of [Guttag-Horning93], for other proof techniques.
  2743.  
  2744. 3.15 Can you give me some tips on proving things with LP?
  2745.  
  2746. The most important tip for using LP is to think about your conjectures, and
  2747. to be very skeptical of their truth.
  2748.  
  2749. When you first start using LP, you will be tempted to have it do the
  2750. thinking for you. You may find yourself trying random proof techniques to
  2751. prove the current subgoal. Resist that temptation! Curb your desire for
  2752. automatic proof! Instead, use one of the following two ideas (see the
  2753. section titled "Sample Proofs: how to guide a proof" in [Garland-Guttag95]).
  2754.  
  2755. Think about whether the conjecture is true, and if so, why you believe it.
  2756. (Imagine trying to convince a very skeptical, but logical, person.) If you
  2757. believe your conjecture, then your reason may suggest a proof technique.
  2758. Here is a small table relating reasons and some of LP's proof techniques.
  2759.  
  2760.   If your argument         Then
  2761.   has the shape ...        try the following ...
  2762.   ------------------------------------------------------
  2763.   For a simple case ...,   resume by induction on
  2764.     then assuming ...
  2765.     for bigger cases...
  2766.  
  2767.   On the one hand,         resume by cases ...
  2768.     on the other hand...     % or sometimes
  2769.                            resume by induction on ...
  2770.  
  2771.   If that weren't true,    resume by contradiction
  2772.     then ...,                % sometimes followed by
  2773.                            critical-pairs *Hyp with *
  2774.  
  2775.   By axiom R, ...          apply R to conjecture
  2776.                              % or if R contains a free or
  2777.                              %    universally quantified variable, x
  2778.                            instantiate x by t in R
  2779.                              % or if R has an existentially
  2780.                              %     quantified variable, x
  2781.                            fix x as t in ...
  2782.  
  2783.   This should simplify     normalize conjecture with ...
  2784.     by ...
  2785.                              % or if the ... is a formula
  2786.                            rewrite conjecture with ...
  2787.  
  2788. Proofs by induction are very common and more useful than you might think.
  2789. For example, induction is used to prove the last two implications in
  2790. ResponseTrait (see section 2.19 Can you give me some tips for specifying
  2791. things with LSL?); in that proof, there are three basis cases, and no
  2792. inductive case. This shows that any time you have a generated sort, a proof
  2793. by induction can be used, even if there are only a finite number of values
  2794. of that sort. Furthermore, you should consider a proof by induction first,
  2795. as some other proof techniques (by cases, =>, if-method, contradiction) make
  2796. proof by induction more difficult or impossible, because they replace free
  2797. variables by constants (see [Garland-Guttag91], page 65).
  2798.  
  2799. Another idea is to see if the form of your conjecture suggests a proof
  2800. technique. Here is a small table of conjecture forms and proof techniques.
  2801. (A name of the form fresh1 is to be replaced by a fresh variable name, that
  2802. is, by a name that is not used elsewhere.)
  2803.  
  2804.   If your conjecture    Then
  2805.   looks like ...        try the following ...
  2806.   ------------------------------------------------------
  2807.   ~(E1 = E2)            resume by contradiction
  2808.                           % sometimes followed by
  2809.                           critical-pairs *Hyp with *
  2810.   P1 /\ P2 /\ ...       resume by /\
  2811.   P => Q                resume by =>
  2812.   P <=> Q               resume by <=>
  2813.   if H then P else Q    resume by if-method
  2814.   ...(if P then ...)... resume by cases P
  2815.   \E x (P(x))           resume by generalizing x from fresh1
  2816.  
  2817. If your conjecture looks like \A x (P(x)), then just try whatever method is
  2818. suggested for P(x) by itself.
  2819.  
  2820. There are some technical caveats for the above suggestions
  2821. [Garland-Guttag95]. Using resume by /\ can lead to longer proofs, if the
  2822. same lemma is needed in the proof of each conjunct. Using resume by => and
  2823. resume by <=> makes certain kinds of proofs by induction impossible (so if
  2824. you want to do a proof by induction, do that before using these methods).
  2825. The generalization techniques are not helpful if there are other free
  2826. variables in the formula.
  2827.  
  2828. For complex proofs, it is quite useful to prove lemmas first. You can either
  2829. state these as things to be proved before what you are trying to prove, or
  2830. use the prove command during the proof. You may need to use the command set
  2831. immunity on to keep LP from deleting your lemma after you prove it.
  2832.  
  2833. When all else fails, use the old mathematician's trick of trying to
  2834. construct a counterexample to your conjecture. If you can't do it, try to
  2835. figure out why you can't (that will suggest a proof technique). Or, if you
  2836. start making progress towards a counterexample, keep going. Repeat the
  2837. following mantra to yourself.
  2838.  
  2839.      It might not be true.
  2840.  
  2841. Finally, when you finally succeed in proving your conjecture, don't
  2842. celebrate unless you have also shown that your theory is consistent (see
  2843. section 3.17 How do I prove that my theory is consistent with LP?).
  2844.  
  2845. See section 3.20 How can I develop a proof that I can replay later?, for
  2846. advice on how to work noninteractively with LP.
  2847.  
  2848. For a short, but important list of tips, see the section titled "Sample
  2849. Proofs: how to guide a proof" in [Garland-Guttag95]. See Chapter 7 of
  2850. [Guttag-Horning93] for more details.
  2851.  
  2852. 3.16 What pitfalls are there for LP users?
  2853.  
  2854. The biggest pitfall is to not think about what you are doing, but to simply
  2855. try random proof strategies. This quickly becomes frustrating. See section
  2856. 3.15 Can you give me some tips on proving things with LP?, for how to work
  2857. with LP in a more fruitful way.
  2858.  
  2859. If your theory is inconsistent, proofs may not be easy, but they will always
  2860. be possible. Always try to convince yourself of your theory's consistency
  2861. before celebrating your proof. See section 3.17 How do I prove that my
  2862. theory is consistent with LP?.
  2863.  
  2864. 3.17 How do I prove that my theory is consistent with LP?
  2865.  
  2866. It is difficult to prove a theory is consistent using LP. However, one can
  2867. profitably use LP to search for inconsistency. (See section 2.18 What
  2868. pitfalls are there for LSL specifiers?, for some common LSL problems that
  2869. lead to inconsistency.)
  2870.  
  2871. One way to use LP to search for inconsistency is using the complete command.
  2872. This directs LP to attempt to add enough rewrite rules to make the theory
  2873. equationally complete. If this process finds an inconsistency, such as
  2874. proving that true == false, then your theory is inconsistent. (This usually
  2875. doesn't stop in an acceptable amount of time and space, but if it does, and
  2876. if it hasn't found an inconsistency, and if your theory is purely
  2877. equational, then you have proved your theory is consistent.)
  2878.  
  2879. Often the completion procedure seems to go off down some path, generating
  2880. more and more complex formulas. If this happens, interrupt it (see section
  2881. 3.7 How do I interrupt LP?) and try using the critical-pairs command to
  2882. direct the search for inconsistency by naming two sets (not necessarily
  2883. disjoint) of axioms that you wish to deduce consequences of. You can also
  2884. use any other of the forward inference techniques in LP (such as the apply
  2885. command) to try to deduce an inconsistency in a more directed manner.
  2886.  
  2887. See [Guttag-Horning93], section 7.6, for more on this topic. See section
  2888. 2.21 Is there a way to write a trait that will guarantee consistency?, for a
  2889. discussion of the tradeoffs involved between writing an LSL trait in a way
  2890. that avoids inconsistency and the difficulty in proving consistency.
  2891.  
  2892. 3.18 How can I backtrack if I made a mistake in my proof?
  2893.  
  2894. If you decide you don't like the way your current proof is going in LP, use
  2895. the cancel command to abort the current proof, backtracking to the previous
  2896. subgoal. Note that this "suspends work on other proofs until an explicit
  2897. resume command is given" [Garland-Guttag95]. See the documentation for
  2898. variations of this command.
  2899.  
  2900. If you want to start over from scratch, without using the quit command and
  2901. restarting LP, use the clear command.
  2902.  
  2903. 3.19 How do I prove something like 0 <= 2 in LP?
  2904.  
  2905. As a way of making the problem of proving things like 0 <= 2 concrete,
  2906. consider the following LSL trait. This trait uses the Integer trait in
  2907. Guttag and Horning's handbook (see [Guttag-Horning93], p. 163)
  2908.  
  2909. DecimalProblem: trait
  2910.   includes Integer
  2911.   implies
  2912.     equations
  2913.       ~(1 <= 0);
  2914.       0 <= 2;
  2915.  
  2916. The problem is how to coax LP into proving these implications. The following
  2917. answer is adapted from a posting of Vandevoorde's `comp.specification.larch'
  2918. (September 7, 1995).
  2919.  
  2920. When the LSL checker translates LSL into LP input, it makes the rewrite
  2921. rules for the trait DecimalLiterals (see [Guttag-Horning93], p. 164)
  2922. passive, which means that they don't get applied automatically
  2923. [Garland-Guttag95]. For example, 2 will not be rewritten to succ(succ(0)).
  2924. One reason for this is to keep the conjectures and facts more readable.
  2925.  
  2926. However, to prove the implications in your trait, you need to make them
  2927. active with the following command.
  2928.  
  2929.   make active DecimalLiterals
  2930.  
  2931. This is enough to prove ~(1 <= 0) by rewriting. It's also a necessary first
  2932. step for the proofs below.
  2933.  
  2934. To prove 0 <= 2, you also need to use facts named IsTO* (from the trait
  2935. IsTO, see page 194 of [Guttag-Horning93]). The easiest proof to understand
  2936. is to instantiate the rule for transitivity as follows.
  2937.  
  2938.    instantiate x by 0, y by 1, z by 2 in IsTO.2
  2939.  
  2940. (It's a good thing you didn't want to prove 0 <= 9!)
  2941.  
  2942. The critical-pairs command is useful for finding such instantiations
  2943. automatically. For example, to prove 0 <= 2, you can give the following
  2944. commands to LP.
  2945.  
  2946.    resume by contradiction    % This turns the (negated) conjecture into
  2947.                               % a rewrite rule for critical-pairs.
  2948.    critical-pairs *Hyp with * % This is common in contradiction proofs.
  2949.                               % For this proof, it suffices to use
  2950.                               % critical-pairs *contraHyp with IsTO.4
  2951.  
  2952. 3.20 How can I develop a proof that I can replay later?
  2953.  
  2954. There are probably many ways to develop a proof that you can replay later.
  2955. Our technique has the following steps, and starts with an LSL trait. (If you
  2956. don't use LSL, you can just use a file of LP input.)
  2957.  
  2958.   1. Write a trait Foo into the file `Foo.lsl'.
  2959.   2. Use the LSL checker to generate the `Foo_Checks.lp' file.
  2960.  
  2961.         % lsl -lp Foo.lsl
  2962.  
  2963.   3. Optional: use LP to debug your trait and to try out ideas for proofs of
  2964.      the implications interactively.
  2965.   4. Copy the file `Foo_Checks.lp' into the file `Foo.proof'.
  2966.  
  2967.         % cp Foo_Checks.lp Foo.proof
  2968.  
  2969.   5. Optional: if you have used LP already on this trait, then you have a
  2970.      head start. There are lines in the `Foo.lpscr' that indicate what to do
  2971.      for the proof, and what happened in LP. Copy those lines from the
  2972.      `Foo.lpscr' and put them in the `Foo.proof'. For example, after the
  2973.      following line in Foo.proof
  2974.  
  2975.         prove
  2976.           (_x1_ \in _x2_) = (_x1_ \in' _x2_)
  2977.           ..
  2978.  
  2979.      you might want to add the following lines from the script file. The
  2980.      first indicates how you did the proof, and the rest indicate what
  2981.      happened.
  2982.  
  2983.           resume by induction
  2984.              <> basis subgoal
  2985.              [] basis subgoal
  2986.              <> basis subgoal
  2987.              [] basis subgoal
  2988.              <> induction subgoal
  2989.              [] induction subgoal
  2990.           [] conjecture
  2991.  
  2992.   6. Optional: put the command set box-checking on at the top of your proof,
  2993.      so that these box comments will be checked. You only need this once per
  2994.      file.
  2995.   7. Optional: if you haven't used LP yet, think about each conjecture, and
  2996.      (if you still believe it), after each conjecture, write a LP command
  2997.      (or commands) that will complete the proof of that conjecture.
  2998.   8. After each conjecture to be proved, following the commands to prove it,
  2999.      if any, each list of reasons prove command add the LP command qed. For
  3000.      example, your file `Foo.proof', might have a section that looks like
  3001.      the following.
  3002.  
  3003.         prove
  3004.           (_x1_ \in _x2_) = (_x1_ \in' _x2_)
  3005.           ..
  3006.           resume by induction
  3007.              <> basis subgoal
  3008.              [] basis subgoal
  3009.              <> basis subgoal
  3010.              [] basis subgoal
  3011.              <> induction subgoal
  3012.              [] induction subgoal
  3013.           [] conjecture
  3014.         qed
  3015.  
  3016.   9. Execute the file `Foo.proof' in LP by using the command
  3017.  
  3018.        execute Foo.proof
  3019.  
  3020.      If this doesn't work, edit the corrections into the file `Foo.proof'.
  3021.      Often you can obtain input for this file from the file `Foo.lpscr'.
  3022.  10. When your proof executes to completion, use the file `Foo.lpscr' to put
  3023.      into `Foo.proof' all of the <> and [] comments that help keep your
  3024.      proof synchronized with LP. When you are done, edit `Foo.proof' so that
  3025.      the differences with the file `Foo_Checks.lp' are minimal, as shown by
  3026.      the following Unix command.
  3027.  
  3028.         % diff Foo_Checks.lp Foo.proof | more
  3029.  
  3030. One advantage of the above procedure is that you can work on one conjecture
  3031. at a time, which allows you to control the order in which the lemmas are
  3032. proved. Another advantage is that you tend to think more about what you are
  3033. doing than if you are interacting directly with LP. Finally, the above
  3034. procedure is quite helpful when, inevitably, you revise your trait.
  3035.  
  3036. When you revise your trait, by editing the file `Foo.lsl', use the following
  3037. steps to revise your proof.
  3038.  
  3039.   1. Use the LSL checker to generate the `Foo_Checks.lp' file for the
  3040.      revised trait.
  3041.  
  3042.         % lsl -lp Foo.lsl
  3043.  
  3044.   2. Use the Unix diff command to check to see what you need to change in
  3045.      your proof.
  3046.  
  3047.         % diff Foo_Checks.lp Foo.proof | more
  3048.  
  3049.      Ignore all the added lines that you put in your proofs such as the
  3050.      following.
  3051.  
  3052.         20a21
  3053.         > set box-checking on
  3054.         78a88,95
  3055.         >   resume by induction
  3056.         >     <> basis subgoal
  3057.         >     [] basis subgoal
  3058.         >     <> basis subgoal
  3059.         >     [] basis subgoal
  3060.         >     <> induction subgoal
  3061.         >     [] induction subgoal
  3062.         >   [] conjecture
  3063.         > qed
  3064.  
  3065.      But pay attention to other differences, particularly those for which
  3066.      there is a < at the beginning of the line.
  3067.   3. Revise your `Foo.proof' file according to the output of the previous
  3068.      step, trying to minimize differences as shown by the diff command.
  3069.   4. Use LP to rerun your proof. In LP, use the command.
  3070.  
  3071.         execute Foo.proof
  3072.  
  3073.      If this doesn't work, edit the corrections into the file `Foo.proof'.
  3074.      Often you can obtain input for this file from the file `Foo.lpscr'.
  3075.  
  3076. 3.21 Do I have to reprove everything in an included trait?
  3077.  
  3078. No, you should only have to prove that the assumptions from whatever assumes
  3079. clauses you have in the included trait hold in your trait. (See pages
  3080. 124-125 of [Guttag-Horning93].)
  3081.  
  3082. 3.22 Does LP use assertions in the implies section of an included trait?
  3083.  
  3084. According to [Guttag-Horning93] (page 128), LP will reuse the assertions in
  3085. the implies section of a trait without forcing you to prove them again "when
  3086. it is sound to do so". [[But when is that exactly?]]
  3087.  
  3088. 4. Behavioral Interface Specification Languages (BISLs)
  3089.  
  3090. In this chapter, we discuss questions about Larch Behavioral Interface
  3091. Specification Languages (BISLs).
  3092.  
  3093.    * What is a behavioral interface specification language (BISL)?
  3094.    * Where can I get a BISL for my favorite programming language?
  3095.    * Do I need to write an LSL trait to specify something in a BISL?
  3096.    * What is an abstract value?
  3097.    * What do mutable and immutable mean?
  3098.    * If I specify an ADT in a BISL do I prove it is the same as the trait?
  3099.    * What does requires mean?
  3100.    * What does ensures mean?
  3101.    * What does modifies mean?
  3102.    * What does trashes mean?
  3103.    * What does claims mean?
  3104.    * What is the meaning of a specification written in a BISL?
  3105.    * How do I specify something that is finite or partial?
  3106.    * How do I specify errors or error-checking?
  3107.    * How do I specify that all the values of a type satisfy some property?
  3108.    * What pitfalls are there for BISL specifiers?
  3109.    * Can you give me some tips for specifying things in a BISL?
  3110.  
  3111. 4.1 What is a behavioral interface specification language (BISL)?
  3112.  
  3113. A behavioral interface specification language (BISL) is a kind of
  3114. specification language that has the following characteristics.
  3115.  
  3116.    * It can specify an exact interface for modules written in some
  3117.      particular programming language. For example, Larch/CLU [Wing83]
  3118.      [Wing87] can specify the details of how a CLU procedure is called,
  3119.      including the types of its arguments, the types of its results, whether
  3120.      it is an iterator, and the names and types of exception results.
  3121.    * It can specify the behavior of a program module written in that
  3122.      programming language. For example, in Larch/CLU one can specify that a
  3123.      procedure can signal an exception.
  3124.  
  3125. An interface describes exactly how to use a module written in some
  3126. programming language. For example, a function declaration in C tells how to
  3127. call that function, by giving the function's name, and by describing the
  3128. number and types of its arguments.
  3129.  
  3130. The concept of behavioral interface specification is an important feature of
  3131. the Larch family of specification languages [Wing87]. A particularly good
  3132. explanation of the concept of behavioral interface specification is
  3133. [Lamport89]. In that paper, Lamport describes a vending machine
  3134. specification. To specify a vending machine, it is not sufficient to merely
  3135. describe a mathematical mapping between abstract values (money to cans of
  3136. soda). One also needs to specify that there will be buttons, a coin slot, a
  3137. place for the can of soda to appear, and the meaning of the user interface
  3138. events. The buttons, the coin slot, etc. form the interface of the vending
  3139. machine; the behavior is described using a mathematical vocabulary that is
  3140. an abstraction of the physical machinery that will be used to realize the
  3141. specification. The same two pieces are needed to precisely specify a
  3142. function to be implemented in, say, C++: the C++ interface information and a
  3143. description of its behavior.
  3144.  
  3145. Many authors use the term interface specification language for this type of
  3146. language. However, there is a natural confusion between this term and an
  3147. "interface definition language", such as the CORBA IDL, which merely
  3148. specifies interface information and not behavior. To avoid this confusion,
  3149. we advocate the term "behavioral interface specification language" for any
  3150. language that specifies not only interface information, but also behavior.
  3151.  
  3152. In the Larch family there are several BISLs (see section 1.1 What is Larch?
  3153. What is the Larch family of specification languages?). In the silver book
  3154. [Guttag-Horning93], a Larch BISL is called a "Larch interface language".
  3155. However, we do not use the term "Larch interface language" as a synonym for
  3156. "BISL", because there are BISLs outside the Larch family (such as those in
  3157. the RESOLVE family [Edwards-etal94]). However, "Larch interface language" is
  3158. a synonym for "Larch BISL". Another synonym is "Larch interface
  3159. specification language".
  3160.  
  3161. The first Larch BISL was Larch/CLU [Wing83] [Wing87]. There are now several
  3162. others. See section 4.2 Where can I get a BISL for my favorite programming
  3163. language?, for information about how to get an implementation.
  3164.  
  3165. See section 1.1 What is Larch? What is the Larch family of specification
  3166. languages?, and [Guttag-Horning93] for more information.
  3167.  
  3168. 4.2 Where can I get a BISL for my favorite programming language?
  3169.  
  3170. See section 1.1 What is Larch? What is the Larch family of specification
  3171. languages? for what Larch BISLs have been discussed in literature and
  3172. technical reports. In this section, we concentrate on Larch BISLs that have
  3173. some kind of tool support. As far as we know, these are the following.
  3174. (Except as noted, the tools are all free.)
  3175.  
  3176. LCL  LCL ([Guttag-Horning93], Chapter 5, [Tan94] [Evans00]) is a BISL for
  3177.      ANSI C. Tool support includes LCLint, which can use specification
  3178.      information to help find errors in programs. The current implementation
  3179.      is available from the following URL.
  3180.  
  3181.        http://lclint.cs.virginia.edu/
  3182.  
  3183.      There is also a mailing list for LCLint, which you can subscribe to
  3184.      using the first URL above, or by sending email to
  3185.      lclint-request@virginia.edu.
  3186. Larch/Ada
  3187.      Larch/Ada [Guaspari-Marceau-Polak90] [ORA94] is a BISL for Ada. It is
  3188.      part of the specification environment, Penelope, which also has a proof
  3189.      assistant and a tool, AdaWise, for checking the subset of Ada used in
  3190.      Penelope. AdaWise is free for academic users; for others it can be
  3191.      licensed from Oddessy Research Associates (send email to Peter Rukavena
  3192.      at marketing@oracorp.com). Information on Penelope and AdaWise is
  3193.      available at the following URLs.
  3194.  
  3195.        http://www.oracorp.com/ada/penelope.htm
  3196.        http://www.oracorp.com/ada/adawise.htm
  3197.  
  3198. Larch/Smalltalk
  3199.      Larch/Smalltalk [Cheon-Leavens94] [Cheon-Leavens94b] is a BISL for
  3200.      Smalltalk-80. It has a syntax and type checker, as well as a
  3201.      specification browser. It runs under ParcPlace Objectworks\Smalltalk.
  3202.      It can be obtained from the following URLs.
  3203.  
  3204.        http://www.cs.iastate.edu/~leavens/larchSmalltalk.html
  3205.        ftp://ftp.cs.iastate.edu/pub/larchSmalltalk/
  3206.  
  3207. Larch/C++
  3208.      Larch/C++ [Leavens97] [Leavens96b] is a BISL for C++. The current
  3209.      release has a syntax checker, examples, and a reference manual. It can
  3210.      be obtained from the following URLs.
  3211.  
  3212.        http://www.cs.iastate.edu/~leavens/larchc++.html
  3213.        ftp://ftp.cs.iastate.edu/pub/larchc++/
  3214.  
  3215. VSPEC
  3216.      VSPEC [Baraona-Penix-Alexander95] [Baraona-Alexander96]
  3217.      [Baraona-Alexander-Wilsey96] is a BISL for VHDL. The current release
  3218.      has a syntax checker. It can be obtained from the following URLs.
  3219.  
  3220.        http://www.ece.uc.edu/~pbaraona/vspec/index.html
  3221.        ftp://ftp.ece.uc.edu/pub/users/pbaraona/vspec2.0.tar.gz
  3222.  
  3223. GCIL
  3224.      The Generic Concurrent Interface Language, GCIL, [Lerner91] has a
  3225.      syntax and type checker. It can be obtained from the following URL.
  3226.  
  3227.        ftp://ftp.cs.cmu.edu/afs/cs.cmu.edu/project/larch/ftp/gcil.tar.Z
  3228.  
  3229. 4.3 Do I need to write an LSL trait to specify something in a BISL?
  3230.  
  3231. No, you don't always have to write an LSL trait to specify something in a
  3232. BISL, it just seems that way. Seriously, you don't have to write a trait in
  3233. the following circumstances.
  3234.  
  3235.    * You are specifying a procedure and all of the mathematical vocabulary
  3236.      needed is available in existing traits. These traits may come from a
  3237.      handbook (see section 2.23 Where can I find handbooks of LSL traits?),
  3238.      or they may be built-in to your BISL. For example, in most Larch BISLs,
  3239.      you would not have to write a trait for your language's built-in
  3240.      integer type.
  3241.    * Your BISL may create a trait for some compound type for you
  3242.      automatically. For example, in LCL, traits are created automatically to
  3243.      model C struct types.
  3244.    * You have imported a specification file that defines an abstract data
  3245.      type (ADT), which is based on an already written trait.
  3246.  
  3247. If you are specifying an ADT in a Larch BISL, you will always have to use
  3248. some trait to describe its abstract values (see section 4.4 What is an
  3249. abstract value?). It might be a trait from a handbook, or some combination
  3250. of traits that already exist, but there will have to be one that defines the
  3251. abstract values for your ADT.
  3252.  
  3253. Note that it is almost always possible to use one of LSL's shorthands or a
  3254. combination of handbook traits to specify the abstract values of an ADT. The
  3255. only drawback might be that such descriptions of abstract values might not
  3256. be as close to your way of thinking about your problem domain as you might
  3257. like or it might not have enough high-level vocabulary for your purposes.
  3258. For example, when specifying the abstract values of symbol tables, one might
  3259. use the handbook trait FiniteMap (see [Guttag-Horning93], page 185).
  3260. However, if your symbol table has to handle nested scopes, that trait, by
  3261. itself might not be adequate. You might, for example, want to use a stack of
  3262. finite maps as abstract values, in which case you might also use the both
  3263. the FiniteMap and Stack traits (see [Guttag-Horning93], page 170), and also
  3264. add some additional operators to search the abstract values appropriately.
  3265. If that kind of thing gets too complex, then it might be better to start
  3266. writing your own trait (see section 2.20 How do I know when my trait is
  3267. abstract enough?). Also, when using LSL shorthands and standard handbook
  3268. traits, be careful that you do not state contradictory constraints as axioms
  3269. (see section 2.18 What pitfalls are there for LSL specifiers?).
  3270.  
  3271. Usually, when you are specifying a procedure, you won't have to specify a
  3272. separate trait, because you will use the vocabulary of the traits that
  3273. describe the abstract values of whatever types of arguments and results (and
  3274. global variables) your procedure uses. However, if this vocabulary isn't
  3275. expressive enough, then you may find it necessary or convenient (see
  3276. [Wing95], Section 4.1) to write your own trait. This trait would specify the
  3277. additional LSL operators you need to state your procedure's pre- and
  3278. postconditions; it would normally assume the traits describing the abstract
  3279. values of the procedure's argument and result types (see section 2.8 What is
  3280. the difference between assumes and includes?).
  3281.  
  3282. The way you tell your BISL what trait it should use differs between BISLs.
  3283. For example, in LCL and Larch/C++, the keyword that starts the list of
  3284. traits to be used is uses. In Larch/ML, the keyword is using; in Larch/CLU,
  3285. it is based on; in LM3 it is TRAITS; in Larch/Smalltalk it is trait, in
  3286. Larch/Ada it is TRAIT.
  3287.  
  3288. 4.4 What is an abstract value?
  3289.  
  3290. An abstract value is a mathematical abstraction of some bits that might
  3291. exist in your computer. (It's an abstraction in the same sense that a road
  3292. map of the United States is an abstraction of the geography and roads of the
  3293. United States.) In a Larch BISL's model of your computer, each variable
  3294. contains an abstract value. The idea is that, you shouldn't have to reason
  3295. about the bit patterns inside the computer, which are mathematically messy,
  3296. far removed from the concepts that are important in your problem domain, and
  3297. subject to change. Instead, you should reason about your programs using
  3298. simple ideas that are close to your problem and independent of the changing
  3299. details of your program's data structures.
  3300.  
  3301. This idea originated in Hoare's article on specification and verification of
  3302. ADTs [Hoare72a]. Hoare's example used an ADT of small integer sets, which
  3303. were implemented using arrays, but specified using mathematical sets. The
  3304. mathematical sets were thus the abstract values of the arrays used in the
  3305. implementation.
  3306.  
  3307. See [Liskov-Guttag86] and Chapters 3, 5, and 6 of [Guttag-Horning93] for
  3308. more background and information.
  3309.  
  3310. 4.5 What do mutable and immutable mean?
  3311.  
  3312. An object is mutable if its abstract value can change over time. (See
  3313. section 4.4 What is an abstract value? for more about abstract values.) For
  3314. example, most collection types, such as arrays or records in typical
  3315. programming langauges are types with mutable objects.
  3316.  
  3317. By contrast, an object is immutable if its abstract value cannot change. For
  3318. example, the integers are not mutable, as you cannot change the number 3 to
  3319. be 4.
  3320.  
  3321. Typically, immutable objects are atomic and do not contain subobjects, while
  3322. mutable objects often contain subobjects.
  3323.  
  3324. A type with mutable objects is sometimes called an mutable type and a type
  3325. with immutable objects is called an immutable type. The specifications of
  3326. mutable and immutable types differ in that an immutable type cannot have
  3327. operations that mutate objects of that type.
  3328.  
  3329. 4.6 If I specify an ADT in a BISL do I prove it is the same as the trait?
  3330.  
  3331. No, you don't prove the specification of an ADT in a BISL is the same as a
  3332. trait. Those are completely different concepts. An LSL trait specifies a
  3333. theory, not what is to be implemented in a programming language; the BISL is
  3334. what is used to specify an implementation (program module). You use the
  3335. vocabulary in a trait to help specify program modules in a BISL, but there
  3336. is no proof obligation that you engender by doing so. See section 1.1 What
  3337. is Larch? What is the Larch family of specification languages?, and Chapter
  3338. 3 of [Guttag-Horning93], for more on the general idea of two-tiered
  3339. specifications.
  3340.  
  3341. What you might want to prove instead is the correctness of an implementation
  3342. of your ADT specification; for example, if you specify a class Stack in the
  3343. BISL Larch/C++, then you would use an LSL trait to aid the specification
  3344. (see section 1.2 Why does Larch have two tiers?), and implement the class in
  3345. C++. You could then try to prove that your C++ code is correct with respect
  3346. to your Larch/C++ specification. In this proof, you could make use of the
  3347. trait's theory. However, you wouldn't be proving any correspondence between
  3348. the trait and the BISL specification.
  3349.  
  3350. 4.7 What does requires mean?
  3351.  
  3352. In most Larch BISLs(2), the keyword requires introduces a precondition into
  3353. a procedure specification. (This usage dates back to at least Larch/CLU
  3354. [Wing83].)
  3355.  
  3356. A precondition is a predicate that must hold before a the procedure is
  3357. invoked. It documents the obligations of the caller in the contract that is
  3358. being specified. Therefore, it can be assumed to be true in an
  3359. implementation of the procedure, because if it is does not hold when the
  3360. procedure is not obligated to fulfill the contract. This semantics is a
  3361. "disclaimer" semantics [Jackson95] [Khosla-Maibaum87]; it differs from an
  3362. "enabling condition" semantics, which would mean that the procedure would
  3363. not run if called in a state that did not satisfy the precondition.
  3364.  
  3365. As an example, consider the specification of a square root function, which
  3366. is to be written in C (see [Guttag-Horning93], page 2). In this
  3367. specification the precondition is specified by the following line.
  3368.  
  3369.   requires x >= 0;
  3370.  
  3371. This means that if the value of the formal parameter x is not greater than
  3372. or equal to 0, then the specification says nothing about what the
  3373. implementation should do. Thus that case does not have to be considered when
  3374. writing an implementation.
  3375.  
  3376. If the precondition of a procedure is the constant predicate true, the
  3377. entire requires clause can usually be omitted. Such procedures can always be
  3378. called, and an implementation can make no assumptions about the call except
  3379. that the formal parameters will all have whatever types are specified.
  3380. Because such a procedure will have to validate any properties it needs from
  3381. its arguments, it may be safer in the sense of defensive programming.
  3382. However, it may also be slower than one that requires a stronger
  3383. precondition, because it will have to spend time validating its arguments.
  3384. This is a design tradeoff that can be made either way, but documenting
  3385. preconditions in procedure specifications prevents the common performance
  3386. problem of having both the caller and the procedure checking the validity of
  3387. the arguments. (See [Liskov-Guttag86] for more discussion of this issue.)
  3388.  
  3389. A precondition refers to the state just before the specified procedure's
  3390. body is run (but after parameter passing). The term comes from Hoare's
  3391. original paper on program verification [Hoare69], in which each piece of
  3392. program code was described with two predicates: a precondition and a
  3393. postcondition. Both the pre- and the postcondition were predicates on states
  3394. (that is, they can be considered functions that take a state and return a
  3395. boolean). The precondition described the pre-state; that is, it describes
  3396. the values of program variables just before the execution of a piece of
  3397. code. The postcondition described the post-state, which is the state after
  3398. the code's execution. In a Larch BISL the precondition is like this, but the
  3399. postcondition is typically a predicate on both the pre- and the post-state.
  3400. See section 4.8 What does ensures mean?, for more information.
  3401.  
  3402. 4.8 What does ensures mean?
  3403.  
  3404. In most Larch BISLs, the keyword ensures introduces a postcondition into a
  3405. procedure specification. (This usage dates back to at least Larch/CLU
  3406. [Wing83].)
  3407.  
  3408. A postcondition in a Larch BISL is typically a predicate that is defined on
  3409. the pre-state and post-state of a procedure call. (See section 4.7 What does
  3410. requires mean?, for background and terminology.) It documents the
  3411. obligations of the called procedure in the contract that is being specified.
  3412. Therefore, it can be assumed to be true at the end of a call to the
  3413. procedure, when reasoning about the call.
  3414.  
  3415. As an example, consider the following specification of an integer swap
  3416. function which is to be written in C++ (this example is quoted from
  3417. [Leavens97]).
  3418.  
  3419. extern void swap(int& x, int& y) throw();
  3420. //@ behavior {
  3421. //@   requires assigned(x, pre) /\ assigned(y, pre);
  3422. //@   modifies x, y;
  3423. //@   ensures x' = y^ /\ y' = x^;
  3424. //@ }
  3425.  
  3426. In this specification, the parameters x and y are passed by reference, and
  3427. thus each is an alias for a variable in the caller's environment. Because x
  3428. and y denote variables, they can have different values in the pre-state and
  3429. the post-state. The postcondition of the example above says that the pre-
  3430. and post-state values of the variables x and y are exchanged. The notation
  3431. x^ refers to the value of x in the pre-state, and x' refers to its value in
  3432. the post-state. (This Larch/C++ notation is taken from LCL. In LM3 the ^
  3433. notation is not used. In Larch/Smalltalk, the ^ is likewise dropped, and a
  3434. subscript "post" is used instead of '.)
  3435.  
  3436. Depending on the particular BISL, a procedure specification may have one of
  3437. two different interpretations. In most Larch BISLs for sequential
  3438. programming languages, the interpretation is that if the precondition holds,
  3439. then the procedure must terminate normally in a state where the
  3440. postcondition holds. This is called a total correctness interpretation of a
  3441. procedure specification. In Hoare's original paper [Hoare69], and in GCIL
  3442. and Larch/CORBA, a partial correctness interpretation is used. This means
  3443. that if the precondition holds and if the procedure terminates normally,
  3444. then the postcondition must hold. You should check the documentation for
  3445. your BISL to be sure of its semantics on this point. (Larch/C++ is unique in
  3446. that it allows you to specify either interpretation; see [Leavens97],
  3447. Chapter 6).
  3448.  
  3449. 4.9 What does modifies mean?
  3450.  
  3451. In most Larch BISLs, the keyword modifies introduces a list of objects that
  3452. can be modified by an execution of the specified procedure. (This usage
  3453. dates back to Larch/CLU [Wing83].)
  3454.  
  3455. An object is modified if its abstract value is changed by the execution of
  3456. the specified procedure. (That is, if it has a different abstract value in
  3457. the pre-state from the post-state.) Note that the modifies clause does not
  3458. mean that the execution must change the object's abstract values; it simply
  3459. gives the procedure permission to change them. For example, if a swap
  3460. procedure were passed variables with identical values (see section 4.8 What
  3461. does ensures mean?, for the specification of swap), then the values would
  3462. not be changed.
  3463.  
  3464. Note also that a variable's bits may change without a corresponding change
  3465. in abstract value (see section 4.4 What is an abstract value?). For example,
  3466. if one has a rational number object, whose representation uses two integers.
  3467. Let us write the two integers in the representation as (i,j); thus (2,4)
  3468. might be one bit pattern that represents the abstract value 1/2. However,
  3469. changing the bits from (2,4) to (1,2) would not affect the abstract value.
  3470.  
  3471. The modifies clause can be considered syntactic sugar for writing a larger
  3472. predicate in the postcondition. Since only the objects listed in the
  3473. modifies clause can have their abstract values changed by the execution of
  3474. the procedure, all other objects must retain their abstract values. There is
  3475. a problem in artificial intelligence called the "frame problem", which is
  3476. how to know that "nothing else has changed" when you make some changes to
  3477. the world. For this reason, the modifies clause in a Larch BISL can be said
  3478. to specify a frame axiom for the specified procedure. See [Borgida-etal95]
  3479. for a general discussion of the frame problem for procedure specifications.
  3480.  
  3481. In many specification languages, the frame axiom for a procedure
  3482. specification is stated in terms of variable names, but in Larch BISLs it is
  3483. typically stated in terms of objects. The difference is crucial when the
  3484. programming language allows aliasing. If the modifies clause in a Larch BISL
  3485. specified that only certain variable names could change their values, then
  3486. one would typically need to have either prohibit aliasing completely, or one
  3487. would need to write preconditions that prohibited aliases to variables that
  3488. were to be modified in procedures.
  3489.  
  3490. Mentioning an object in a modifies clause should not give the procedure
  3491. being specified permission to deallocate the object. If that were allowed,
  3492. it would lead to problems in the BISL's semantics [Chalin95]
  3493. [Chalin-etal96]. See section 4.10 What does trashes mean?, for more
  3494. information on this topic.
  3495.  
  3496. 4.10 What does trashes mean?
  3497.  
  3498. A trashes clause is similar to a modifies clause (see section 4.9 What does
  3499. modifies mean?) in a procedure specification. It gives the procedure
  3500. permission to deallocate or trash the objects listed. These objects do not
  3501. have to be deallocated or trashed, but no other objects may be deallocated
  3502. or trashed.
  3503.  
  3504. The notion of trashing an object means that its abstract value should not be
  3505. used again. In Larch/C++, allocated variables can be in one of two states:
  3506. assigned or unassigned; a variable is unassigned if it has not been assigned
  3507. a sensible value. However, if one assigns to an assigned variable, a, the
  3508. value of an unassigned variable, then a becomes unassigned, and hence is
  3509. considered to be trashed.
  3510.  
  3511. Chalin [Chalin95] [Chalin-etal96] pointed out that specification of what a
  3512. procedure can modify should be separated from the specification of what it
  3513. can deallocate or trash. When these notions are separated, as they are in
  3514. Larch/C++ (see [Leavens97], chapter 6), there are two frame axioms for
  3515. procedure specifications.
  3516.  
  3517. An alternative to a trashes clause, used in LCL, is to specify input/output
  3518. modes for formal parameters [Evans00]. Some parameter modes do not allow
  3519. trashing, and some do not allow modification.
  3520.  
  3521. 4.11 What does claims mean?
  3522.  
  3523. The claims clause, and other kinds of checkable redundancy for BISLs, were
  3524. introduced into LCL by Tan [Tan94]. In a procedure specification, the
  3525. keyword claims introduces a predicate, called a claim, that, like the
  3526. postcondition, relates the pre- and post-states of a procedure's execution.
  3527. Roughly speaking, the meaning is that the conjunction of the precondition
  3528. and the post condition should imply the claim. This implication can be
  3529. checked, for example, by using LP.
  3530.  
  3531. You could use the claims clause if you wish to highlight some consequences
  3532. of your procedure specification for the reader. It can also be used to help
  3533. debug your understanding of a procedure specification; for example, if you
  3534. think of more than one way to express a postcondition, write all but one way
  3535. in a claims clause. Thus the purpose of this clause is similar to the
  3536. purpose of the implies section of an LSL trait (see section 2.11 When should
  3537. I use an implies section?).
  3538.  
  3539. 4.12 What is the meaning of a specification written in a BISL?
  3540.  
  3541. The exact meaning of a specification in a BISL is, of course, described by
  3542. the reference manual for that particular BISL. But in general, the meaning
  3543. of a BISL specification is a set of program modules that satisfy the
  3544. specification. These program modules are to be written in the programming
  3545. language specified. For example, the meaning of a LCL specification is a set
  3546. of ANSI C program modules that satisfy the specification. Similarly, the
  3547. meaning of a Larch/C++ specification is a set of C++ program modules that
  3548. satisfy the specification; a Larch/C++ specification cannot be implemented
  3549. in, say, Ada or Modula-3.
  3550.  
  3551. How does one describe the satisfaction relation for a BISL? Suppose you want
  3552. to describe satisfaction for the BISL Larch/X, whose programs are to be
  3553. written in language X. Then you describe the satisfaction relation in at
  3554. least the following ways.
  3555.  
  3556.    * Give a semantics for language X, that assigns to each program module,
  3557.      P, a meaning, M(P). Describe, for each specification, S, written in
  3558.      Larch/X, when M(P) is in the set of meanings specified by S.
  3559.    * Develop a verification logic for language X, that says how to check
  3560.      that code satisfies a specification (or some other specification). Then
  3561.      a program module P satisfies a specification S if one can use the
  3562.      verification logic to check that P satisfies S.
  3563.  
  3564. The first technique will probably allow more programs, in principle, to
  3565. satisfy the specification, especially if the semantics of language X covers
  3566. all aspects of the language. The second technique is probably more limiting,
  3567. but is certainly more useful in practice. These techniques are not mutually
  3568. exclusive; for example, a relatively complete verification logic could be
  3569. used as a semantics for that language. Furthermore, by using complimentary
  3570. definitions of the programming language (e.g., a denotational semantics and
  3571. a verification logic), one could prove soundness and completeness results,
  3572. which would help debug each kind of semantics, and thus the semantics of the
  3573. BISL as well.
  3574.  
  3575. See [Wing83] for a semantics of Larch/CLU. See [Jones93] for a semantics of
  3576. LM3. See [Tan94] [Chalin95] for semantics of LCL.
  3577.  
  3578. 4.13 How do I specify something that is finite or partial?
  3579.  
  3580. In a procedure specification, you would normally use a precondition to limit
  3581. the acceptable arguments that the procedure can work with. For example, the
  3582. standard LSL handbook trait Integer (see [Guttag-Horning93], page 163)
  3583. specifies an unbounded set of integers. Many Larch BISLs use this kind of
  3584. unbounded set of integers as their model of a programming language's
  3585. built-in integer type. Suppose that you want to specify an integer
  3586. discriminant function, say to be implemented in C++. In Larch/C++ you could
  3587. specify this as follows.
  3588.  
  3589. extern int discriminant (int a, int b, int c) throw();
  3590. //@ behavior {
  3591. //@   requires inRange((b * b) - (4 * a * c));
  3592. //@   ensures result = (b * b) - (4 * a * c);
  3593. //@ }
  3594.  
  3595. Notice the precondition; it says that the result must be able to be
  3596. represented as an int in the computer (according to the definition of the
  3597. operator inRange, which is defined in a built-in trait of Larch/C++
  3598. [Leavens97]). Without this precondition, the specification could not be
  3599. implemented, because if b were the maximum representable integer, and if a
  3600. and c were 0, then the specification without the precondition would say that
  3601. the execution would have to terminate normally and return an integer larger
  3602. than the maximum representable integer.
  3603.  
  3604. (The specification of descriminant above may not be the best design for the
  3605. procedure, because it requires a precondition that is difficult to test
  3606. without performing the computation specified. See section 4.17 Can you give
  3607. me some tips for specifying things in a BISL?, for more discussion of this
  3608. point.)
  3609.  
  3610. The idea of using preconditions to get around partiality and finiteness
  3611. problems in procedures goes back to Hoare's original paper on program
  3612. verification [Hoare69].
  3613.  
  3614. To specify an ADT with a finite set of values, such as a bounded queue, use
  3615. a trait with unbounded values to specify the abstract values. You can then
  3616. use an invariant in the BISL specification of your ADT to state that the
  3617. size of the abstract values is limited. Most likely the ADT operations that
  3618. construct and mutate objects would need to have preconditions that prevent
  3619. the abstract value from growing too large. This approach is preferred over
  3620. an approach that specifies a finite set of abstract values in LSL, because
  3621. that trait would be more complicated and less likely to be able to be reused
  3622. (see section 2.20 How do I know when my trait is abstract enough?). Even
  3623. with such a trait, you would still need to have preconditions on your
  3624. operations that construct and mutate objects, so there is little gained.
  3625.  
  3626. 4.14 How do I specify errors or error-checking?
  3627.  
  3628. Ways of specifying errors and error checking vary between Larch BISLs,
  3629. depending primarily on whether the programming language that the BISL is
  3630. tailored to has exceptions. In a language without exceptions (like ANSI C),
  3631. a procedure would have to signal an error by producing an error message and
  3632. halting the program, or by returning some error indication to the caller of
  3633. a procedure. If you want to specify that the program halts, most likey you
  3634. will just not include the conditions under which it can do so in your
  3635. precondition (see section 4.13 How do I specify something that is finite or
  3636. partial?). If you want to specify the returning of some error indication (a
  3637. return code, etc.), this is done as if you were specifying any other normal
  3638. result of a procedure. In a language with exceptions (like C++), there is
  3639. the additional option of using the exception handling mechanism to signal
  3640. errors to the caller. The syntax of this varies, but typically you will
  3641. declare the exceptions as usual for the programming language, and there will
  3642. be some special way to indicate in the postcondition that an exception is to
  3643. be raised.
  3644.  
  3645. Many Larch BISLs (including LCL, LM3, Larch/Ada, and Larch/C++) have special
  3646. syntax to support the specification of error checking and signalling
  3647. exceptions. However, there is little common agreement among the various
  3648. Larch BISLs on the syntax for doing so; please check the manual for your
  3649. particular BISL. (See section 1.1 What is Larch? What is the Larch family of
  3650. specification languages?, for how to find your language manual.)
  3651.  
  3652. See [Liskov-Guttag86] for a discussion of the tradeoffs between using
  3653. preconditions and various kinds of defensive programming.
  3654.  
  3655. 4.15 How do I specify that all the values of a type satisfy some property?
  3656.  
  3657. A property that is true for all values of a type is called an invariant.
  3658. Many Larch BISLs have syntax for declaring invariants. For example, LM3 uses
  3659. the keyword TYPE_INVARIANT, and Larch/C++ uses the keyword invariant. The
  3660. predicate following the appropriate keyword has to hold for all objects
  3661. having that type, whenever a client-visible operation of that type is called
  3662. or returns. (This allows the invariant to be violated temporarily within an
  3663. operation implementation.)
  3664.  
  3665. Stating an invariant in the BISL specification of an ADT is often preferable
  3666. to designing an LSL trait so that the abstract values all satisfy the
  3667. property. For example, if you attempt to state such a property as an axiom
  3668. in a trait, you can cause the trait to be inconsistent, if the abstract
  3669. values of your type are freely generated (see section 2.18 What pitfalls are
  3670. there for LSL specifiers?). But invariants in a BISL do not lead to such
  3671. inconsistencies, because they describe properties of objects created by an
  3672. ADT, not properties of all abstract values.
  3673.  
  3674. See section 4.13 How do I specify something that is finite or partial?, for
  3675. more discussion about ways to specify that all values of an ADT are finite.
  3676.  
  3677. 4.16 What pitfalls are there for BISL specifiers?
  3678.  
  3679. The main thing to watch out for in a BISL specification is that you don't
  3680. specify something that cannot be implemented. It's worth repeating the
  3681. following mantra to yourself whenever you write a procedure specification.
  3682.  
  3683.      Could I correctly implement that?
  3684.  
  3685. Of course, you would never intentionally specify a procedure that cannot be
  3686. implemented. So you are only likely to fall into this pit by accident. The
  3687. following are some ways it might happen.
  3688.  
  3689. A very simple problem is forgetting to write a modifies (or trashes) clause
  3690. in a procedure specification when your postcondition calls for some object
  3691. to change state (or be deallocated). Remember that leaving out a modifies
  3692. clause means that no objects can be modified. Consider the following bad
  3693. specification of an increment procedure in Larch/C++. (The formal parameter
  3694. i is passed by reference. The throw() says that no exceptions can be thrown.
  3695. In the precondition, the term assigned(i, pre) is a technical detail; it
  3696. says that i has been previously assigned a value [Leavens97].)
  3697.  
  3698. extern void incBad(int& i) throw();
  3699. //@ behavior {
  3700. //@   requires assigned(i, pre);
  3701. //@   ensures i' = i^ + 1;
  3702. //@ }
  3703.  
  3704. There can be no correct implementation of the above specification, because
  3705. the omitted modifies clause does not allow i to be modified, but the
  3706. postcondition guarantees that it will be modified. This contradiction
  3707. prevents correct implementations.
  3708.  
  3709. A more subtle way that your specification might not be implementable is if
  3710. you forget to specify a necessary precondition. Suppose we fix the above
  3711. specification and produce the following specification of an increment
  3712. function. What's wrong now?
  3713.  
  3714. extern void incStillBad(int& i) throw();
  3715. //@ behavior {
  3716. //@   requires assigned(i, pre);
  3717. //@   modifies i;
  3718. //@   ensures i' = i^ + 1;
  3719. //@ }
  3720.  
  3721. This specification can't be implemented, because if the pre-state value of i
  3722. is the largest int, INT_MAX, then the value INT_MAX+1 can't be stored in it.
  3723. So, as specified, there are no correct implementations. Something has to be
  3724. done to accommodate the finite range of integers that can be stored in i.
  3725. Changing the precondition to be the following would take care of the
  3726. problem.
  3727.  
  3728.   assigned(i, pre) /\ i^ < INT_MAX
  3729.  
  3730. In summary, one thing to watch for is whether you have taken finiteness into
  3731. account. See section 4.13 How do I specify something that is finite or
  3732. partial?, for more about finiteness considerations in BISL specifications.
  3733.  
  3734. Another way that your specification might be unimplementable is if your
  3735. stated postcondition contradicts some invariant property (see section 4.15
  3736. How do I specify that all the values of a type satisfy some property?) that
  3737. you specified elsewhere.
  3738.  
  3739. The following is another Larch/C++ example. The term inRange(e), used in the
  3740. precondition, means that e is within the range of representable integer
  3741. values, hence the specification takes finiteness into account. What else
  3742. could be wrong with the specification?
  3743.  
  3744. extern void transfer(int& source, int& sink, int amt);
  3745. //@ behavior {
  3746. //@   requires assigned(source, pre) /\ assigned(sink, pre) /\ amt >= 0
  3747. //@            /\ inRange(source^ - amt) /\ inRange(sink^ + amt);
  3748. //@   modifies source, sink;
  3749. //@   ensures source' = source^ - amt /\ sink' = sink^ + amt;
  3750. //@ }
  3751.  
  3752. The above specification can't be implemented because it doesn't require that
  3753. source and sink not be aliased. Since both source and sink are passed by
  3754. reference, suppose that both refer to the same variable i. Then if amt is
  3755. nonzero, the postcondition cannot be satisfied. (Suppose the pre-state value
  3756. of i is 10, and that amt is 5, then the post-state must satisfy source' = 10
  3757. - 5 /\ sink' = 10 + 5, but since both source and sink are aliases for i,
  3758. this would require that i' be both 5 and 15, which is impossible.) In
  3759. Larch/C++, this could be fixed by adding the following conjunct to the
  3760. precondition, which requires that source and sink not be aliased.
  3761.  
  3762.   source ~= sink
  3763.  
  3764. Some Larch BISLs (e.g., Larch/Ada) prohibit aliasing in client programs, so
  3765. if you are using such a BISL, then you don't have to worry about this
  3766. particular way of falling in the pit. But if your BISL does not prohibit
  3767. aliasing, then you should think about aliasing whenever you are dealing with
  3768. mutable objects or call-by-reference.
  3769.  
  3770. 4.17 Can you give me some tips for specifying things in a BISL?
  3771.  
  3772. A basic tip for writing a BISL specification is to try to permit as many
  3773. implementations as possible. That is, you want to specify a contract between
  3774. clients and implementors that does everything the client needs, but does not
  3775. impose any unneeded restrictions on the implementation.
  3776.  
  3777. One thing that experienced specifiers think about is whether the
  3778. specification permits implementations to be tested. This is particularly
  3779. important for preconditions. For example, when specifying an ADT, check that
  3780. the ADT has enough operations to allow the pre- and postconditions specified
  3781. to be tested. If you specify a Stack ADT but leave out a test for the empty
  3782. stack, then it will be impossible for a client to test the precondition of
  3783. the pop operation. (However, there are some rare examples, such as a
  3784. statistical database, where you might not want to allow clients to have such
  3785. access.)
  3786.  
  3787. If implementations can be tested, it is often useful to compare the
  3788. difficulty in testing the specified precondition with the difficulty of
  3789. doing the specified computation. For example, in the specification of
  3790. discriminant (see section 4.13 How do I specify something that is finite or
  3791. partial?), checking the precondition is likely to be as difficult as the
  3792. specified computation. In such a case, it may be wise to change the
  3793. specification by weakening the precondition and allowing the procedure to
  3794. signal some kind of error or exception.
  3795.  
  3796. Another tip is to try to use names for operators in traits that are distinct
  3797. from the name of the procedure you are trying to specify (or vice versa).
  3798. For example, the casual reader might incorrectly think that the following
  3799. specification is recursive.
  3800.  
  3801. //@ uses FooTrait;
  3802.  
  3803. extern int foo(int input);
  3804. //@ behavior {
  3805. //@  ensures result = foo(input);
  3806. //@ }
  3807.  
  3808. There is no logical problem with the above example, since the operators used
  3809. in a postcondition cannot have anything to do with the interface procedure
  3810. being specified. However, naive readers of specifications are (in our
  3811. experience) sometimes confused by such details.
  3812.  
  3813. See section 4.16 What pitfalls are there for BISL specifiers?, for pitfalls
  3814. to avoid. See [Liskov-Guttag86] [Meyer97] [Meyer92] for general advice on
  3815. designing and specifying software. See [Wing95] for some other tips on
  3816. formal specification.
  3817.  
  3818. Bibliography
  3819.  
  3820. Please send corrections in this bibliography to
  3821. larch-faq@cs-DOT-iastate-DOT-edu.
  3822.  
  3823. [Baraona-Alexander-Wilsey96]
  3824.      Phillip Baraona, Perry Alexander, and Philip A. Wilsey. Representing
  3825.      Abstract Architectures with Axiomatic Specifications and Activation
  3826.      Conditions. Department of Electrical and Computer Engineering and
  3827.      Computer Science, PO Box 210030, The University of Cincinnati,
  3828.      Cincinnati, OH, April 1996. Available from the URL
  3829.      `http://www.ece.uc.edu/~pbaraona/vspec/papers/fmcad96.ps'.
  3830. [Baraona-Alexander96]
  3831.      Phillip Baraona and Perry Alexander. Abstract Architecture
  3832.      Representation Using VSPEC. Department of Electrical and Computer
  3833.      Engineering and Computer Science, PO Box 210030, The University of
  3834.      Cincinnati, Cincinnati, OH, April 1996. Available from the URL
  3835.      `http://www.ece.uc.edu/~pbaraona/vspec/papers/vspec-arch96.ps'.
  3836. [Baraona-Penix-Alexander95]
  3837.      Phillip Baraona, John Penix, and Perry Alexander. VSPEC: A Declarative
  3838.      Requirements Specification Language for VHDL. In J. M. Berge, O. Levia,
  3839.      and J. Rouilard (eds.), High-Level System Modeling: Specification
  3840.      Languages, pages 51-75. Volume 3 of Current Issues in Electronic
  3841.      Modeling (Kluwer Academic Publishers, June 1995).
  3842. [Baumeister96]
  3843.      Hubert Baumeister. Using Algebraic Specification Languages for
  3844.      Model-Oriented Specifications. Technical Report MPI-I-96-2-003,
  3845.      Max-Planck-Institut fuer Informatik, February 1996. Available from the
  3846.      URL
  3847.      `http://www.mpi-sb.mpg.de/~hubert/MPII-96-2-003.html'.
  3848. [Borgida-etal95]
  3849.      Alex Borgida, John Mylopoulos, and Raymond Reiter. On the Frame Problem
  3850.      in Procedure Specifications. IEEE Transactions on Software Engineering,
  3851.      21(10):785-798, October 1995.
  3852. [Bowen-Hinchey95]
  3853.      J. P. Bowen and M. G. Hinchey. Seven More Myths of Formal Methods. IEEE
  3854.      Software, 12(4):34-41 (July 1995).
  3855. [Bowen-Hinchey95b]
  3856.      J. P. Bowen and M. G. Hinchey. Ten Commandments of Formal Methods. IEEE
  3857.      Computer, 28(4):56-63 (April 1995).
  3858. [Boyer-Moore79]
  3859.      Robert S. Boyer and J Strother Moore. A Computational Logic. Academic
  3860.      Press, 1979.
  3861. [Boyer-Moore88]
  3862.      Robert S. Boyer and J Strother Moore. A Computational Logic Handbook.
  3863.      Academic Press, 1988.
  3864. [Chalin95]
  3865.      Patrice Chalin. On the Language Design and Semantic Foundation of LCL,
  3866.      a Larch/C Interface Specification Language. PhD thesis, Computer
  3867.      Science Department, Concordia University, October 1995. Also Technical
  3868.      Report CU/DCS TR 95-12, which can be obtained from the URL
  3869.      `ftp://ftp.cs.concordia.ca/pub/chalin/tr.ps.Z'.
  3870. [Chalin-etal96]
  3871.      Patrice Chalin, Peter Grogono, and T. Radhakrishnan. Identification of
  3872.      and solutions to shortcomings of LCL, a Larch/C interface specification
  3873.      language. In Marie-Claude Gaudel and James Woodcock (eds.), FME'96:
  3874.      Industrial Benefit and Advances in Formal Methods, pages 385-404.
  3875.      Volume 1051 of Lecture Notes in Computer Science, Springer-Verlag,
  3876.      1996. See also CU/DCS TR 95-04, which can be obtained from the URL
  3877.      `ftp://ftp.cs.concordia.ca/pub/chalin/CU-DCS-TR-95-04.ps.Z'.
  3878. [Chen89]
  3879.      Jolly Chen. The Larch/Generic Interface Language. Bachelor's thesis,
  3880.      Massachusetts Institute of Technology, EECS department, May, 1989.
  3881.      (Available from John Guttag: guttag@lcs.mit.edu.)
  3882. [Cheon-Leavens94]
  3883.      Yoonsik Cheon and Gary T. Leavens. The Larch/Smalltalk Interface
  3884.      Specification Language ACM Transactions on Software Engineering and
  3885.      Methodology, 3(3):221-253 (July 1994).
  3886. [Cheon-Leavens94b]
  3887.      Yoonsik Cheon and Gary T. Leavens. A Gentle Introduction to
  3888.      Larch/Smalltalk Specification Browsers. Department of Computer Science,
  3889.      Iowa State University, TR #94-01, January 1994. Available from the URL
  3890.      `ftp://ftp.cs.iastate.edu/pub/techreports/TR94-01/TR.ps.Z'.
  3891. [Chetali98]
  3892.      Boutheina Chetali. Formal Verification of Concurrent Programs Using the
  3893.      Larch Prover. IEEE Transactions on Software Engineering, 24(1):46-62
  3894.      (Jan., 1998).
  3895. [DeMillo-Lipton79]
  3896.      Richard A. De Millo and Richard J. Lipton and Alan J. Perlis. Social
  3897.      Processes and Proofs of Theorems and Programs. Communications of the
  3898.      ACM, 22(5):271-280 (May 1979).
  3899. [Edwards-etal94]
  3900.      Stephen H. Edwards, Wayne D. Heym, Timothy J. Long, Murali Sitaraman,
  3901.      and Bruce W. Weide. Part II: Specifying Components in RESOLVE. ACM
  3902.      SIGSOFT Software Engineering Notes, 19(4):29-39 (Oct. 1994).
  3903. [Ehrig-Mahr85]
  3904.      Hartmut Ehrig and Bernd Mahr. Fundamentals of Algebraic Specification
  3905.      1: Equations and Initial Semantics. EATCS Monographs on Theoretical
  3906.      Computer Science, volume 6 (Springer-Verlag, NY, 1985).
  3907. [Evans00]
  3908.      David Evans. LCLint User's Guide, Version 2.5, May 2000. Available at
  3909.      the following URL `http://lclint.cs.virginia.edu/guide/'.
  3910. [Feijs-Jonkers92]
  3911.      L. M. G. Feijs and H. B. M. Jonkers. Formal Specification and Design.
  3912.      Volume 35 of Cambridge Tracts in Theoretical Computer Science
  3913.      (Cambridge University Press, Cambridge, UK, 1992).
  3914. [Fetzer88]
  3915.      James H. Fetzer. Program Verification: The Very Idea. Communications of
  3916.      the ACM, 31(9):1048-1063 (Sept. 1988).
  3917. [Finney96]
  3918.      Kate Finney. Mathematical Notation in Formal Specifications: Too
  3919.      Difficult for the Masses? IEEE Transactions on Software Engineering,
  3920.      22(2):158-159 (February 1996).
  3921. [Fitzgerald-Larsen98]
  3922.      John Fitzgerald and Peter Gorm Larsen Modelling Systems: practical
  3923.      tools and techniques in software development. Cambridge University
  3924.      Press, 1998.
  3925. [Futatsugi-etal85]
  3926.      Kokichi Futatsugi, Joseph A. Goguen, Jean-Pierre Jouannaud, and Jose
  3927.      Meseguer. Principles of OBJ2. In Conference Record of the Twelfth
  3928.      Annual ACM Symposium on Principles of Programming Languages, pages
  3929.      52-66 (ACM, January 1985).
  3930. [Garland-Guttag91]
  3931.      S. J. Garland and J. V. Guttag. A Guide to LP, The Larch Prover.
  3932.      Technical Report 82, Digital Equipment Corp, Systems Research Center,
  3933.      130 Lytton Avenue Palo Alto, CA 94301, December, 1991. This is
  3934.      superseded by [Garland-Guttag95].
  3935. [Garland-Guttag-Horning90]
  3936.      Stephen J. Garland, John V. Guttag, and James J. Horning. Debugging
  3937.      Larch Shared Language Specifications. IEEE Transactions on Software
  3938.      Engineering, 16(6):1044-1057 (Sept. 1990). Superseded by Chapter 7 in
  3939.      [Guttag-Horning93].
  3940. [Garland-Guttag95]
  3941.      Stephen J. Garland and John V. Guttag. LP, the Larch Prover. On-line
  3942.      documentation for release 3.1a (MIT Laboratory for Computer Science,
  3943.      April 1995). Available in the LP distribution and from the URL
  3944.      `http://www.sds.lcs.mit.edu/spd/larch/LP/contents.html'.
  3945. [Goguen-etal87]
  3946.      J. Goguen, C. Kirchner, A. Megrelis, J. Meseguer, and T. Winkler. An
  3947.      Introduction to OBJ3. In S. Kaplan and J.-P. Jouannaud (eds.),
  3948.      Conditional Term Rewriting Systems, 1st International Workshop, Orsay,
  3949.      France, pages 258-263. Lecture Notes in Computer Science, Volume 308
  3950.      (Springer-Verlag, NY, 1987).
  3951. [Goguen-Thatcher-Wagner78]
  3952.      J. A. Goguen, J. W. Thatcher, and E. G. Wagner. An Initial Algebra
  3953.      Approach to the Specification, Correctness and Implementation of
  3954.      Abstract Data Types. In Raymond T. Yeh (ed.), Current Trends in
  3955.      Programming Methodology, volume 4, pages 80-149 (Prentice-Hall,
  3956.      Englewood Cliffs, N.J., 1978).
  3957. [Goguen84]
  3958.      J. A. Goguen. Parameterized Programming. IEEE Transactions on Software
  3959.      Engineering, SE-10(5):528-543 (Sept. 1984).
  3960. [Goguen86]
  3961.      J. A. Goguen. Reusing and Interconnecting Software Components IEEE
  3962.      Computer, 19(2):16-28 (February 1986).
  3963. [Gordon-Melham93]
  3964.      M. J. C. Gordon and T. F. Melham. Introduction to HOL: A Theorem
  3965.      Proving Environment for Higher Order Logic. Cambridge University Press,
  3966.      1993.
  3967. [Gries-Schneider95]
  3968.      David Gries and Fred B. Schneider. Avoiding the Undefined by
  3969.      Underspecification. In Jan van Leeuwen (ed.), Computer Science Today:
  3970.      Recent Trends and Developments, pages 366-373. Volume 1000 of Lecture
  3971.      Notes in Computer Science (Springer-Verlag, NY, 1995).
  3972. [Guaspari-Marceau-Polak90]
  3973.      David Guaspari, Carla Marceau, and Wolfgang Polak. Formal Verification
  3974.      of Ada Programs. IEEE Transactions on Software Engineering,
  3975.      16(9):1058-1075 (Sept. 1990). Reprinted in [Martin-Wing93], pages
  3976.      104-141.
  3977. [Guttag-Horning-Modet90]
  3978.      John V. Guttag, J. J. Horning, and Andres Modet. Report on the Larch
  3979.      Shared Language: Version 2.3. Technical Report 58, Digital Equipment
  3980.      Corp, Systems Research Center, 130 Lytton Avenue Palo Alto, CA 94301,
  3981.      April, 1990. Order from src-report@src.dec.com or from the URL
  3982.      `http://www.research.digital.com/SRC/publications/src-rr.html'.
  3983. [Guttag-Horning-Wing85a]
  3984.      J. V. Guttag, J. J. Horning, and J. M. Wing. Larch in Five Easy Pieces.
  3985.      Technical Report 5, Digital Equipment Corp, Systems Research Center,
  3986.      130 Lytton Avenue Palo Alto, CA 94301, July 1985. Superseded by
  3987.      [Guttag-Horning93].
  3988. [Guttag-Horning-Wing85b]
  3989.      John V. Guttag, James J. Horning and Jeannette M. Wing. The Larch
  3990.      Family of Specification Languages. IEEE Software, 2(5):24-36 (Sept.
  3991.      1985).
  3992. [Guttag-Horning78]
  3993.      J. V. Guttag and J. J. Horning. The Algebraic Specification of Abstract
  3994.      Data Types. Acta Informatica, 10(1):27-52 (1978).
  3995. [Guttag-Horning91b]
  3996.      J. V. Guttag and J. J. Horning. A Tutorial on Larch and LCL, a Larch/C
  3997.      Interface Language. In S. Prehn and W. J. Toetenel (eds.), VDM '91
  3998.      Formal Software Development Methods 4th International Symposium of VDM
  3999.      Europe Noordwijkerhout, The Netherlands, Volume 2: Tutorials. Lecture
  4000.      Notes in Computer Science, vol. 552, (Springer-Verlag, NY, 1991), pages
  4001.      1-78.
  4002. [Guttag-Horning93]
  4003.      John V. Guttag and James J. Horning with S.J. Garland, K.D. Jones, A.
  4004.      Modet and J.M. Wing. Larch: Languages and Tools for Formal
  4005.      Specification. Texts and Monographs in Computer Science series
  4006.      (Springer-Verlag, NY, 1993). (The ISBN numbers are 0-387-94006-5 and
  4007.      3-540-94006-5.) This is currently out of print, but a (large)
  4008.      postscript file for the entire book can be obtained from the following
  4009.      URL
  4010.      `http://www.sds.lcs.mit.edu/spd/larch/pub/larchBook.ps'.
  4011.      Appendix A is available separately from the following URLs.
  4012.      `http://www.research.digital.com/SRC/larch/toc.html'
  4013.      `http://www.research.digital.com/SRC/larch/handbook.ps'
  4014. [Guttag75]
  4015.      John V. Guttag. The Specification and Application to Programming of
  4016.      Abstract Data Types. Ph.D. Thesis, University of Toronto, Toronto,
  4017.      Canada, September, 1975.
  4018. [Hall90]
  4019.      Anthony Hall. Seven Myths of Formal Methods. IEEE Software, 7(5):11-19
  4020.      (Sept. 1990).
  4021. [Hayes93]
  4022.      I. Hayes (ed.), Specification Case Studies, second edition
  4023.      (Prentice-Hall, Englewood Cliffs, N.J., 1990).
  4024. [Hoare69]
  4025.      C. A. R. Hoare. An Axiomatic Basis for Computer Programming. Comm. ACM,
  4026.      12(10):576-583 (Oct. 1969).
  4027. [Hoare72a]
  4028.      C. A. R. Hoare. Proof of correctness of data representations. Acta
  4029.      Informatica, 1(4):271-281 (1972).
  4030. [ISO-VDM96]
  4031.      International Standards Organization. Information technology --
  4032.      Programming languages, their environments and system software
  4033.      interfaces -- Vienna Development Method -- Specification Language --
  4034.      Part 1: Base language. Document ISO/IEC 13817-1, December, 1996.
  4035. [Jackson95]
  4036.      Daniel Jackson. Structuring Z Specifications with Views. ACM
  4037.      Transactions on Software Engineering and Methodology, 4(4):365-389
  4038.      (Oct, 1995).
  4039. [Jones90]
  4040.      Cliff B. Jones, Systematic software development using VDM, second
  4041.      edition (Prentice-Hall, Englewood Cliffs, N.J., 1990). Out-of-print,
  4042.      but available on-line at the URL
  4043.      `http://www.cs.ncl.ac.uk/people/cliff.jones/home.formal/research-other.html'
  4044. [Jones91]
  4045.      Kevin D. Jones. LM3: A Larch Interface Language for Modula-3: A
  4046.      Definition and Introduction: Version 1.0. Technical Report 72, Digital
  4047.      Equipment Corp, Systems Research Center, 130 Lytton Avenue Palo Alto,
  4048.      CA 94301, June, 1991. Order from src-report@src.dec.com or from the URL
  4049.      `http://www.research.digital.com/SRC/publications/src-rr.html'.
  4050. [Jones93]
  4051.      Kevin D. Jones. A Semantics for a Larch/Modula-3 Interface Language. In
  4052.      [Martin-Wing93], pages 142-158.
  4053. [Jonkers91]
  4054.      H. B. M. Jonkers. Upgrading the pre- and postcondition technique. In S.
  4055.      Prehn and W. J. Toetenel (eds.), VDM '91 Formal Software Development
  4056.      Methods 4th International Symposium of VDM Europe Noordwijkerhout, The
  4057.      Netherlands, Volume 1: Conference Contributions, volume 551 of Lecture
  4058.      Notes in Computer Science, pages 428-456. Springer-Verlag, NY, 1991.
  4059. [Kaufmann-Moore97]
  4060.      Matt Kaufmann and J S. Moore. An Industrial Strength Theorem Prover for
  4061.      a Logic Based on Common Lisp. IEEE Transactions on Software
  4062.      Engineering, 23(4):203-213 (Apr. 1997).
  4063. [Khosla-Maibaum87]
  4064.      S. Khosla and T. S. E. Maibaum. The Prescription and Description of
  4065.      State Based Systems. In B. Banieqbal, H. Barringer, and A. Puneli
  4066.      (eds.), Temporal Logic in Specification. Volume 398 of Lecture Notes in
  4067.      Computer Science, pages 243-294. Springer-Verlag, NY, 1987.
  4068. [Lamport89]
  4069.      Leslie Lamport. A Simple Approach to Specifying Concurrent Systems.
  4070.      CACM, 32(1):32-45 (Jan. 1989).
  4071. [Leavens97]
  4072.      Gary T. Leavens. Larch/C++ Reference Manual. Version 5.14, October
  4073.      1997. Available in `ftp://ftp.cs.iastate.edu/pub/larchc++/lcpp.ps.gz'
  4074.      or on the world wide web via the URL
  4075.      `http://www.cs.iastate.edu/~leavens/larchc++.html'.
  4076. [Leavens96b]
  4077.      Gary T. Leavens. An Overview of Larch/C++: Behavioral Specifications
  4078.      for C++ Modules. Technical Report TR #96-01d, Department of Computer
  4079.      Science, Iowa State University, Ames, Iowa, 50011, April 1996, revised
  4080.      July 1997. In Haim Kilov and William Harvey, editors, Specification of
  4081.      Behavioral Semantics in Object-Oriented Information Modeling (Kluwer
  4082.      Academic Publishers, 1996), Chapter 8, pages 121-142. TR version
  4083.      available from the URL
  4084.      `ftp://ftp.cs.iastate.edu/pub/techreports/TR96-01/TR.ps.gz'.
  4085. [Leavens-Wing97]
  4086.      Gary T. Leavens and Jeannette M. Wing. Protective Interface
  4087.      Specifications In Michel Bidoit and Max Dauchet (editors), TAPSOFT '97:
  4088.      Theory and Practice of Software Development, 7th International Joint
  4089.      Conference CAAP/FASE, Lille, France, pages 520-534. An extended version
  4090.      is Technical Report TR #96-04d, Department of Computer Science, Iowa
  4091.      State University, Ames, Iowa, 50011, April 1996, revised October,
  4092.      December 1996, February, September 1997. Available from the URL
  4093.      `ftp://ftp.cs.iastate.edu/pub/techreports/TR96-04/TR.ps.gz'.
  4094. [Lerner91]
  4095.      Richard Allen Lerner. Specifying Objects of Concurrent Systems. School
  4096.      of Computer Science, Carnegie Mellon University, CMU-CS-91-131, May
  4097.      1991. Available from the URL
  4098.      `ftp://ftp.cs.cmu.edu/afs/cs.cmu.edu/project/larch/ftp/thesis.ps.Z'.
  4099. [Liskov-Guttag86]
  4100.      Barbara Liskov and John Guttag. Abstraction and Specification in
  4101.      Program Development (MIT Press, Cambridge, Mass., 1986).
  4102. [Loeckx-Ehrich-Wolf96]
  4103.      Jacques Loeckx, Hans-Dieter Ehrich, and Markus Wolf Specification of
  4104.      Abstract Data Types (John Wiley & Sons Ltd and B. G. Teubner, NY,
  4105.      1996).
  4106. [Luchangco-etal94]
  4107.      Victor Luchangco, Ekrem Soylemez, Stephen Garland, and Nancy Lynch.
  4108.      Verifying timing properties of concurrent algorithms. In FORTE'94:
  4109.      Seventh International Conference on Formal Description Techniques for
  4110.      Distributed Systems and Communications Protocols, Berne, Switzerland
  4111.      (Chapman and Hall, Oct. 1994).
  4112. [Martin-Lai92]
  4113.      U. Martin and M. Lai. Some experiments with a completion theorem
  4114.      prover. Journal of Symbolic Computation, 13:81-100 (1992).
  4115. [Martin-Wing93]
  4116.      U. Martin and J. Wing. Proceedings of the First International Workshop
  4117.      on Larch, July 1992. Workshops in Computing series (Springer-Verlag,
  4118.      New York, 1993). (The ISBN is 0-387-19804-0.)
  4119. [Meyer92]
  4120.      Bertrand Meyer. Applying "Design by Contract". Computer, 25(10):40-51
  4121.      (Oct. 1992).
  4122. [Meyer97]
  4123.      Bertrand Meyer. Object-oriented Software Construction, second edition
  4124.      (Prentice-Hall, 1997).
  4125. [Mosses96]
  4126.      Peter D. Mosses (editor). CFI Catalogue: Language Design. May 1996.
  4127.      Available from the URL
  4128.      `http://www.brics.dk/Projects/CFI/Catalogue/2/index.html'.
  4129. [ORA94]
  4130.      Odyssey Research Associates. Penelope Reference Manual, Version 3-3.
  4131.      Informal Technical Report STARS-AC-C001/001/00, September 1994.
  4132.      Available from the URL
  4133.      `http://source.asset.com/WSRD/ASSET/A/874/elements/RefManual.tty'.
  4134. [Owre-etal95]
  4135.      Formal Verification for Fault-tolerant Architectures: Prolegomena to
  4136.      the Deisgn of PVS. Sam Owre, John Rushby, Natarajan Shankar, and
  4137.      Friedrich von Henke. IEEE Transactions on Software Engineering,
  4138.      21(2):107-125 (February 1995). See also the URL
  4139.      `http://www.csl.sri.com/pvs.html'.
  4140. [Paulson94]
  4141.      Lawrence C. Paulson, with contributions by Tobias Nipkow. Isabelle: A
  4142.      Generic Theorem Prover. Volume 828 of Lecture Notes in Computer
  4143.      Science, Springer-Verlag 1994. See also the URL
  4144.      `http://www.cl.cam.ac.uk/Research/HVG/isabelle.html'.
  4145. [Saiedian-etal96]
  4146.      An Invitation to Formal Methods. Hossein Saiedian, et al. IEEE
  4147.      Computer, 29(4):16-30 (April 1996).
  4148. [Saxe-etal92]
  4149.      J. B. Saxe, S. J. Garland, J. V. Guttag, and J. J. Horning. Using
  4150.      transformations and verification in circuit design. International
  4151.      Workshop on Designing Correct Circuits, IFIP Transactions A-5,
  4152.      (North-Holland 1992). Also Technical Report 78, Digital Equipment Corp,
  4153.      Systems Research Center, 130 Lytton Avenue Palo Alto, CA 94301,
  4154.      September 1991.
  4155. [Schmidt86]
  4156.      David A. Schmidt. Denotational Semantics: A Methodology for Language
  4157.      Development (Allyn and Bacon, Inc., Boston, Mass., 1986).
  4158. [Sitaraman-Welch-Harms93]
  4159.      M. Sitaraman, L. R. Welch, and D. E. Harms. On Specification of
  4160.      Reusable Software Components. International Journal of Software
  4161.      Engineering and Knowledege Engineering, 3(2):207-229 (World Scientific
  4162.      Publishing Company, 1993).
  4163. [Sivaprasad95]
  4164.      Gowri Sankar Sivaprasad. Larch/CORBA: Specifying the Behavior of
  4165.      CORBA-IDL Interfaces. Department of Computer Science, Iowa State
  4166.      University, TR #95-27a, December 1995, revised December 1995.
  4167. [Soegaard-Anderson-etal93]
  4168.      J. F. Soegaard-Anderson, S. J. Garland, J. V. Guttag, N. A. Lynch, and
  4169.      A. Pogosyants. Computed-assisted simulation proofs. In Fourth
  4170.      Conference on Computer-Aided Verification, Elounda, Greece, Volume 697
  4171.      of Lecture Notes in Computer Science, pages 305-319 (Springer-Verlag,
  4172.      June 1993).
  4173. [Spivey92]
  4174.      J. Michael Spivey. The Z Notation: A Reference Manual, second edition,
  4175.      (Prentice-Hall, Englewood Cliffs, N.J., 1992).
  4176. [Staunstrup-Garland-Guttag89]
  4177.      J. Staunstrup, S. J. Garland, and J. V. Guttag. Localized verification
  4178.      of circuit descriptions. In Proc. Int. Workshop on Automatic
  4179.      Verification Methods for Finite State Systems, Grenoble, France. Volume
  4180.      407 of Lecture Notes in Computer Science, pages 349-364
  4181.      (Springer-Verlag, 1989).
  4182. [Staunstrup-Garland-Guttag92]
  4183.      J. Staunstrup, S. J. Garland, and J. V. Guttag. Mechanized verification
  4184.      of circuit descriptions using the Larch Prover. In Theorem Provers in
  4185.      Circuit Design. IFIP Transactions A-10, pages 277-299 (North-Holland,
  4186.      June, 1992).
  4187. [Tan94]
  4188.      Yang Meng Tan. Formal Specification Techniques for Promoting Software
  4189.      Modularity, Enhancing Documentation, and Testing Specifications. MIT
  4190.      Lab. for Comp. Sci., TR 619, June 1994. Also published as Formal
  4191.      Specification Techniques for Engineering Modular C Programs.
  4192.      International Series in Software Engineering (Kluwer Academic
  4193.      Publishers, Boston, 1995).
  4194. [Wing-Rollins-Zaremski93]
  4195.      Jeannette M. Wing, Eugene Rollins, and Amy Moormann Zaremski. Thoughts
  4196.      on a Larch/ML and a New Application for LP. In [Martin-Wing93], pages
  4197.      297-312.
  4198. [Wing83]
  4199.      Jeannette Marie Wing. A Two-Tiered Approach to Specifying Programs
  4200.      Technical Report TR-299, Mass. Institute of Technology, Laboratory for
  4201.      Computer Science, 1983.
  4202. [Wing87]
  4203.      Jeannette M. Wing. Writing Larch Interface Language Specifications. ACM
  4204.      Transactions on Programming Languages and Systems, 9(1):1-24 (Jan.
  4205.      1987).
  4206. [Wing90]
  4207.      Jeannette M. Wing. A Specifier's Introduction to Formal Methods.
  4208.      Computer, 23(9):8-24 (Sept. 1990)
  4209. [Wing95]
  4210.      Jeannette M. Wing. Hints to Specifiers. Technical Report,
  4211.      CMU-CS-95-118R, Carnegie Mellon University, School of Computer Science,
  4212.      May 1995. Revision of the paper, "Teaching Mathematics to Software
  4213.      Engineers," Proceedings of AMAST '95, July 1995. Revision available
  4214.      from the URL
  4215.      `http://www.cs.cmu.edu/afs/cs.cmu.edu/project/venari/papers/education/paper.ps'.
  4216.  
  4217. --
  4218.         Department of Computer Science, Iowa State University
  4219.         229 Atanasoff Hall, Ames, Iowa 50011-1040 USA
  4220.         leavens@cs.iastate.edu  phone: +1 515 294-1580 fax: +1 515 294-0258
  4221.         URL: http://www.cs.iastate.edu/~leavens
  4222.