MetaPRL Module System

Introduction

Theories are defined in MetaPRL as modules. Logical modules can be expressed as extensions of previous modules, forming an object-oriented logical construction, and theories can be related using the module system.

Each logical module defines syntax, display, computational rewriting, and inference rules, defined in the previous pages. Theories are extended and related with the extends directive, discussed here. The extends directive is the logical equivalent of the open directive in OCaml. The extends directive "opens" the logical namespace, and it establishes a logical dependence between modules. The general form form of the include directive is as follows:

extends module-path

Multiple extends directives may appear in interfaces and implementations, establishing multiple dependencies that establish a logical inheritance graph. For example, the following module uses the basic logical definitions, and reasoning about numbers to express a well-known problem in number theory:

extends Itt_logic
extends Itt_int

interactive fermat 'H : :
    sequent ['ext] { 'H >- 
       all i: nat. (i >= 3) =>
          not (exst a: nat. exst b: nat. exst c: nat.
             power{a; i} + power{b; i} = power{c; i} in nat)

The included modules Itt_logic and Itt_int provide the logical context. Itt_logic provides logical definitions for all and exst, implication, and the Itt_int modules provides reasoning about numbers. These modules have extends directives of their own. The Itt_logic module contains the following logical dependencies:

extends Itt_equal
extends Itt_rfun
extends Itt_dfun
extends Itt_fun
extends Itt_dprod
extends Itt_prod
extends Itt_union
extends Itt_void
extends Itt_unit
extends Itt_struct

Each of the modules used in Itt_logic are recursively included in the Fermat theory. In general, an extends recursively opens all ancestors of the module included.

The extends directive performs the following operations for each included module:

The extends does not open the ML namespace. That operation must be performed separately for ML content, including tactics and conversions.

Naming conflicts

Modules may define operators with the same name. For example, two theories (say A and B) may both declare a conjunction

declare "and"{'a; 'b}

and they may impose different logical interpretations of the "and" term. The general rule for solving conflicts is the following:

A theory that relates the theories A and B must refer to both terms. Qualified names are expressed by module paths composed with the ! symbol. Here is an example, showing an interpretation of A.and as the "conditional" form of B.and. (The "and" operator is quoted because it is an ML keyword.)

extends A
extends B

rewrite a_and_interp : (A!"and"{'a; 'b}) <--> (B!"and"{'a; B!implies{'a; 'b}})