src/Tools/isac/Doc/Lucas_Interpreter/Lucas_Interpreter.thy
author Walther Neuper <walther.neuper@jku.at>
Wed, 11 Mar 2020 15:25:52 +0100
changeset 59827 168abe8dd1e3
child 59866 3b194392ea71
permissions -rw-r--r--
start formally checked documentation with Lucas_Interpreter

note: the text is a partial copy from the IJCAR/ThEdu'20 paper
walther@59827
     1
(*<*)
walther@59827
     2
(*%:wrap=soft:maxLineLen=78:*)
walther@59827
     3
(*partially copied from
walther@59827
     4
  ~/material/texts/emat/lucin-isa/paper-isabisac/Lucin_Isa_IJCAR.thy *)
walther@59827
     5
theory Lucas_Interpreter
walther@59827
     6
  imports "~~/src/Tools/isac/Interpret/Interpret"
walther@59827
     7
begin
walther@59827
     8
ML \<open>
walther@59827
     9
  open LI
walther@59827
    10
  open Istate
walther@59827
    11
  open TermC
walther@59827
    12
\<close>
walther@59827
    13
(*>*)
walther@59827
    14
walther@59827
    15
text \<open>
walther@59827
    16
\section{Lucas--Interpretation (\LI)}\label{lucin}
walther@59827
    17
%=============================================================================
walther@59827
    18
The interpreter is named after the inventor of top-down-parsing in the ALGOL 
walther@59827
    19
project~\cite{pl:formal-lang-hist}, Peter Lucas. As a dedicated expert in 
walther@59827
    20
programming languages he initially objected ``yet another programming 
walther@59827
    21
language'' (in analogy to ``Yacc'' \cite{Yacc-1975}), but then he helped to 
walther@59827
    22
clarify the unusual requirements for a novel programming language in the 
walther@59827
    23
\sisac-project, which later led to the notion of \LI. 
walther@59827
    24
walther@59827
    25
\LI{} is the most prominent component in a prototype developed in the 
walther@59827
    26
\sisac-project, there embedded in a mathematics-engine, which interacts with a 
walther@59827
    27
dialogue-module in a Java-based front-end managing interaction with students 
walther@59827
    28
(out of scope of this paper).
walther@59827
    29
walther@59827
    30
\subsection{The Concept of \LI}\label{concept-LI}
walther@59827
    31
%-----------------------------------------------------------------------------
walther@59827
    32
The concept of \LI{} is simple: \LI{} \emph{acts as a debugger on functional 
walther@59827
    33
programs with hard-coded breakpoints, where control is handed over to a 
walther@59827
    34
student; a student, however, does \emph{not} interact with the software 
walther@59827
    35
presenting the program, but with the software presenting steps of forward 
walther@59827
    36
reasoning, where the steps are rigorously constructed by tactics acting as the 
walther@59827
    37
break-points mentioned}. Following the \LI{} terminology, we will call 
walther@59827
    38
``programs'' the functions defined with the function package and refer to 
walther@59827
    39
their evaluation as ``execution''.
walther@59827
    40
walther@59827
    41
\paragraph{Types occurring in the signatures} of \LI{} are as follows. Besides 
walther@59827
    42
the program of type @{ML_type Program.T} there is an interpreter state 
walther@59827
    43
@{ML_type Istate.T}, a record type passing data from one step of execution to 
walther@59827
    44
the next step, in particular a location in the program, where the next step 
walther@59827
    45
will be read off, and an environment for evaluating the step.
walther@59827
    46
As invisible in the program language as the interpreter state is @{ML_type 
walther@59827
    47
Calc.T}, a ``calculation'' as a sequence of steps in forward reasoning, a 
walther@59827
    48
variant of ``structured derivations'' \cite{back-SD-2010}. Visible in the 
walther@59827
    49
language and in the signature, however, are the tactics @{ML_type Tactic.T}, 
walther@59827
    50
which create steps in a calculation.
walther@59827
    51
walther@59827
    52
Novel in connection with calculations is the idea to maintain a logical 
walther@59827
    53
context in order to provide automated provers with data required for checking 
walther@59827
    54
input by the student. Isabelle's @{ML_type Proof.context}, as is, turned out 
walther@59827
    55
perfect for this task~\cite{mlehnf:bakk-11}.
walther@59827
    56
walther@59827
    57
\paragraph{The signatures of the main functions,} the functions @{term 
walther@59827
    58
find_next_step}, \\@{term locate_input_tactic} and @{term locate_input_term}, 
walther@59827
    59
are as follows:\label{sig-lucin}
walther@59827
    60
\<close>
walther@59827
    61
(*<*)ML(*>*) \<open>
walther@59827
    62
signature LUCAS_INTERPRETER =
walther@59827
    63
sig
walther@59827
    64
  datatype next_step_result =
walther@59827
    65
      Next_Step of Istate.T * Proof.context * Tactic.T
walther@59827
    66
    | Helpless | End_Program of Istate.T * Tactic.T
walther@59827
    67
  val find_next_step: Program.T -> Calc.T -> Istate.T -> Proof.context
walther@59827
    68
    -> next_step_result
walther@59827
    69
walther@59827
    70
  datatype input_tactic_result =
walther@59827
    71
      Safe_Step of Istate.T * Proof.context * Tactic.T
walther@59827
    72
    | Unsafe_Step of Istate.T * Proof.context * Tactic.T
walther@59827
    73
    | Not_Locatable of message
walther@59827
    74
  val locate_input_tactic: Program.T -> Calc.T -> Istate.T -> Proof.context
walther@59827
    75
      -> Tactic.T -> input_tactic_result
walther@59827
    76
walther@59827
    77
  datatype input_term_result =
walther@59827
    78
    Found_Step of Calc.T | Not_Derivable
walther@59827
    79
  val locate_input_term: Calc.T -> term -> input_term_result
walther@59827
    80
end
walther@59827
    81
\<close>
walther@59827
    82
text \<open>
walther@59827
    83
\begin{description}
walther@59827
    84
\item[@{term find_next_step}] accomplishes what usually is expected from a 
walther@59827
    85
@{ML_type Program.T}: find a @{term Next_Step} to be executed, in the case of 
walther@59827
    86
\LI{} to be inserted into a \texttt{\small Calc.T} under construction. This 
walther@59827
    87
step can be a @{ML_type Tactic.T}, directly found in @{term next_step_result}, 
walther@59827
    88
or a @{ML_type term} produced by applying the tactic. If such a step cannot be 
walther@59827
    89
found (due to previous student interaction), \LI{} is @{term Helpless}.
walther@59827
    90
walther@59827
    91
\item[@{term locate_input_tactic}] gets a  @{ML_type Tactic.T} as argument 
walther@59827
    92
(which has been input and checked applicable in  @{ML_type  Calc.T}) and tries 
walther@59827
    93
to locate it in the \texttt{Prog.T} such that a @{term Next_Step} can be 
walther@59827
    94
generated from the subsequent location in the @{ML_type Program.T}. A step can 
walther@59827
    95
be an @{term Unsafe_Step}, if the input @{ML_type Tactic.T} cannot safely be 
walther@59827
    96
associated with any tactic in the @{ML_type Program.T}. This function has a 
walther@59827
    97
signature similar to @{term find_next_step} (here the respective input 
walther@59827
    98
@{ML_type Tactic.T} and the one in the result are the same) in order to unify 
walther@59827
    99
internal technicalities of \LI{}.
walther@59827
   100
walther@59827
   101
\item[@{term locate_input_term}] tries to find a derivation from the current 
walther@59827
   102
@{ML_type Proof.context} for the term input to @{ML_type Calc.T} and to locate 
walther@59827
   103
a \texttt{Tactic.T} in the @{ML_type Program.T}, which as @{term Found_Step} 
walther@59827
   104
allows to find a next step later. Such a @{term Found_Step} can be located in 
walther@59827
   105
another program (a sub-program or a calling program); thus @{ML_type 
walther@59827
   106
Program.T}, @{ML_type Istate.T} and @{ML_type Proof.context} are packed into 
walther@59827
   107
@{ML_type Calc.T} at appropriate positions and do not show up in the 
walther@59827
   108
signature.
walther@59827
   109
\end{description}
walther@59827
   110
walther@59827
   111
Automated reasoning is concern of the third function @{term 
walther@59827
   112
locate_input_term}, actually a typical application case for Isabelle's 
walther@59827
   113
Sledgehammer~\cite{sledgehammer-tutorial}, but not yet realised and 
walther@59827
   114
preliminarily substituted by \sisac's simplifier. @{term locate_input_term} is 
walther@59827
   115
the function used predominantly in interaction with students: these input term 
walther@59827
   116
by term into the calculation under construction (as familiar from 
walther@59827
   117
paper\&pencil work) and \LI{} checks for correctness automatically.
walther@59827
   118
\<close>
walther@59827
   119
text \<open>
walther@59827
   120
\subsection{Examples for \LI}\label{expl-lucin}
walther@59827
   121
%-----------------------------------------------------------------------------
walther@59827
   122
\LI's novel concept relating program execution with construction of 
walther@59827
   123
calculations is best demonstrated by examples. The first one is from 
walther@59827
   124
structural engineering given by the following problem statement:\\
walther@59827
   125
\medskip
walther@59827
   126
walther@59827
   127
% first column
walther@59827
   128
\begin{minipage}{0.55\textwidth}
walther@59827
   129
\textit{Determine the bending line of a beam of length $L$,
walther@59827
   130
which consists of homogeneous material, which is clamped on one side
walther@59827
   131
and which is under constant line load $q_0$; see the Figure right.}\\
walther@59827
   132
\end{minipage}
walther@59827
   133
\hfill
walther@59827
   134
%second column
walther@59827
   135
\begin{minipage}{0.42\textwidth}
walther@59827
   136
  \includegraphics[width=0.6\textwidth]{bend-7-70-en.png}\\
walther@59827
   137
\end{minipage}
walther@59827
   138
walther@59827
   139
\medskip
walther@59827
   140
This problem is solved by the following program, which is shown by a 
walther@59827
   141
screen-shot\footnote{The corresponding code is at 
walther@59827
   142
\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/df1b56b0d2a2/src/Tools/isac/Knowledge/Biegelinie.thy\#l174}.
walther@59827
   143
%When inner syntax double-quotes are discontinued eventually, the inner syntax 
walther@59827
   144
of the HOL library may use double quotes for char/string literals, instead of 
walther@59827
   145
slightly odd double single-quotes.
walther@59827
   146
}
walther@59827
   147
in order to demonstrate the colouring helpful for programmers (compare the old 
walther@59827
   148
bare string version in \cite[p.~92]{wn:proto-sys}).
walther@59827
   149
\begin{figure} [htb]
walther@59827
   150
  \centering
walther@59827
   151
  \includegraphics[width=\textwidth]{fun-pack-biegelinie-2.png}
walther@59827
   152
  \caption{The program implemented by the function package}
walther@59827
   153
  \label{fig:fun-pack-biegelinie}
walther@59827
   154
\end{figure}
walther@59827
   155
The program is implemented as a @{theory_text partial_function}: it calculates 
walther@59827
   156
results for a whole class of problems and termination cannot be proven in such 
walther@59827
   157
generality, although preconditions guard execution.
walther@59827
   158
%
walther@59827
   159
The program reflects a ``divide \& conquer'' strategy by calling three @{term 
walther@59827
   160
SubProblem}s. It was implemented for field-tests in German-speaking countries, 
walther@59827
   161
so arguments of the @{term SubProblem}s are in German, because they appear in 
walther@59827
   162
the calculation as well. The third @{term SubProblem} adopts the format from 
walther@59827
   163
Computer Algebra. The calculation, if finished successfully, looks as follows 
walther@59827
   164
(a screen-shot of intermediate steps on the prototype's front-end is shown in 
walther@59827
   165
\cite[p.~97]{wn:proto-sys}):\label{biegel_calc}
walther@59827
   166
{\footnotesize\begin{tabbing}
walther@59827
   167
123\=12\=12\=12\=12\=12\=12\=123\=123\=123\=123\=\kill
walther@59827
   168
01\> Problem (Biegelinie, [Biegelinien]) \\
walther@59827
   169
02\>\> Specification: \\
walther@59827
   170
03\>\> Solution: \\
walther@59827
   171
04\>\>\> Problem (Biegelinie, [vonBelastungZu, Biegelinien]) \\
walther@59827
   172
05\>\>\> $[$\>$V\,x = c + -1\cdot q_0\cdot x, $\\
walther@59827
   173
06\>\>\>    \>$M_b\,x = c_2 + c\cdot x + \frac{-1\cdot q_0}{2\cdot x ^ 2}, $\\
walther@59827
   174
07\>\>\>    \>$\frac{d}{dx}y\,x =  c_3 + \frac{-1}{EI} \cdot (c_2\cdot x + 
walther@59827
   175
\frac{c}{2\cdot x ^ 2} + \frac{-1\cdot q_0}{6\cdot x ^ 3}, $\\
walther@59827
   176
08\>\>\>    \>$y\,x =  c_4 + c_3\cdot x +  \frac{-1}{EI} \cdot  
walther@59827
   177
(\frac{c_2}{2}\cdot x ^ 2 + \frac{c}{6}\cdot x ^ 3 + \frac{-1\cdot 
walther@59827
   178
q_0}{24}\cdot x ^ 4)\;\;]$ \\
walther@59827
   179
09\>\>\> Problem (Biegelinie, [setzeRandbedingungen, Biegelinien])\\
walther@59827
   180
10\>\>\> $[$\>$L \cdot q_0 = c,\; 0 = \frac{2 \cdot c_2 + 2 \cdot L \cdot c + 
walther@59827
   181
-1 \dot L ^ 2 \cdot q_0}{2},\; 0 = c_4,\; 0 = c_3\;\;]$\\
walther@59827
   182
11\>\>\> solveSystem $(L \cdot q_0 = c,\; 0 = \frac{2 \cdot c_2 + 2 \cdot L 
walther@59827
   183
\cdot c + -1 \cdot L ^ 2 \cdot q_0}{2},\; 0 = c_4,\; 0 = c_3\;\;],\; [c, c_2, 
walther@59827
   184
c_3, c_4])$\\
walther@59827
   185
12\>\>\> $[$\>$c = L \cdot q_0 ,\; c_2 = \frac{-1 \cdot L ^ 2 \cdot q_0}{2},\; 
walther@59827
   186
c_3 = 0,\; c_4 = 0]$\\
walther@59827
   187
13  \` Take $y\,x =  c_4 + c_3\cdot x +  \frac{-1}{EI} \cdot  
walther@59827
   188
(\frac{c_2}{2}\cdot x ^ 2 + \frac{c}{6}\cdot x ^ 3 + \frac{-1\cdot 
walther@59827
   189
q_0}{24}\cdot x ^ 4)$ \\
walther@59827
   190
walther@59827
   191
14\>\>\> $y\,x = c_4 + c_3 \cdot x + \frac{-1}{EI} \cdot (\frac{c_2}{2} \cdot 
walther@59827
   192
x ^ 2 + \frac{c}{6} \cdot x ^ 3 + \frac{-1 \cdot q_0}{24} \cdot x ^ 4)$\\
walther@59827
   193
15  \` Substitute $[c,c_2,c_3,c_4]$ \\
walther@59827
   194
walther@59827
   195
16\>\>\> $y\,x = 0 + 0 \cdot x + \frac{-1}{EI} \cdot (\frac{\frac{-1 \cdot L ^ 
walther@59827
   196
2 \cdot q_0}{2}}{2} \cdot x ^ 2 + \frac{L \cdot q_0}{6} \cdot x ^ 3 + \frac{-1 
walther@59827
   197
\cdot q_0}{24} \cdot x ^ 4)$\label{exp-biegel-Substitute}\\
walther@59827
   198
17  \` Rewrite\_Set\_Inst $([({\it bdv},x)], {\it make\_ratpoly\_in})$ \\
walther@59827
   199
walther@59827
   200
18\>\>\> $y\;x = \frac{q_0 \cdot L ^ 2}{4 \cdot EI} \cdot x ^ 2 + \frac{L 
walther@59827
   201
\cdot q_0 }{6 \cdot EI} \cdot x ^ 3 + \frac{q_0}{24 \cdot EI} \cdot x ^ 4$\\
walther@59827
   202
19\> $y\;x = \frac{q_0 \cdot L ^ 2}{4 \cdot EI} \cdot x ^ 2 + \frac{L \cdot 
walther@59827
   203
q_0 }{6 \cdot EI} \cdot x ^ 3 + \frac{q_0}{24 \cdot EI} \cdot x ^ 4$
walther@59827
   204
\end{tabbing}}
walther@59827
   205
The calculation is what a student interacts with. Above the \texttt{\small 
walther@59827
   206
Specification} is folded in, the specification phase and respective user 
walther@59827
   207
interaction is skipped here. The \texttt{\small Solution} must be constructed 
walther@59827
   208
step-wise line by line (while the line numbers do not belong to the 
walther@59827
   209
calculation) in forward reasoning. 
walther@59827
   210
\label{1-2-3}A student inputs either (1) a term (displayed on the left above 
walther@59827
   211
with indentations) or (2) a tactic (shifted to the right margin). If the 
walther@59827
   212
student gets stuck (3) a next step (as a term or a tactic) is suggested by 
walther@59827
   213
\LI{}, which works behind the scenes; the corresponding functions have been 
walther@59827
   214
introduced in \S\ref{concept-LI} (for (1) @{term locate_input_term}, (2) 
walther@59827
   215
@{term locate_input_tactic} and for (3) @{term find_next_step}).
walther@59827
   216
walther@59827
   217
\medskip
walther@59827
   218
This example hopefully clarifies the relation between program and calculation 
walther@59827
   219
in \LI{}: execution of the program stops at tactics (above called  
walther@59827
   220
break-points), displays the tactic or the result produced by the tactic (as 
walther@59827
   221
decided by the dialogue-module) in the calculation under construction, hands 
walther@59827
   222
over control to the student working on the calculation and resumes checking 
walther@59827
   223
user input.
walther@59827
   224
walther@59827
   225
\paragraph{A typical example from Computer Algebra}\label{expl-rewrite} shall 
walther@59827
   226
shed light on a notions introduced later, on tacticals. The program in 
walther@59827
   227
Fig.\ref{fig:fun-pack-diff} %on p.\pageref{fig:fun-pack-diff}
walther@59827
   228
simplifies rational terms (typed as ``real'' due to limited development 
walther@59827
   229
resources):
walther@59827
   230
\begin{figure} [htb]
walther@59827
   231
  \centering
walther@59827
   232
  \includegraphics[width=0.95\textwidth]{fun-pack-simplify.png}
walther@59827
   233
 %\includegraphics[width=0.85\textwidth]{fig/scrshot/fun-pack/fun-pack-diff.png}
walther@59827
   234
  \caption{Simplification implemented by the function package}
walther@59827
   235
  \label{fig:fun-pack-diff}
walther@59827
   236
\end{figure}
walther@59827
   237
walther@59827
   238
The program executes the tactic @{const Rewrite'_Set}\footnote{Isabelle's 
walther@59827
   239
document preparation system preserves the apostroph from the definition, while 
walther@59827
   240
Isabelle's pretty printer drops it in the presentation of the program as 
walther@59827
   241
above.}
walther@59827
   242
with different canonical term rewriting systems (called ``rule sets'' in 
walther@59827
   243
\sisac) guided by tacticals. The output (disregarding user interaction) is a 
walther@59827
   244
calculation with steps of simplification, where the steps are created by  
walther@59827
   245
@{const Rewrite'_Set}.
walther@59827
   246
walther@59827
   247
Chained functions (by \texttt{\small \#>}) %TODO which antiquot?
walther@59827
   248
are applied curried to @{ML_type term}. The initial part of the chain, from 
walther@59827
   249
\texttt{\small ''discard\_minus''} to \texttt{\small ''cancel''} does 
walther@59827
   250
preprocessing, for instance replaces $\;a - b\;$ by $\;a + (-b)\;$ in 
walther@59827
   251
\texttt{\small ''discard\_minus''} for reducing 
walther@59827
   252
the number of theorems to be used in simplification.
walther@59827
   253
%
walther@59827
   254
The second chain of @{const Rewrite'_Set} is @{const Repeat}ed until no 
walther@59827
   255
further rewrites are possible; this is necessary in case of nested fractions.
walther@59827
   256
walther@59827
   257
In cases like the one above, a confluent and terminating term rewrite system, 
walther@59827
   258
not only \emph{all} correct input terms are accepted, but also \emph{all} 
walther@59827
   259
incorrect input is rejected as @{term Not_Derivable} by the function  @{term 
walther@59827
   260
locate_input_term}.
walther@59827
   261
walther@59827
   262
walther@59827
   263
\section{Adaptation of Isabelle's Functions}\label{lucin-funpack}
walther@59827
   264
%=============================================================================
walther@59827
   265
Isabelle's function package presents functions in ``inner syntax'' to users, 
walther@59827
   266
i.e. as terms in Isabelle/HOL. The \LI{} design recognised these terms 
walther@59827
   267
suitable for parse trees of programs, Isabelle realised the same idea in a 
walther@59827
   268
more general way with the function package a few years later --- so migration 
walther@59827
   269
from \sisac's programs to Isabelle's functions was surprisingly easy. The main 
walther@59827
   270
features required were tactics, tacticals and program expressions as described 
walther@59827
   271
below.
walther@59827
   272
walther@59827
   273
\subsection{Tactics Creating Steps in Calculations}\label{tactics}
walther@59827
   274
%-----------------------------------------------------------------------------
walther@59827
   275
The examples in the previous section showed how tactics in programs create 
walther@59827
   276
steps in calculations. Tactics in programs are defined as follows\footnote{
walther@59827
   277
\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/df1b56b0d2a2/src/Tools/isac/ProgLang/Prog_Tac.thy\#l36}}
walther@59827
   278
:
walther@59827
   279
\<close>
walther@59827
   280
consts
walther@59827
   281
  Calculate          :: "[char list, 'a] => 'a"
walther@59827
   282
  Rewrite            :: "[char list, 'a] => 'a"
walther@59827
   283
  Rewrite'_Inst      :: "[(char list * 'a) list, char list, 'a] => 'a"   
walther@59827
   284
  Rewrite'_Set       :: "[char list, 'a] => 'a"
walther@59827
   285
  Rewrite'_Set'_Inst :: "[((char list) * 'a) list, char list, 'a] => 'a"
walther@59827
   286
  Or'_to'_List       :: "bool => 'a list"
walther@59827
   287
  SubProblem         ::
walther@59827
   288
    "[char list * char list list * char list list, arg list] => 'a"
walther@59827
   289
  Substitute         :: "[bool list, 'a] => 'a"
walther@59827
   290
  Take               :: "'a => 'a"
walther@59827
   291
walther@59827
   292
text \<open>
walther@59827
   293
These tactics transform a term of some type @{typ "'a"} to a resulting term of 
walther@59827
   294
the same type.  @{const[names_short] Calculate} applies operators like $+,-,*$ 
walther@59827
   295
as @{typ "char list"} (i.e. a string in inner syntax) to numerals of type  
walther@59827
   296
@{typ "'a"}. The tactics beginning with @{const[names_short] Rewrite} do 
walther@59827
   297
exactly what they indicate by applying a theorem (in the program given by type 
walther@59827
   298
@{typ "char list"}) or a list of theorems, called  ``rule-set''. The 
walther@59827
   299
corresponding \texttt{\small \_Inst} variants instantiate bound variables with 
walther@59827
   300
respective constants before rewriting (this is due to the user requirement, 
walther@59827
   301
that terms in calculations are close to traditional notation, which excludes 
walther@59827
   302
$\lambda$-terms), for instance modelling bound variables in equation solving. 
walther@59827
   303
@{const[names_short] Or'_to'_List} is due to a similar requirement: logically 
walther@59827
   304
appropriate for describing solution sets in equation solving are equalities 
walther@59827
   305
connected by $\land,\lor$, but traditional notation uses sets (and these are 
walther@59827
   306
still lists for convenience). @{const[names_short] SubProblem}s not only take 
walther@59827
   307
arguments (@{typ "arg list"} like any (sub-)program, but also three references 
walther@59827
   308
into \sisac's knowledge base  (theory, formal specification, method) for 
walther@59827
   309
guided interaction in the specification phase.
walther@59827
   310
walther@59827
   311
Tactics appear simple: they operate on terms adhering to one type --- 
walther@59827
   312
different types are handled by different tactics and (sub-) programs; and they 
walther@59827
   313
cover only basic functionality --- but they operate on terms, which are well 
walther@59827
   314
tooled by Isabelle and which can contain functions evaluated as program 
walther@59827
   315
expressions introduced in the next but one subsection.
walther@59827
   316
walther@59827
   317
Section \S\ref{expl-lucin} showed how tactics can be input by students. So 
walther@59827
   318
tactics in programs have analogies for user input with type @{ML_type 
walther@59827
   319
Tactic.input} defined at\footnote{
walther@59827
   320
\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/df1b56b0d2a2/src/Tools/isac/MathEngBasic/tactic-def.sml\#l122}}. These tactics also cover the specification phase (wich is out of scope of the 
walther@59827
   321
paper). And there is another @{ML_type Tactic.T} defined at\footnote{
walther@59827
   322
\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/df1b56b0d2a2/src/Tools/isac/MathEngBasic/tactic-def.sml\#l241}} for internal use by the mathematics-engine, which already appeared in the 
walther@59827
   323
signature of Lucas-Interpretation on p.\pageref{sig-lucin}.
walther@59827
   324
walther@59827
   325
\subsection{Tacticals Guiding Flow of Execution}\label{tacticals}
walther@59827
   326
%-----------------------------------------------------------------------------
walther@59827
   327
The example on p.\pageref{expl-rewrite} for canonical rewriting showed, how 
walther@59827
   328
tacticals guide the flow of execution. The complete list of tacticals is as 
walther@59827
   329
follows.
walther@59827
   330
\<close>
walther@59827
   331
consts
walther@59827
   332
  Chain    :: "['a => 'a, 'a => 'a, 'a] => 'a" (infixr "#>" 10)
walther@59827
   333
  If       :: "[bool, 'a => 'a, 'a => 'a, 'a] => 'a"
walther@59827
   334
  Or       :: "['a => 'a, 'a => 'a, 'a] => 'a" (infixr "Or" 10)
walther@59827
   335
  Repeat   :: "['a => 'a, 'a] => 'a" 
walther@59827
   336
  Try      :: "['a => 'a, 'a] => 'a"
walther@59827
   337
  While    :: "[bool, 'a => 'a, 'a] => 'a" ("((While (_) Do)//(_))" 9)
walther@59827
   338
walther@59827
   339
text \<open>
walther@59827
   340
\texttt{\small Chain}  is forward application of functions and made an infix 
walther@59827
   341
operator @{const[names_short] Chain}; @{const[names_short] If} decides by 
walther@59827
   342
@{typ bool}en expression for execution of one of two arguments of type @{typ 
walther@59827
   343
"'a => 'a"} (which can be combinations of tacticals or tactics); 
walther@59827
   344
@{const[names_short] Or} decides on execution of one of the arguments 
walther@59827
   345
depending of applicability of tactics; @{const[names_short] Repeat} is a one 
walther@59827
   346
way loop which terminates, if the argument is not applicable (e.g. 
walther@59827
   347
applicability of a theorem for rewriting on a term) any more; 
walther@59827
   348
@{const[names_short] Try} skips the argument if not applicable and 
walther@59827
   349
@{const[names_short] While} is a zero way loop as usual.
walther@59827
   350
walther@59827
   351
\subsection{Program Expressions to be Evaluated}\label{prog-expr}
walther@59827
   352
%-----------------------------------------------------------------------------
walther@59827
   353
Some tacticals, \texttt{If} and \texttt{While}, involve boolean expressions, 
walther@59827
   354
which need to be evaluated: such expressions denote another element of 
walther@59827
   355
programs. This kind of element has been shown in the example on 
walther@59827
   356
p.\pageref{fig:fun-pack-biegelinie} as argument of  @{const[names_short] 
walther@59827
   357
Take}: sometimes it is necessary to pick parts of elements of a calculation, 
walther@59827
   358
for instance the last element from a list. So Isabelle's @{theory_text List} 
walther@59827
   359
is adapted for \sisac's purposes in @{theory_text ListC}\footnote{
walther@59827
   360
\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/df1b56b0d2a2/src/Tools/isac/ProgLang/ListC.thy}}.
walther@59827
   361
%
walther@59827
   362
Such expressions are substituted from the environment in @{ML_type Istate.T}, 
walther@59827
   363
evaluated to terms by rewriting (and for that purpose using the same rewrite 
walther@59827
   364
engine as for the tactics @{const[names_short] Rewrite}*) and marked by the 
walther@59827
   365
constructor @{term Term_Val} which is introduced below.
walther@59827
   366
walther@59827
   367
walther@59827
   368
\section{Implementation of \LI}\label{LI-impl}
walther@59827
   369
%=============================================================================
walther@59827
   370
The implementation of the interpreter is as experimental as is the respective 
walther@59827
   371
programming language introduced in the previous section. So below there will 
walther@59827
   372
be particularly such implementation details, which are required for discussing 
walther@59827
   373
open design \& implementation issues.
walther@59827
   374
walther@59827
   375
All of the function package's syntactic part plus semantic markup is perfect 
walther@59827
   376
for \LI. The evaluation part of the function package, however, implements 
walther@59827
   377
automated evaluation in one go and automated 
walther@59827
   378
code-generation~\cite{code-gen-tutorial} --- both goals are not compatible 
walther@59827
   379
with \sisac's goal to feature step-wise construction of calculations, so this 
walther@59827
   380
part had to be done from scratch.
walther@59827
   381
walther@59827
   382
walther@59827
   383
\subsection{Scanning the Parse Tree}\label{scanning}
walther@59827
   384
%-----------------------------------------------------------------------------
walther@59827
   385
Isabelle's function package parses the program body from function definitions 
walther@59827
   386
to terms, the data structure of simply typed $\lambda$ terms, which also 
walther@59827
   387
encode the objects of proofs. Thus there is a remarkable collection of tools, 
walther@59827
   388
readily available in Isabelle; but this collection does not accommodate the 
walther@59827
   389
requirement of scanning a term to a certain location, remembering the location 
walther@59827
   390
and returning there later, as required by \LI. So this has been introduced
walther@59827
   391
\<close> 
walther@59827
   392
(*<*)ML(*>*) \<open>
walther@59827
   393
datatype lrd = L | R | D
walther@59827
   394
type path = lrd list
walther@59827
   395
\<close> 
walther@59827
   396
(*<*)ML \<open>
walther@59827
   397
open TermC (*avoids type clashes below from the new typ above*)
walther@59827
   398
\<close> 
walther@59827
   399
    ML(*>*) \<open>
walther@59827
   400
fun at_location [] t = t
walther@59827
   401
  | at_location (D :: p) (Abs(_, _, body)) = at_location p body
walther@59827
   402
  | at_location (L :: p) (t1 $ _) = at_location p t1
walther@59827
   403
  | at_location (R :: p) (_ $ t2) = at_location p t2
walther@59827
   404
  | at_location l t =
walther@59827
   405
    raise TERM ("at_location: no " ^ string_of_path l ^ " for ", [t]);
walther@59827
   406
\<close>
walther@59827
   407
text \<open>
walther@59827
   408
with a @{term path} to a location according to the term constructors 
walther@59827
   409
\texttt{\small \$} and @{term Abs}. This is an implementation detail; an 
walther@59827
   410
abstract, denotational view starts with this datatype
walther@59827
   411
\<close> 
walther@59827
   412
(*<*)ML(*>*) \<open>
walther@59827
   413
datatype expr_val =
walther@59827
   414
    Term_Val of term  | Reject_Tac
walther@59827
   415
  | Accept_Tac of Istate.pstate * Proof.context * Tactic.T
walther@59827
   416
\<close>
walther@59827
   417
text \<open>
walther@59827
   418
which models the meaning of an expression in the parse-tree: this is either a  
walther@59827
   419
@{term Term_Val}ue  (introduced in \S\ref{prog-expr}) or a tactic (introduced 
walther@59827
   420
in \S\ref{tactics}); the latter is either accepted by  @{term Accept_Tac} or 
walther@59827
   421
rejected by  @{term Reject_Tac}; an error value is still missing.
walther@59827
   422
%
walther@59827
   423
The arguments of the above constant @{term Accept_Tac} are the same as 
walther@59827
   424
introduced for \LI{} in \S\ref{concept-LI}. Thus @{ML_type expr_val} is the 
walther@59827
   425
return value for functions scanning the parse-tree for an acceptable tactic:
walther@59827
   426
\<close> 
walther@59827
   427
(*<*)ML \<open>
walther@59827
   428
open LI (*avoids type clashes below from the new typ above*)
walther@59827
   429
\<close> 
walther@59827
   430
    ML(*>*) \<open>
walther@59827
   431
scan_to_tactic: term * (Calc.T * Proof.context) -> Istate.T -> expr_val;
walther@59827
   432
scan_dn: Calc.T * Proof.context -> Istate.pstate -> term -> expr_val;
walther@59827
   433
go_scan_up: term * (Calc.T * Proof.context) -> Istate.pstate -> expr_val;
walther@59827
   434
scan_up: term * (Calc.T * Proof.context) -> Istate.pstate -> term -> expr_val;
walther@59827
   435
check_tac: Calc.T * Proof.context -> Istate.pstate -> term * term option -> 
walther@59827
   436
expr_val;
walther@59827
   437
\<close>
walther@59827
   438
text \<open>
walther@59827
   439
The first argument of each function above, if of type  @{ML_type term}, is the 
walther@59827
   440
whole program. It is not required by @{term scan_dn}, simple top-down 
walther@59827
   441
scanning, and by @{term check_tac}, if a tactic has been reached. The 
walther@59827
   442
rightmost argument, if of type  @{ML_type term}, serves matching as shown 
walther@59827
   443
later. @{term scan_to_tactic} recognises, whether interpretation is just 
walther@59827
   444
starting a new program (@{term "path = []"}) or interpretation resumes at a 
walther@59827
   445
certain location:
walther@59827
   446
\<close> 
walther@59827
   447
(*<*)ML \<open>
walther@59827
   448
open Celem
walther@59827
   449
open LI
walther@59827
   450
\<close> 
walther@59827
   451
    ML(*>*) \<open>
walther@59827
   452
fun scan_to_tactic (prog, cc) (Pstate (ist as {path, ...})) =
walther@59827
   453
    if path = []
walther@59827
   454
    then scan_dn cc (ist |> set_path [R]) (Program.body_of prog)
walther@59827
   455
    else go_scan_up (prog, cc) ist
walther@59827
   456
  | scan_to_tactic _ _ =
walther@59827
   457
    raise ERROR "scan_to_tactic1: uncovered pattern in fun.def"
walther@59827
   458
\<close>
walther@59827
   459
    text \<open>
walther@59827
   460
@{term scan_dn} sets the path in the interpreter state @{term ist} to @{term 
walther@59827
   461
R}, the program body, while @{term go_scan_up} goes one level up the path in 
walther@59827
   462
order to call @{term go_scan_up}. Both functions, scanning down and up, are 
walther@59827
   463
shown below\footnote{
walther@59827
   464
Referring to the example in Fig.\ref{fig:fun-pack-diff} on 
walther@59827
   465
p.\pageref{fig:fun-pack-diff} we show the interpreter code only for tacticals 
walther@59827
   466
@{const[names_short] Try}, @{const[names_short] Repeat} and chaining 
walther@59827
   467
\texttt{\small \#>} (which is \texttt{\small "Tactical.Chain"} in the code). 
walther@59827
   468
We also omit the cases for uncurried application, which only occurs once (in 
walther@59827
   469
the first, i.e. the out-most @{const[names_short] Try}) in the example.
walther@59827
   470
}:
walther@59827
   471
\<close> 
walther@59827
   472
(*<*)ML(*>*) \<open>
walther@59827
   473
fun scan_dn cc (ist as {act_arg, ...}) (Const ("Tactical.Try", _) $ e) =
walther@59827
   474
    (case scan_dn cc (ist |> path_down [R]) e of
walther@59827
   475
      Reject_Tac => Term_Val act_arg
walther@59827
   476
    | goback => goback)
walther@59827
   477
  | scan_dn cc ist (Const ("Tactical.Repeat", _) $ e) =
walther@59827
   478
    scan_dn cc (ist |> path_down [R]) e
walther@59827
   479
  | scan_dn cc ist (Const ("Tactical.Chain"(*2*), _) $ e1 $ e2) =
walther@59827
   480
    (case scan_dn cc (ist |> path_down [L, R]) e1 of
walther@59827
   481
	    Term_Val v => scan_dn cc (ist |> path_down [R] |> set_act v) e2
walther@59827
   482
    | goback => goback)
walther@59827
   483
(*|*)
walther@59827
   484
  | scan_dn (cc as (_, ctxt)) (ist as {eval, ...}) t =
walther@59827
   485
    if Tactical.contained_in t
walther@59827
   486
    then raise TERM ("scan_dn expects Prog_Tac or Prog_Expr", [t])
walther@59827
   487
    else
walther@59827
   488
      case LItool.check_leaf "next  " ctxt eval (get_subst ist) t of
walther@59827
   489
  	    (Program.Expr s, _) => Term_Val s
walther@59827
   490
      | (Program.Tac prog_tac, form_arg) =>
walther@59827
   491
          check_tac cc ist (prog_tac, form_arg)
walther@59827
   492
\<close>
walther@59827
   493
    text \<open>
walther@59827
   494
The last case of @{term scan_dn} must have reached a leaf. @{term check_leaf} 
walther@59827
   495
distinguishes between @{term Expr} and @{term Tac}; the former returns a 
walther@59827
   496
@{term Term_Val}, the latter returns the result of @{term check_tac} called by 
walther@59827
   497
@{term scan_dn}, where the result is either @{term Accept_Tac} or @{term 
walther@59827
   498
Reject_Tac}. In case of  @{term Accept_Tac} scanning is stalled (in 
walther@59827
   499
\S\ref{expl-lucin} such a tactic has been called a beak-point), the respective 
walther@59827
   500
tactic is returned (together with corresponding @{ML_type Istate.T} and 
walther@59827
   501
@{ML_type Proof.context}) to the mathematics-engine. 
walther@59827
   502
In case of @{term Reject_Tac} an explicit back tracking by @{term scan_up} 
walther@59827
   503
tries other branches with @{term scan_dn}.
walther@59827
   504
walther@59827
   505
\medskip
walther@59827
   506
@{term scan_up} is as simple as @{term scan_dn}; an essential difference is, 
walther@59827
   507
that the former requires the whole program for @{term go_scan_up} as follows:
walther@59827
   508
\<close> 
walther@59827
   509
(*<*)ML(*>*) \<open>
walther@59827
   510
fun go_scan_up (pcc as (sc, _)) (ist as {path, act_arg, found_accept,...})=
walther@59827
   511
    if path = [R]
walther@59827
   512
    then
walther@59827
   513
      if found_accept then Term_Val act_arg else Reject_Tac
walther@59827
   514
    else 
walther@59827
   515
      scan_up pcc (ist |> path_up) (go_up path sc)
walther@59827
   516
and scan_up pcc ist (Const ("Tactical.Try"(*2*), _) $ _) = go_scan_up pcc ist
walther@59827
   517
  | scan_up (pcc as (_, cc)) ist (Const ("Tactical.Repeat"(*2*), _) $ e) =
walther@59827
   518
    (case scan_dn cc (ist |> path_down [R]) e of
walther@59827
   519
      Accept_Tac ict => Accept_Tac ict
walther@59827
   520
    | Reject_Tac => go_scan_up pcc ist
walther@59827
   521
    | Term_Val v => go_scan_up pcc (ist |> set_act v |> set_found))
walther@59827
   522
  | scan_up pcc ist (Const ("Tactical.Chain"(*2*), _) $ _ $ _) =
walther@59827
   523
    go_scan_up pcc ist
walther@59827
   524
  | scan_up (pcc as (sc, cc)) ist (Const ("Tactical.Chain"(*3*), _) $ _) =
walther@59827
   525
      let 
walther@59827
   526
        val e2 = check_Seq_up ist sc
walther@59827
   527
      in
walther@59827
   528
        case scan_dn cc (ist |> path_up_down [R]) e2 of
walther@59827
   529
          Accept_Tac ict => Accept_Tac ict
walther@59827
   530
        | Reject_Tac => go_scan_up pcc (ist |> path_up)
walther@59827
   531
        | Term_Val v => go_scan_up pcc (ist |> path_up |> set_act v |> 
walther@59827
   532
set_found)
walther@59827
   533
      end
walther@59827
   534
(*|*)
walther@59827
   535
\<close>
walther@59827
   536
text \<open>
walther@59827
   537
\subsection{Use of Isabelle's Contexts}\label{ctxt}
walther@59827
   538
%-----------------------------------------------------------------------------
walther@59827
   539
Isabelle's \textit{``logical context represents the background that is 
walther@59827
   540
required for formulating statements and composing proofs. It acts as a medium 
walther@59827
   541
to produce formal content, depending on earlier material (declarations, 
walther@59827
   542
results etc.).''} \cite{implem-tutorial}. The \sisac-prototype introduced 
walther@59827
   543
Isabelle's @{ML_structure Context} in collaboration with a 
walther@59827
   544
student~\cite{mlehnf:bakk-11}, now uses them throughout construction of 
walther@59827
   545
problem solutions and implements a specific structure @{ML_structure 
walther@59827
   546
ContextC}\footnote{A closing ``C'' indicates an \sisac{} extension, see 
walther@59827
   547
{\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/00612574cbfd/src/Tools/isac/CalcElements/contextC.sml}}}.
walther@59827
   548
walther@59827
   549
At the beginning of the specification phase (briefly touched by tactic 
walther@59827
   550
@{term[names_short] SubProblem} in \S\ref{expl-lucin} and explained in little 
walther@59827
   551
more detail in the subsequent section) an Isabelle theory must be specified, 
walther@59827
   552
this is followed by \texttt{\small Proof\_Context.init\_global} in the 
walther@59827
   553
specification module. Then \texttt{\small Proof\_Context.initialise'} takes a 
walther@59827
   554
formalisation of the problem as strings, which are parsed by \texttt{\small  
walther@59827
   555
Syntax.read\_term} using the context, and finally the resulting term's types 
walther@59827
   556
are recorded in the context by \texttt{\small Variable.declare\_constraints}. 
walther@59827
   557
The latter relieves students from type constraints for input terms. Finally, 
walther@59827
   558
as soon as a problem type is specified, the respective preconditions are 
walther@59827
   559
stored by \texttt{\small ContextC.insert\_assumptions}.
walther@59827
   560
walther@59827
   561
\medskip
walther@59827
   562
During \LI{} the context is updated with assumptions generated by conditional 
walther@59827
   563
rewriting and by switching to and from sub-programs. An example for the former 
walther@59827
   564
is tactic  @{term[names_short] SubProblem} applied with theorem $x \ne 0 
walther@59827
   565
\Rightarrow (\frac{a}{x} = b) = (a = b\cdot x)$ during equation solving.
walther@59827
   566
walther@59827
   567
A still not completely solved issue is switching to and from 
walther@59827
   568
@{term[names_short] SubProblem}s; the scope of an interpreter's environment is 
walther@59827
   569
different from a logical context's scope. When calling a sub-program, \sisac{} 
walther@59827
   570
uses \texttt{\small Proof\_Context.initialise}, but returning execution from a 
walther@59827
   571
@{term[names_short] SubProblem} is not so clear. For instance, if such a 
walther@59827
   572
sub-program determined the solutions $[x=0,\;x=\sqrt{2}]$, while the calling 
walther@59827
   573
program maintains the assumption $x\not=0$ from above, then the solution $x=0$ 
walther@59827
   574
must be dropped, this is clear. But how determine in full generality, which 
walther@59827
   575
context data to consider when returning execution to a calling program? 
walther@59827
   576
Presently the decision in \texttt{\small 
walther@59827
   577
ContextC.subpbl\_to\_caller}\footnote{
walther@59827
   578
\url{https://hg.risc.uni-linz.ac.at/wneuper/isa/file/ce071aa3eae4/src/Tools/isac/CalcElements/contextC.sml\#l73}} 
walther@59827
   579
is, to transfer all content data which contain at least one variable of the 
walther@59827
   580
calling program and drop them on contradiction.
walther@59827
   581
walther@59827
   582
\subsection{Guarding and Embedding Execution}\label{embedding}
walther@59827
   583
%-----------------------------------------------------------------------------
walther@59827
   584
Guardin
walther@59827
   585
walther@59827
   586
@{theory_text partial_function}s as used by \LI{} are alien to HOL for 
walther@59827
   587
fundamental reasons. And when the \sisac-project started with the aim to 
walther@59827
   588
support learning mathematics as taught at engineering faculties, it was clear, 
walther@59827
   589
that formal specifications should guard execution of programs under \LI{} 
walther@59827
   590
(i.e. execution only starts, when the specification's preconditions evaluate 
walther@59827
   591
to true).
walther@59827
   592
walther@59827
   593
So formal specification is required for technical reasons \emph{and} for 
walther@59827
   594
educational reasons in engineering education. The \sisac-project designed a 
walther@59827
   595
separate specification phase, where input to a problem and corresponding 
walther@59827
   596
output as well as preconditions and post-condition are handled explicitly by 
walther@59827
   597
students; example in  Fig.\ref{fig:fun-pack-biegelinie} shows several 
walther@59827
   598
@{term[names_short] SubProblem}s, which lead to mutual recursion between 
walther@59827
   599
specification phase and phases creating a solution (supported by \LI).
walther@59827
   600
walther@59827
   601
\paragraph{Embedding} \LI{} into a dialogue-module is required in order to 
walther@59827
   602
meet user requirements in educational settings. Looking at the calculation 
walther@59827
   603
shown on p.\pageref{biegel_calc} and considering the power of the three 
walther@59827
   604
mainfunction (1)\dots(3) mentioned in the respective comment on 
walther@59827
   605
p.\pageref{1-2-3}, it is clear, that in particular @{term[names_short] 
walther@59827
   606
find_next_step} needs control: The dialogue-module hands over control to a 
walther@59827
   607
student at each step of \LI, but students should also be warned against using 
walther@59827
   608
a button creating the next step too frequently. A careful reduction of help 
walther@59827
   609
from \LI{} might make the learning system also usable for written exams.
walther@59827
   610
walther@59827
   611
\<close>
walther@59827
   612
walther@59827
   613
(*<*)
walther@59827
   614
end
walther@59827
   615
(*>*)