MetaPRL Tutorial: Basic Automation

Introduction

The rules for true and false are unwieldy. To apply the rule, that arguments for the parameters have to be constructed explicitly, and the rules have to chosen explicitly for the two constructors. MetaPRL provides a resource that addresses this very problem. The dT tactic is a general tactic for applying introduction and elimination rules. The following steps describe how to add the true and false terms to the dT tactic.

False automation

The rules are added to the dT tactic by providing a tactic that performs the dT operation. The dT tactic is declared as follows:

val dT : int -> tactic

The argument of the tactic is the clause number that the tactic is applied to: if the argument is 0, the tactic applies the introduction rule to the conclusion. Otherwise, the clause number specifies the hypothesis number for application of an elimination rule.

First, we need to open some extra modules that will allow adding to the dT tactic.

1. Add the following lines after the extends Fol_type line in the file fol_false.ml

open Mp_resource
open Dtactic
open Refiner.Refiner.RefineError

The next step is to add reasoning for the well-formedness of the false term. The dT tactic is extended by providing a tactic to do reasoning specifically for the false term.

2. Add a dT component for proving well-formedness to the Fol_false module, by adding the following function to the fol_false.ml file:

let d_false_type i p =
   if i = 0 then
      false_type (Sequent.hyp_count_addr p) p
   else
      raise (RefineError ("d_false_type", StringError "no elimination form"))

This tactic checks the clause number, and applies the tactic only if the clause refers to the conclusion. Otherwise, the tactic raises an error. The errors are defined in the refiner/refsig/refine_error.mlz file. Each error includes the name of the function raising the exception, and a message describing the error.

The false_type rule is applied as a tactic. It takes two arguments: the address for the context 'H, and a tactic argument. The Sequent module defines functions to compute address values from the tactic argument. In this case, the context 'H refers to all of the hypotheses, and the address can be computed with the Sequent.hyp_count_addr function.

The next step is to add this tactic to the dT tactic. This is accomplished by calling the Mp_improve method of the d_resource resource. Resources are managed functionally, and the d_resource is improved by binding it to a new value.

3. Add the d_false_type component to the dT resource, by adding the following lines after the definition of d_false_type:

let false_type_term = << "type"{."false"} >>
let d_resource = Mp_resource.resource_improve d_resource
                    (false_type_term, d_false_type)

The resource is "improved" by providing the pattern false_type_term, and associating the d_false_type tactic with the pattern. We'll see an example of using the dT tactic when we add binary logical operators to FOL.

As the last step in this module, add the elimination for to the dT tactic.

4. Add the elimination form to the dT tactic, by adding the following lines to the fol_false.ml file:

let d_false i p =
   if i = 0 then
      raise (RefineError ("d_false_type", StringError "no introduction form"))
   else
      let j, k = Sequent.hyp_indices p i in
         false_elim j k p

let false_term = << "false" >>
let d_resource = Mp_resource.resource_improve d_resource (false_term, d_false)

True automation

The Fol_true module has similar tactics for automation. After you are finished with the Fol_false module, see if you can add automation to the Fol_true module.