
Lightweight Lemmas in λProlog Andrew W. Appel Amy P. Felty Bell Laboratories and Princeton University Bell Laboratories May 14, 1999 Abstract Def'n λProlog is known to be well-suited for expressing and Lemma implementing logics and inference systems. We show Lemma that lemmas and definitions in such logics can be imple- mented with a great economy of expression. The terms of the meta-language (λProlog) can be used to express the Proof Theorem statement of a lemma, and the type checking of the meta- language can directly implement the type checking of the lemma. The ML-style prenex polymorphism of λProlog EM allows easy expression of polymorphic inference rules, L M A E M C C Logic but a more general polymorphism would be necessary to O A express polymorphic lemmas directly. We discuss both the Terzo and Teyjus implementations of λProlog as well as related systems such as Elf. Trusted code base Figure 1: Lemma machinery is inside the TCB. 1 Introduction It has long been the goal of mathematicians to minimize Definitions and lemmas are essential in constructing the set of assumptions and axioms in their systems. Im- proofs of reasonable size and clarity. A proof system plementers of theorem provers use this principle: they use should have machinery for checking lemmas, and apply- a logic with as few inference rules as possible, and prove ing lemmas and definitions, in the checking of proofs. lemmas outside the core logic in preference to adding new This machinery also is within the TCB; see Figure 1. inference rules. In applications of logic to computer secu- Many theorem-provers support definitions and lemmas rity – such as proof-carrying code [Nec97] and distributed and provide a variety of advanced features designed to authentication frameworks [AF99] – the implementation help with tasks such as organizing definitions and lem- of the core logic is inside the trusted code base (TCB), mas into libraries, keeping track of dependencies, and while proofs need not be in the TCB because they can be providing modularization etc.; in our work we are particu- checked. larly concerned with separating that part of the machinery Two aspects of the core logic are in the TCB: a set of necessary for proof checking (i.e., in the TCB) from the logical connectives and inference rules, and a program in programming-environment support that is used in proof some underlying programming language that implements development. In this paper we will demonstrate a defini- proof-checking – that is, interpreting the inference rules tion/lemma implementation that is about two dozen lines and matching them against a theorem and its proof. of code. 1 kind form type. 2 A core logic kind proof type. The clauses we present use the syntax of the Terzo im- type eq A→A→form. plementation of λProlog [Wic99]. λProlog is a higher- type and form→form→form. type imp form→form→form. order logic programming language which extends Prolog type forall (A→form)→form. in essentially two ways. First, it replaces first-order terms with the more expressive simply-typed λ-terms. Both type proves proof→form→o. Terzo and Teyjus [NM99] (which we discuss later) extend simple types to include ML-style prenex polymorphism infixl and 7. [DM82], which we make use of in our implementation. infixr imp 8. Second, it permits implication and universal quantifica- infix proves 5. tion over objects of any type. We introduce new types and new constants using kind → type assume form o. and type declarations, respectively. For example, a new primitive type t and a new constant f of type t → t → t type initial proof. type and_l form→form→proof are declared as follows: → proof. kind t type. → → type and_r proof proof proof. type f t -> t -> t. type imp_r proof→proof. type imp_l form→form→proof→proof Capital letters in type declarations denote type variables →proof. and are used in representing polymorphic types. In pro- type forall_r (A→proof)→proof. gram goals and clauses, tokens with initial capital letters → → → type forall_l (A form) A proof will denote either bound or free variables. All other to- →proof. kens will denote constants. λ-abstraction is written us- type cut proof→proof→form \ →proof. ing backslash as an infix operator. Universal quantifica- type congr proof→proof tion is written using the constant pi in conjunction with →(A→form)→A→A→proof. a λ-abstraction, eg., pi X\ represents universal quantifi- type refl proof. cation over variable X. The symbols , and => represent conjunction and implication, respectively. The symbol :- denotes the converse of => and is used to write the top- Program 2: Type declarations for core logic. level implication in clauses. The type o is the type of clauses and goals of λProlog. We usually omit universal quantifiers at the top level in definite clauses, and assume implicit quantification over all free variables. The λProlog language [NM88] also has several fea- We will use a running example based on a tiny core tures that allow concise and clean implementation of log- logic of a sequent calculus for a higher-order logic, il- ics, proof checkers, and theorem provers [Fel93]. We use lustrated in Program 2 and 3. We call this the object λProlog [NM88], but the ideas should also be applicable logic to distinguish it from the metalogic implemented by to logical frameworks such as Elf/Twelf [Pfe91, PS99]. λProlog. An important purpose of this paper is to show which To implement assumptions (that is, formulas to the left language features allow a small TCB and efficient rep- of the sequent arrow) we use implication. The goal A => resentation of proofs. We will discuss higher-order ab- B adds clause A to the Prolog clause database, evaluates stract syntax, dynamically constructed clauses, dynam- B, and then (upon either the success or failure of B) re- ically constructed goals, metalevel formulas as terms, moves A from the clause database. It is a dynamically prenex and non-prenex polymorphism, nonparametricity, scoped version of Prolog’s assert and retract.For and type abbreviations. example, suppose we use imp_r(initial) to prove 2 ((eq x y) imp (eq x y)); then λProlog will ex- A,Γ A ecute the (instantiated) body of the imp_r clause: initial proves A :- assume A. assume (eq x y) => Γ A Γ B initial proves (eq x y) Γ A ∧ B (and_r Q1 Q2) proves (A and B) :- This adds assume (eq x y) to the database; then the Q1 proves A, Q2 proves B. subgoal A,Γ B initial proves (eq x y) Γ A → B (imp_r Q) proves (A imp B) :- generates a subgoal assume (eq x y) which assume A => Q proves B. matches our dynamically added clause. A,B,Γ C In our forall_r, forall_l, and congr rules for (A ∧ B),Γ C universal quantification and congruence we take advan- (and_l A B Q) proves C :- tage of λProlog’s higher-order data structures. That is, in assume (A and B), the formula forall A, the term A is a lambda expres- assume A => assume B => Q proves C. sion taking a bound variable and returning a formula; in Γ AB,Γ C this case the bound variable is intended to be the quanti- (A → B),Γ C fied variable. An example of its use is (imp_l A B Q1 Q2) proves C :- forall (X\ forall (Y\ assume (A imp B), Q1 proves A, (eq X Y) imp (eq Y X))) assume B => Q2 proves C. Γ A(Y) for any Y not in the conclusion The parser uses the usual rule for the syntactic extent of a lambda, so this expression is equivalent to Γ ∀x. A(x) (forall_r Q) proves (forall A) :- forall X\ forall Y\ eq X Y imp eq Y X pi Y\ ((Q Y) proves (A Y)). This use of higher-order data structures is called higher- A(T),Γ C order abstract syntax [PE88]; it is very valuable as a (∀x. A(x)), Γ C mechanism for avoiding the need to describe the mechan- (forall_l A T Q) proves C :- ics of substitution explicitly in the object logic [Fel93]. assume (forall A), λ assume (A T) => Q proves C. We have used Prolog’s ML-style prenex polymor- phism to reduce the number of inference rules in the TCB. Γ AA,Γ C Instead of a different forall constructor at each type – C and a corresponding pair of inference rules – we have a (cut Q1 Q2 A) proves C :- single polymorphic forall constructor. Our full core Q1 proves A, logic (not shown in this paper) uses a base type exp of assume A => Q2 proves C. machine integers, and a type exp→exp of functions, Γ X = Z Γ H(Z) so if we desire quantification both at expressions and at Γ H(X) predicates we have already saved one constructor and two (congr Q P H X Z) proves H X :- inference rules! But the user of our logic may wish to Q proves (eq X Z), P proves (H Z). construct a proof that uses universal quantification at an arbitrary higher-order type, so we cannot possibly antic- Γ X = X ipate all the types at which monomorphic forall con- refl proves (eq X X). structors would be needed. Therefore, polymorphism is not just a syntactic convenience – it makes the logic more expressive. Program 3: Inference rules of core logic. 3 We have also used polymorphism to define a general type lemma (A→o)→A→(A→proof)→proof. congruence rule on the eq operator, from which many (lemma Inference Proof Rest) proves C :- other desirable facts (transitivity and symmetry of equal- pi Name\ ity, congruence at specific functions) may be proved as (valid_clause (Inference Name), lemmas.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages15 Page
-
File Size-