Computation and Deduction

Frank Pfenning Carnegie Mellon University

Draft of April 1, 1997

Draft notes for a course given at Carnegie Mellon University during the fall semester of 1994. Please send comments to fp@cs.cmu.edu. Do not cite, copy, or distribute without the express written consent of Frank Pfenning and the National Football League.

Copyright \begin{matrix}c \\ ◯ \end{matrix} Frank Pfenning 1992–1997 ii

Contents

1 Introduction 1 1.1 The Theory of Programming Languages . . . . . . . . . . . . . . . . 2 1.2 Deductive Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Goals and Approach . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2 The Mini-ML Language 9 2.1 Abstract Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2 Substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3 Operational Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.4 A First Meta-Theorem: Evaluation Returns a Value . . . . . . . . . 17 2.5 The Type System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.6 Type Preservation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.7 Further Discussion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3 Formalization in a Logical Framework 37 3.1 The Simply-Typed Fragment of LF . . . . . . . . . . . . . . . . . . . 38 3.2 Higher-Order Abstract Syntax . . . . . . . . . . . . . . . . . . . . . 40 3.3 Representing Mini-ML Expressions . . . . . . . . . . . . . . . . . . . 45 3.4 Judgments as Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 3.5 Adding Dependent Types to the Framework . . . . . . . . . . . . . . 53 3.6 Representing Evaluations . . . . . . . . . . . . . . . . . . . . . . . . 56 3.7 Meta-Theory via Higher-Level Judgments . . . . . . . . . . . . . . . 63 3.8 The Full LF Type Theory . . . . . . . . . . . . . . . . . . . . . . . . 71 3.9 Canonical Forms in LF . . . . . . . . . . . . . . . . . . . . . . . . . . 74 3.10 Summary and Further Discussion . . . . . . . . . . . . . . . . . . . . 76 3.11 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 4 The Elf Programming Language 81

4.1 Concrete Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 4.2 Type and Term Reconstruction . . . . . . . . . . . . . . . . . . . . . 84 4.3 A Mini-ML Interpreter in Elf . . . . . . . . . . . . . . . . . . . . . . 88 4.4 An Implementation of Value Soundness . . . . . . . . . . . . . . . . 97 4.5 Dynamic and Static Constants . . . . . . . . . . . . . . . . . . . . . 101 4.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

5 Parametric and Hypothetical Judgments 107 5.1 Closed Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 5.2 Function Types as Goals in Elf . . . . . . . . . . . . . . . . . . . . . 118 5.3 Negation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 5.4 Representing Mini-ML Typing Derivations . . . . . . . . . . . . . . . 123 5.5 An Elf Program for Mini-ML Type Inference . . . . . . . . . . . . . 127 5.6 Representing the Proof of Type Preservation . . . . . . . . . . . . . 133 5.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

6 Compilation 145 6.1 An Environment Model for Evaluation . . . . . . . . . . . . . . . . . 146 6.2 Adding Data Values and Recursion . . . . . . . . . . . . . . . . . . . 158 6.3 Computations as Transition Sequences . . . . . . . . . . . . . . . . . 168 6.4 Complete Induction over Computations . . . . . . . . . . . . . . . . 180 6.5 A Continuation Machine . . . . . . . . . . . . . . . . . . . . . . . . . 181 6.6 Relating Relations between Derivations . . . . . . . . . . . . . . . . 192 6.7 Contextual Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . 194 6.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199

7 Natural Deduction 205 7.1 Natural Deduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 7.2 Representation in LF . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 7.3 Implementation in Elf . . . . . . . . . . . . . . . . . . . . . . . . . . 224 7.4 The Curry-Howard Isomorphism . . . . . . . . . . . . . . . . . . . . 229 7.5 Generalization to First-Order Arithmetic . . . . . . . . . . . . . . . 233 7.6 Contracting Proofs to Programs^{∗} . . . . . . . . . . . . . . . . . . . . 239 7.7 Proof Reduction and Computation^{∗} . . . . . . . . . . . . . . . . . . 241 7.8 Termination^{∗} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 7.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241

8 Logic Programming 243 8.1 Uniform Derivations . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 8.2 Canonical Forms for the Simply-Typed λ-Calculus . . . . . . . . . . 255 8.3 Canonical Forms for Natural Deductions . . . . . . . . . . . . . . . . 266 8.4 Completeness of Uniform Derivations . . . . . . . . . . . . . . . . . . 272 8.5 Resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 8.6 Success and Failure Continuations . . . . . . . . . . . . . . . . . . . 286

9 Advanced Type Systems^{∗} 289 9.1 Polymorphism^{∗} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 9.2 Continuations^{∗} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292 9.3 Intersection and Refinement Types^{∗} . . . . . . . . . . . . . . . . . . 292 9.4 Dependent Types^{∗} . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293

10 Equational Reasoning^{∗} 295 10.1 Cartesian Closed Categories^{∗} . . . . . . . . . . . . . . . . . . . . . . 295 10.2 A Church-Rosser Theorem^{∗} . . . . . . . . . . . . . . . . . . . . . . . 295 10.3 Unification^{∗} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

Bibliography 296 vi CONTENTS

Chapter 8

Logic Programming

In pure functional languages computation proceeds by transforming a given expression to a value. Different expression languages and evaluation strategies lead to different programming languages. In this chapter we shift to the computational paradigm of logic programming. In logic programming computation arises from the search for a proof within a logical system. Different logical languages and search strategies lead to different programming languages. The most widely used logic programming language is Prolog. Its pure subset is based on Horn logic, a particularly simple fragment of predicate logic with some attractive theoretical properties. Elf can also be considered as a logic programming language with its formal basis in the LF type theory.

We approach logic programming by studying properties of search procedures for logical systems. Given are a goal formula or query G, a logic program Δ, and a derivability judgment Δ ⊢ G. The procedure attempts to establish if Δ ⊢ G is derivable, that is, if G follows from assumptions Δ within the logical system under consideration. The most important property of a search procedure is soundness: if search succeeds then there must be a derivation of G from Δ. The second property we consider is non-deterministic completeness: if Δ ⊢ G is derivable then the search procedure must be able to establish this. However, these properties alone do not lead to a useful logic programming language. There must also be an underlying intuition about the meaning of the logical connectives and quantifiers as search instructions. Only then will programmers be able to effectively employ a language to implement algorithms.

Logic programming languages are often advertised as declarative. In its most extreme form one would only need to express a problem (declarative specification) and not the strategy for its solution (procedural implementation). This is not only unattainable, but also undesirable. For example, one may specify the concepts of permutation and order, but one still must implement any of a variety of algorithms for sorting, depending on the intended application. A programming language should allow the implementation of specific algorithms and not just specifications. However, we should strive for languages in which algorithms can be expressed at a very high level of abstraction, and logic programming languages provide this for some domains. A valuable related property of logic programming languages is that specifications and implementations can be expressed within the same formal language. We have taken advantage of this in our use of Elf in order to express specifications, implementations, and some aspects of their correctness proofs.

We begin the study of logic programming with the notion of uniform derivation. It arises naturally from an interpretation of the logical quantifiers and connective as search operations. It is easy to see that uniform proofs are sound with respect to natural deduction. Completeness, on the other hand, fails for full intuitionistic logic. By restricting ourselves to a certain fragment we can recover completeness, but the proof is difficult and subject of Sections 8.3 and 8.4.

8.1 Uniform Derivations

By fixing a proof-search strategy for a particular logic, we specify an operational semantics for an associated logic programming language. There is a wide variety of logic programming languages based on different proof-search strategies. We will concentrate on a Prolog-like execution model which is often characterized as “topdown” which unfortunately conflicts with our terminology where such proofs are constructed “bottom-up.” Concurrent logic programming languages and database query languages are just two possible alternatives that we do not explore.

The basic idea behind Prolog’s execution model is goal-directed search. We assume we are given a program as a collection of formulas Δ. The query G is also a formula and the process of computation attempts to find a proof of the query G from the program Δ. We furthermore allow free variables, called logic variables, in the query. These variables are interpreted existentially: computation should simultaneously find a substitution θ for the logic variables and a deduction of [θ] G, the result of applying θ to G. Pure Prolog programs are restricted to consist entirely of Horn clauses, and a goal can only be a conjunction of atoms. Under this restriction the interpretation of logical connectives as search operators is complete, but there are more expressive fragments of the predicate calculus for which goal-directed search remains complete.

In the literature, the process of proof search and thus the operational semantics of Prolog are often described as a form of resolution. This accurately reflects the historical development of logic programming, but it is somewhat narrowly focussed. In particular, for more expressive logics than Horn clauses the view of logic programming as resolution is less helpful. Our perspective will be different: we specify the desired search behavior of the connectives and quantifiers of the logic directly and then analyze which restrictions to the logical language lead to a complete search procedure. This approach is very abstract and ignores many important issues in practical logic programming languages. It provides insight into the foundation of logic programming, similar to the way that an investigation of a pure λ-calculus provides insights into the nature of functional languages.

Since we are considering goal-directed search, we deal with sequents^{1} of the form Γ ⟶ A, that is, sequents where the succedent is a single formula. We refer to A as the goal and to Γ as the program. We factor out the problem of unification and present a system in which existential choices (finding terms t in the description below) are not explicit. After this prelude, we now give conditions that specify the operational reading of connectives and quantifiers when they appear as goals. These conditions can be seen as desirable properties of a judgment Γ ⟶^{u} A which has yet to be defined.

Γ ⟶^{u} A ∧ B iff Γ ⟶^{u} A and Γ ⟶^{u} B
Γ ⟶^{u} A ∨ B iff Γ ⟶^{u} A or Γ ⟶^{u} B
Γ ⟶^{u} ⊤  iff truth (⊤ represents success)
Γ ⟶^{u} ⊥  iff falsehood (⊥ represents failure)
Γ ⟶^{u} A ⊃ B iff Γ, A ⟶^{u} B
Γ ⟶^{u} ∃x. A iff Γ ⟶^{u} [t/x]A for some t
Γ ⟶^{u} ∀x. A iff Γ ⟶^{u} [a/x]A for some new parameter a.

We have omitted a case for negation, since the natural condition,

Γ ⟶^{u} ¬A iff Γ, A ⟶^{u}

involves a sequent with an empty conclusion which is outside our framework. In the intuitionistic calculus we can consider ¬A as an abbreviation for A ⊃ ⊥; thus the absence of negation is not a restriction. Even without any further specifications (that is, how search is to be performed in the case of an atomic goal), we can already see that a strategy based on this specification is not complete for either intuitionistic or classical logic. The three judgments below should all be derivable in the sense that the right-hand side follows from the hypothesis on the left-hand side using intuitionistic natural deduction, but none of them has a uniform derivation.

\begin{matrix}A ∨ B & ⟶^{u} & B ∨ A \\ ∃x. (P (x) ∧ C) & ⟶^{u} & ∃x. P (x) \\ A ∧ (A ⊃ ⊥) & ⟶^{u} & ⊥ \end{matrix}

For example, neither B nor A by themselves can be derived from A∨B: a complete search procedure would have to proceed by analyzing the program before breaking down the structure of the goal.

1[more on the sequent calculus]

We have not yet specified how to interpret atomic goals P (t_{1}, …, t_{n}). In logic programming, this is considered as a procedure call of P with arguments t_{1}, …, t_{n}. In the simplest case we look for a an element of Γ of the form A ⊃ P (t_{1}, …, t_{n}) and then solve the subgoal A. In the more general case, we may also have to instantiate a universal quantifier. For example,

N(0), ∀x. N(x) ⊃ N(s(x)) ⟶ N(s(0))

requires the instantiation of x with 0 before we can reduce the goal N(s(0)) to the subgoal N(0). In order to capture this intuition for the operational interpretation of connectives and quantifiers in programs concisely, we introduce the auxiliary judgment

Γ ⟶^{u} A ≫ P A immediately entails P.

Here, and in the rest of this chapter, we use P to stand for atomic formulas. Immediate entailment is closely related to resolution, a connection explored in Section 8.5. The connection to the basic search judgment is given by the requirement that

Γ ⟶^{u} P iff Γ ⟶^{u} A ≫ P for some A in Γ.

Thus, immediate entailment serves to focus attention on a particular assumption A, rather than allowing arbitrary inferences among different formulas in Γ. We then have the following natural specification.

Γ ⟶^{u} P ≫ P  iff truth (an atomic goal immediately entails itself)
Γ ⟶^{u} A_{1} ∧ A_{2} ≫ P iff Γ ⟶^{u} A_{1} ≫ P or Γ ⟶^{u} A_{2} ≫ P
Γ ⟶^{u} A_{1} ∨ A_{2} ≫ P iff Γ ⟶^{u} A_{1} ≫ P and Γ ⟶^{u} A_{2} ≫ P
Γ ⟶^{u} A_{1} ⊃ A_{2} ≫ P iff Γ ⟶^{u} A_{1} and Γ ⟶^{u} A_{2} ≫ P
Γ ⟶^{u} ⊤ ≫ P  iff falsehood (⊤ has no information)
Γ ⟶^{u} ⊥ ≫ P  iff truth (⊥ immmediately entails everything)
Γ ⟶^{u} ∀x. A ≫ P  iff Γ ⟶^{u} [t/x]A ≫ P for some t
Γ ⟶^{u} ∃x. A ≫ P  iff Γ ⟶^{u} [a/x]A ≫ P for some new parameter a

Note that the requirements for this judgment depend on the uniform derivability judgment (in the case for implication) and vice versa (in the case for atoms).

The relevant requirements above are satisfied in the fragment of the logic that contains only conjunction, implication, truth and universal quantification. We refer to this as the positive fragment of intuitionistic logic.

Positive Formulas A ::= P | A_{1} ∧ A_{2} | A_{1} ⊃ A_{2} | ⊤ | ∀x. A
Programs  Δ ::= · | Δ, D

We capture the operational semantics in two mutual recursive judgments that embody goal-directed search and procedure calls. We model execution of a goal A from program Δ as the bottom-up construction of a derivation of the sequent Δ ⟶^{u} A. Inversion guarantees trivially that the postulated properties for the logical quantifiers and connectives are satisfied.

Δ ⟶^{u} A  Program Δ uniformly entails goal A
Δ ⟶^{u} A ≫ P A immediately entails atom P under Δ

These two mutually recursive judgments are defined by the following inference rules.

\begin{aligned}Δ ⟶^{u} A_{1}  Δ ⟶^{u} A_{2} \\ & S∧ \\ Δ ⟶^{u} A_{1} ∧ A_{2} \end{aligned}  \frac{S⊤}{Δ ⟶^{u} ⊤}

\begin{aligned}Δ, A_{2} ⟶^{u} A_{1} \\ & S⊃ \\ Δ ⟶^{u} A_{2} ⊃ A_{1} \end{aligned}  \begin{aligned}Δ ⟶^{u} [a/x]A_{1} \\ & S∀^{a} \\ Δ ⟶^{u} ∀x. A_{1} \end{aligned}
Δ ⟶^{u} A ≫ P for A in Δ

S atom

Δ ⟶^{u} P

\frac{I atom}{Δ ⟶^{u} P ≫ P}

\begin{aligned}Δ ⟶^{u} A_{1} ≫ P \\ & I∧_{L} \\ Δ ⟶^{u} A_{1} ∧ A_{2} ≫ P \end{aligned}  \begin{aligned}Δ ⟶^{u} A_{2} ≫ P \\ & I∧_{R} \\ Δ ⟶^{u} A_{1} ∧ A_{2} ≫ P \end{aligned}

\begin{aligned}Δ ⟶^{u} A_{1} ≫ P  Δ ⟶^{u} A_{2} \\ & I⊃ \\ Δ ⟶^{u} (A_{2} ⊃ A_{1}) ≫ P \end{aligned} \begin{aligned}Δ ⟶^{u} [t/x]A_{1} ≫ P \\ & I∀ \\ Δ ⟶^{u} ∀x. A_{1} ≫ P \end{aligned}

The rule S∀^{a} is restricted to the case where the parameter a does not occur in Δ or ∀x. A_{1}. We say a sequent Δ ⟶ A has a uniform derivation if there exists a derivation of Δ ⟶^{u} A. In order to emphasize the operational reading of uniform derivation we also refer to a derivtion S :: Δ ⟶^{u} A as the solution of A. As a simple example, we consider a solution of ∀x. N(x) ⊃ N(s(x)) ⟶ N(0) ⊃ N(s(s(0))). We use the abbreviation Δ_{0} for N(0), ∀x. N(x) ⊃ N(s(x)).

\frac{\frac{\frac{\frac{\overline{Δ_{0} ⟶^{u} N(0) ≫ N(0)}}{Δ_{0} ⟶^{u} N(0)} \overline{Δ_{0} ⟶ N(s(0)) ≫ N(s(0))}}{Δ_{0} ⟶^{u} N(0) ⊃ N(s(0)) ≫ N(s(0))}}{Δ_{0} ⟶^{u} ∀x. N(x) ⊃ N(s(x)) ≫ N(s(0))}}{Δ_{0} ⟶^{u} N(s(0))} \overline{Δ_{0} ⟶^{u} N(s(s(0))) ≫ N(s(s(0)))}

Δ_{0} ⟶^{u} N(s(0)) ⊃ N(s(s(0))) ≫ N(s(s(0)))

Δ_{0} ⟶^{u} ∀x. N(x) ⊃ N(s(x)) ≫ N(s(s(0)))

Δ_{0} ⟶^{u} N(s(s(0)))

∀x. N(x) ⊃ N(s(x)) ⟶^{u} N(0) ⊃ N(s(s(0)))

The fundamental theorems regarding uniform derivations on positive formulas are their soundness and completeness with respect to intuitionistic natural deduction.

Theorem 8.1 (Soundness of Uniform Derivations) For any goal A and program Δ,

if Δ ⟶^{u} A then \begin{matrix}Δ \\ D \\ A \end{matrix} .

Proof: We generalize this to:

1. If \begin{matrix}S \\ Δ ⟶^{u} A \end{matrix} then \begin{matrix}Δ \\ D \\ A \end{matrix} ;

2. if \begin{matrix}I \\ Δ ⟶^{u} A ≫ P \end{matrix} then \begin{matrix}Δ, A \\ D \\ P \end{matrix} .

The proof is by straightforward induction over the structures of S and I. We show a few cases. Case:

S = \begin{matrix}I_{1} \\ Δ ⟶^{u} A ≫ P for A in Δ \end{matrix} S atom Δ ⟶^{u} P

By induction hypothesis (2) on I_{1}, \begin{matrix}Δ, A \\ D_{1} \\ P \end{matrix} . Since A is in Δ and assumptions

in hypothetical judgments may be used more than once, we also have \begin{matrix}Δ \\ D_{1} \\ P \end{matrix} .

Case:

I = \begin{aligned}\begin{matrix}I_{1} \\ Δ ⟶^{u} A_{1} ≫ P \end{matrix} & \begin{matrix}S_{2} \\ Δ ⟶^{u} A_{2} \end{matrix} \\ & I⊃ \\ Δ ⟶^{u} (A_{2} ⊃ A_{1}) ≫ P \end{aligned}

By induction hypothesis on I_{1} and S_{2},

\begin{matrix}Δ, A_{1} \\ D_{1} \\ P \end{matrix} and \begin{matrix}Δ \\ D_{2} \\ A_{2} \end{matrix} .

We construct the natural deduction

Δ, \begin{aligned}A_{1} ⊃ A_{1} \begin{matrix}Δ \\ D_{2} \\ A_{2} \end{matrix} \\ & ⊃E \\ A_{1} \end{aligned}

D_{1}

P

which is a derivation of P from hypothesis Δ, A_{2} ⊃ A_{1} as required.

□

Theorem 8.2 (Completeness of Uniform Derivations) For any goal G and program

Δ, if \begin{matrix}Δ \\ D \\ G \end{matrix} then Δ ⟶^{u} G.

Proof: We exploit the canonical form theorem for natural deductions 8.15 and Theorem 8.16 which asserts the completeness with respect to canonical deductions. □

Search for a uniform derivation can be divided into two interlocked phases: goal decomposition and program decomposition. Many choices have been eliminated by a restriction of the language, but there are still various choices to be made during search. In order to obtain a deterministic language, Prolog and related languages make further commitments which are not expressed in the inference rules for uniform derivability. We list the choices that arise in the various phases and show how they are resolved in Prolog and Prolog-like languages.

Conjunctive Choices: Which subgoal of a conjunction should be solved first? Since both have to be solved eventually, this potentially affects efficiency, but not termination unless other choices are also made deterministically. In Prolog, this is referred to as the selection rule. Another form of conjunctive choice arises when the program is an implication. There, we always solve the immediate entailment before solving the subgoal.

Disjunctive Choices: Which program formula D do we pick from the program Δ in order to see if it immediately entails an atomic goal P? This disjunctive choice is eliminated by always trying the formulas from left to right. This is referred to depth-first search for a uniform derivation and is incomplete. Note that this strategy requires that Δ is maintained as a list rather than a multi-set. New assumptions (which arise from implicational goals) are added to the beginning of the program, that is, the most recently made assumption is always tried first. An analogous choice arises when considering a conjunctive program formula. There, too, we try the possibilities from left to right.

Existential Choices: Which term t should be used to instantiate x when the program formula has the form ∀x. D_{1}? This choice is postponed by instantiating x with a logic variable X and determining its value later via unification.

Universal Choices: Which parameter a should be used to instantiate x when solving a goal ∀x. G? This choice is arbitrary as long as the parameter is new, that is, does not already appear in goal or program.

As remarked above, the way non-determinstic choices are eliminated in Prolog is incomplete, that is, search for a provable goal may never terminate. The commonly given reason for this is efficiency of the implementation, but there is a deeper reason. At the point where a search strategy is turned into a logic programming language we must know the precise operational semantics in order to predict the behavior of computation and therefore, for example, the complexity of the implementation of a particular algorithm. The order given above is natural and predictable from the programmers point of view. As a simple example of the incompleteness, consider

p, p ⊃ p ⟶^{u} p

which terminates successfully, and

p ⊃ p, p ⟶^{u} p

which is equivalent in a very strong sense, but does not terminate. Moreover, the various choices listed above interact in unexpected ways. For example, for some approximation to Prolog’s true operational model it may not matter which subgoal of a conjunction is solved first. However, when combined with depth-first search and unification, the order of subgoal selection can become crucial. For example, with the program

∀x. p(x) ⊃ p(x).
p(0).
q(0).

the goal p(X)∧q(X) does not terminate, while q(X)∧p(X) terminates, substituting 0 for X.

One may conclude from this discussion that non-deterministic completeness for a language is not of practical interest. However, it is still important, since it allows us to draw conclusions from failure. For example, the goal corresponding to Peirce’s law ((q ⊃ r) ⊃ q) ⊃ q fails (see page 8.4), and therefore, by completeness, Peirce’s law is not intuitionistically provable.

The implementation of uniform proofs in Elf models pure Prolog’s^{2} choices regarding search faithfully. At a declarative level, the LF specification adequately models uniform proofs. At an operational level, the Elf implementation models Prolog’s search behavior. This is because Elf is in spirit also a logic programming language and the inherent choices are resolved in Elf in a way that is consistent with pure Prolog. This comes close to the often puzzling phenomenon of metacircular interpretation. In some sense, the implementation does not fully specify the semantics of the object language, since different choices for the semantics of the meta-language lead to analogous choices for the object language. Perhaps the most striking example of this is the notion of unification, which seems basic to Prolog, but is not explicit in the system of uniform proofs or their implementation. Elf will simply postpone its own existential choices and solve them by unification; consequently the existential choices in the object language are also postponed and solved by unification.

  solve  : o -> type.       % solve goal formulas
  assume : o -> type.       % assume program formulas
  >>     : o -> p -> type.  % immediate entailment
  %infix none 8 >>

We model the program by hypotheses, so that the rule for implicational goals^{3} employs a hypothetical judgment. Similarly, the premiss of the rule for a universal goal requires a parametric judgment.

  s_and  : solve (A1 and A2)
            <- solve A1

2[some words on pure vs impure]

3[embedded implication—somewhere mention and compare to Prolog]

          <- solve A2.
s_imp  : solve (A2 imp A1)
          <- (assume A2 -> solve A1).
s_true : solve (true).
s_forall : solve (forall A1)
            <- {a:i} solve (A1 a).
s_atom : solve (atom P)
          <- assume A
          <- A >> P.

Program decomposition is even simpler. In the case of a universal program we make the quantification over T explicit, since T can not always be determined from the context.

i_andl : A1 and A2 >> P
           <- A1 >> P.
i_andr : A1 and A2 >> P
           <- A2 >> P.
i_imp  : A2 imp A1 >> P
          <- A1 >> P
          <- solve A2.
i_forall : {T:i}
             forall A1 >> P
             <- A1 T >> P.
i_atom : (atom P) >> P.

As an example, we consider addition for natural numbers. As a pure Prolog program, this might be written as

plus(0,X,X).
plus(s(X),Y,s(Z)) :- plus(X,Y,Z).

Its representation in Elf uses the prog type family. Furthermore, the quantification over X, Y, and Z is made explicit and atoms must be coerced to formulas with the atom constructor.

0 : i.
s : i -> i.
plus : i -> i -> i -> p.
plz : prog (forall [Y] atom (plus 0 Y Y)).
pls : prog (forall [X] forall [Y] forall [Z]
              atom (plus X Y Z) imp atom (plus (s X) Y (s Z))).

The operational behavior of the Elf interpreter on well-typed queries is the behavior of pure Prolog.^{4} For example,

?- solve (atom (plus (s (s 0)) (s (s (s 0))) Z)).
Z = s (s (s (s (s 0)))).
;
no more solutions
?- solve (atom (plus X Y (s (s (s (s 0)))))).
Y = s (s (s (s 0))),
X = 0.
;
Y = s (s (s 0)),
X = s 0.
;
Y = s (s 0),
X = s (s 0).
;
Y = s 0,
X = s (s (s 0)).
;
Y = 0,
X = s (s (s (s 0))).
;
no more solutions

The difference in type-checking is illustrated by the following query which is rejected as ill-typed. Its corresponding incarnation in Prolog would succeed with Z = s.

4One remaining difference is that Prolog unification may construct infinite terms which are not permitted in Elf.

?- solve (atom (plus 0 s Z)).
std_in:1.22-1.23 Error: Type checking failed
s  : i -> i <> i
Unification failure due to clash: -> <> i
caught exception TypeCheckFail

The implementation of the soundness proof for uniform derivations (Theorem 8.1) is most conveniently represented using a functional implementation of the hypothetical judgment its conclusion (2).

s_sound : solve A -> pf A -> type.
h_sound : assume A -> pf A -> type.
i_sound : A >> P -> (pf A -> pf (atom P)) -> type.

The family h_sound is used to associate assumption labels for natural deductions with assumption labels in uniform derivations. In the informal proof, these labels were omitted and the correspondence implicit. First the rules for goals.

ss_and  : s_sound (s_and S2 S1) (andi D2 D1)
           <- s_sound S1 D1
           <- s_sound S2 D2.
ss_imp  : s_sound (s_imp S1) (impi D1)
           <- {d:assume A} {u:pf A}
              h_sound d u -> s_sound (S1 d) (D1 u).
ss_true : s_sound (s_true) (truei).
ss_forall : s_sound (s_forall S1) (foralli D1)
             <- {a:i} s_sound (S1 a) (D1 a).
ss_atom : s_sound (s_atom I2 H1) (D2 D1)
           <- h_sound H1 D1
           <- i_sound I2 D2.

In the last case we use the meta-level application D2 D1 to substitute D1, the assumption label for the member of Δ, for the hypothesis in the conclusion (2). This is an instance of a (trivial) substitution lemma where one assumption label is substituted for another. In the rules below small derivation fragments from a new hypothesis u are substituted for this hypothesis.

is_andl : i_sound (i_andl I1) ([u:pf (A1 and A2)] D1 (andel u))
           <- i_sound I1 D1.

8.2. CANONICAL FORMS FOR THE SIMPLY-TYPED λ-CALCULUS 255

  is_andr : i_sound (i_andr I2) ([u:pf (A1 and A2)] D2 (ander u))
             <- i_sound I2 D2.
  is_imp  : i_sound (i_imp S2 I1) ([u:pf (A2 imp A1)] D1 (impe u D2))
             <- i_sound I1 D1
             <- s_sound S2 D2.
  is_forall : i_sound (i_forall T I1) ([u:pf (forall A1)] D1 (foralle u T))
               <- i_sound I1 D1.
  is_atom : i_sound (i_atom) ([u:pf (atom P)] u).

8.2 Canonical Forms for the Simply-Typed λ-Calculus

The study of completeness for uniform proofs hinges on the notion of canonical natural deduction. We show that every natural deduction in the positive fragment is equivalent to a canonical deduction, and that uniform proofs are sound and complete with respect to canonical deductions. Under the Curry-Howard isomorphism, the definition of canonical deductions can be seen as an extension of the notion of canonical form for the simply-typed λ-calculus from Section 3.9.^{5}

Natural deductions are notationally awkward, so we use proof terms under the Curry-Howard isomorphism to prove the existence of canonical forms in the positive^{6} propositional fragment of natural deduction. This proof can be transliterated to use natural deductions; we only restate the definitions and results in Section 8.3.

The method used in this section is also of independent interest in the study of typed λ-calculi. We extend it to the case of a dependently typed calculus in Section ?? which ultimately yields a proof of non-deterministic completeness for the Elf programming language relative to the LF typing judgment.

Types  A ::= a | A_{1} × A_{2} | A_{1} → A_{2} | 1
Objects M ::= ⟨M_{1}, M_{2}⟩ | fst M | snd M
| x | λx:A. M | M_{1} M_{2}
| ⟨ ⟩

Here, a stands for atomic types and u for variables. A context Γ consists of a sequence of assumptions.

Contexts Γ ::= · | Γ, x:A

5[The proof in the form given here contains a subtle bug which, fortunately, is easy to fix. I am tempted to offer $64 to the first one to find it, but I will refrain from that and simply fix it soon.]

6[terminology?]

As usual, no variable may be declared more than once in a context Γ. The first two judgments define canonical forms.

Γ ⊢ M ⇑ A M is canonical of type A
Γ ⊢ M ↓ A M is atomic of type A

Intuitively, an atomic object consists of a sequence of elimination forms (fst, snd, and application) applied to a variable. Further subobjects must be canonical. A canonical object of a non-atomic type consists of the appropriate introduction construct (⟨·, ·⟩, λ, ⟨ ⟩) with canonical subobjects (if there are any). A canonical object of atomic type must be atomic.

Γ ⊢ M ⇑ A Γ ⊢ N ⇑ B

can pair

Γ ⊢ ⟨M, N⟩ ⇑ A × B

Γ, x:A ⊢ M ⇑ B

can lam Γ ⊢ λx:A. M ⇑ A → B

\frac{can triv}{Γ ⊢ ⟨ ⟩ ⇑ 1}

Γ ⊢ M ↓ a ; can atm ; Γ ⊢ M ⇑ a  Γ(x) = A ; atm var ; Γ ⊢ x ↓ A
Γ ⊢ M ↓ A × B

atm fst

Γ ⊢ fst M ↓ A

Γ ⊢ M ↓ A × B

atm snd

Γ ⊢ snd M ↓ B

Γ ⊢ M ↓ B → A Γ ⊢ N ⇑ B atm app

Γ ⊢ M N ↓ A

It is also possible to represent canonical forms as a property of typing derivations, rather than objects. This is simpler to implement, but difficult to represent typographically. The algorithm for conversion to canonical form is based on the following strategy. When considering an object M of non-atomic type, we obtain canonical forms for the result of applying appropriate elimination rules to M. The resulting canonical forms are then combined with an introduction rule. When the considering an object of atomic type we apply certain local reductions (so-called weak head reductions) until the object has the form of some elimination rules applied to a variable. We then convert the remaining non-canonical subobjects to canonical form.

M ⟶^{whr} M′  M weakly head reduces to M′
Γ ⊢ M ⇑ M′ : A M converts to canonical form M′ at type A
Γ ⊢ M ↓ M′ : A M converts to atomic form M′ at type A

The rules for weak head reduction can be divided into two classes: those applying local reductions (in the sense of Section ??) and partial congruences that allow passing over elimination rules.

\frac{π_{1}}{fst ⟨M, N⟩ ⟶^{whr} M}  \frac{π_{2}}{snd ⟨M, N⟩ ⟶^{whr} N}

\frac{β}{(λx:A. M) N ⟶^{whr} [N/x]M}

M ⟶^{whr} M′ whr fst

fst M ⟶^{whr} fst M′

M ⟶^{whr} M′ whr snd

snd M ⟶^{whr} snd M′

M ⟶^{whr} M′ whr app

M N ⟶^{whr} M′ N

The rules for conversion to canonical and atomic form mutually depend on each other. Note how the rules for canonical form are type-directed, while the rules for atomic form are object-directed.

Γ ⊢ fst M ⇑ M′_{1} : A Γ ⊢ snd M ⇑ M′_{2} : B
tc×
Γ ⊢ M ⇑ ⟨M′_{1}, M′_{2}⟩ : A × B
Γ, x:A ⊢ M x ⇑ M′_{1} : B
tc →
Γ ⊢ M ⇑ (λx:A. M′_{1}) : A → B

\frac{tc1}{Γ ⊢ M ⇑ ⟨ ⟩ : 1}

M ⟶^{whr} M′ Γ ⊢ M′ ⇑ M′′ : a

tc whr

Γ ⊢ M ⇑ M′′ : a

\begin{aligned}Γ ⊢ M ↓ M′ : a \\ & tc atm \\ Γ ⊢ M ⇑ M′ : a \end{aligned}  \begin{aligned}Γ(x) = A \\ & ta var \\ Γ ⊢ x ↓ x : A \end{aligned}
Γ ⊢ M ↓ M′ : A × B

ta fst

Γ ⊢ fst M ↓ fst M′ : A

Γ ⊢ M ↓ M′ : A × B

ta snd

Γ ⊢ snd M ↓ snd M′ : B

Γ ⊢ M ↓ M′ : B → A Γ ⊢ N ⇑ N′ : B ta app

Γ ⊢ M N ↓ M′ N′ : A

It is easy to check that canonical forms are well-typed, and that the result of conversion to canonical form is in fact canonical.

Theorem 8.3 (Conversion Yields Canonical Forms)

1. If Γ ⊢ M ⇑ A then Γ ⊢ M : A;

2. if Γ ⊢ M ↓ A then Γ ⊢ M : A;

3. if Γ ⊢ M ⇑ M′ : A then Γ ⊢ M′ ⇑ A;

4. if Γ ⊢ M ↓ M′ : A then Γ ⊢ M′ ⇑ A.

Proof: By straightforward inductions over the derivation of the assumption. □

The canonical form theorem states that if Γ ⊢ M : A then Γ ⊢ M ⇑ M′ : A for some M′. We prove this by Tait’s method, often called an argument by logical relations or reducibility candidates. In such an argument we construct an interpretation of types as a relation between objects, in our case a unary relation. Assume we are trying to establish a property P of all well-typed objects (in our case, P holds of M if there is an N such that Γ ⊢ M ⇑ N : A). At atomic types the logical relation holds if and only if P itself holds. We then extend it to all types by induction on the structure of types, without further reference to P. For example, pairs are related if their first and second components are related. Functions are related whenever they map related arguments to related results. We then check that (1) at all types, all related objects satisfy the property P, and (2) all welltyped objects are related. These two lemmas together establish that P holds of all well-typed objects.

Often it is sufficient to consider logical relations consisting of only closed objects; here we need to consider objects constructed over various contexts. Thus the interpretation of a type also depends on a context Γ, a construction that has been called a Kripke logical relation. In the definition we need to refer to arbitrary extensions Γ′ of a given context Γ. This is defined by the following two rules.

Γ′ ≥ Γ Γ′ extends Γ

\overline{Γ ≥ Γ}  \frac{Γ′ ≥ Γ}{Γ′, x:A ≥ Γ}

The following weakening lemma is required in the proof of Lemma 8.5.

Lemma 8.4 (Weakening for Conversion to Canonical and Atomic Form)

1. If Γ ⊢ M ⇑ N : A and Γ′ ≥ Γ then Γ′ ⊢ M ⇑ N : A; and

2. if Γ ⊢ M ↓ N : A and Γ′ ≥ Γ then Γ′ ⊢ M ↓ N : A.

Proof: By induction on the structure of the derivations of Γ ⊢ M ⇑ N : A and Γ ⊢ M ↓ N : A.^{7} □

Unfortunately, the question whether a logical relation argument can be represented naturally within LF is an open research issue. This is closely connected to the question whether the logical relation itself can somehow be presented as a judgment defined solely by inference rules. Instead, we make an informal mathematical definition. We write Γ ⊢ M ∈ [[A]] if M satisfies the relation [[A]] in context Γ. This notion is defined by induction on the structure of A.

1. Γ ⊢ M ∈ [[a]] iff Γ ⊢ M ⇑ N : a for some N.

2. Γ ⊢ M ∈ [[A_{1} × A_{2}]] iff Γ ⊢ fst M ∈ [[A_{1}]] and Γ ⊢ snd M ∈ [[A_{2}]].

3. Γ ⊢ M ∈ [[A_{1} → A_{2}]] iff for every Γ′ ≥ Γ and every N, Γ′ ⊢ N ∈ [[A_{1}]] implies Γ′ ⊢ M N ∈ [[A_{2}]].

7[check details]

4. Γ ⊢ M ∈ [[1]].

We have not built in any requirements that the objects in the interpretation we well-typed, but merely that at atomic type, they can be converted to canonical form.

The principal lemmas we need are

1. If Γ ⊢ M ∈ [[A]] then Γ ⊢ M ⇑ N : A.

2. If Γ ⊢ M : A then Γ ⊢ M ∈ [[A]].

Both of these require further non-obvious generalization before they can be proved by induction. Since the definitions of canonical form and atomic form mutually depend on each other, we need to generalize item 1 to include objects convertible to atomic form. Because atomic forms and the logical relation are both based on eliminations, the generalization is surprisingly simple.^{8}

Lemma 8.5 1. If Γ ⊢ M ∈ [[A]] then Γ ⊢ M ⇑ N : A; and

2. if Γ ⊢ M ↓ N : A then Γ ⊢ M ∈ [[A]].

Proof: By induction on A.

Case: A = a.

1. Γ ⊢ M ∈ [[a]]  Assumption
Γ ⊢ M ⇑ N : A  By definition of [[a]]
2. Γ ⊢ M ↓ N : a  Assumption
Γ ⊢ M ⇑ N : a  By rule tc atm
Γ ⊢ M ∈ [[A]]  By definition of [[a]].

Case: A = A_{1} × A_{2}.

1. Γ ⊢ M ∈ [[A_{1} × A_{2}]]  Assumption
Γ ⊢ fst M ∈ [[A_{1}]] and Γ ⊢ snd M ∈ [[A_{2}]]  By definition
Γ ⊢ fst M ⇑ M′_{1} : A_{1} and Γ ⊢ snd M ⇑ M′_{2} : A_{2}  By ind. hyp.
Γ ⊢ M ⇑ ⟨M′_{1}, M′_{2}⟩ : A_{1} × A_{2}  By rule tc×
2. Γ ⊢ M ↓ M′ : A_{1} × A_{2}  Assumption
Γ ⊢ fst M ↓ fst M′ : A_{1}  By rule ta fst
Γ ⊢ fst M ∈ [[A_{1}]]  By ind. hyp. on A_{1}
Γ ⊢ snd M ↓ snd M′ : A_{2}  By rule ta snd
Γ ⊢ snd M ∈ [[A_{2}]]  By ind. hyp. on A_{2}
Γ ⊢ M ∈ [[A_{1} × A_{2}]]  By definition of [[A_{1} × A_{2}]]

8[introduce notion of “reducibility”]

Case: A = A_{1} → A_{2}.

1. Γ ⊢ M ∈ [[A_{1} → A_{2}]]  Assumption
Γ, x:A_{1} ≥ Γ  By definition
Γ, x:A_{1} ⊢ x ↓ x : A_{1}  By rule ta var
Γ, x:A_{1} ⊢ x ∈ [[A_{1}]]  By ind. hyp. (2)
Γ, x:A_{1} ⊢ M x ∈ [[A_{2}]]  By definition of [[A_{1} → A_{2}]]
Γ, x:A_{1} ⊢ M x ⇑ M′ : A_{2}  By ind. hyp. (1)
Γ ⊢ M ⇑ λx:A_{1}. M′ : A_{1} → A_{2}  By rule tc →
2. Γ ⊢ M ↓ M′ : A_{1} → A_{2}  Assumption
Γ′ ≥ Γ and Γ′ ⊢ N ∈ [[A_{1}]]  Assumption
Γ′ ⊢ N ⇑ N′ : A_{1}  By ind. hyp. (1)
Γ′ ⊢ M ↓ M′ : A_{1} → A_{2}  By Weakening
Γ′ ⊢ M N ↓ M′ N′ : A_{2}  By rule ta app
Γ′ ⊢ M N ∈ [[A_{2}]]  By ind. hyp. (2)
Γ ⊢ M ∈ [[A_{1} → A_{2}]]  By definition of [[A_{1} → A_{2}]]
□

The second property we need states that every well-typed term is in the logical relation:

If Γ ⊢ M : A then Γ ⊢ M ∈ [[A]].

The basic idea is to prove this by induction over the typing derivation of Γ ⊢ M : A. However, a direct proof attempt will fail, since during conversion to canonical form we may substitute for variables bound by λ. In general, we must account for a simultaneous substitution for all variables declared in Γ. This leads us to the concept of a well-typed substitution which we develop here briefly.

Substitutions θ ::= · | θ, M/x

We assume that no variable is defined more than once in a substitution and write θ(x) = M if M/x occurs in θ. We refer to the variables defined in a substitution θ as the domain of θ. We also write M_{1}/x_{1}, …, M_{n}/x_{n} for ·, M_{1}/x_{1}, …, M_{n}/x_{n}. Substitutions mimic the structure of contexts so that we can easily define well-typed substitutions.

Δ ⊢ θ : Γ Substitution θ matches Γ in Δ

If Δ ⊢ θ : Γ then θ supplies appropriately typed substitution terms for all variables declared in Γ. The substitution terms can contain the free variables declared in Δ.

\overline{Δ ⊢ · : ·}  \frac{Δ ⊢ θ : Γ  Δ ⊢ M : A}{Δ ⊢ (θ, M/x) : (Γ, x:A)}

We will take great care to apply substitutions only to objects whose free variables are contained in the domain of θ. Assume Γ ⊢ M : A and Δ ⊢ θ : Γ. Then

[θ]M the application of θ to M

is defined inductively on the structure of M.

[θ]⟨M_{1}, M_{2}⟩ = ⟨[θ]M_{1}, [θ]M_{2}⟩
[θ](fst M) = fst ([θ]M)
[θ](snd M) = snd ([θ]M)
[θ]x = θ(x)
[θ](λx:A. M) = λx:A. [θ, x/x]M
[θ](M_{1} M_{2}) = ([θ]M_{1}) ([θ]M_{2})
[θ]⟨ ⟩ = ⟨ ⟩

Well-typed substitutions map well-typed objects to well-typed objects.

Lemma 8.6 (Well-Typed Substitutions) If Γ ⊢ M : A and Δ ⊢ θ : Γ then Δ ⊢ [θ]M : A.

Proof: By induction on the structure of the derivation D :: Γ ⊢ M : A.^{9} □

An important notion in many proofs is the composition of substitution. In our formulation, this can be viewed as applying a substitution to every object in another substitution. Assume Γ ⊢ θ′ : Γ′ and Δ ⊢ θ : Γ. Then we define

[θ]θ′ the composition of θ and θ′

by induction on the structure of θ′.

\begin{aligned}[θ](·) & = & · \\ [θ](θ′, M/x) & = & [θ]θ′, ([θ]M)/x \end{aligned}

Composing well-typed substitutions with matching domain and range leads to well-typed substitutions.

Lemma 8.7 (Composition of Substitutions) If Δ ⊢ θ : Γ and Γ ⊢ θ′ : Γ′ then Δ ⊢ [θ]θ′ : Γ′. Furthermore, for objects M such that Γ′ ⊢ M : A and substitutions θ′′ such that Γ′ ⊢ θ′′ : Γ′′,

\begin{aligned}[[θ]θ′]M & = & [θ]([θ′]M), \\ [[θ]θ′]θ′′ & = & [θ]([θ′]θ′′). \end{aligned}

Proof: By induction on the structure of M and θ′′.^{10} □

9[write out?]

10[write out?]

Given a context Γ = x_{1}:A_{1}, …, x_{n}:A_{n} we define the identity substitution over Γ by id_{Γ} = x_{1}/x_{1}, …, x_{n}/x_{n}. We have the following obvious properties.

Lemma 8.8 (Identity Substitution) If Γ ⊢ M : A then Γ ⊢ [id_{Γ}]M : A. Also, if Γ ⊢ θ′ : Γ′ then Γ ⊢ [id_{Γ}]θ′ : Γ′. Moreover,

\begin{aligned}[id_{Γ}]M & = & M, \\ [id_{Γ}]θ′ & = & θ′. \end{aligned}

We now extend the notion of logical relation to contexts. A substitution θ is in the relation [[Γ]] if for every definition M/x in θ and corresponding declaration x:A in Γ, M is in the relation [[A]].

1. Δ ⊢ · ∈ [[·]].

2. Δ ⊢ θ′ ∈ [[Γ, x:A]] iff θ′ = (θ, M/x), Δ ⊢ θ ∈ [[Γ]] and Δ ⊢ M ∈ [[A]].

Lemma 8.9 (Weakening for Logical Relations)

1. If Δ ⊢ M ∈ [[A]] and Δ′ ≥ Δ then Δ′ ⊢ M ∈ [[A]].

2. If Δ ⊢ θ ∈ [[Γ]] and Δ′ ≥ Δ then Δ′ ⊢ θ ∈ [[Γ]].

Proof: ^{11} □

Lemma 8.10 (Closure under Head Expansion) If Γ ⊢ M′ ∈ [[A]] and M ⟶^{whr} M′ then Γ ⊢ M ∈ [[A]].

Proof: By induction on A.

Case: A = a.

Γ ⊢ M′ ∈ [[a]]  Assumption
Γ ⊢ M′ ⇑ M′′ : a  By Lemma 8.5
M ⟶^{whr} M′  Assumption
Γ ⊢ M ⇑ M′′ : a  By rule tc whr
Γ ⊢ M ∈ [[a]]  By definition of [[a]]

Case: A = A_{1} × A_{2}.

11[skip, exercise, or fill in]

Γ ⊢ M′ ∈ [[A_{1} × A_{2}]]  Assumption
Γ ⊢ fst M′ ∈ [[A_{1}]]  By definition of [[A_{1} × A_{2}]]
fst M ⟶^{whr} fst M′  By rule whr fst
Γ ⊢ fst M ∈ [[A_{1}]]  By ind. hyp. on A_{1}
Γ ⊢ snd M′ ∈ [[A_{2}]]  By definition of [[A_{1} × A_{2}]]
snd M ⟶^{whr} snd M′  By rule whr snd
Γ ⊢ snd M ∈ [[A_{2}]]  By ind. hyp. on A_{2}
Γ ⊢ M ∈ [[A_{1} × A_{2}]]  By definition of [[A_{1} × A_{2}]]

Case: A = A_{1} → A_{2}.

Γ ⊢ M′ ∈ [[A_{1} → A_{2}]]  Assumption
Γ′ ⊢ N ∈ [[A_{1}]] for Γ′ ≥ Γ  Assumption
Γ′ ⊢ M′ N ∈ [[A_{2}]]  By definition of [[A_{1} → A_{2}]]
M N ⟶^{whr} M′ N  By rule whr app
Γ′ ⊢ M N ∈ [[A_{2}]]  By ind. hyp. on A_{2}
Γ ⊢ M ∈ [[A_{1} → A_{2}]]  By definition of [[A_{1} → A_{2}]]

Case: A = 1. The Γ ⊢ M ∈ [[1]] by definition of [[1]].

□

We can now generalize the central lemma appropriately to all substitution instances of M. Using the identity substitution for θ yields the desired theorem.

Lemma 8.11 If Γ ⊢ M : A then for any Δ ⊢ θ ∈ [[Γ]], Δ ⊢ [θ]M ∈ [[A]].

Proof: By induction on the structure of D :: Γ ⊢ M : A.

Case:

D = \begin{aligned}Γ(x) = A \\ & tp var. \\ Γ ⊢ x : A \end{aligned}

Δ ⊢ θ ∈ [[Γ]]  Assumption
[θ]M = [θ]x = θ(x) ∈ [[A]]  By definition of [[Γ]]

Case:

D = \begin{matrix}D_{1} \\ Γ ⊢ M_{1} : A_{1} \end{matrix} \begin{matrix}D_{2} \\ Γ ⊢ M_{2} : A_{2} \end{matrix} tp pair. Γ ⊢ ⟨M_{1}, M_{2}⟩ : A_{1} × A_{2}

Δ ⊢ [θ]M_{1} ∈ [[A_{1}]]  By ind. hyp. on D_{1}
Δ ⊢ fst ⟨[θ]M_{1}, [θ]M_{2}⟩ ∈ [[A_{1}]]  By closure under head expansion
Δ ⊢ fst [θ]⟨M_{1}, M_{2}⟩ ∈ [[A_{1}]]  By definition of substitution
Δ ⊢ [θ]M_{2} ∈ [[A_{2}]]  By ind. hyp. on D_{2}
Δ ⊢ snd ⟨[θ]M_{1}, [θ]M_{2}⟩ ∈ [[A_{2}]]  By closure under head expansion
Δ ⊢ snd [θ]⟨M_{1}, M_{2}⟩ ∈ [[A_{2}]]  By definition of substitution
Δ ⊢ [θ]⟨M_{1}, M_{2}⟩ ∈ [[A_{1} × A_{2}]]  By definition of [[A_{1} × A_{2}]]

Case:

D = \begin{matrix}D_{1} \\ Γ ⊢ M_{1} : A_{1} × A_{2} \end{matrix} tp fst. Γ ⊢ fst M_{1} : A_{1}

Δ ⊢ [θ]M_{1} ∈ [[A_{1} × A_{2}]]  By ind. hyp. on D_{1}
Δ ⊢ fst ([θ]M_{1}) ∈ [[A_{1}]]  By definition of [[A_{1} × A_{2}]]
Δ ⊢ [θ](fst M_{1}) ∈ [[A_{1}]]  By definition of substitution

Case: D ends in tp snd. Dual to the previous case. Case:

D = \begin{matrix}D_{1} \\ Γ, x:A_{1} ⊢ M_{2} : A_{2} \end{matrix} ; tp lam. ; Γ ⊢ λx:A_{1}. M_{2} : A_{1} → A_{2}

We need to show that Δ ⊢ [θ](λx:A_{1}. M_{2}) ∈ [[A_{1} → A_{2}]].

Δ′ ≥ Δ and Δ′ ⊢ N ∈ [[A_{1}]]  Assumption
Δ′ ⊢ (θ, N/x) ∈ [[Γ, x:A_{1}]]  By definition and weakening of [[ ]]
Δ′ ⊢ [θ, N/x]M_{2} ∈ [[A_{2}]]  By ind. hyp. on D_{1}
Δ′ ⊢ [id_{Δ′}, N/x]([θ, x/x]M_{2}) ∈ [[A_{2}]]  By composition of substitutions
Δ′ ⊢ (λx:A_{1}. [θ, x/x]M_{2}) N ∈ [[A_{2}]]  By closure under head expansion
Δ′ ⊢ ([θ](λx:A_{1}. M_{2})) N ∈ [[A_{2}]]  By definition of substitution
Δ ⊢ [θ](λx:A_{1}. M_{2}) ∈ [[A_{1} → A_{2}]]  By definition of [[A_{1} → A_{2}]]

Case:

D = \begin{matrix}D_{1} \\ Γ ⊢ M_{1} : A_{2} → A_{1} \end{matrix} \begin{matrix}D_{2} \\ Γ ⊢ M_{2} : A_{2} \end{matrix} tp app. Γ ⊢ M_{1} M_{2} : A_{1}

Δ ⊢ [θ]M_{1} ∈ [[A_{2} → A_{1}]]  By ind. hyp. on D_{1}
Δ ⊢ [θ]M_{2} ∈ [[A_{2}]]  By ind. hyp. on D_{2}
Δ ≥ Δ  By definition
Δ ⊢ ([θ]M_{1}) ([θ]M_{2}) ∈ [[A_{1}]]  By definition of [[A_{2} → A_{1}]]
Δ ⊢ [θ](M_{1} M_{2}) ∈ [[A_{1}]]  By definition of substitution

Case:

D = \frac{tp triv.}{Γ ⊢ ⟨ ⟩ : 1}

Since [θ]⟨ ⟩ = ⟨ ⟩ we have to show that Δ ⊢ ⟨ ⟩ ∈ [[1]] which holds by definition of [[1]].

□

Lemma 8.12 If Γ ⊢ M : A then Γ ⊢ M ∈ [[A]].

Proof: We first show that Γ ⊢ id_{Γ} ∈ [[Γ]]. This holds if Γ ⊢ x ∈ [[A]] for every x:A declared in Γ. But Γ ⊢ x ↓ x : A by rule atm var, so we can apply Lemma 8.5(2) to conclude that Γ ⊢ x ∈ [[A]]. Thus, by Lemma 8.11, Γ ⊢ [id_{Γ}]M ∈ [[A]] and thus Γ ⊢ M ∈ [[A]]. □

Theorem 8.13 If Γ ⊢ M : A then there exists an N such that Γ ⊢ M ⇑ N : A.

Proof: By Lemma 8.12, Γ ⊢ M ∈ [[A]]. By Lemma 8.5(1), Γ ⊢ M ⇑ N : A for some N. □

8.3 Canonical Forms for Natural Deductions

The canonical form theorem can be generalized to first-order natural deductions with the universal quantifier.^{12} There are two basic approaches to its proof: we can map the first-order case into the propositional case via a simplifying extraction as in Section 7.6, or we can extend the logical relations argument directly. Since a further generalization to the dependently typed λ-calculus λ^{Π} is given in Section ??, we do not repeat the argument here. Instead we concentrate on the definition of the necessary judgments directly on natural deductions and their formalization in Elf.

12It fails under the extension by falsehood, disjunction, or existential quantification; some counterexamples are given below.

Canonical Natural Deductions. A natural deduction of an atomic formula must be an atomic deduction; otherwise it must end in an elimination rule. An atomic deduction is a sequence of elimination rules applied to an hypothesis; the minor premiss in implication elimination must again be canonical. This informal definition is easily written out as a judgment and implemented in Elf.

\begin{matrix}D \\ A \end{matrix} ⇑ D is canonical
\begin{matrix}D \\ A \end{matrix} ↓ D is atomic

Since the definition of canonical deductions is inductive on the structure of the formula A, we make this index explicit in the implementation of the judgment as a type family can. Furthermore, it is convenient to introduce a separate type p for atomic formulas. At the cost of some clarity and efficiency, we could also introduce a judgment of atomic formula.

  p : type.  % atomic formulas
  atom : p -> o.

We use P and Q throughout this section to stand for atomic formulas P (t_{1}, …, t_{n}) in order to simplify notation. One should remember that (first-order) terms may occur in atomic formulas.

  can : {A:o} pf A -> type.  % Canonical deductions
  atm : pf A -> type.        % Atomic deductions

A deduction ending in the ∧I rule is canonical if the subdeductions are canonical. As a higher-level inference rule, this would be expressed as

\begin{matrix}D \\ A \end{matrix} ⇑ \begin{matrix}E \\ B \end{matrix} ⇑

can ∧ I.

\begin{aligned}\begin{matrix}D \\ A \end{matrix} & & \begin{matrix}E \\ B \end{matrix} \\ & & & ∧I \\ & A ∧ B \end{aligned} ⇑

This notation becomes unwieldy, especially when it involves hypothetical and parametric judgments at different levels. Instead, we write it as follows.

\begin{aligned}\begin{matrix}D \\ A \end{matrix} ⇑ \begin{matrix}E \\ B \end{matrix} ⇑ \\ & ∧I \\ A ∧ B \end{aligned} if \begin{matrix}D \\ A \end{matrix} ⇑ and \begin{matrix}E \\ B \end{matrix} ⇑

It should be understood as a shorthand for the higher-level inference rules above, which is underscored by its implementation in Elf. For the implementation of natural deduction, see Section 7.3.

can_andi : can (A and B) (andi D E)
            <- can A D
            <- can B E.

\frac{u}{A} ; D ; B ; ⊃I^{u} ; A ⊃ B ⇑ if \frac{u}{A} ; D ; B ⇑ under hypothesis \frac{u}{A} ↓

can_impi : can (A imp B) (impi D)
            <- {u:pf A} atm u -> can B (D u).

\frac{⊤I}{⊤} ⇑

can_truei : can (true) (truei).

\begin{matrix}D \\ [a/x]A \end{matrix} ; ∀I ; ∀x. A ⇑ if \begin{matrix}D \\ [a/x]A \end{matrix} ⇑

can_foralli : can (forall A) (foralli D)
               <- {a:i} can (A a) (D a).

\begin{matrix}D \\ P \end{matrix} ⇑ if \begin{matrix}D \\ P \end{matrix} ↓

can_atm : can (atom P) D
            <- atm D.

\begin{matrix}D \\ A ∧ B \end{matrix} ; ∧E_{L} ; A ↓ if \begin{matrix}D \\ A ∧ B \end{matrix} ↓

atm_andel : atm (andel D) <- atm D.

\begin{matrix}D \\ A ∧ B \end{matrix} ; ∧E_{R} ; B ↓ if \begin{matrix}D \\ A ∧ B \end{matrix} ↓

  atm_ander : atm (ander D) <- atm D.

\begin{aligned}\begin{matrix}D \\ B ⊃ A \end{matrix} & & \begin{matrix}E \\ B \end{matrix} \\ & & & ⊃E \\ & A \end{aligned} ↓ if \begin{matrix}D \\ B ⊃ A \end{matrix} ↓ and \begin{matrix}E \\ B \end{matrix} ⇑

  atm_impe : atm (impe D (E : pf B))
              <- atm D
              <- can B E.

\begin{matrix}D \\ ∀x. A \end{matrix} ; ∀E ; [t/x]A ↓ if \begin{matrix}D \\ ∀x. A \end{matrix} ↓

  atm_foralle : atm (foralle D T)
                 <- atm D.

Conversion to Canonical Deductions. Conversion to canonical deductions closely follows the ideas in Section 8.2. We only show the cases for universal quantification in weak head reduction, conversion to canonical, and conversion to atomic form.

\begin{matrix}D \\ A \end{matrix} ⟶^{whr} \begin{matrix}D′ \\ A \end{matrix} D weakly head reduces to D′
\begin{matrix}D \\ A \end{matrix} ⇑ \begin{matrix}D′ \\ A \end{matrix}  D converts to canonical form D′
\begin{matrix}D \\ A \end{matrix} ↓ \begin{matrix}D′ \\ A \end{matrix}  D converts to atomic form D′

\begin{matrix}\begin{matrix}D \\ [a/x]A \end{matrix} ; ∀I ; ∀x. A ; ∀E ; [t/x]A & ⟶^{whr} & \begin{matrix}[t/a]D \\ [t/x]A \end{matrix} \\ \begin{matrix}D \\ ∀x. A \end{matrix} ; ∀E ; [t/x]A & ⟶^{whr} & \begin{matrix}D′ \\ ∀x. A \end{matrix} ; ∀E ; [t/x]A & if & \begin{matrix}D \\ ∀x. A \end{matrix} & ⟶^{whr} & \begin{matrix}D′ \\ ∀x. A \end{matrix} \end{matrix}

\begin{matrix}D \\ ∀x. A \end{matrix} ⇑ \begin{matrix}D′ \\ [a/x]A \end{matrix} ; ∀I ; ∀x. A if \begin{matrix}D \\ ∀x. A \end{matrix} ; ∀E ; [a/x]A ⇑ \begin{matrix}D′ \\ [a/x]A \end{matrix}

\begin{matrix}D \\ ∀x. A \end{matrix} ; ∀E ; [t/x]A ↓ \begin{matrix}D′ \\ ∀x. A \end{matrix} ; ∀E ; [t/x]A if \begin{matrix}D \\ ∀x. A \end{matrix} ↓ \begin{matrix}D′ \\ ∀x. A \end{matrix}

Below we give the full implementation of the judgments. We use the familiar technique of representation object-level substitution by meta-level application. First, the local reductions.

whr : pf A -> pf A -> type.  % Weak head reduction
whr_andl : whr (andel (andi D E)) D.
whr_andr : whr (ander (andi D E)) E.
whr_imp  : whr (impe (impi D) E) (D E).
whr_forall : whr (foralle (foralli D) T) (D T).

Next, the congruences on elimination rules. These embody the reduction strategy that permits reductions in the head only.

whr_andel : whr (andel D) (andel D')
             <- whr D D'.
whr_ander : whr (ander D) (ander D')
             <- whr D D'.
whr_impe  : whr (impe D E) (impe D' E)
             <- whr D D'.
whr_foralle : whr (foralle D T) (foralle D' T)
               <- whr D D'.

Conversion to canonical forms depends on the structure of the formula A. As a stylistic choice we thus make this argument explicit.

tocan : {A:o} pf A -> pf A -> type. % Conversion to canonical form
toatm : pf A -> pf A -> type.       % Conversion to atomic form
tc_and : tocan (A and B) D (andi D1' D2')
          <- tocan A (andel D) D1'
          <- tocan B (ander D) D2'.
tc_imp : tocan (A imp B) D (impi D')
          <- {u:pf A} toatm u u -> tocan B (impe D u) (D' u).

  tc_true : tocan (true) D (truei).
  tc_forall : tocan (forall A) D (foralli D')
                <- {a:i} tocan (A a) (foralle D a) (D' a).
  tc_whr : tocan (atom P) D D'
            <- whr D D''
            <- tocan (atom P) D'' D'.
  tc_atm : tocan (atom P) D D'
            <- toatm D D'.

In the conversion to atomic form we use an explicit type annotation (E : pf A) in order to show that the formula A in the recursive call is determined by the input derivation. From an operational point of view this is not necessary.

  ta_impe : toatm (impe D (E : pf A)) (impe D' E')
             <- toatm D D'
             <- tocan A E E'.
  ta_andel : toatm (andel D) (andel D')
              <- toatm D D'.
  ta_ander : toatm (ander D) (ander D')
              <- toatm D D'.
  ta_foralle : toatm (foralle D T) (foralle D' T)
                <- toatm D D'.

The first theorem shows that conversion yields canonical deductions.

Theorem 8.14 (Conversion Yields Canonical Deductions)

1. If \begin{matrix}D \\ A \end{matrix} ⇑ \begin{matrix}D′ \\ A \end{matrix} then \begin{matrix}D′ \\ A \end{matrix} ⇑.

2. If \begin{matrix}D \\ A \end{matrix} ↓ \begin{matrix}D′ \\ A \end{matrix} then \begin{matrix}D′ \\ A \end{matrix} ↓.

Proof: By induction over the structure of the derivations that show the conversion judgments hold, after we generalize to permit hypotheses. This generalization is explicit in the context Γ in the appropriate analogue for the simply typed λ-calculus (Theorem 8.3). □

The representation of this proof is straightforward, except for the case involving a hypothetical derivation. We only show this case; the remaining cases can be found in the code that accompanies these notes.^{13}

  iscan : tocan A D D' -> can A D' -> type.
  isatm : toatm D D' -> atm D' -> type.
  isc_imp : iscan (tc_imp TC1) (can_impi CN1)
             <- {u:pf A} {ta:toatm u u} {at:atm u}
                isatm ta at -> iscan (TC1 u ta) (CN1 u at).

The hypothesis isatm ta at expresses that at is the derivation showing that the result of converting u to atomic form is atomic. It may be helpful to recall the declarations for can_impi and tc_imp.

  can_impi : can (A imp B) (impi D)
              <- {u:pf A} atm u -> can B (D u).
  tc_imp : tocan (A imp B) D (impi D')
            <- {u:pf A} toatm u u -> tocan B (impe D u) (D' u).

We have the following theorem, which we state here without proof.^{14}

Theorem 8.15 (Canonical Deductions) If \begin{matrix}D \\ A \end{matrix} then there exists a \begin{matrix}D′ \\ A \end{matrix} such that

\begin{matrix}D \\ A \end{matrix} ⇑ \begin{matrix}D′ \\ A \end{matrix}

8.4 Completeness of Uniform Derivations

The canonical form theorem for natural deductions for positive, intuitionistic logic

implies the completeness of uniform derivations. Completeness states that \begin{matrix}Δ \\ D \\ G \end{matrix}

implies Δ ⟶^{u} G. This is a direct corollary of the following theorem and the canonical form theorem.

Theorem 8.16 (Completeness of Uniform Derivations with Respect to Canonical Deductions)

13[filename pointer?]

14[consider further]

1. If \begin{matrix}Δ \\ D \\ A \end{matrix} ⇑ then Δ ⟶^{u} A;

2. if \begin{matrix}Δ \\ D \\ A \end{matrix} ↓ then for any atom P,

Δ ⟶^{u} A ≫ P ; ⋮ ; Δ ⟶^{u} P

The conclusion in statement (2) should be understood as a judgment parametric in P and hypothetical in Δ ⟶^{u} A ≫ P.

Proof: The proof proceeds by induction on the structure of the derivation showing that the natural deduction D is canonical (1) and atomic (2).

It is implemented by two mutually recursive type families. The parametric and hypothetical derivation in the conclusion is represented functionally in the framework.

  cmpcs : can A D -> solve A -> type.
  cmpai : {D:pf A} atm D -> ({P:p} A >> P -> solve (atom P)) -> type.

In the proof below we suppress the hypothesis Δ when possible. Case:

D = \begin{aligned}\begin{matrix}D_{1} \\ A_{1} \end{matrix} & & \begin{matrix}D_{2} \\ A_{2} \end{matrix} \\ & & & ∧I \\ & A_{1} ∧ A_{2} \end{aligned}

where D_{1} ⇑ and D_{2} ⇑. Then Δ ⟶^{u} A_{1} and Δ ⟶^{u} A_{2} by induction hypothesis (1) and thus, by rule S∧, Δ ⟶^{u} A_{1} ∧ A_{2}.

       cmpcs_andi : cmpcs (can_andi CN2 CN1) (s_and S2 S1)
                    <- cmpcs CN1 S1
                    <- cmpcs CN2 S2.

Case:

D = \frac{u}{A_{2}} ; D_{1} ; A_{1} ; ⊃I^{u} ; A_{2} ⊃ A_{1}

where D_{1} ⇑ under that hypothesis that u ↓. Then Δ, A_{2} ⟶^{u} A_{1} by induction hypothesis (1) and hence, by rule S⊃, Δ ⟶^{u} A_{2} ⊃ A_{1}. In the representation we need to fold in the case for hypotheses below.

  cmpcs_impi : cmpcs (can_impi CN1) (s_imp S1)
               <- {u:pf A2} {a:atm u} {d:assume A2}
                  cmpai u a ([P:p] [i:A2 >> P] s_atom i d)
                  -> cmpcs (CN1 u a) (S1 d).

Case:

D = \frac{⊤I}{⊤}

which is canonical. Then Δ ⟶^{u} ⊤ by rule S⊤.

  cmpcs_truei : cmpcs (can_truei) (s_true).

Case:

D = \begin{matrix}D_{1} \\ [a/x]A_{1} \end{matrix} ; ∀I ; ∀x. A_{1}

where D_{1} ⇑ and D_{1} is parametric in a. By induction hypothesis (1), Δ ⟶^{u} [a/x]A_{1}, also parametric in a, and thus Δ ⟶^{u} ∀x. A_{1} by rule S∀.

  cmpcs_foralli : cmpcs (can_foralli CN1) (s_forall S1)
                  <- {a:i} cmpcs (CN1 a) (S1 a).

Case: \begin{matrix}D \\ A \end{matrix} ⇑ since A = Q is atomic and D ↓. By induction hypothesis (2), for any

P,

\begin{matrix}Δ ⟶^{u} Q ≫ P \\ I_{1} \\ Δ ⟶^{u} P \end{matrix}

If we substitute Q for P and

\frac{I atom}{Δ ⟶^{u} Q ≫ Q}

for the hypothesis, we obtain

\frac{I atom}{Δ ⟶^{u} Q ≫ Q}

I_{1}

Δ ⟶^{u} Q

which is the required derivation of Δ ⟶^{u} A. The substitution for P and the hypothesis is represented in Elf by function application.

  cmpcs_atm : cmpcs (can_atm (AT1 : atm D)) (I1 Q (i_atom))
              <- cmpai D AT1 I1.

Case:

D = \frac{u}{A_{2}}

and u ↓. Then A_{2} is a hypothesis in Δ and

Δ ⟶^{u} A_{2} ≫ P for A_{2} in Δ

S atom

Δ ⟶^{u} P

is the required deduction which is parametric in P and hypothetical Δ ⟶^{u} A_{1} ≫ P. The implementation of this case is implicit in the case for ⊃I above.

Case:

D = \begin{matrix}D_{1} \\ A_{1} ∧ A_{2} \end{matrix} ; ∧E_{L} ; A_{1}

where D_{1} ↓. By induction hypothesis (2), there is a derivation

Δ ⟶^{u} A_{1} ∧ A_{2} ≫ P

I_{1}

Δ ⟶^{u} P

From this we construct

Δ ⟶^{u} A_{1} I∧_{L}

Δ ⟶^{u} A_{1} ∧ A_{2} ≫ P

I_{1}

Δ ⟶^{u} P

which satisfies the requirement of (2).

  cmpai_andel : cmpai (andel D1) (atm_andel CN1)
                ([P:p] [i:A >> P] I1 P (i_andl i))
                <- cmpai D1 CN1 I1.

Case: D ends in ∧E_{R} and the premiss is an atomic deduction. This is dual to the previous case.

  cmpai_ander : cmpai (ander D1) (atm_ander CN1)
                ([P:p] [i:A >> P] I1 P (i_andr i))
                <- cmpai D1 CN1 I1.

Case:

D = \begin{aligned}\begin{matrix}D_{1} \\ A_{2} ⊃ A_{1} \end{matrix} & & \begin{matrix}D_{2} \\ A_{2} \end{matrix} \\ & & & ⊃E \\ & A_{1} \end{aligned}

where D_{1} ↓ and D_{2} ⇑. By induction hypothesis (2) we have

Δ ⟶^{u} A_{2} ⊃ A_{1} ≫ P

I_{1}

Δ ⟶^{u} P

By induction hypothesis (1) we have

\begin{matrix}S_{2} \\ Δ ⟶^{u} A_{2} \end{matrix}

We construct

Δ ⟶^{u} A_{1} ≫ P \begin{matrix}S_{2} \\ Δ ⟶^{u} A_{2} \end{matrix}

I⊃

Δ ⟶^{u} A_{2} ⊃ A_{1} ≫ P

I_{1}

Δ ⟶^{u} P

which is the required hypothetical derivation.

  cmpai_impe : cmpai (impe D1 D2) (atm_impe CN2 AT1)
               ([P:p] [i:A >> P] I1 P (i_imp S2 i))
               <- cmpai D1 AT1 I1
               <- cmpcs CN2 S2.

Case:

D = \begin{matrix}D_{1} \\ ∀x. A_{1} \end{matrix} ; ∀E ; [t/x]A_{1}

where D_{1} ↓. By induction hypothesis (2) we have

Δ ⟶^{u} ∀x. A_{1} ≫ P

I_{1}

Δ ⟶^{u} P

We construct

Δ ⟶^{u} [t/x]A_{1} ≫ P

I∀

Δ ⟶^{u} ∀x. A_{1} ≫ P

I_{1}

Δ ⟶^{u} P

which is the required hypothetical derivation.

       cmpai_foralle : cmpai (foralle D1 T) (atm_foralle AT1)
                       ([P:p] [i] I1 P (i_forall T i))
                       <- cmpai D1 AT1 I1.

□

Theorem 8.17 (Completeness of Uniform Derivations) If \begin{matrix}Δ \\ D \\ A \end{matrix} then Δ ⟶^{u} A.

Proof: If \begin{matrix}Δ \\ D \\ A \end{matrix} then there exists a D′ such that \begin{matrix}Δ \\ D′ \\ A \end{matrix} and D′ ⇑ by Theorem 8.15.

By Theorem 8.16(1), Δ ⟶^{u} A. □

Completeness of uniform derivations is a non-deterministic completeness result from the programming language point of view. The implementation of pure Prolog, even with sound unification, will diverge on some queries that are provable. However, non-deterministic completeness is still valuable, since it allows us to draw strong conclusions from failure of a query. As an example, we consider Peirce’s law

((q ⊃ r) ⊃ q) ⊃ q

which is classically provable (using the law of excluded middle, for example). However, we show that is not intuitionistically provable. Assume there were a derivation D :: ((q ⊃ r) ⊃ q) ⊃ q from no hypotheses. By completeness of uniform derivations, there must be a uniform derivation of ((q ⊃r)⊃q)⊃q. By a sequence of applications of the inversion principle, this uniform derivation must have the shape

\frac{I atom}{L_{0} ⟶^{u} q ≫ q} \frac{?}{L_{0}, q ⟶^{u} r} ; S⊃ ; L_{0} ⟶^{u} q ⊃ r
I⊃

L_{0} ⟶^{u} ((q ⊃ r) ⊃ q) ≫ q

S atom

(q ⊃ r) ⊃ q ⟶^{u} q

S⊃

⟶^{u} ((q ⊃ r) ⊃ q) ⊃ q

where L_{0} = (q ⊃ r) ⊃ q. At the topmost point in this incomplete derivation we have two choices: we can attempt immediate implication with L_{0} or with the hypothesis q. Either one will fail in a few stepse since both hypothesis only allow us to potentially establish q but not r. This reasoning can be confirmed by using the Elf implementation of uniform derivations. Since the Elf interpreter has a similar non-deterministic completeness guarantee, if it fails we know that there cannot be a uniform derivation of the query.

  ?- {q:p} {r:p} solve (((atom q imp atom r) imp atom q) imp atom q).
  no

Note the role of the quantification over q and r here: since there are no a priori given atoms, we in effect say (at the meta-level) that for any atoms q and r, in the absence of any assumptions on q and r, the given formula has no uniform derivation.

We have not yet characterized the notion of uniform derivations completely with regard to natural deductions. The constructive proof of Theorem 8.16 shows how each canonical natural deduction directly corresponds to a uniform derivation. Conversely, every uniform derivation corresponds to a canonical derivation. In fact, the construction that was implicit in the proof of soundness of uniform derivations 8.1 always yields canonical deductions. In order to formulately this observation precisely, we would have to make the construction in the proof of Theorem 8.1 explicit

as a higher-level judgment relating uniform derivations \begin{matrix}S \\ Δ ⟶^{u} A \end{matrix} and natural de-

ductions \begin{matrix}Δ \\ D \\ A \end{matrix} and then show that all derivations D in this judgment are canonical.

The informal presentation of this higher-level judgment is left to Exercise ??; we only show its declaration in Elf. Recall that s_sound S D is the type family implementing the higher-level judgment. A derivation of this higher-level judgment is now related to a derivation that shows that D is canonical. This judgment of level 3 is represented by the type family ss_can below; the other two are auxiliary judgments for program formulas and immediate implications.

  ss_can : s_sound (S : solve A) D -> can A D -> type.
  hs_atm : h_sound H D -> atm D -> type.
  is_atm : i_sound I D -> ({u:pf A} atm u -> atm (D u)) -> type.

The full implementation of these type families can be found in the code.^{15}

8.5 Resolution

In actual logic programming languages the processes of goal decomposition (uniform derivability) and program decomposition (immediate entailment) are not mutually recursive. Instead, procedure call is modelled by backwards chaining or resolution. We can view a program formula D as an complex search instruction that transforms an atomic goal into a complex subgoal. If the subgoal can be solved, then the original goal has a solution. The syntactic simplicity of Horn logic^{16} supports this view very directly; in our more general setting the goal transformation is more complex. In this section we define a generalized form of resolution and show that it is sound and complete with respect to uniform derivability.

The strategy of this transformation is to modify immediate entailment Δ ⟶^{u} D ≫ P to arrive at D ≫ P \ G (where G is the residual subgoal for P with respect to D) so that all choices present in the definition of immediate implication have been postponed and are represented in G. For example, instead of solving G_{2} directly in

Δ ⟶^{u} D_{1} ≫ P Δ ⟶^{u} G_{2}

I⊃

Δ ⟶^{u} G_{2} ⊃ D_{1} ≫ P

we add it to the residual subgoal

D_{1} ≫ P \ G_{1}
R ⊃ .
G_{2} ⊃ D_{1} ≫ P \ G_{1} ∧ G_{2}

The conjunctive choice: Which of the two premisses of I⊃ do we derive first? has been postponed to the conjunctive choice for goals Which of the subgoals in G_{1} ∧G_{2} do we solve first? This strategy for defining resolution meets obstacles quickly. For example, there is no obvious disjunctive choice during goal decomposition to match the disjunctive choice between

\begin{aligned}Δ ⟶^{u} D_{1} ≫ P \\ & I∧_{L} \\ Δ ⟶^{u} D_{1} ∧ D_{2} ≫ P \end{aligned} and \begin{aligned}Δ ⟶^{u} D_{2} ≫ P \\ & I ∧_{R} . \\ Δ ⟶^{u} D_{1} ∧ D_{2} ≫ P \end{aligned}

Thus we need to extend the language of goals to represent various choices in immediate entailment. We use the new form of goal G_{1} ∨G_{2} to model the disjunctive choice between G_{1} and G_{2}. Since ⊤ carries no information as a program, Δ ⟶^{u} ⊤ ≫ P fails. Hence we need a goal ⊥ to represent failure. A universally quantified program represents an existential choice: Which term t do we use to instantiate x?

15[precise pointer?]

16[pointer]

Δ ⟶^{u} [t/x]D ≫ P

I∀

Δ ⟶^{u} ∀x. D ≫ P

This choice is represented by an existential goal ∃x. G. Finally, immediate implication can fail for atoms if the program and goal do not match. To shift possible failure to the residual goal, we need a goals P_{1} ≐ P_{2} equating atoms.

The counterexamples on page 245 show that at least disjunction, existential, and falsehood cannot be simply added to our language, since the uniform derivations would no longer be complete. If we do not insist on a single language for goals and programs, then it is possible to permit them in goals, but rule them out in programs. Uniform derivability remains complete with respect to natural deduction on this smaller class of formulas (see Exercise ??). In slight deviation from the terminology in [MNPS91], we will call them first-order hereditary Harrop formulas.

Goal Formulas  G ::= P | G_{1} ∧ G_{2} | D ⊃ G | ⊤ | ∀x. G
| G_{1} ∨ G_{2} | ⊥ | ∃x. G | P_{1} ≐ P_{2}
Program Formulas D ::= P | D_{1} ∧ D_{2} | G ⊃ D | ⊤ | ∀x. D
Programs  Δ ::= · | Δ, D

The language of program formulas has changed only insofar as the goals G embedded in them have changed. Adding any of the new constructs as programs destroys the uniform proof property. The following rules are consistent with the postulated search interpretation of the connectives on page 245.

Δ ⟶^{r} G G has a uniform resolution derivation
D ≫ P \ G Resolution of D with atom P yields residual goal G

\begin{aligned}Δ ⟶^{r} G_{1}  Δ ⟶^{r} G_{2} \\ & S∧ \\ Δ ⟶^{r} G_{1} ∧ G_{2} \end{aligned}  \frac{S⊤}{Δ ⟶^{r} ⊤}

\begin{aligned}Δ ⟶^{r} G_{1} \\ & S∨_{L} \\ Δ ⟶^{r} G_{1} ∨ G_{2} \end{aligned}  \begin{aligned}Δ ⟶^{r} G_{2} \\ & S∨_{R} \\ Δ ⟶^{r} G_{1} ∨ G_{2} \end{aligned}

\begin{aligned}Δ, D_{2} ⟶^{r} G_{1} \\ & S⊃ \\ Δ ⟶^{r} D_{2} ⊃ G_{1} \end{aligned}  \begin{aligned}Δ ⟶^{r} [a/x]G_{1} \\ & S∀^{∗} \\ Δ ⟶^{r} ∀x. G_{1} \end{aligned}

\begin{aligned}Δ ⟶^{r} [t/x]G_{1} \\ & S∃ \\ Δ ⟶^{r} ∃x. G_{1} \end{aligned}  \frac{S ≐}{Δ ⟶^{r} P ≐ P}

D ≫ P \ G for D in Δ Δ ⟶^{r} G

S atom

Δ ⟶^{r} P

\begin{aligned}D_{1} ≫ P \ G_{1}  D_{2} ≫ P \ G_{2} \\ & R∧ \\ D_{1} ∧ D_{2} ≫ P \ G_{1} ∨ G_{2} \end{aligned} \begin{aligned}D_{1} ≫ P \ G_{1} \\ & R⊃ \\ G_{2} ⊃ D_{1} ≫ P \ G_{1} ∧ G_{2} \end{aligned}

\frac{R⊤}{⊤ ≫ P \ ⊥}  \begin{aligned}[a/x]D ≫ P \ [a/x]G \\ & R∀^{∗} \\ ∀x. D ≫ P \ ∃x. G \end{aligned}

\frac{R atom}{Q ≫ P \ Q ≐ P}

The parameter a in the rules S∀ and R∀ must not already occur in the conclusion judgment. The implementation is complicated by the lack of subtyping in the framework. We would like to declare positive formulas, legal goal and program formulas all as subtypes of arbitrary formulas. An extension of the framework that permit such declarations is sketched in [KP93, Pfe93]. In the absence of such an extension, we introduce various versions of the logical connectives and quantifiers in their various roles (in positive formulas, goal formulas, and program formulas).

  goal : type.
  prog : type.
  %name goal G
  %name prog D
  atom' : p -> goal.
  and'  : goal -> goal -> goal.  %infix right 11 and'
  imp'  : prog -> goal -> goal.  %infix right 10 imp'

true' : goal.
forall' : (i -> goal) -> goal.
or'   : goal -> goal -> goal.  %infix right 11 or'
false'  : goal.
exists' : (i -> goal) -> goal.
==    : p -> p -> goal.        %infix none 12 ==
atom^: p -> prog.
and^: prog -> prog -> prog.  %infix right 11 and^
imp^: goal -> prog -> prog.  %infix right 10 imp^
true^: prog. forall^: (i -> prog) -> prog.

These goal and program formulas are related to positive formulas by two trivial judgments.

gl : o -> goal -> type.
pg : o -> prog -> type.
gl_atom : gl (atom P) (atom' P).
gl_and : gl (A1 and A2) (G1 and' G2)
          <- gl A1 G1
          <- gl A2 G2.
gl_imp : gl (A2 imp A1) (D2 imp' G1)
          <- gl A1 G1
          <- pg A2 D2.
gl_true : gl (true) (true').
gl_forall : gl (forall A1) (forall' G1)
             <- {a:i} gl (A1 a) (G1 a).
pg_atom : pg (atom P) (atom^P).
pg_and : pg (A1 and A2) (G1 and^G2)
          <- pg A1 G1
          <- pg A2 G2.
pg_imp : pg (A2 imp A1) (G2 imp^D1)
          <- pg A1 D1
          <- gl A2 G2.

pg_true: pg (true) (true^).
pg_forall : pg (forall A1) (forall^D1)
             <- {a:i} pg (A1 a) (D1 a).

Resolution enforces legality of goals and programs via the typing.

solve'  : goal -> type.
assume' : prog -> type.
resolve : prog -> p -> goal -> type.
s'_and : solve' (G1 and' G2)
         <- solve' G1
         <- solve' G2.
s'_imp : solve' (D2 imp' G1)
         <- (assume' D2 -> solve' G1).
s'_true : solve' (true').
s'_forall : solve' (forall' G1)
            <- {a:i} solve' (G1 a).
s'_eqp : solve' (P == P).
s'_orl : solve' (G1 or' G2)
          <- solve' G1.
s'_orr : solve' (G1 or' G2)
          <- solve' G2.
s'_exists : {T:i}
             solve' (exists' G1)
             <- solve' (G1 T).
s'_atom : solve' (atom' P)
           <- assume' D
           <- resolve D P G
           <- solve' G.
r_and : resolve (D1 and^D2) P (G1 or' G2)
           <- resolve D1 P G1
           <- resolve D2 P G2.

  r_imp  : resolve (G2 imp^D1) P (G1 and' G2)
             <- resolve D1 P G1.
  r_true : resolve (true^) P (false').
  r_forall : resolve (forall^D1) P (exists' G1)
               <- {a:i} resolve (D1 a) P (G1 a).
  r_atom : resolve (atom^Q) P (Q == P).

We first observe that one of our objectives has been achieved: all choices have been removed from resolution.

Lemma 8.18 (Uniqueness of Residual Goal) For any D and P there exists a unique G such that D ≫ P \ G is derivable.

Proof: By a straightforward induction on the structure of the program formula D. We only show the implementation.

  r_total : {D:prog} resolve D P G -> type.
  rt_and : r_total (D1 and^D2) (r_and R2 R1)
             <- r_total D1 R1
             <- r_total D2 R2.
  rt_imp : r_total (G2 imp^D1) (r_imp R1)
             <- r_total D1 R1.
  rt_true : r_total (true^) (r_true).
  rt_forall : r_total (forall^D1) (r_forall R1)
                <- {a:i} r_total (D1 a) (R1 a).
  rt_atom : r_total (atom^Q) (r_atom).

□

For the remainder of this section we will use A to stand for positive formulas (the domain of definition for uniform derivability and immediate entailment) and Δ for a program consisting entirely of positive formulas. The soundness and completeness theorems for resolution require appropriate generalization so that they can be shown by induction.

Theorem 8.19 (Soundness of Resolution)

1. If Δ ⟶^{r} A then Δ ⟶^{u} A;

2. if A ≫ P \ G and Δ ⟶^{r} G then Δ ⟶^{u} A ≫ P.

Proof: By induction on the structures of \begin{matrix}S′ \\ Δ ⟶^{r} A \end{matrix} and \begin{matrix}R \\ A ≫ P \ G \end{matrix} .^{17}

Since every positive formula is a legal goal and program, the informal proof does not distinguish between them. As pointed out above, the implementation must due to the lack of subtyping. The implementation of the proof must therefore explicitly establish the connection between the goals and positive formulas. We only show the declaration of the type families.^{18}

  s'_sound : solve' G -> gl A G -> solve A -> type.
  h'_sound : assume' D -> pg A D -> assume A -> type.
  r_sound : resolve D P G -> solve' G -> pg A D -> A >> P -> type.

□

Theorem 8.20 (Completeness of Resolution)

1. If Δ ⟶^{u} A then Δ ⟶^{r} A;

2. if Δ ⟶^{u} A ≫ P and A ≫ P \ G then Δ ⟶^{r} G.

Proof: By induction on the structures of \begin{matrix}S \\ Δ ⟶^{u} A \end{matrix} and \begin{matrix}I \\ Δ ⟶^{u} A ≫ P \end{matrix} .^{19}

Once again we only show the speciation of the type families implementing this proof.^{20}

  s'_comp : solve A -> gl A G -> solve' G -> type.
  h'_comp : assume A -> pg A D -> assume' D -> type.
  r_comp : A >> P -> pg A D -> resolve D P G -> solve' G -> type.

□

If the program is fixed, the resolution judgment allows us to characterize the circumstances under which an atomic goal may succeed. For example, consider

D_{0} = double(0, 0) ∧ (∀x. ∀y. double(x, y) ⊃ double(s(x), s(y)).

17[fill in]

18[file pointer]

19[fill in]

20[code pointer]

Then D_{0} ≫ double(x, y) \ G_{0} is derivable if and only if

G_{0} = double(0, 0) ≐ double(x, y)
∨ ∃x′. ∃y′. double(s(x′), s(y′)) ≐ double(x, y)
∧ double(x′, y′).

Since backchaining always yields a unique answer, and there is only one rule for solving an atomic goal, we know that double(X, Y) will have a proof if and only if G_{0} succeeds. That is, we could transform D_{0} into the equivalent program

D′_{0} = ∀x. ∀y.

(double(0, 0) ≐ double(x, y)

∨ ∃x′. ∃y′. double(s(x′), s(y′)) ≐ double(x, y)

∧ double(x′, y′)) ⊃ double(x, y).

If we replace the last implication by a biconditional,then this is referred to as the iff-completion of the program D_{0}. This is clearly a dubious operation, since the reverse implication is not a legal program. We can assert at the meta-level that if double(x, y) is derivable by resolution from D_{0}, then the formula G_{0} must be derivable from D_{0}; replacing this statement by the implication ∀x. ∀y. double(x, y)⊃ G_{0} is not in general justified. As a logical statement (outside of hereditary Harrop formulas) it only holds under the so-called closed world assumption, namely that no further assumptions about double will ever be made. For Horn clauses (see Section 8.6) this may be a reasonable assumption since the program never changes during the solution of a goal. For hereditary Harrop formulas this is not the case.

8.6 Success and Failure Continuations

The system of resolution presented in the preceding section has consolidated choices when compared to uniform derivations. It also more clearly identifies the procedure call mechanism, since goal solution and immediate entailment have been disentangled. However, all choices are still inherited from the Elf meta-language. For example, the order of the subgoals when solving G_{1} ∧G_{2} or G_{1} ∨G_{2} remains implicit in the deductive system. Only the operational semantics of Elf determines that they are attempted from left to right, when their deductive description is viewed as an Elf program, rather than a pure specification. The goal in this section is to make the intended operational semantics of the object language (first-order hereditary Harrop formulas) more explicit and less dependent on the operational semantics of the meta-language.

In our study of Mini-ML we have already encountered a situation where a semantic specification was a priori non-deterministic and involved conjunctive and disjunctive choices. For example, in the evaluation rule for pairing,

e_{1} ↪ v_{1} e_{2} ↪ v_{2} ev pair

⟨e_{1}, e_{2}⟩ ↪ ⟨v_{1}, v_{2}⟩

the evaluation order of e_{1} and e_{2} is not specified. This represents a conjunctive choice, since both expressions have to be evaluated to obtain the final value. In the transition to an abstract machine the evaluation order is made explicit without affecting the semantics (as the soundness and completeness theorems for the compiler proved). A disjunctive choice arose from the two rules for the evaluation of case e_{1} of z ⇒ e_{2} | s x ⇒ e_{3}. Since Mini-ML is deterministic removing this choice does not affect the semantics.

Because logic programming is more complex, we do not investigate it to the same depth as Mini-ML. In particular, we do not develop an abstract machine or an execution model in which all non-deterministic choices have been resolved. Instead we leave the existential choice to the meta-language and eliminate conjunctive and disjunctive choice. We also restrict ourselves to a Horn logic, which means that program and the available parameters remain constant throughout the execution of any logic program. The definition below actually generalizes ordinary definitions of Horn logic slightly by not enforcing a certain normal form for programs (see Exercise ??).

Horn Goals  G ::= P | G_{1} ∧ G_{2} | ⊤ | G_{1} ∨ G_{2} | ⊥ | ∃x. G | P_{1} ≐ P_{2}
Horn Programs D ::= P | D_{1} ∧ D_{2} | G ⊃ D | ⊤ | ∀x. D

We represent a collection of program formulas as a single formula by using conjunction. This allows us to be more explicit about the choice implicit in clause selection, embodied in the premiss “for D in Δ” of the S atom rule. In the main solvability judgment we carry a success continuation and a failure continuation. The success continuation represents the remaining goal to be solved when the current goal succeeds. The failure continuation represents the possible alternatives to be tried when the current goals fails.

[ to be completed ]