logic design
The logic package turns the equality calculus of the kernel into propositional logic. It defines the connectives as kernel definitions, derives the natural-deduction rules from the ten primitive rules, and keeps the catalog of theorem names that proof scripts may cite. This page gives the definitions, derives the rules, and explains why the package can do all this without being trusted.
Design goal
The kernel knows only equality and choice. Users want , , , , and with their usual rules. The goal is to provide them with no new authority: every connective is a definition admitted by the DefOK gate, and every rule is a MoonBit function that calls kernel rules. The package may be wrong in the sense of failing to prove something, but it cannot prove anything false.
Mathematical background
Connectives as definitions
QED follows the definitions of HOL Light, where every connective is reduced to equality.11 J. Harrison, HOL Light Tutorial, section on the logical constants; the definitions go back to Andrews’ type theory Q0. QED’s disjunction differs from HOL Light’s, see below. Let be the truth term . The prelude defines
where a primed name stands for the definition body already expanded, so that each right-hand side is a closed term over alone. The reading of each definition:
- is true because it is an instance of REFL.
- says the identity predicate on booleans equals the constantly-true predicate, that is with . It is false in the standard model because itself would have to be true.
- says the pair cannot be told apart from by any function , which holds exactly when and are both true.
- is : adding to changes nothing.
- is .
- is .
Basis terms
prop_mk_and and its siblings return the basis form, the expanded right-hand side, rather than the application of the constant. The rules below work on basis forms, because only on those can the kernel rules act directly; the constants exist so that the definitions are recorded, can be cited, and can be recognised in terms that users write.
Design decisions
Derive, do not postulate
Every rule of the package is a derivation. The derivations below are the ones the code performs; each line is a kernel rule.
Truth. From the definition , symmetry gives , and is REFL, so EQ_MP gives (logic_prop_truth_const_thm). Symmetry itself is derived:
From a proof to an equation with truth. From and , DEDUCT_ANTISYM_RULE gives , and unless is itself a hypothesis, in which case dropping it is harmless because is provable. This “EQT_INTRO” step is how propositions are put inside terms.
Conjunction introduction. From and obtain and . For a fresh variable ,
The last line is . Freshness of is what makes ABS applicable.
Conjunction elimination. Apply both sides of to the selector with MK_COMB and REFL, then reduce both sides with BETA and TRANS:
Symmetry and EQ_MP with give . The selector gives .
Implication elimination. From and : symmetry gives , EQ_MP gives , and conjunction elimination gives .
Implication introduction. From with : conjunction introduction with gives , and elimination from the assumption gives . Then
and the hypothesis set is . The conclusion is by definition. logic_prop_imp_intro_thm requires ; discharging an absent hypothesis would need weakening first.
Ex falso. From and any proposition , MK_COMB with and two BETA steps give , hence . Negation elimination is implication elimination with conclusion .
Disjunction introduction. From : assume , eliminate it against to get , derive by ex falso, and discharge :
From the right introduction discharges an unused after conjoining it with .
No disjunction elimination
The prelude defines as . Introduction is derivable, as shown. Elimination, from , and infer , is not: it needs a case split on , that is excluded middle . In HOL excluded middle follows from the choice axiom and extensionality (Diaconescu’s theorem),22 R. Diaconescu, “Axiom of choice and complementation”, Proc. AMS 51, 1975. HOL Light derives EXCLUDED_MIDDLE this way in class.ml. but the kernel exposes no theorem for the choice axiom and the package does not derive excluded middle. Rather than ship a rule it cannot justify, the catalog has or_intro_l and or_intro_r and no or_elim, and the tactic layer has left and right but no case analysis.
Trusted recognition of connective constants
Problem. A user can declare a constant named and that means something else. If prop_dest_and recognised any application of a constant called and, a tactic could treat an arbitrary term as a conjunction.
Choice. The destructors accept the basis form, which is checked structurally, and an application of a connective constant only when the state holds the canonical definition theorem for that constant (with the current identity). install_prop_prelude refuses to install over a placeholder constant with the right name and type but no definition.
Why. Recognition errors would not break soundness, because every rule is replayed through the kernel. They would produce confusing failures at replay time instead of clear failures at the tactic, and the specification requires connector recognition to be backed by definitions.
One catalog, two modes
Problem. exact th and apply th mean different things. exact needs a theorem whose conclusion is the goal; apply needs an implication whose consequent is the goal and leaves its antecedent as the new goal. Letting a name be used in the wrong mode silently would either fail late or, worse, make exact quietly behave like apply.
Choice. Each catalog entry records an exact_class and an apply_class. exact consults only the first, apply only the second, and a name that exists but is unusable in a mode resolves to KnownButUnavailable, which the tactics layer reports as a shape or apply mismatch. A local hypothesis name always takes precedence over a catalog name and never falls back to it.
Why. The table is the single source for the tactics layer, the prover’s corpus, the mapping matrix and the documentation, so the theorem names a user may write cannot drift between them.
Errors from the kernel only
Kernel error constructors are read-only outside the kernel. The package obtains the LogicError and SigError values it returns by running small kernel operations that are known to fail in the required way. This keeps the error vocabulary owned by the kernel, at the cost of less specific errors: many helper failures surface as TypeMismatch or AlphaMismatch.
Correctness and invariants
- Soundness. Every
Thmreturned by this package is the result of kernel functions, so the kernel’s soundness argument covers it. The derivations above show that each rule is also complete for its intended use: whenever its premises have the stated shapes, it succeeds. - Conservativity of the prelude. The six constants are admitted by
DefOKwith closed right-hand sides, no type variables and no cycles, so the prelude is a conservative extension of the empty theory. - Idempotence.
install_prop_prelude(install_prop_prelude(s))equalsinstall_prop_prelude(s): an existing canonical definition is accepted as is. - Exact sequents. The replay helpers check hypotheses as sets up to α-equivalence.
logic_prop_strengthen_to_hypsonly adds hypotheses, so a theorem that needs a hypothesis the goal does not have is rejected rather than accepted with extra assumptions. - β-normalisation is proof-producing.
logic_beta_normalize_eqandlogic_normalize_prop_betabuild kernel equations step by step; the term-levellogic_beta_nf_*functions return the right-hand side of such an equation. Normalisation does not enter abstractions and is bounded (512 steps per pass, 32 passes for the deep form), which suffices for the connective encodings.
Alternatives rejected
- Connectives as kernel primitives. This would add rules to the kernel and to its soundness proof. Definitions cost nothing in trust.
- HOL Light’s disjunction . With it, elimination is derivable without excluded middle, at the cost of a universal quantifier over propositions inside every disjunction. The prelude uses the shorter encoding and states its limit instead; switching would change every disjunction term and the corpus built on them.
- A mixed resolver.
logic_prop_resolve_refresolves names without distinguishing modes; it is kept for tests, while the tactics layer uses the mode-specific resolvers.
Boundaries
- The package proves propositional facts only; it has no quantifier rules beyond what the tactics layer builds for theorem-header binders.
- It has no disjunction elimination, no excluded middle and no classical reasoning.
- It does not store user theorems: the catalog is fixed in the source, and adding a name means adding code and a test.
- It adds no authority. Any change to it is reviewed for usefulness, not for soundness.
- It does not parse or print formulas; terms are built by the parser and printed by the kernel’s structural printer.
Footnotes
-
J. Harrison, HOL Light Tutorial, section on the logical constants; the definitions go back to Andrews’ type theory Q0. QED’s disjunction differs from HOL Light’s, see below. ↩
-
R. Diaconescu, “Axiom of choice and complementation”, Proc. AMS 51, 1975. HOL Light derives
EXCLUDED_MIDDLEthis way inclass.ml. ↩