To enable classical reasoning in this single-conclusion logic, we introduce a rule for explicit classical reasoning. The proof term in this logic has no computational meaning, so we provide a new term magic to represent proofs by excluded middle.
The interface defines the proof term, and a tactic for classical reasoning. The classical rule we use is based on the reasoning (not not 'T => 'T), and so we need to include the Fol_not theory.
1. Define the proof term, and reasoning tactic in the file fol_class.mli:
extends Fol_not open Tacticals declare magic{x. 't['x]} val magicT : tactic
The implementation of classical reasoning is short. We need just define the rule and tactic for classical reasoning.
2. Define the syntax, rule, a tactic for classical reasoning in the fol_class.ml file:
extends Fol_not declare magic{x. 't['x]} dform magic_df : magic = `"magic" prim magic 'H 'x : ('t['x] : sequent ['ext] { 'H; x: "not"{'T} >- "false" }) --> sequent ['ext] { 'H >- 'T } = magic{x. 't['x]} let magicT p = let v = Var.maybe_new_vars1 p "v" in magic (Sequent.hyp_count_addr p) v p
The magic proof term is a value: computation over proof terms does not evaluate magic terms, and so computations formed from classical proofs have little meaning (without introducing a semantics of classical computations).