| 
7160
 | 
     1  | 
%% $Id$
  | 
| 
 | 
     2  | 
\chapter{Defining A Sequent-Based Logic}
 | 
| 
 | 
     3  | 
\label{chap:sequents}
 | 
| 
 | 
     4  | 
  | 
| 
 | 
     5  | 
\underscoreon %this file contains the @ character
  | 
| 
 | 
     6  | 
  | 
| 
 | 
     7  | 
The Isabelle theory \texttt{Sequents.thy} provides facilities for using
 | 
| 
 | 
     8  | 
sequent notation in users' object logics. This theory allows users to
  | 
| 
 | 
     9  | 
easily interface the surface syntax of sequences with an underlying
  | 
| 
 | 
    10  | 
representation suitable for higher-order unification.
  | 
| 
 | 
    11  | 
  | 
| 
 | 
    12  | 
\section{Concrete syntax of sequences}
 | 
| 
 | 
    13  | 
  | 
| 
 | 
    14  | 
Mathematicians and logicians have used sequences in an informal way
  | 
| 
 | 
    15  | 
much before proof systems such as Isabelle were created. It seems
  | 
| 
 | 
    16  | 
sensible to allow people using Isabelle to express sequents and
  | 
| 
 | 
    17  | 
perform proofs in this same informal way, and without requiring the
  | 
| 
 | 
    18  | 
theory developer to spend a lot of time in \ML{} programming.
 | 
| 
 | 
    19  | 
  | 
| 
 | 
    20  | 
By using {\tt Sequents.thy}
 | 
| 
 | 
    21  | 
appropriately, a logic developer can allow users to refer to sequences
  | 
| 
 | 
    22  | 
in several ways:
  | 
| 
 | 
    23  | 
%
  | 
| 
 | 
    24  | 
\begin{itemize}
 | 
| 
 | 
    25  | 
\item A sequence variable is any alphanumeric string with the first
  | 
| 
 | 
    26  | 
 character being a \verb%$% sign. 
  | 
| 
 | 
    27  | 
So, consider the sequent \verb%$A |- B%, where \verb%$A%
  | 
| 
 | 
    28  | 
is intended to match a sequence of zero or more items.
  | 
| 
 | 
    29  | 
 
  | 
| 
 | 
    30  | 
\item A sequence with unspecified sub-sequences and unspecified or
  | 
| 
 | 
    31  | 
individual items is written as a comma-separated list of regular
  | 
| 
 | 
    32  | 
variables (representing items), particular items, and
  | 
| 
 | 
    33  | 
sequence variables, as in  
  | 
| 
 | 
    34  | 
\begin{ttbox}
 | 
| 
 | 
    35  | 
$A, B, C, $D(x) |- E
  | 
| 
 | 
    36  | 
\end{ttbox}
 | 
| 
 | 
    37  | 
Here both \verb%$A% and \verb%$D(x)%
  | 
| 
 | 
    38  | 
are allowed to match any subsequences of items on either side of the
  | 
| 
 | 
    39  | 
two items that match $B$ and $C$.  Moreover, the sequence matching
  | 
| 
 | 
    40  | 
\verb%$D(x)% may contain occurrences of~$x$.
  | 
| 
 | 
    41  | 
  | 
| 
 | 
    42  | 
\item An empty sequence can be represented by a blank space, as in
  | 
| 
 | 
    43  | 
\verb? |- true?.
  | 
| 
 | 
    44  | 
\end{itemize}
 | 
| 
 | 
    45  | 
  | 
| 
 | 
    46  | 
These syntactic constructs need to be assimilated into the object
  | 
| 
 | 
    47  | 
theory being developed. The type that we use for these visible objects
  | 
| 
 | 
    48  | 
is given the name {\tt seq}.
 | 
| 
 | 
    49  | 
A {\tt seq} is created either by the empty space, a {\tt seqobj} or a
 | 
| 
 | 
    50  | 
{\tt seqobj} followed by a {\tt seq}, with a comma between them. A
 | 
| 
 | 
    51  | 
{\tt seqobj} is either an item or a variable representing a
 | 
| 
 | 
    52  | 
sequence. Thus, a theory designer can specify a function that takes
  | 
| 
 | 
    53  | 
two sequences and returns a meta-level proposition by giving it the
  | 
| 
 | 
    54  | 
Isabelle type \verb|[seq, seq] => prop|.
  | 
| 
 | 
    55  | 
  | 
| 
 | 
    56  | 
This is all part of the concrete syntax, but one may wish to
  | 
| 
 | 
    57  | 
exploit Isabelle's higher-order abstract syntax by actually having a
  | 
| 
 | 
    58  | 
different, more powerful {\em internal} syntax.
 | 
| 
 | 
    59  | 
  | 
| 
 | 
    60  | 
  | 
| 
 | 
    61  | 
  | 
| 
 | 
    62  | 
\section{ Basis}
 | 
| 
 | 
    63  | 
  | 
| 
 | 
    64  | 
One could opt to represent sequences as first-order objects (such as
  | 
| 
 | 
    65  | 
simple lists), but this would not allow us to use many facilities
  | 
| 
 | 
    66  | 
Isabelle provides for matching.  By using a slightly more complex
  | 
| 
 | 
    67  | 
representation, users of the logic can reap many benefits in
  | 
| 
 | 
    68  | 
facilities for proofs and ease of reading logical terms.
  | 
| 
 | 
    69  | 
  | 
| 
 | 
    70  | 
A sequence can be represented as a function --- a constructor for
  | 
| 
 | 
    71  | 
further sequences --- by defining a binary {\em abstract} function
 | 
| 
 | 
    72  | 
\verb|Seq0'| with type \verb|[o,seq']=>seq'|, and translating a
  | 
| 
 | 
    73  | 
sequence such as \verb|A, B, C| into
  | 
| 
 | 
    74  | 
\begin{ttbox}
 | 
| 
 | 
    75  | 
\%s. Seq0'(A, SeqO'(B, SeqO'(C, s)))  
  | 
| 
 | 
    76  | 
\end{ttbox}
 | 
| 
 | 
    77  | 
This sequence can therefore be seen as a constructor 
  | 
| 
 | 
    78  | 
for further sequences. The constructor \verb|Seq0'| is never given a
  | 
| 
 | 
    79  | 
value, and therefore it is not possible to evaluate this expression
  | 
| 
 | 
    80  | 
into a basic value.
  | 
| 
 | 
    81  | 
  | 
| 
 | 
    82  | 
Furthermore, if we want to represent the sequence \verb|A, $B, C|,
  | 
| 
 | 
    83  | 
we note that \verb|$B| already represents a sequence, so we can use
  | 
| 
 | 
    84  | 
\verb|B| itself to refer to the function, and therefore the sequence
  | 
| 
 | 
    85  | 
can be mapped to the internal form:
  | 
| 
 | 
    86  | 
\verb|%s. SeqO'(A, B(SeqO'(C, s)))|.
  | 
| 
 | 
    87  | 
  | 
| 
 | 
    88  | 
So, while we wish to continue with the standard, well-liked {\em
 | 
| 
 | 
    89  | 
external} representation of sequences, we can represent them {\em
 | 
| 
 | 
    90  | 
internally} as functions of type \verb|seq'=>seq'|.
  | 
| 
 | 
    91  | 
  | 
| 
 | 
    92  | 
  | 
| 
 | 
    93  | 
\section{Object logics}
 | 
| 
 | 
    94  | 
  | 
| 
 | 
    95  | 
Recall that object logics are defined by mapping elements of
  | 
| 
 | 
    96  | 
particular types to the Isabelle type \verb|prop|, usually with a
  | 
| 
 | 
    97  | 
function called {\tt Trueprop}. So, an object
 | 
| 
 | 
    98  | 
logic proposition {\tt P} is matched to the Isabelle proposition
 | 
| 
 | 
    99  | 
{\tt Trueprop(P)}\@.  The name of the function is often hidden, so the
 | 
| 
 | 
   100  | 
user just sees {\tt P}\@. Isabelle is eager to make types match, so it
 | 
| 
 | 
   101  | 
inserts {\tt Trueprop} automatically when an object of type {\tt prop}
 | 
| 
 | 
   102  | 
is expected. This mechanism can be observed in most of the object
  | 
| 
 | 
   103  | 
logics which are direct descendants of {\tt Pure}.
 | 
| 
 | 
   104  | 
  | 
| 
 | 
   105  | 
In order to provide the desired syntactic facilities for sequent
  | 
| 
 | 
   106  | 
calculi, rather than use just one function that maps object-level
  | 
| 
 | 
   107  | 
propositions to meta-level propositions, we use two functions, and
  | 
| 
 | 
   108  | 
separate internal from the external representation. 
  | 
| 
 | 
   109  | 
  | 
| 
 | 
   110  | 
These functions need to be given a type that is appropriate for the particular
  | 
| 
 | 
   111  | 
form of sequents required: single or multiple conclusions.  So
  | 
| 
 | 
   112  | 
multiple-conclusion sequents (used in the LK logic) can be
  | 
| 
 | 
   113  | 
specified by the following two definitions, which are lifted from the inbuilt
  | 
| 
 | 
   114  | 
{\tt Sequents/LK.thy}:
 | 
| 
 | 
   115  | 
\begin{ttbox}
 | 
| 
 | 
   116  | 
 Trueprop       :: two_seqi
  | 
| 
 | 
   117  | 
 "@Trueprop"    :: two_seqe   ("((_)/ |- (_))" [6,6] 5)
 | 
| 
 | 
   118  | 
\end{ttbox}
 | 
| 
 | 
   119  | 
%
  | 
| 
 | 
   120  | 
where the types used are defined in {\tt Sequents.thy} as
 | 
| 
 | 
   121  | 
abbreviations:
  | 
| 
 | 
   122  | 
\begin{ttbox}
 | 
| 
 | 
   123  | 
 two_seqi = [seq'=>seq', seq'=>seq'] => prop
  | 
| 
 | 
   124  | 
 two_seqe = [seq, seq] => prop
  | 
| 
 | 
   125  | 
\end{ttbox}
 | 
| 
 | 
   126  | 
  | 
| 
 | 
   127  | 
The next step is to actually create links into the low-level parsing
  | 
| 
 | 
   128  | 
and pretty-printing mechanisms, which map external and internal
  | 
| 
 | 
   129  | 
representations. These functions go below the user level and capture
  | 
| 
 | 
   130  | 
the underlying structure of Isabelle terms in \ML{}\@.  Fortunately the
 | 
| 
 | 
   131  | 
theory developer need not delve in this level; {\tt Sequents.thy}
 | 
| 
 | 
   132  | 
provides the necessary facilities. All the theory developer needs to
  | 
| 
 | 
   133  | 
add in the \ML{} section is a specification of the two translation
 | 
| 
 | 
   134  | 
functions:
  | 
| 
 | 
   135  | 
\begin{ttbox}
 | 
| 
 | 
   136  | 
ML
  | 
| 
 | 
   137  | 
val parse_translation = [("@Trueprop",Sequents.two_seq_tr "Trueprop")];
 | 
| 
 | 
   138  | 
val print_translation = [("Trueprop",Sequents.two_seq_tr' "@Trueprop")];
 | 
| 
 | 
   139  | 
\end{ttbox}
 | 
| 
 | 
   140  | 
  | 
| 
 | 
   141  | 
In summary: in the logic theory being developed, the developer needs
  | 
| 
 | 
   142  | 
to specify the types for the internal and external representation of
  | 
| 
 | 
   143  | 
the sequences, and use the appropriate parsing and pretty-printing
  | 
| 
 | 
   144  | 
functions. 
  | 
| 
 | 
   145  | 
  | 
| 
 | 
   146  | 
\section{What's in \texttt{Sequents.thy}}
 | 
| 
 | 
   147  | 
  | 
| 
 | 
   148  | 
Theory \texttt{Sequents.thy} makes many declarations that you need to know
 | 
| 
 | 
   149  | 
about: 
  | 
| 
 | 
   150  | 
\begin{enumerate}
 | 
| 
 | 
   151  | 
\item The Isabelle types given below, which can be used for the
  | 
| 
 | 
   152  | 
constants that map object-level sequents and meta-level propositions:
  | 
| 
 | 
   153  | 
%
  | 
| 
 | 
   154  | 
\begin{ttbox}
 | 
| 
 | 
   155  | 
 single_seqe = [seq,seqobj] => prop
  | 
| 
 | 
   156  | 
 single_seqi = [seq'=>seq',seq'=>seq'] => prop
  | 
| 
 | 
   157  | 
 two_seqi    = [seq'=>seq', seq'=>seq'] => prop
  | 
| 
 | 
   158  | 
 two_seqe    = [seq, seq] => prop
  | 
| 
 | 
   159  | 
 three_seqi  = [seq'=>seq', seq'=>seq', seq'=>seq'] => prop
  | 
| 
 | 
   160  | 
 three_seqe  = [seq, seq, seq] => prop
  | 
| 
 | 
   161  | 
 four_seqi   = [seq'=>seq', seq'=>seq', seq'=>seq', seq'=>seq'] => prop
  | 
| 
 | 
   162  | 
 four_seqe   = [seq, seq, seq, seq] => prop
  | 
| 
 | 
   163  | 
\end{ttbox}
 | 
| 
 | 
   164  | 
  | 
| 
 | 
   165  | 
The \verb|single_| and \verb|two_| sets of mappings for internal and
  | 
| 
 | 
   166  | 
external representations are the ones used for, say single and
  | 
| 
 | 
   167  | 
multiple conclusion sequents. The other functions are provided to
  | 
| 
 | 
   168  | 
allow rules that manipulate more than two functions, as can be seen in
  | 
| 
 | 
   169  | 
the inbuilt object logics.
  | 
| 
 | 
   170  | 
  | 
| 
 | 
   171  | 
\item An auxiliary syntactic constant has been
  | 
| 
 | 
   172  | 
defined that directly maps a sequence to its internal representation:
  | 
| 
 | 
   173  | 
\begin{ttbox}
 | 
| 
 | 
   174  | 
"@Side"  :: seq=>(seq'=>seq')     ("<<(_)>>")
 | 
| 
 | 
   175  | 
\end{ttbox}
 | 
| 
 | 
   176  | 
Whenever a sequence (such as \verb|<< A, $B, $C>>|) is entered using this
  | 
| 
 | 
   177  | 
syntax, it is translated into the appropriate internal representation.  This
  | 
| 
 | 
   178  | 
form can be used only where a sequence is expected.
  | 
| 
 | 
   179  | 
  | 
| 
 | 
   180  | 
\item The \ML{} functions \texttt{single\_tr}, \texttt{two\_seq\_tr},
 | 
| 
 | 
   181  | 
  \texttt{three\_seq\_tr}, \texttt{four\_seq\_tr} for parsing, that is, the
 | 
| 
 | 
   182  | 
  translation from external to internal form.  Analogously there are
  | 
| 
 | 
   183  | 
  \texttt{single\_tr'}, \texttt{two\_seq\_tr'}, \texttt{three\_seq\_tr'},
 | 
| 
 | 
   184  | 
  \texttt{four\_seq\_tr'} for pretty-printing, that is, the translation from
 | 
| 
 | 
   185  | 
  internal to external form.  These functions can be used in the \ML{} section
 | 
| 
 | 
   186  | 
  of a theory file to specify the translations to be used.  As an example of
  | 
| 
 | 
   187  | 
  use, note that in {\tt LK.thy} we declare two identifiers:
 | 
| 
 | 
   188  | 
\begin{ttbox}
 | 
| 
 | 
   189  | 
val parse_translation =
  | 
| 
 | 
   190  | 
    [("@Trueprop",Sequents.two_seq_tr "Trueprop")];
 | 
| 
 | 
   191  | 
val print_translation =
  | 
| 
 | 
   192  | 
    [("Trueprop",Sequents.two_seq_tr' "@Trueprop")];
 | 
| 
 | 
   193  | 
\end{ttbox}
 | 
| 
 | 
   194  | 
The given parse translation will be applied whenever a \verb|@Trueprop|
  | 
| 
 | 
   195  | 
constant is found, translating using \verb|two_seq_tr| and inserting the
  | 
| 
 | 
   196  | 
constant \verb|Trueprop|.  The pretty-printing translation is applied
  | 
| 
 | 
   197  | 
analogously; a term that contains \verb|Trueprop| is printed as a
  | 
| 
 | 
   198  | 
\verb|@Trueprop|.
  | 
| 
 | 
   199  | 
\end{enumerate}
 | 
| 
 | 
   200  | 
  | 
| 
 | 
   201  | 
  |