Lectures onType Theory
Chapter 114
Chapter 114Optional

Proof-Producing Tactics and the Kernel Boundary

Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.

Suppose a search procedure is asked to prove A(BA). It may introduce two hypotheses and return the first one. The result is safe only if the object returned is the term λx.λy.x:A(BA) and the ordinary kernel checks that judgment. A Boolean answer from the search procedure would place the search procedure inside the trusted base. The construction below instead makes every successful search carry a kernel-checkable proof term.

Goals and validations

Fix the dependent core and kernel checker of chapter 48. No new kernel rule is added in this chapter.

Definition 114.1 — Goals and proof states

A goal is a pair g=(ΓG), where Γ ctx and ΓG type. A validation from goals gi=(ΓiGi), for 1in, to g=(ΓG) is a partial meta-level function V whose domain contains every tuple of kernel proofs of the displayed goals and such that (Γipi:Gi for every i)ΓV(p1,,pn):G. Write each context as a telescope Γi=(xi1:Ai1,,xiki:Aiki). A contextual metavariable for gi is a fresh declaration ?mi:(xi1:Ai1)(xiki:Aiki)Gi. Its identity occurrence in Γi is ?mixi1xiki. A proof state for g is S=(?m1:g1,,?mn:gn;V), where the ?mi are pairwise distinct, there is exactly one declaration for each open goal, and V is a validation from those goals to g. The state represents the suspended meta-expression S:=V(?m1x11x1k1,,?mnxn1xnkn). Each argument in this display is formed in its own goal context before the validation abstracts or otherwise assembles it in Γ. No metavariable other than the displayed ?mi may occur in S. The empty state (;V) is successful: its suspended expression is the ordinary kernel term V().

The validation clause is the LCF invariant. It is stronger than saying that every subgoal looks plausible: it states how proofs of all subgoals assemble to a proof of the original goal.

Definition 114.2 — Primitive proof-producing tactics

A tactic maps a goal either to failure or to a proof state for that goal. The following primitive tactics are defined when their displayed side conditions hold.

  1. exact(q) on (ΓG) returns the empty state with validation ()q, provided the kernel derives Γq:G.

  2. intro on (Γx:AB) returns (?m:(Γ,x:AB);pλx.p), where ?m is fresh.

  3. split on (ΓA×B) returns the goals explicitly represented by (?m:(ΓA),?n:(ΓB);(p,q)(p,q)), where ?m and ?n are fresh and distinct.

  4. assumption returns exact(x) for the first declaration x:G in Γ, and fails if there is none.

The ordering in the last clause is part of the replayable tactic semantics.

For the opening goal, the first intro returns (?m1:(x:ABA);pλx.p),S1=λx.?m1x. Applying intro to its one open goal and composing validations returns (?m2:(x:A,y:BA);qλx.λy.q),S2=λx.λy.?m2xy. The assumption tactic selects x:A and directly supplies it as the proof argument for ?m2. The resulting empty state has suspended term λx.λy.x. Each transition performs an actual meta-level substitution into a validation; none is a kernel reduction rule.

Lemma 114.3 — Primitive validity

Every successful primitive tactic in definition 114.2 returns a proof state satisfying definition 114.1.

Proof of Lemma 114.3 — Primitive validity

Proof. For exact(q), the side condition is precisely the conclusion required of its nullary validation. For intro, inversion of the goal-formation judgment gives Γ,x:A ctx and Γ,x:AB type, so its contextual-metavariable declaration is well formed. Assuming Γ,x:Ap:B, the Π-introduction rule gives Γλx.p:x:AB. For split, inversion of product formation makes both displayed metavariable declarations well formed. The two assumptions Γp:A and Γq:B give Γ(p,q):A×B by product introduction. The assumption case reduces to the exact case because the variable rule derives Γx:G. ◻

Exercise 114.1

★☆☆ Let f:AB occur in Γ. Define a primitive tactic for the goal (ΓB) that creates the single goal (ΓA). Give its validation and prove its validity in two lines.

Sequencing, choice, and metavariables

Applying a tactic only to the first generated goal loses the remaining validation arguments. Sequencing must therefore distribute a second tactic over every subgoal and compose all validations.

Definition 114.4 — Tactic evaluation

Write T@gS when tactic T succeeds on goal g with proof state S, and write fails(T,g) for failure. The four primitives have exactly the successful results in definition 114.2. Their failure rules are

Γq:G
fails(exact(q),(ΓG))
Tac-Exact-Fail
¬x,A,B.G=x:AB
fails(intro,(ΓG))
Tac-Intro-Fail
¬A,B.G=A×B
fails(split,(ΓG))
Tac-Split-Fail
no declaration x:G occurs in Γ
fails(assumption,(ΓG))
Tac-Assumption-Fail

The first premise means that the kernel rejects the exact judgment; it is not a second typing relation. The two shape failures are syntactic because the primitive success clauses in definition 114.2 match those two outer forms; a front end may normalize a goal before invoking a primitive. For a vector of goals hi, write ?ni:hi for a vector containing one fresh contextual metavariable declaration for each component of hi. Metavariable vectors generated by separate premises are chosen disjointly. Given V and W1,,Wn, define their composite validation by VW(q1,,qn):=V(W1(q1),,Wn(qn)). The rules for sequence and left-biased choice are

T@g(?m1:g1,,?mn:gn;V)U@gi(?ni:hi;Wi)(1in)
(T;U)@g(?n1:h1,,?nn:hn;VW)
Tac-Seq
fails(T,g)
fails(T;U,g)
Tac-Seq-Fail_1
T@g(?m1:g1,,?mn:gn;V)fails(U,gi)
fails(T;U,g)
Tac-Seq-Fail_2
T@g(?m:h;V)
(TorelseU)@g(?m:h;V)
Tac-Or-Left
fails(T,g)U@g(?m:h;V)
(TorelseU)@g(?m:h;V)
Tac-Or-Right
fails(T,g)fails(U,g)
fails(TorelseU,g)
Tac-Or-Fail

The sequence rule removes the intermediate declarations ?mi:gi: each Wi directly supplies the corresponding argument of V. Its result contains exactly the final declarations ?ni:hi, and splits their proof arguments according to the displayed concatenation. If T succeeds on no goals, Tac-Seq has no U-premises and returns the same nullary validation.

For repetition, write a state relative to its original goal as S=(?m1:g1,,?mn:gn;V). Put μ((;V)):=(0,0),μ((?m1:g1,,?mn:gn;V)):=(1+c(g1),n)(n>0), ordered lexicographically, where c(g1) counts and × in the conclusion of g1. Thus the empty state is below every nonempty state, including a single atomic goal. Suppose T@g1(?n:h;W), where every declaration in ?n:h is fresh for the declarations retained from S. Define S=(?n:h,?m2:g2,,?mn:gn;V),V(q,p2,,pn):=V(W(q),p2,,pn). A one-step transition on the first goal is then

T@g1(?n:h;W)μ(S)<μ(S)
SstepTS
Rep-Step

Define stopsT(S) to hold exactly when S is empty, or its first goal g1 satisfies fails(T,g1), or every successful evaluation of T on g1 produces a state whose measure is not below μ(S). The terminating closure is generated by

stopsT(S)
RepT(S,S)
Rep-Done
SstepTS1RepT(S1,S2)
RepT(S,S2)
Rep-More

Thus Rep-Done is available exactly at a stopping state. For a fresh contextual metavariable ?m:g, the identity state has suspended expression ?m applied to the variables of the context of g. Finally, repeat(T)@gSRepT((?m:g;pp),S). Thus choice and repetition fix both the returned proof term and its replay trace; the decrease side condition excludes repeat(id).

The decrease premise in repeat is indispensable. The tactic id always succeeds without changing its goal; unrestricted repetition of it diverges.

Theorem 114.5 — Tactic soundness

Let T be generated from the primitives in definition 114.2 by the tacticals in definition 114.4. If T succeeds on g=(ΓG) with the empty state, then its nullary validation returns a term p satisfying Γp:G.

Proof of Theorem 114.5 — Tactic soundness

Proof. We prove the stronger claim that every successful evaluation returns a proof state valid for its input goal, by structural induction on the construction of the tactic. For a fixed tactic constructor, we then invert its successful evaluation rule. The four primitive constructors are lemma 114.3; the structural induction hypotheses are available for each proper sub-tactic of sequencing, choice, and repetition.

In Tac-Seq, suppose the first evaluation returns V, and the evaluations on its subgoals return Wi. Given kernel proofs for every final goal, validity of Wi gives a proof of gi. Validity of V then gives a proof of g, exactly as the composite in the conclusion of Tac-Seq. The output declarations are exactly the fresh declarations generated by the Wi, so every final goal is represented once and no intermediate ?mi remains in the suspended expression. The two sequence-failure rules have no successful conclusion. In Tac-Or-Left use the induction hypothesis for T; in Tac-Or-Right use it for U. Failure of both branches likewise has no successful conclusion.

For repetition, fix the structural induction hypothesis that every successful evaluation of the proper sub-tactic T returns a valid state. Prove the following two claims simultaneously by rule induction on the displayed derivations:

  1. if SstepTS1 and S is valid for its original goal, then S1 is valid for that goal;

  2. if RepT(S,S) and S is valid for its original goal, then S is valid for that goal.

The sole case of the first claim is Rep-Step. The structural induction hypothesis makes W a validation of (h1,,hk) to g1. Substituting that validation into the first argument of V gives exactly V. Freshness of the declarations generated by W and retention of exactly the declarations for g2,,gn give the required one-to-one goal representation, hence validity of the target state. For the second claim, Rep-Done returns the same state. In Rep-More, claim 1 gives validity of S1, and the induction hypothesis for its RepT(S1,S2) premise gives validity of S2. These are all rules of the mutually established step/closure invariant. The strict decrease in Rep-Step, using μ((;V))=(0,0) at the empty boundary, also proves that no infinite chain of Rep-More premises exists. Applying claim 2 to the initial identity state proves the repeat case. These are all successful evaluation-rule families. For an empty result list, validity of the resulting proof state is precisely the theorem’s conclusion. ◻

A generated metavariable is the explicit representative of an open goal, not an unscoped hole. General occurrences need not be identity occurrences: if ?m:(x1:A1)(xk:Ak)B, then ?mu1uk is formed only when the kernel checks the arguments in telescope order.

Definition 114.6 — Closing a proof state

Let S=(?m1:g1,,?mn:gn;V), where gi=(ΓiGi). A meta-substitution ρ closes S when both conditions hold:

  1. its domain is exactly {?m1,,?mn};

  2. for every i, its assignment ρ(?mi)=qi is a metavariable-free kernel term satisfying Γiqi:Gi;

Contextual substitution acts on an occurrence by (?miu1uki)[ρ]:=qi[u1/xi1,,uki/xiki], and acts pointwise on a validation application: V(t1,,tn)[ρ]:=V(t1[ρ],,tn[ρ]). Thus the empty substitution closes only an empty state; a state with an open goal cannot satisfy closure without a checked proof of that goal.

For the state S2 in the opening calculation, put ρ2(?m2)=x. The variable rule gives x:A,y:Bx:A, so ρ2 closes S2, and S2[ρ2]=λx.λy.x. The empty substitution does not close S2, because its domain omits ?m2.

An unscoped placeholder ?m:B would allow a tactic to construct ?mx after leaving the scope of x. The contextual declaration prevents that term from being formed unless x is an explicit telescope argument.

Proposition 114.7 — Closure removes tactic state

Let S be a proof state for (ΓG). If ρ closes S, then substituting ρ into its suspended expression yields a metavariable-free term p:=S[ρ]withΓp:G.

Proof of Proposition 114.7 — Closure removes tactic state

Proof. Write S=(?m1:g1,,?mn:gn;V). By closure, ρ(?mi)=qi and Γiqi:Gi for every i. The definition of the suspended expression and contextual substitution give S[ρ]=V(q1,,qn). The defining property of the validation therefore gives ΓV(q1,,qn):G. The proof-state definition says that the only metavariables in S are the ?mi, and closure makes every qi metavariable-free. Hence no metavariable occurs in p. Specializing the displayed calculation to n=0 yields p=V(), as required. ◻

Case splitting and deterministic replay

For an inductive family, a case split cannot guess a nondependent return type. It must expose a motive.

Definition 114.8 — Case-split certificate

For s:Iai and goal G, a case-split certificate contains a well-typed motive P:(j:J)IajUk,PisG, where k is the level at which the kernel derives ΓG:Uk, and J is the index telescope of I at the parameters a; one fresh contextual-metavariable declaration for every constructor goal accepted by the family eliminator; and a validation whose eliminator application consumes exactly those branch-proof arguments. Impossible branches have no declaration and no validation argument, and are omitted only when the kernel derives the corresponding index contradiction.

For vectors, splitting v:VecA(sucn) creates only the fresh declaration for the cons branch, and the eliminator validation supplies its identity occurrence at that branch. There is no declaration for a nil branch. Deleting the successor index from the motive would also create an unprovable nil branch. Thus the motive and the exact branch declarations are proof data rather than search metadata.

Definition 114.9 — Replay certificate

A replay certificate records the original goal, the ordered primitive calls, every generated contextual-metavariable declaration, every choice branch, every case-split motive, and the final closed proof term. Replay executes the recorded primitive calls without search and then invokes the kernel on the final term.

Theorem 114.10 — Kernel-boundary theorem

If deterministic replay accepts a certificate for (ΓG), then the kernel accepts its final term p at G. Corruption of a tactic trace cannot make the kernel accept an ill-typed p.

Proof of Theorem 114.10 — Kernel-boundary theorem

Proof. Replay acceptance includes the independent final call to the kernel checker. By checker soundness, that call returns a derivation of Γp:G. The trace is used to reproduce p, but is not a premise of the kernel derivation. Hence altering the trace either reproduces the same well-typed term, produces another term that the kernel checks, or is rejected. ◻

The abstract-theorem architecture and validations follow Cambridge LCF as described by Paulson, Technical Report 39, Section 2 for goals and validations and Section 5 for the tacticals [Pau83], and Gordon’s modern reconstruction [Gor15]. Those sources describe LCF; the soundness theorem above belongs to the finite calculus defined here.

Suggested first pass.

None of these problems is a prerequisite for a later chapter. Begin with exercise 114.2, then complete exercise 114.4.

Exercise 114.2

★★☆ Evaluate intro;(split;assumption) on A(A×A). List every contextual-metavariable declaration and suspended expression in every proof state, then calculate the composite validation to the closed proof term.

Exercise 114.3

★★☆ Construct two left-biased choices whose branches both prove AA but return beta-distinct terms before normalization. Show that the branch order changes the replay trace while kernel soundness is unchanged.

Exercise 114.4

★★★ Practical project.proof-producing-tactic-replayer Implement in Agda or Kappa the propositional fragment with atoms, implication, and products, together with intro, split, assumption, sequencing, and left-biased choice. Maintain the invariant that every open goal has exactly one contextual-metavariable declaration and is supplied as exactly one validation argument. On the named input k, print accepted: lambda-lambda-var. On dup, print accepted: pair-var-var. On bad-drop, print rejected: missing- validation-argument. Mutating sequence to discard the second generated goal must fail the last oracle. The program checks the finite tactic calculus; it does not prove soundness of a product tactic API.

Search the book

Type to search the local edition.