* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Post Systems in Programming Languages Pr ecis 1 Introduction
Survey
Document related concepts
Quantum logic wikipedia , lookup
Mathematical logic wikipedia , lookup
Intuitionistic logic wikipedia , lookup
Laws of Form wikipedia , lookup
Intuitionistic type theory wikipedia , lookup
Turing's proof wikipedia , lookup
Mathematical proof wikipedia , lookup
Sequent calculus wikipedia , lookup
Interpretation (logic) wikipedia , lookup
Combinatory logic wikipedia , lookup
Kolmogorov complexity wikipedia , lookup
Law of thought wikipedia , lookup
Propositional calculus wikipedia , lookup
Type safety wikipedia , lookup
Principia Mathematica wikipedia , lookup
Transcript
Post Systems in Programming Languages Precis Ryan Stansifer Department of Computer Sciences University of North Texas Denton, Texas 76203{3886 Internet: [email protected] February 5, 1999 Abstract Post systems are important in the study of programming languages. They are used in axiomatic and natural semantics to formalize the meaning of programming languages. They are also used in describing the type systems of strongly-typed languages. In this paper we put this important formal method in perspective by showing how it is used in many dierent examples. 1 Introduction There are many kinds of formal systems that are relevant to computer science. Grammars are among the most well-known, and they are useful in describing certain aspects of programming languages. Other formal systems are useful in the study of programming languages. For instance, the lambda-calculus is a formal system that is useful for models of programming languages. Deductive formal systems are useful in various capacities in reasoning about programming languages. Deductive systems are rarely presented as grammars; they are more often given as Post systems, named after Emil Post who rst used them. 1.1 Denition of Post system A Post system consists of a list of signs, a list of variables, and a nite set of productions. The signs form the alphabet of the system. A term is a string of signs and variables, a word is a string of signs, and a production is a gure of the form t1 t2 tn t 1 where t, t1 , : : :, tn (n 0) are all terms. The ti are called the premises and t the conclusion of the production. A production without premises (n = 0) is called an axiom. An instance of a production is obtained from a production by substituting strings of signs for all the variables, the same string being substituted for all occurrences of one and the same variable. Given a Post system, we shall dene inductively the notion of a proof of a word. 1. An instance of an axiom is a proof of the conclusion. 2. If Pr1, Pr2, : : :, Prn are proofs of a1 , a2 , : : :, an, respectively, and a1 a2 an a is an instance of a production, then Pr1 Pr2 Prn a is a proof of a. A term is provable in a Post system if we can nd a proof of it. The set of words provable from a Post system forms the language derived by the system. Sometimes it is necessary to consider the language derived by a Post system to be the set of strings from a subset of the signs which are provable. Usually a Post system derives some (not all) strings of a certain form. Strings of this form represent something of interest to the designer of the Post system. We call the strings in the form of interest judgments, following the terminology of Gottlob Frege. Post systems have a lot in common with grammars. Both formal systems derive strings. But there are some important dierences. One of these is the pattern matching capacity of a premise. If a variable appears twice in a premise, then any instance of the production must insert the same string in place of all occurrences of the variable. A single production in a grammar cannot achieve the same result (although the same eect can be achieved in a grammar through a complex collection of productions). A second important dierence between Post systems and grammars results from the multiple premises that a production can have. These permits a sort of conjunction of subtasks. If something can be derived and something else can be derived, then something more can be derived. A production in a Post system does not need to have more than one premise and many do not. It is possible to construct an equivalent Post system without multiple premises for any Post system, a theorem Post himself proved. In summary, Post systems are equivalent to (unrestricted) grammars, but they have dierent facilities that make them appropriate for certain tasks. 1.2 Tally notation We give an example a simple example of a Post system, we call tally notation. The signs we shall use are fN; g. We need just one variable, x. There are two productions: Nx N Nx 2 Clearly this Post system derives the word N . Other words can be derived from N using the second production. An instance of the second production is: N N Here the variable x has been replaced by the empty string. This instance can be used in the proof of N : N N It is easy to see that the tally notation Post system derives strings of the form N : : : . In fact all strings of that form are derivable. We call it tally notation because we can represent all natural numbers with some derivable string: N N N N N 0 1 2 3 4 N 5 1.3 Arithmetic equations Using the tally notation introduced in the example, we can use Post systems to compute many common functions on natural numbers. For example, we can derive all addition equations of the form x + y = z. This Post system uses the variables x, y, and z, and the signs fN; ; +; =g. x+y =z Ny Nx N Nx + y = y x +y = z The last two rules reect the recursive denition of addition in terms of the successor function (concatenating to a string is like adding one). From this Post system correct equations are derivable like 2 + 2 = 4: N N N + = + = + = The numerals in tally notation are also derivable in this Post system. It is easy to ignore these strings, as they are the only strings that begin with the sign N . Multiplication facts can be derived by adding two productions to the Post system for addition: xy =z z+y =w Ny y = x y = w 3 1.4 More examples of Post systems Other interesting Post systems can be built using just a few rules. The MIU system of Hofstadter can be framed in terms of a Post system with ve rules: xI Mx xIIIy xUUy MI xIU Mxx xUy xy This Post system produces strings containing M, I and U. Obviously the string MI is derivable, so is MIU, MII and innitely many other strings. The following is a derivation of the string MUIIU: 1 MI rule 3 MII rule 3 MIIII rule 2 MIIIIU rule 4 MUIU rule 3 MUIUUIU rule MUIIU rule 5 Each step is labeled with the rule used in making the derivation. Using structural induction it is possible to prove properties about the MIU system and other Post systems. For example, all strings derivable in the MIU system have the property that they begin with the symbol M. To show that this property holds of all strings, we prove that it holds of the axioms and prove that all rules preserve this property. Clearly the one axiom derives a string beginning with M. The second rule always derives a string beginning with M. The argument in the case of the other rules is identical. Assuming the hypothesis is a string beginning with the symbol M, then the variable x must begin with M. If x begins with M, then the conclusion of the rules must also begin with M. So, no matter how the string is derived in the MIU system, it must begin with M. Many other questions can be asked about the MIU system. For example, is the string MU derivable? The following theorem states that it is not. Theorem 1 The string MU is not provable in the MIU Post system. The proof is left as an exercise. 1.5 Power of Post systems The power of a formal system can be gauged by comparing it to a particular formal system, Turing machines. It is generally accepted that anything that is computable by some automatic process can be computed with a Turing machine. In fact, Post systems are as powerful as a Turing machines, and hence as powerful as any means of computation. It is relatively easy to show that this is true by simulating a Turing machine with a Post system. In this section we show how this is possible by constructing a Post system for every Turing machine. 4 We consider a Turing machine to be constructed from a nite control, and a potentially innite input tape that is divided into cells. At any given instant the machine is reading a symbol on the tape. We assume that there is a distinguished tape symbol 0, the default tape symbol called the \blank." There may be a nite number of additional tape symbols 1; : : : ; p. The nite control maintains the state of the machine in one of q states 0; : : : ; q . The state 0 is the unique start state. The machine executes a series of moves until the machine enters one of a set of nal states F f0; : : : ; q g. Based on the symbol in the current cell and the current state, a Turing machine writes a new tape symbol on the current cell, moves to the left, or moves to the right and goes into a new state. The language accepted by a Turing machine is the set of those words w in an input alphabet f1; : : : ; pg such that the machine enters a nal state when w 2 is placed with the leftmost symbol as the current cell and the machine starts in the start state 0 . Given a Turing machine TM a Post system can be constructed that derives the same strings accepted by the Turing machine. The following Post system with signs f0; 1; : : : ; p; 0; : : : ; q ; g and variables x, y and z will do the simulation. The productions of the Post system can be divided into four groups: initialization, simulation, boundary conditions, and nalization. The individual rules themselves all depend on the states and symbols of the given Turning machine. The simulation rules depend on the specic moves the Turing machine can make. The initialization productions are: xx x x for 2 x x x x0 The rst initialization production is the only axiom of the entire Post system. This production introduces a marker . A copy of the original input string is kept at all times to the left of the marker. This copy will be kept unchanged while the operation of the TM works on the other copy. The second rule is actually a family of productions, one for each in the input alphabet. A family of productions is not formally a part of Post systems; it is stands for a number of productions that are all related. The purpose of this family of productions to duplicate the input string. Any string in can be generated. The third rule forms the initial conguration of the machine. A conguration is kept by maintaining a copy of a nite portion of the tape and marking the current cell by placing the state symbol just to the left of it. Initially the state symbol is the start symbol of TM . The next set of productions depends on the specic actions TM can take. TM can have one of three types: change the state, move left, and move right. x yij z x yij z x yij Sz for S 2 f0; 1; : : : ; pg x yk l z x yl iz x yiSl z In all cases the state of TM changes from j (one of the states 0; : : : ; q ) to another of the states l . The contents of the current cell on the tape is denoted by i in these rules. For each specic action TM can take, the appropriate production (or productions) is added to 5 the Post system that we are building. For example, if TM moves left when at symbol 3 in state 7 and goes into state 4 , then the production x y34 z x y73z Two additional rules are needed to insure that the blank symbol is found whenever the ends of the tape are reached. x Ty x yT for T 2 f0; : : : ; q g for T 2 f0; : : : ; q g x 0Ty x yT0 If a nal state is reached by TM the input string is accepted. x yfz x for f 2 F We have just provided the construction for the following theorem: Theorem 2 For all Turing machines TM there is a Post system such that if the string s is accepted by TM then s is derivable in the Post system. More generally we have the following theorem: Theorem 3 For all computable functions there is a Post system which computes it. Just exactly what it means for a Post system to compute a function is left unspecied here. The point is that Post systems are as powerful as any formalism, so we need not look for any additional mechanisms for the sake of their power. And secondly, we will not be able to write programs that will decide whether or not a string is derivable from an arbitrary Post system. For if we could, then we could tell if a Turing machine accepts a string or not and this is known to be impossible. 1.6 An ML program for Post systems Since a Post system is a purely symbol manipulating system, it should be possible to write a program to mechanically verify that a derivation follows the rules. We write a simple ML program that performs the verication. The following ML type denitions are used to represent proofs in a Post system. The built-in ML datatype string is used for strings of symbols. This means we take all the ASCII characters as symbols for any Post system we represent in ML. A rule is any function that produces a list of hypotheses and a conclusion given the values for any variables that appear in the rule. ML type denitions for Post systems 6 type Signs = string; type Rule = Signs list -> (Signs list * Signs); datatype Proof = Proof of Proof list * (Signs list * Signs); Consider for example the Post system for tally notation. It has two rules. The rst rule rule1 is an axiom with no variables. Hence the function rule1 expects the empty list as an argument and produces an empty list of hypotheses as well as the constant, conclusion string "N". The function rule2 expects one string, the instance of the variable x, and produces a single hypothesis and the conclusion. Notice that if these functions receive a list as an argument with the wrong number of arguments, a run-time exception is raised indicating the rule is begin misused. The predened ML function implode concatenates a list of strings to form a single string. ML rules and proofs for tally notation fun rule1 [] = (nil, "N"); (* -> "N" *) fun rule2 [x] = (* "N"x -> "N"x"|" *) ([implode ["N", x]], implode ["N", x, "|"]); val p = Proof (nil, rule1 nil); val q = Proof ([p], rule2 [""]); val r = Proof ([q], rule2 ["|"]); (* proof of "N" *) (* proof of "N|" *) (* proof of "N||" *) The ML function verify checks if the derivation in a Post system is correct. It checks that each subproof derives a string that is syntactically identical to the hypothesis required by each application of a rule in the derivation. If so, then verify returns the string derived. If not, then a run-time exception is raised. ML function to verify that proof is well-formed exception not_wf and unequal_hypotheses; fun verify (Proof (p, (h, c))) = let val conc = map verify p (* verify all hypotheses *) in (* number of subproofs must equal number of hypotheses *) if List.length conc <> List.length h then raise unequal_hypotheses (* if any not identical, then proof is not well-formed *) else if exists (op <>) (ListUtil.zip (conc, h)) then raise not_wf else c end; The result of the function verify is the conclusion derived by the proof. We can run verify on the proofs p, q, and r, constructed earlier. The dialog with ML implementation SML-NJ shows that all three proofs are correct derivations of numerals in tally notation. But building a proof with the wrong instance of rule2 is caught. 7 Interaction with SML-NJ - verify val it = - verify val it = - verify val it = - verify p; "N" : Signs q; "N|" : Signs r; "N||" : Signs (Proof ([r], rule2 ["|||"])); uncaught exception not_wf 2 Predicate logic The tradition of axioms and proofs goes back 2000 years, and the search for logical language at least 300 years. But it was not until 1879, when Gottlob Frege's booklet entitled Berisschrift was published, was a systematic and comprehensive theory developed. This theory makes possible the derivation of logical conclusions according to the form of the utterances for most commonly accepted \laws of thought" including quantication. The language of thought is called predicate logic. Then Alfred Tarski stripped the language of any lingering meaning giving rise to the dichotomy between syntax and semantics. The bare language of predicate logic contains a limited number of concepts, although dierent authors use dierent symbols for these concepts. Some of these are listed in the following table. symbol meaning 8 for all 9 exists conjunction & : negation ) implication A calculus for logical thinking like the highly successful calculus of variations for astronomical and physical laws is very desirable. Although Leibnitz and Boole might be disappointed with the result, a successful calculus, the predicate calculus, is the universal system for reasoning with the language of predicate logic. One view of the predicate calculus is called natural deduction. The laws of thought are formulated in a Post system. The ancient law of modus ponens looks like this: ) where and are formulas. The law of modus ponens, or \implication elimination" as it is sometimes called today, expresses the idea that if the formula implies and we know holds, then we can conclude that holds. We can accept or reject this production as we judge most appropriate. This is reminiscent of the Lewis Carroll's clever story \What the Tortoise said to Achilles." In the end the 8 exasperated Achilles remarks that logic will take the Tortoise by the throat and force it to accept the law of modus ponens. What forces us to accept this rule along with the other productions of the predicate calculus is the following theorem. We can derive exactly those formulas in the language of predicate logic that are valid in Tarski's semantics (a notion of truth that is overwhelmingly compelling). Theorem 4 A formula is derivable in the Post system for predicate calculus if, and only if, the formula is valid. This theorem is a great boon. Mechanical derivation can substitute for the more slippery notion of truth. Regrettably, this simple and profoundly important calculus has the following property. Theorem 5 There is no algorithm that can decide if a formula is derivable in the Post system for predicate calculus. This is the challenge of theorem proving: to automatically deduce as many interesting subsets of valid formulas as possible. A Post system for predicate logic is not conceptionally dicult, but to be completely formal requires attention to several unpleasant problems. One of these problems is caused by the variables governed by the existential and universal quantiers. A Post system for a subset of predicate logic, propositional logic, avoids this problem and can be presented in just nine rules so we examine it instead. Propositional logic consists of a collection of propositions P , R, Q, etc., and statements about these propositional symbols using various connectives. For example, : P , P & Q, P ) Q are statements (called formulas) for \not P ," \P and Q," and \P implies Q." We now describe the Post system for propositional logic. The Post system uses the set fP; j; N; C; F; Thg as signs and fx; y; zg as variables. We have two productions for propositions P , Q, R, etc. However, we need a systematic way to name propositions. Picking letters P , Q, R is not uniform, so we instead use P0, P1, P2, etc. Actually we simplify further by using tally notation for the subscripts, so we arrive at the strings P , P , P , etc., as names for propositions. We have two productions for propositions: Px P Px The words of the form Px provable in the Post system are concrete representations of propositions. This set of words is particularly simple. It is just the set fP; P ; P ; : : :g For formulas we have three productions. Fx Fx Fy Px FPx FNx FCxy The words of the form Fx provable in the Post system are concrete representations of formulas of the propositional logic. Strings of the form FNx (where x is a formula), correspond to 9 negated formulas and strings of the form FCxy (where x and y are formulas) correspond to implications. The prex notation is convenient, since no parentheses are required. We use but the two connectives, negation and implication, since all other connectives can be dened from them. For deriving theorems we have four productions. The rst three productions correspond to three \axioms" of propositional logic. Fx Fx Fy Fx Fy Fz ThCCNxxx ThCxCNxy ThCCxyCCyzCxz Curiously these productions are not axioms in the Post system because of the well-formedness conditions that are the premises of the productions. These conditions are needed to ensure that if a term has the form Thx then Fx is a formula. The last production corresponds to modus ponens. ThCxy Thx Thy The rule of inference modus ponens captures the classic law of logic that states: if A implies B is true, and A is true, then it follows that B must be true. In the Post system for propositional logic we have just given, modus ponens is the only way to derive new theorems from other previously derived theorems. A derivation of anything substantial in this Post system is a challenge as it was designed with economy of symbols in mind. The following is an example of a complete derivation of a theorem. P P FP P FNP FP P P P FCNPP FP FP FP ThCCCNPPPCCPP CCNPPP ThCCNPPP ThCCPP CCNPPP Notice that the formulas as well as the theorems are derived by the Post system. In the rst phase (the top of the tree) all the formulas are derived, and then the formulas as used in axioms to derive theorems, nally theorem are combined with the rules of inference (in this case there is only one, modus ponens) to make new theorems. If we omit the the derivations that the formulas are well-formed and use more usual syntax we get a natural deduction proof of the propositional formula of the previous derivation. ((: P ) P ) ) P ) ) ((P ) Q) ) ((: P ) P ) ) Q)) axiom 3 (: P ) P ) ) P (P ) Q) ) ((: P ) P ) ) Q) axiom 1 modus ponens The same proof can be mechanically veried using the ML Post system proof checker. This requires rst that we encode all the nine productions of the propositional logic Post system. Using the ML the type and function denitions introduced already, the system looks like this: 10 ML rules for propositional logic fun rule1 [] = (nil, "P"); fun rule2 [x] = ([implode ["P", x]], implode ["P", x, "|"]); fun rule3 [x] = ([implode ["P", x]], implode ["FP", x]); fun rule4 [x] = ([implode ["F", x]], implode ["FN", x]); fun rule5 [x, y] = ([implode ["F", x], implode ["F", y]], implode ["FC", x, y]); fun ax1 [x] = ([implode ["F", x]], implode ["ThCCN", x, x, x]); fun ax2 [x, y] = ([implode["F",x],implode["F",y]], implode["ThC",x,"CN",x,y]); fun ax3 [x, y, z] = ([implode ["F", x], implode ["F", y], implode ["F", z]], implode ["ThCC", x, y, "CC", y, z, "C", x, z]); fun modus_ponens [x, y] = ([implode ["ThC",x,y], implode ["Th",x]], implode ["Th",y]); We build the proof of the desired theorem one production at a time. The proof (as we have already seen) is a tree, so there is more than one order that can be used. Sometimes a step depends on more than one previous step. The rst step (naturally) depends on no other step. The same proof is sometimes used in more than one subsequent step, e.g., a, and b. In the proof tree we must ll in the same proof again. In the ML program we can simply use the name of the proof as many times as needed. A proof in propositional logic val val val val val val val val val a b c d e f g h i = = = = = = = = = Proof Proof Proof Proof Proof Proof Proof Proof Proof ([], rule1 []); ([a], rule2 [""]); ([a], rule3 [""]); ([b], rule3 ["|"]); ([c], rule4 ["P"]); (* ˜P *) ([e,c], rule5 ["NP", "P"]); (* ˜P => P *) ([f,c,d], ax3 ["CNPP", "P", "P|"]); ([c], ax1 ["P"]); (* |- (˜P=>P) => P *) ([g,h], modus_ponens ["CCNPPP", "CCPP|CCNPPP|"]); These \proofs" are not really proofs until they have been veried. We could verify them at each step using the function verify, or we could verify the whole tree at once by calling verify on the entire proof i. If any step were incorrect, an exception would be raised by verify. Interaction with SML-NJ - verify i; val it = "ThCCPP|CCNPPP|" : Signs 11 3 Axiomatic semantics In the study of programming languages we have a number of problems in which Post systems are a useful way to formalize the solutions. One important problem is describing of formalizing the semantics of programming languages. Following the method Tarski used for the language of predicate logic leads to the denotational semantic approach for programming languages. One way Post systems have been used for describing semantics is the axiomatic approach. The axiomatic approach expresses the eect of a program on the state of the computer using predicate logic as a specication language. We consider a simple, imperative language, the language of while programs described by the following BNF denition: W W W W ::= V := T ::= if B then W else W ::= while B do W end ::= W ; W fi It is important that this language has some parts in common with the specication language. The nonterminal V stands for any of the variables in the specication language. The expressions of this while language, T , are any terms from the language of predicate logic. And we take B to be from the set of quantier-free formulas of the specication language, since these formulas most closely resemble conditional expressions in programming languages. The execution of a construct S in a programming language can be described by the state obtained by executing a program segment starting in some other state. This suggests that we consider triples f P g S f Q g, where P and Q are formulas and S is a piece of code. Constructs of this form are called Hoare triples. We say the triple f P g S f Q g is valid if execution of the program segment S is begun in any state satisfying P , and if S terminates, then it terminates in a state satisfying Q. Valid Hoare triples can be derived using a simple Post system. The rule for the if statement is quite natural. The rule of consequence has a dierent character. This rule injects information from outside Hoare logic. The judgments above the line are not all Hoare triples; two of them are formulas. It appears the rule is useless since we cannot derive formulas, but only Hoare triples. What we mean by the formulas above the line in the rule of consequence is that the rule is applicable only if the two formulas are valid. This is an abuse of the Post system. We could use the Post system for predicate logic as an adjunct to the post system for Hoare logic (although we will want to add arithmetic to it.) But it is easier to pretend there is an oracle that will take care of that part. The signicance of the rule of consequence is that it permits less precise (but more focused) formulas as preconditions and postconditions. In addition, the rule can be used for arithmetic simplication as in y=1+1 ) y=2. It is possible to prove the following important fact about the Hoare calculus: only true Hoare triples can be derived and all true Hoare triples can be derived. Theorem 6 The proof system for the while language is sound and complete. 12 f B & P g S1 f Q g f : B & P g S2 f Q g (conditional rule) f P g if B then S1 else S2 f Q g f P g S1 f Q g f Q g S2 f R g (composition rule) f P g S1 ; S2 f R g f Q[V := T ] g V := T fQg (assignment rule) fB &I g S fI g f I g while B do S end f : B & I g P 0 ) P f P g S f Q g Q ) Q0 f P 0 g S f Q0 g (loop rule) (rule of consequence) Figure 1: The rules for Hoare logic 3.1 A simple proof of correctness Hoare logic can be used to prove the correctness of simple programs. In this section we consider the problem of multiplying two numbers using repeated additions. The following program does this: z := 0; n := y; while n>0 do z:=z+x; n:=n-1 end We want to prove that the following Hoare triple is valid. fy>=0g z:=0; n:=y; while n>0 do z:=z+x; n:=n-1 end fz = x yg Figure 2 shows a derivation of the previous Hoare triple using the rules of Hoare logic. The top of the derivation tree (the leaves) are four instances of the axiom of assignment. The rule of consequence is used three times. Twice the rule is used to strengthen the precondition and once to weaken the postcondition. It is not used in full generality to do both at the same time. 4 Process calculus Robin Milner dened a Post system to describe the fundamental interactions of communicating processes. The calculus is shown in gure 3. The calculus concerns a language 13 f y>=0 & 0=x*(y-y) g z:=0 f y>=0 & z=x*(y-y) g f y>=0 & z=x*(y-y) g n:=y f I g y>=0 ) y>=0 & 0=x*(y-y) f y>=0 & 0=x*(y-y) g z:=0; n:=y f I g f y>=0 g z:=0; n:=y f I g 14 f P g z:=z+x f n-1>=0 & z=x*(y-(n-1)) g f n-1>=0 & z=x*(y-(n-1)) g n:=n-1 f I g n>0 & I ) P f P g z:=z+x; n:=n-1 f I g f n>0 & I g z:=z+x; n:=n-1 f I g f I g while n>0 do z:=z+x; n:=n-1 end f : (n>0) & I g : (n>0) & I ) z=x*y f I g while n>0 do z:=z+x; n:=n-1 end f z=x*y g f y>=0 g z:=0; n:=y f I g f I g while n>0 do z:=z+x; n:=n-1 end f z=x*y g f y>=0 g z:=0; n:=y; while n>0 do z:=z+x; n:=n-1 end f z=x*y g I = P = n>=0 & z=x*(y-n) n-1>=0 & z+x=x*(y-(n-1)) Figure 2: A derivation in Hoare logic :E ! E Act 0 E! E Com1 0 EjF !E jF 0 F! F Com2 EjF ! E j F0 E !l E 0 F !l F 0 Com 3 E j F ! E 0 j F 0 0 Ej ! Ej Pi2I Ei ! E 0 Sumj (for j 2 I ) j 0 E! E Res (; 2= L 0 E \L ! E \L 0 E! E Rel f () 0 E [f ] ! E [f ] Figure 3: The rules for the process calculus which describes labeled transitions. These transitions represent a synchronization between separately executing processing on a named channel. The basic language has ve constructs. prex :E for all actions summation Pi2I Ei composition E1 j E2 restriction E \L where L is a subset of the labels relabeling E [f ] where f is a permutation 15 Act a:E !a E Sum Act 1 a:E + b:0 !a E a:F !a F Com 3 (a:E + b:0) j a:F ! EjF Res ((a:E + b:0) j a:F )\a ! (E j F )\a Act b:0 ! 0 Sum 2 a:E + b:0 !b 0 Com1 (a:E + b:0) j a:F !b 0 j a:F Res ((a:E + b:0) j a:F )\a !b (0 j a:F )\a b Figure 4: Two derivations in the process calculus 5 Natural semantics Another way Post systems are used to describe formal semantics is called natural semantics. We consider a simple functional language we call \mini-ML." The mini-ML language has four constructs: hexpr i ::= hidentier i j (fn hidentier i => hexpr i) (1) j hexpr i hexpr i j if hexpr i then hexpr i else hexpr i This grammar is ambiguous, so we will occasionally use additional parentheses to render the structure of expressions more clearly. Mini-ML has a conditional construct and function application (represented by the juxtaposition of the function and its one argument). Functions of one argument are dened using a syntactic construct of the form (fn hidentier i => hexpr i) where hidentier i is the formal parameter name and hexpr i is the value returned. This expression may contain the formal parameter hence the rst production in the grammar for mini-ML. For example, the identity function in mini-ML is (fn x => x). This language is hopelessly impractical for even small examples, so we add some constants to the syntax whenever convenient. hexpr i ::= : : : j 0 j true j false 16 We can dene the meaning of any mini-ML program by giving the execution of the program, or equivalently how to reduce the program to simplest form. Here are two reduction rules. E ` hexpr i1 7 ! true E ` hexpr i2 7 ! v2 E ` if hexpr i1 then hexpr i2 else hexpr i3 7 ! v2 E ` hexpr i1 7 ! false E ` hexpr i3 7 ! v3 E ` if hexpr i1 then hexpr i2 else hexpr i3 7 ! v3 These rules dene the usual semantics of an if statement. The most important rule concerns applying a function to its argument. E ` hexpr i1 7 ! v1 E; x 7! v1 ` hexpr i2 7 ! v2 E ` (fn x => hexpr i2 ) hexpr i1 7 ! v2 6 Type inference We consider the problem of giving the expressions in mini-ML language types from the following collection: htype i ::= htype variablei j int (2) j bool j htype i -> htype i Besides the two base types int and bool, the type system includes type variables. For type variables we will use the identiers 'a and 'b. The type system also includes the type of functions indicated by the arrow -> between the range and the domain. In mini-ML the polymorphic identity function has type int->int, and type real->real, and type 'a->'a. In fact, it has an innite number of types, all instances of the type 'a->'a. Not all expressions in mini-ML have a type; if they do, they may have more than one. We now consider how to dene the type of an expression in the language mini-ML. The rules for the four constructs are what one would expect. The type of the function application hexpr i1 hexpr i2 is the range of hexpr i1, if type of hexpr i2 is equal to the domain. The type of the conditional construct is the type of hexpr i2 and hexpr i3. Now the type of a variable must somehow be known from context. The type of (fn hidentier i => hexpr i) is more subtle. It is -> where is the type of the domain and is the type of the expression returned by the function. The key is to make this intuition precise and polymorphic. We will dene the collection of types that an expression may assume by giving a Post system. The Post system will separate the \good" strings from the \bad" strings. If the expression does not have a type, then no derivation for the expression will have a conclusion in the set of \good" strings. It is possible that more than one type can be derived for an expression. In this case we say the expression is polymorphic. If it has exactly one type is monomorphic. 17 To give the Post system for types, we require two denitions. First, the strings derived by the type system are called judgments. A typing judgment is a triple of the form A`e: where A is a type assignment, e is an expression, and is a type. In this case, we say \expression e has type under the assignment A." The turnstile symbol ` and the colon are used just to separate the parts. Second, a type assignment, which we shall denote by the letter A, is a set of pairs. It maintains the already established bindings of identiers to their types. A Post system of typing judgments for mini-ML is given by the rules that follow. We begin with the typing rule for the conditional statement: A ` e1 : bool A ` e2 : A ` e3 : A ` (if e1 then e2 else e3 ) : In words this rule says: if e1 has type bool, and e2 and e3 both have the same type (call it ), then the whole if construct has type . We insist that the two branches of the if be reconcilable, otherwise we would have undesirable complications. If the type is e2 is bool and the type e3 is int, what type should the if construct have? We shall derive no type for it and say that it is not typable in the type system (2). The type of an identier x is determined by the context. For this reason a type assignment is necessary. If x has been bound by some fn construct, then x has some value in the assignment A. The value in A is the type of x. This is the content of the next rule in the deductive system. A; x : ` x : By this rule we mean: if x is one of the identiers assigned a type in the type assignment A; x : , then the type of x is ; otherwise the rule does not apply. The following rule is for function denitions: A; x : 1 ` e1 : 2 A ` (fn x => e1) : 1 -> 2 The type assignment denoted by A; x : 1 is just like the assignment A, except that the value for the variable x is the type 1 . This rule is understood to mean that if we can derive that the type of the function body is 2 under the assumption that the formal parameter has type 1 , then the type of the function is 1 ->2 . The following type rule is for the application of the expression e1 to e2. A ` e1 : 2 -> A ` e2 : 2 A ` e1 e2 : The type of the rst expression e1 must be a function. The type of the second expression must be equal to the domain of the type of e1. These rules dene what it means for an expression to have a type in mini-ML. Some typing judgments are derivable in the given Post system, some are not. For example, the 18 typing judgment ; ` (fn x => x) : int->int is derivable. Here ; stands for the empty type assignment, the assignment with no bindings. The fact that the judgment is derivable means that the identity function has type int->int (among others). On the other hand, no typing judgment of the form A ` (fn x => x x) : is derivable no matter what choice is made for the type . This means the expression (fn x => x x) does not have a type in the type system dened for mini-ML by our Post system. Type checking can be viewed as proving theorems in the deductive system dened by the Post system. There is an algorithm or theorem prover for computing the type of expressions. We call the algorithm TypeOf (Milner called it W ). The function TypeOf has two important properties expressed by the following theorems. Theorem 7 If TypeOf(A,e) succeeds with , then A ` e : is derivable from the typing rules. Theorem 8 If A ` e : 0 is derivable from the typing rules, then TypeOf(A,e) succeeds with and 0 is an instance of . The rst theorem insures that any type the function TypeOf nds for an expression is indeed one given by the typing rules. Hence, the algorithm is correct. The second theorem insures that if there is a type for an expression the algorithm will nd it, i.e., the algorithm is complete. Moreover, all the types derivable for an expression are instances of one, most general type. 7 Exercises 1 Dene a Post system for deriving equations of the form x y = z, where x, y, and z are numerals in tally notation, and x y. 2 Add two productions to the following Post system to derive strings of the form n! = m, where n and m are non-negative numbers in tally notation. If the string n! = m is derivable, then m must be the factorial of n. The Post system has signs fN; ; ; !; =g and productions: Nx xy =z Nx N Nx x = x y = xz Give a derivation of ! = . 3 Consider the following Post system. xy = z Nx x y = z Nx N Nx x = x y = xz z The signs of this Post system are fN; ; ; =g and the variables are fx; y; zg. Describe in fewer than ten words the set of words provable in this Post system that contain only the sign (i.e., ignore the words containing the signs fN; ; = g). 19 4 (Herwig Egghart) In the text a Post system was given that derives all addition equations of the form x + y = z. Give a context free grammar that derives the same set of strings. 5 Suppose we intend to augment the Post system that derives all addition equations of the form x + y = z with some production to derive equations of the form w = x + y + z. What is wrong with adding the following rule: x+y =z z+w =u u=x+y+w 6 Consider the Post system over the alphabet f2; ; =g given by the following two rules: x2 = y 2 = x 2 = yxx (a) Show that the set of strings derivable from this Post system is an inductive set by giving a set of atoms and a set of constructor functions. (b) Is the inductive set in part (a) freely generated or not? (c) Prove by induction (on integers) that for any integer i, the string |:{z:i :} 2 = |:{z: :} i2 is derivable from the Post system. (d) Prove by induction that if the string |:{z:i :} 7 8 9 10 2 = |:{z: :} j is derivable in the Post system, then j = i2 . Is MU derivable in the formal system MIU of Hofstadter? Why, or why not? (Hint: No, it is not derivable. Find some property possessed by all axioms of the system, but not by MU. Prove that all the inference rules preserve this property.) Prove that any language denable by a Post system can be dened by an unrestricted grammar, and vice versa. Be sure to use the fact that any Post system can be written without multiple premises and with distinct variables in the premise. Also crucial is the fact that some of the signs in a Post system can be excluded from the terminal strings. In the Post system for propositional logic derive the string ThCPP representing the tautology P ) P . Give a Post system for predicate logic. 20 References [1] John M. Anderson and Henry W. Johnstone, Jr. Natural Deduction: The Logical Basis of Axiom Systems. Wadsworth, Belmont, California, 1962. [2] Lewis Carroll. What the Tortoise said to Achilles. Mind, new series, 4(14):278{280, April 1895. [3] Steven A. Cook. Soundness and completeness of an axiom system for program verication. SIAM Journal on Computing, 7(1):70{90, February 1978. [4] Jacobus Willem de Bakker. Mathematical Theory of Program Correctness. Prentice-Hall International, London, 1980. [5] Peter J. Denning, Jack Bonnell Dennis, and Joseph E. Qualitz. Machines, Languages, and Computation, chapter 14: Post Systems. Prentice Hall, Englewood Clis, New Jersey, 1978. [6] Matthew Hennessy. The Semantics of Programming Languages: an Elementary Introduction Using Structural Operational Semantics. Wiley, Chichester, England, 1990. [7] Charles Antony Richard Hoare. An axiomatic basis for computer programming. Communications of the ACM, 12(10):576{580, 583, October 1969. [8] Douglas R. Hofstadter. Godel, Escher, Bach. Basic Books, New York, 1979. [9] Per Martin-Lof. Notes on Constructive Mathematics. Almqvist & Wiksell, Stockholm, 1970. [10] Robin Milner. A theory of type polymorphism in programming. Journal of Computer and System Sciences, 17(3):348{375, December 1978. [11] Robin Milner. Communication and Concurrency. Prentice-Hall, Englewood Clis, New Jersey, 1989. [12] Marvin L. Minsky. Computation, chapter 13. Prentice-Hall, New York, 1967. [13] Gordon D. Plotkin. A structural approach to operational semantics. Technical Report DAIMI FN-19, Computer Science Department, Aarhus University, Aarhus, Denmark, 1981. [14] Emil L. Post. Finite combinatory processes|formulation I. Journal of Symbolic Logic, 1(3):103{105, September 1936. [15] Emil L. Post. Formal reductions of the general combinatorial decision problem. American Journal Mathematics, 65(2):197{215, April 1943. [16] David A. Schmidt. The Structure of Typed Programming Languages. Foundations of Computing. MIT Press, Cambridge, Massachusetts, 1994. An errata list is available by anonymous ftp at ftp.cis.ksu.edu in the directory pub/CIS/Schmidt/text. 21 [17] Alan Mathison Turing. On computable numbers, with an application to the entscheidungsproblem. Proceedings of the London Mathematical Society, 42(2):230{265, 1936. A correction appeared in volume 43, pages 544{546, 1937. 22