1\documentclass[a4paper,10pt]{article}
2
3\usepackage[T1]{fontenc}
4\usepackage{upquote}
5\usepackage{alltt}
6\usepackage{url}
7
8\addtolength{\voffset}{-1em}
9\addtolength{\textheight}{-2em}
10\addtolength{\textwidth}{0.5em}
11\setlength{\arraycolsep}{0.1em}
12\input{../LaTeX/commands}
13
14\begin{document}
15
16\title{\bf\Large Guide to HOL4 interaction and basic proofs\vspace{-0.3em}}
17
18\author{\normalsize Magnus O. Myreen}
19\date{~\vspace{-2em}}
20
21\maketitle
22
23\newenvironment{code}{\begin{quote}%
24\begin{alltt}\small}{%
25\end{alltt}%
26\end{quote}}
27\newenvironment{enum}{\begin{enumerate}
28\setlength{\itemsep}{-\parsep}
29}{\end{enumerate}}
30
31\renewcommand{\conj}{\(\begin{array}{c}\texttt{\bf\scriptsize/\textbackslash}\\[0.18em]\end{array}\)}
32\newcommand{\mysec}[1]{\section{\large #1}}
33\newcommand{\mysubsec}[1]{\subsection{\normalsize#1}}
34\newcommand{\sq}{\textasciigrave}
35
36\mysec{Introduction}
37
38This document gives readers, with no experience in using HOL4, the most
39minimum knowledge needed to start using HOL4. The aim is to give a
40concise description of the basics in a format usable as a beginners'
41reference manual.
42\begin{enum}
43\item[~] Section \ref{interaction}:~~Interaction with HOL4 (via emacs)
44\item[~] Section \ref{search}:~~Searching for theorems and theories
45\item[~] Section \ref{tactics}:~~Common proof tactics
46\item[~] Section \ref{reading}:~~Further reading and general advice
47\end{enum}
48The text assumes that the reader has HOL4 installed. You can download and install HOL4 following the instructions on \url{https://hol-theorem-prover.org}.
49
50\mysec{Interaction with HOL4 (via emacs)\label{interaction}}
51
52Michael Norrish has written an emacs script which makes interaction
53with HOL easy. To install the script add the following line to your emacs initialisation file ({\tt
54.emacs} or \texttt{.emacs.d/init.el}) with {\tt <path>} replaced with the full path to your HOL4
55installation.
56\begin{code}
57(load "<path>/HOL/tools/hol-mode")
58\end{code}
59I recommend adding the following (by Chun Tian) to the same file
60in order to turn off automatic indentation for the SML mode.
61\begin{code}
62(defun my-sml-mode-hook ()
63  "Local defaults for SML mode"
64  (setq electric-indent-chars '()))
65
66(add-hook 'sml-mode-hook 'my-sml-mode-hook)
67\end{code}
68
69If your version of emacs does not highlight the active region, also add the following line
70to your initialisation file:
71\begin{code}
72(transient-mark-mode 1)
73\end{code}
74Restart emacs to make these changes take effect.
75
76\mysubsec{Starting a HOL4 session}
77
78\begin{enum}
79\item Start emacs.
80\item Press {\tt C-x C-f} to open a file for your proof script.
81\item Press {\tt M-h 3} to split the emacs window into two columns and start HOL4.
82\end{enum}
83The HOL window should look something like this:
84\begin{code}
85---------------------------------------------------------------------
86       HOL-4 [Kananaskis 11 (stdknl, built Mon Feb 05 12:44:20 2018)]
87
88       For introductory HOL help, type: help "hol";
89       To exit type <Control>-D
90---------------------------------------------------------------------
91[Use-ing configuration file /Users/myreen/.hol-config.sml]
92> > > > >
93\end{code}
94
95\mysubsec{Copying input into HOL4 (Opening a theory)\label{copy}}
96
97First, make sure you know how to select text in emacs. Either:
98\begin{itemize}
99\item Move the cursor while holding the shift key; or
100\item Hit \texttt{C-space}, and then move the cursor normally; or
101\item Use the mouse (hold the primary button and drag)
102\end{itemize}
103
104To copy and paste the selected region into the HOL session press {\tt M-h~M-r}.
105For example, selecting the following line, and then pressing {\tt M-h M-r}
106\begin{code}
107open arithmeticTheory listTheory;
108\end{code}
109makes HOL4 open the library theories for arithmetic (over natural numbers)
110and lists. HOL4 prints a long list of definitions and already proved results.
111
112\noindent\rule{0em}{1.5em}\emph{Tip:} To avoid long printouts as above, prefix your command with
113{\tt C-u C-u} i.e. instead of pressing {\tt M-h M-r} press
114{\tt C-u C-u M-h M-r}.
115
116\mysubsec{Starting a goal-oriented proof}
117
118Most HOL4 proofs are constructed using an interactive \emph{goal
119  stack} and then put together using the ML function {\tt prove}
120(Section~\ref{prove1}, \ref{prove2}). To start the goal stack:
121\begin{enum}
122\item Write a goal, \eg{} {\tt \sq !n{.}~n~<~n~+~1\sq}, (we can write $\forall$ as {\tt !} in HOL4).
123\item Move the cursor inside the back-quotes ({\tt \sq}).
124\item Press {\tt M-h~g} to push the goal onto the goal stack.
125\end{enum}
126The HOL4 window should look something like this:
127\begin{code}
128> val it =
129     Proof manager status: 1 proof.
130  1. Incomplete goalstack:
131       Initial goal:
132       \(\forall\)n. n < n + 1
133
134   : proofs
135> val it = () : unit
136\end{code}
137
138\mysubsec{Applying a tactic\label{apply}}
139
140Make progress in a proof using \emph{proof tactics}.
141
142\begin{enum}
143\item Write the name of a tactic, \eg{} {\tt decide\_tac},~see Section~\ref{tactics} for more tactics
144\item Select the text of the tactic
145\item Press {\tt M-h~e} to apply the tactic.
146\end{enum}
147A tactic makes HOL4 update the current goal. The HOL4 window will either
148display the new goal(s) or print:
149\begin{code}
150    Initial goal proved.
151    |- \(\forall\)n. n < n + 1 : goalstack
152\end{code}
153You can undo the effect of the applied tactic by pressing {\tt M-h b}. Press {\tt M-h p} to view the current goal.
154To go all the way back to the start of the proof (to restart), press \texttt{M-h~R}.
155
156\mysubsec{Ending a goal-oriented proof}
157
158One can pop goals off the goal stack by pressing {\tt M-h d}, which gives:
159\begin{code}
160> OK..
161val it = There are currently no proofs. : proofs
162\end{code}
163
164\mysubsec{Saving the resulting theorem\label{prove1}}
165
166One can use {\tt prove} to store the result of a proof (called a
167\emph{theorem}), \eg{} the following stores the theorem $\forall n.\;n < n +
1681$ in an ML variable {\tt LESS\_ADD\_1}:
169\begin{code}
170val LESS_ADD_1 = Q.prove(`!n. n < n + 1`, decide_tac);
171\end{code}
172When the above line is copied into HOL4 (using text-selection then
173{\tt M-h M-r}, as described in Section~\ref{copy}), HOL4 responds with:
174\begin{code}
175> val LESS_ADD_1 = |- !n. n < n + 1 : thm
176\end{code}
177
178\mysubsec{Saving proofs based on multiple tactics\label{prove2}}
179
180Suppose we have proved the goal {\tt \sq !n{.}~n <= n * n\sq} with the following tactics:
181\begin{code}
182Induct_on `n`                   (* comment: induction on n  *)
183
184  decide_tac                    (* comment: solve base case *)
185
186  asm_simp_tac bool_ss [MULT]   (* comment: simplify goal   *)
187  decide_tac                    (* comment: solve step case *)
188\end{code}
189Tactics can be pieced together for {\tt prove} using \ml{\gt\gt} and \ml{\gt-}. The \ml{\gt\gt} operator is an infix that composes tactics. Similarly, \ml{\gt-} \emph{tac} proves the first subgoal using \emph{tac}.
190\begin{code}
191val LESS_EQ_MULT = Q.prove(
192  `!n:num. n <= n * n`,
193  Induct_on `n`
194  >- decide_tac
195  >- (asm_simp_tac bool_ss [MULT]
196      \gt\gt decide_tac));
197\end{code}
198Copy the above into HOL4 using text-selection, and then {\tt M-h M-r}, as in Section~\ref{copy}.
199
200\newcommand{\itemz}[2]{\texttt{#1}\; &-\;\; \textrm{#2}}
201\newcommand{\itemy}[2]{#1&\quad\quad&#2\\}
202
203\begin{figure}[t]
204\hrule
205
206\begin{displaymath}
207\begin{array}{lllll}
208\itemy{\itemz{\rule{0em}{1.5em}M-h h}{start HOL}}{\itemz{M-h g}{push goal onto goal stack}}
209\itemy{\itemz{M-h M-r}{copy region into HOL}}{\itemz{M-h e}{apply tactic to goal}}
210\itemy{\itemz{M-h C-t}{display types on/off}}{\itemz{M-h b}{move back in proof}}
211\itemy{\itemz{M-h C-c}{interrupt HOL}}{\itemz{M-h p}{print current goal}}
212\itemy{&}{\itemz{M-h d}{drop current goal}}
213\end{array}
214\end{displaymath}
215\caption{Most important key bindings in the emacs HOL4 mode.
216Note that all of these actions are also available in the HOL menu within Emacs.}
217
218\rule{0em}{1.5em}\hrule
219\end{figure}
220
221\mysubsec{Displaying types in HOL4}
222
223HOL4 does not by default display types. Press {\tt M-h~C-t} to switch
224printing of type information on or off.
225
226\mysubsec{Interrupting HOL4}
227
228Press {\tt M-h~C-c} to interrupt HOL4 --- useful when a tactic fails to terminate
229(\eg{} {\tt\small metis\_tac} often fails to terminate when unsuccessfully applied).
230
231\mysubsec{Making a definition\label{definition}}
232
233Function can be defined using {\tt Define}, \eg{} square is defined as follows.
234\begin{code}
235val SQUARE_def = Define `SQUARE n = n * n`;
236\end{code}
237
238\noindent
239Data-types are defined using {\tt Datatype}, \eg{} a binary tree
240which holds values of type {\tt 'a} (a type variable) at the leaves:
241\begin{code}
242val _ = Datatype `TREE = LEAF 'a | BRANCH TREE TREE`;
243\end{code}
244
245\noindent
246A valid tree is \eg{} {\tt BRANCH (LEAF 5) (BRANCH (LEAF 1) (LEAF 7))}
247with type {\tt num TREE}, where {\tt  num} is the type name for a natural
248number. We can define recursive functions, \eg{}
249\begin{code}
250val MAP_TREE_def = Define `
251  (MAP_TREE f (LEAF n) = LEAF (f n)) \conj{}
252  (MAP_TREE f (BRANCH u v) = BRANCH (MAP_TREE f u) (MAP_TREE f v))`;
253\end{code}
254{\tt  SQUARE\_def} and {\tt  MAP\_TREE\_def} are theorems containing the
255above definitions. Theorems describing {\tt  TREE} can be retrieved by coping
256the following into HOL4 (by pressing {\tt C-space} then {\tt M-h M-r}, Section~\ref{copy}).
257\begin{code}
258val TREE_11 = fetch "-" "TREE_11";
259val TREE_distinct = fetch "-" "TREE_distinct";
260\end{code}
261
262\mysubsec{Making a theory}
263
264Proofs and definitions are stored in files called scripts, \eg{} we
265can store the definitions from above in a file called {\tt
266  mytreeScript.sml}, which should begin with the lines
267\begin{code}
268open HolKernel boolLib bossLib Parse
269val _ = new_theory "mytree";
270\end{code}
271and end with the line
272\begin{code}
273val _ = export_theory();
274\end{code}
275Replace {\tt prove} by {\tt store\_thm} for results you
276wish to export from the theory, \eg{}
277\begin{code}
278val LESS_ADD_1 = Q.store_thm("LESS_ADD_1",{`}!n.n<n+1{`},decide_tac);
279\end{code}
280Make sure your script only consists of ML definitions ({\tt \small val
281  x = y}, {\tt \small fun g x = y}), open commands ({\tt \small
282  open x y z}) and comments {\tt \small (* comment *)}.
283
284The theory {\tt mytreeTheory} is created by executing {\tt Holmake} in
285the directory where {\tt mytreeScript.sml} is stored. A
286readable version of the theory is stored under {\tt mytreeTheory.sig}.
287
288\mysec{Searching for theorems and theories\label{search}}
289
290\newcommand{\itemx}[2]{\texttt{\small #1} &\;\textrm{--}\;& \textrm{#2} \\}
291
292HOL4 has a large collection of library theories. The most commonly used are:
293\begin{displaymath}
294\begin{array}{lcl}
295\itemx{arithmeticTheory}{natural numbers, \eg{} {\tt\small 0, 1, 2, SUC 0, SUC 6}}
296\itemx{listTheory}{lists, \eg{} {\tt\small [1;2;3] = 1::2::3::[], HD xs}}
297\itemx{pred\_setTheory}{simple sets,\ \eg{} {\tt\small \{1;2;3\}, x IN s UNION t}}
298\itemx{pairTheory}{pairs/tuples,\ \eg{} {\tt\small (1,x), (2,3,4,5), FST (x,y)}}
299\itemx{wordsTheory}{n-bit words,\ \eg{} {\tt\small 0w:word32, 1w:'a word, x {!!}~1w}}
300\end{array}
301\end{displaymath}
302Other standard theories include:
303\begin{code}
304arithmeticTheory  bagTheory  boolTheory  combinTheory  fcpTheory
305finite_mapTheory  fixedPointTheory  floatTheory  integerTheory
306limTheory  optionTheory  probTheory  ratTheory  realTheory
307relationTheory  rich_listTheory  ringTheory  seqTheory
308sortingTheory  state_transformerTheory  stringTheory  sumTheory
309topologyTheory  transcTheory  whileTheory
310\end{code}
311The library theories are conveniently browsed using the following HTML reference page (created when HOL4 is compiled).
312Replace {\tt <path>} with the path to your HOL4 installation.
313\begin{code}
314<path>/HOL/help/HOLindex.html
315\end{code}
316
317Once theories has been opened (see Section~\ref{copy}), one can search for theorems in the current
318context using {\tt print\_match}, \eg{} with {\tt arithmeticTheory} opened,
319\begin{code}
320print_match [] {`}`n DIV m <= k{`}`
321\end{code}
322prints a list of theorems containing $n\; \texttt{\small DIV} \;m \leq k$ for some $n,m,k$:
323\begin{code}
324arithmeticTheory.DIV_LE_MONOTONE (THEOREM)
325------------------------------------------
326|- !n x y. 0 < n \(\land\) x <= y ==> x DIV n <= y DIV n
327
328arithmeticTheory.DIV_LE_X (THEOREM)
329-----------------------------------
330|- !x y z. 0 < z ==> (y DIV z <= x <=> y < (x + 1) * z)
331
332arithmeticTheory.DIV_LESS_EQ (THEOREM)
333--------------------------------------
334|- !n. 0 < n ==> !k. k DIV n <= k
335\end{code}
336Try to write increasingly specific queries if the returned list is long, \eg{}
337{\tt\small print\_match [] \sq \sq n DIV m\sq\sq} returns a list of length 32. Note that {\tt\small print\_match [] \sq \sq DIV\sq\sq}
338does not work since {\tt\small DIV} is an infix operator, but {\tt\small print\_match [] \sq \sq \$DIV\sq \sq} works.
339
340The key-binding \texttt{M-h~m} (and the menu entry ``DB match'') will prompt for the term pattern to search for, and pass this query onto the HOL session (saving the need to type \texttt{print\_match~[]} and the enclosing quotation marks).
341
342\mysec{Common proof tactics\label{tactics}}
343
344Most HOL4 proofs are carried out by stating a goal and then applying
345\emph{proof tactics} that reduce the goal.  This section describes
346basic use of the most important proof tactics.  Press {\tt\small
347  C-space} then {\tt\small M-h e} to apply a tactic
348(Section~\ref{apply}).
349
350
351\mysubsec{Automatic provers}
352
353Simple goals can often be proved automatically by {\tt\small
354  metis\_tac}, {\tt\small decide\_tac} or {\tt\small EVAL\_TAC}.
355{\tt\small metis\_tac} is first-order prover which is good at general
356problems, but requires the user to supply a list of relevant theorems,
357\eg{} the following goal is proved by {\tt\small metis\_tac
358  [MOD\_TIMES2,MOD\_MOD,MOD\_PLUS]}.
359\begin{code}
360!k. 0 < k ==> !m p n. (m MOD k * p + n) MOD k = (m * p + n) MOD k
361\end{code}
362
363\noindent
364{\tt\small decide\_tac} handles linear arithmetic over natural
365numbers, \eg{} {\tt\small decide\_tac} solves:
366\begin{code}
367!m n k. m < n \conj{} n < m+k \conj{} k <= 3 \conj{} ~(n = m+1) ==> (n = m+2)
368\end{code}
369{\tt\small EVAL\_TAC} is good at fully instantiated goals, \eg{} {\tt\small EVAL\_TAC} solves:
370\begin{code}
3710 < 5 \conj{} (HD [4;5;6;7] + 2**32 = 3500 DIV 7 + 4294966800)
372\end{code}
373
374\mysubsec{Proof set-up}
375
376Goals that contain top-level universal quantifiers ({\tt !x.}),
377implication ({\tt ==>}) or conjunction ({\tt \conj{}}) are often
378taken apart using {\tt\small rpt strip\_tac} or just {\tt\small
379  strip\_tac}, \eg{} the goal {\tt\small \sq !x{.}~(!z{.}~x < h z) ==> ?y{.}~f x = y\sq}
380becomes the following. (Assumptions are written under the line.)
381\begin{code}
382    ?y. f x = y
383    ------------------------------------
384      !z. x < h z
385\end{code}
386
387\mysubsec{Existential quantifiers}
388
389Goals that have a top-level existential quantifier can be given a
390witness using {\tt \small qexists\_tac}, \eg{} {\tt \small
391  qexists\_tac \sq 1\sq} applied to goal {\tt \small ?n{.}~!k{.}~n * k = k}
392produces goal {\tt \small !k{.}~1 * k = k}.
393
394\mysubsec{Rewrites}
395
396Most HOL4 proofs are based on rewriting using equality theorems, \eg{}
397\begin{code}
398ADD_0:            |- !n. n + 0 = n
399LESS_MOD:         |- !n k. k < n ==> (k MOD n = k)
400\end{code} {\tt \small asm\_simp\_tac} and {\tt \small full\_simp\_tac} are two
401commonly used rewriting tactics, \eg{} suppose the goal is the following:
402\begin{code}
403    5 + 0 + m = (m MOD 10) + (5 MOD 8)
404    ------------------------------------
405      0.  p = 2 + 0 + (m MOD 10)
406      1.  m < 10
407\end{code}
408{\tt \small asm\_simp\_tac bool\_ss
409  [ADD\_0,LESS\_MOD]} rewrites the
410goal using the supplied theorems together with the current goal's
411assumptions and some boolean simplifications {\tt \small bool\_ss}:
412\begin{code}
413    5 + m = m + (5 MOD 8)
414    ------------------------------------
415      0.  p = 2 + 0 + (m MOD 10)
416      1.  m < 10
417\end{code}
418{\tt \small full\_simp\_tac bool\_ss [ADD\_0,LESS\_MOD]}
419does the same except that it also applies the rewrites to the
420assumptions:
421\begin{code}
422    5 + m = m + (5 MOD 8)
423    ------------------------------------
424      0.  p = 2 + m
425      1.  m < 10
426\end{code}
427{\tt \small bool\_ss} can be replaced by {\tt \small std\_ss}, which
428is a stronger simplification set that would infer {\tt \small 5 < 8}
429and hence simplify {\tt\small 5 MOD 8} as well. I recommend that the
430interested reader also reads about {\tt\small AC}, {\tt\small Once}
431and {\tt\small srw\_tac}.
432
433\mysubsec{Induction}
434
435Use the tactic {\tt\small Induct\_on \sq x\sq} to start an induction on {\tt\small x}.
436Here {\tt x} can be any variable with a recursively defined type,
437\eg{} a natural number, a list or a {\tt\small TREE} as defined in
438Section~\ref{definition}.  One can start a complete (or strong)
439induction over the natural number {\tt\small n} using {\tt\small
440  completeInduct\_on \sq n\sq}.
441As with \texttt{Cases\_on} one can also induct on terms (\eg, \texttt{\small Induct\_on~\sq hi~-~lo\sq}), though these proofs can be harder to carry out.
442
443\mysubsec{Case splits}
444
445A goal can be split into cases using {\tt\small Cases\_on \sq x\sq}. The
446goal is split according to the constructors of the type of {\tt\small
447  x}, \eg{} for the following goal
448\begin{code}
449    !x. ~(x = []) ==> (x = HD x::TL x)
450\end{code}
451{\tt\small Cases\_on \sq x\sq} splits the goal into two:
452\begin{code}
453    ~(h::t = []) ==> (h::t = HD (h::t)::TL (h::t))
454
455    ~([] = []) ==> ([] = HD []::TL [])
456\end{code}
457Case splits on boolean expressions are also useful, \eg{} {\tt\small Cases\_on \sq n < 5\sq}.
458
459\mysubsec{Subproofs}
460
461It is often useful to start a mini-proof inside a larger proof, \eg{} for the goal
462\begin{code}
463    foo n
464    ------------------------------------
465      0 < n
466\end{code}
467we might want to prove {\tt\small h n = g n} assuming {\tt\small 0 <
468  n}.
469We can start such a subproof by typing {\tt\small sg \sq h n = g n\sq}.%
470\footnote{You can also use the emacs binding {\tt\small M-h M-s}
471with the cursor inside the sub-goal.} The new goal stack:
472\begin{code}
473    foo n
474    ------------------------------------
475      0.  0 < n
476      1.  h n = g n
477
478    h n = g n
479    ------------------------------------
480      0 < n
481\end{code}
482If {\tt\small \sq h n = g n\sq} can be proved in one step, \eg{} using {\tt\small metis\_tac [MY\_LEMMA]}, then
483apply {\tt\small \sq h n = g n\sq \ by metis\_tac [MY\_LEMMA]} instead of
484{\tt\small sg \sq h n = g n\sq}.  If the sub-goal requires
485multiple steps the tactic after the \texttt{by} will need to be
486parenthesised: {\tt\small\sq\textit{goal}\sq \ by ($\mathit{tac}_1$ \ml{\gt\gt}
487  $\mathit{tac}_2$ ...)}
488
489\mysubsec{Proof by contradiction}
490
491Use {\tt\small CCONTR\_TAC} to add the negation of the goal to the
492assumptions.  The task is then to prove that one of the assumptions of
493the goal is false. One can \eg{} add more assumptions using
494{\tt\small \sq...\sq \ by ...}, described above, until one assumption is the
495negation of another assumption (and then apply {\tt\small metis\_tac []}).
496
497\mysubsec{More tactics\label{html}}
498
499An HTML reference of all tactics and proof tools is created when HOL4 is compiled.
500Replace {\tt\small <path>} with the path to your HOL4 installation.
501\begin{code}
502<path>/HOL4/help/src/htmlsigs/idIndex.html
503\end{code}
504The reference provides an easy way to access both the implementations of
505tactics as well as their documentation (where such exists).
506The interested reader may want to look up the following:
507\begin{code}
508CONV_TAC  disj1_tac  disj2_tac  match_mp_tac  mp_tac  pat_assum  Q
509\end{code}
510
511\mysec{Further reading and general advice\label{reading}}
512
513General advice on using HOL4:
514\begin{enum}
515\item State definitions carefully with the subsequent proofs in mind.
516\item Make proofs reusable by splitting them into multiple small lemmas.
517\item Strive to make the most of library theories and rewriting.
518\end{enum}
519One can only learn HOL4 via examples, so try proving something.
520Example problems and solutions are presented in the \emph{HOL
521  Tutorial}, available under:
522\begin{center}
523\url{https://hol-theorem-prover.org/#doc}
524\end{center}
525The same page also contains links to:
526\begin{enum}
527\item[~]\emph{HOL Description} -- a description of the HOL4 system
528\item[~]\emph{HOL Reference} -- a detailed descriptions of proof tactics and other tools
529\item[~]\emph{HOL Logic} -- a presentation of the underlying logic
530\end{enum}
531For day-to-day look-ups, I find {\tt print\_match} (illustrated in
532Section~\ref{search}) and the HTML reference (mentioned in
533Section~\ref{html}) most helpful.
534
535\end{document}
536