File: description.tex

package info (click to toggle)
hol88 2.02.19940316dfsg-8
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 65,960 kB
  • sloc: ml: 199,939; ansic: 9,666; sh: 6,913; makefile: 6,032; lisp: 2,747; yacc: 894; sed: 201; cpp: 87; awk: 5
file content (1096 lines) | stat: -rw-r--r-- 44,512 bytes parent folder | download | duplicates (11)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
\newcommand{\hand}{\tt/\symbol{"5C}}
\newcommand{\hor}{\tt\symbol{"5C}/}
\newcommand{\hnot}{\tt\symbol{"7E}}

\newcommand{\nn}[1]{#1n}

\index{<==@{{\ptt <==} (backward implication)}|see{{\ptt PMI\_DEF}}}

\chapter{Statement of Rights}

Jim Grundy, hereafter referred to as `the Author', retains the
copyright and all other legal rights to the software contained in
the window library, hereafter referred to as `the Software'.
The Software is made available free of charge on an `as is' basis.
No guarantee, either express or implied, of maintenance, reliability,
merchantability or suitability for any purpose is made by the Author.

The user is granted the right to make personal or internal use
of the Software provided that both:
\begin{enumerate}
    \item   The Software is not used for commercial gain.
    \item   The user shall not hold the Author liable for any consequences
            arising from use of the Software.
\end{enumerate}
The user is granted the right to further distribute the Software
provided that both:
\begin{enumerate}
    \item   The Software and this statement of rights is not modified.
    \item   The Software does not form part or the whole of a system
            distributed for commercial gain.
\end{enumerate}
The user is granted the right to modify the Software for personal or
internal use provided that all of the following conditions are
observed:
\begin{enumerate}
    \item   The user does not distribute the modified software.
    \item   The modified software is not used for commercial gain.
    \item   The Author retains all rights to the modified software.
\end{enumerate}

Anyone seeking a licence to use this software for commercial purposes
is invited to contact the Author.

\chapter{The window Library}

This manual describes the use of the window library.
The window library has been provided to facilitate a style of 
reasoning called {\it window inference}.
Window inference should prove more useful than goal directed reasoning in
situations where
very fine grain manipulations are required,
when a proof is more easily progressed forwards than backwards,
or when a proof makes extensive use of contextual information.
Users interested in transformational design, refinement and equational 
reasoning should find the window library interesting.

For more details on window inference, see:
\begin{center}
	\begin{minipage}{0.8\columnwidth}
		\small
		\noindent
		Jim Grundy.
		Window Inference in the HOL System.
		In Phil J. Windley, Mylar Archer, Karl N. Levitt and
		Jeff J. Joyce, editors,
		{\it The Proceedings of the International Tutorial and Workshop on
		the HOL Theorem Proving System and its Applications},
		University of California at Davis, 28--30 August 1991.
		IEEE Computer Society / ACM SIGDA, IEEE Computer Society Press,
		10662 Los Vaqueros Circle, PO Box 3014,
		Los Alamitos CA 907020-1264, United States, 1992.
	\end{minipage}
\end{center}

\section{Window Inference}

Window inference is a style of reasoning where the user may transform an
expression by restricting attention to a subexpression and transforming it.
While restricting attention to a subexpression, the user can transform the
subexpression without affecting the remainder of the enclosing expression.
Also, while transforming a subexpression, the user can make assumptions based
on the context of the subexpression.
For example, suppose a user wishes to transform the expression
\ml{"A \hand\ B"};
this may be done by transforming \ml{"A"} under the assumption \ml{"B"}.
It is possible to assume \ml{"B"} while transforming \ml{"A"},
because were \ml{"B"} false,
the enclosing expression \ml{"A \hand\ B"} would be false regardless of
\ml{"A"}.
Using contextual information in the transformation of subexpressions adds a
degree of complexity to the proof tree.
The advantage of the window inference technique is that the user is shielded
from this added complexity.

In the window inference style of proof,
a user starts with an expression \ml{"P"} and transforms it to \ml{"Q"} such
that \ml{"Q R P"} for some relation \ml{"R"}\footnote
{\ml{"R"} denotes an infix, reflexive, transitive relation.};
thus creating a proof that \ml{|- Q R P}.
Such a proof need be neither strictly forward nor backward.
Window inference encompasses both backward and forward reasoning.
The user may start with the expression \ml{"P"} and transform it to
\ml{"T"}(true) while preserving the relation \ml{"==>"}.
Such a process would build the theorem \ml{|- T ==> P},
and would constitute a backward proof of \ml{"P"}.
Alternatively,
the user may start with the expression \ml{"T"} and transform it to
\ml{"P"} while preserving the relation
\ml{"<=="}\index{PMI\_DEF@{\ptt PMI\_DEF}|nn}\footnote
{\ml{PMI\_DEF} \ml{|- !a, b. (a <== b) = (b ==> a)}}.
Such a process would build the theorem
\ml{|- P <== T},
and would constitute a forward proof of \ml{"P"}.

\section{Getting Started}	\label{sec:start}

Before you can use window inference in HOL you must load the
window library.
To load the window library, issue the following command:
\begin{hol}\begin{alltt}
	load_library `window`;;
\end{alltt}\end{hol}
It is not always possible to load the window library.
This is because the library contains a small theory called {\tt win}.
If you have loaded another theory before attempting to load the window
library, and you are not in draft mode, then you will not be able to 
load the window library.
If this happens, a new function
\ml{load\_window}\index{load\_window@{\ptt load\_window}} is defined which
can be used to complete the loading process if \HOL\ is placed in draft mode.

Within a window inference system reasoning is conducted with a stack of windows.
Each window is comprised of a {\it focus}\index{focus},
$f$, that is the expression to be transformed,
a set of formulae $\Gamma$ called the {\it assumptions}\index{assumptions},
that can be assumed true in the context of the focus, and a
relation\index{relation} $R$\/ that
must relate the focus and the expression to which it is transformed.
(Note that the type of the focus is not restricted to \ml{:bool} as is the
case with goals in the subgoal package.)
Such a window will be written as follows.
\begin{hol}\begin{alltt}
     ! \(\Gamma\)
   \(R\!\) * \(f\)
\end{alltt}\end{hol}\index{"!@{{\ptt "!} (assumption prefix)}}

To begin using the system,
you create a window stack which contains a single window.
The focus of that window should be the expression you want to transform,
the assumptions of the window should be those things you wish to assume,
and the relation of the window should be 
the relation you wish to preserve as you transform the focus.
For example, suppose you wish to find something that implies
\ml{"(A \hand\ (B \hand\ C)) \hand\ D"} under the assumption \ml{"\hnot C"}.
To create such a stack, you should use the command:
\begin{boxed}\begin{verbatim}
   BEGIN_STACK : string -> term -> term list -> thm list -> void
\end{verbatim}\end{boxed}\index{BEGIN\_STACK@{\ptt BEGIN\_STACK}|(}
The first parameter is the name that will be associated with the stack.
The second parameter is a term containing both the focus and the relation
to be preserved.
The third parameter is the list of terms that you wish to assume.
The last parameter is a list of theorems that might be relevant to the proof.
The function of the last parameter will be explained in section~\ref{sec:lem},
until then we will give this parameter the empty list.
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #BEGIN_STACK `intro` "(==>) ((A /\ (B /\ C)) /\ D)" ["~C"] [];;
       ! ~C
   ==> * (A /\ B /\ C) /\ D
   () : void
\end{verbatim}\end{session}
As a side effect the
\ml{BEGIN\_STACK}\index{BEGIN\_STACK@{\ptt BEGIN\_STACK}|)}
command prints the top window of the stack.
To print the top window at any time use the
\ml{PRINT\_STACK}\index{PRINT\_STACK@{\ptt PRINT\_STACK}|(}
command.
\begin{boxed}\begin{verbatim}
   PRINT_STACK : void -> void
\end{verbatim}\end{boxed}\index{PRINT\_STACK@{\ptt PRINT\_STACK}|)}

Initially the user may choose one of \ml{"="}, \ml{"==>"} or \ml{"<=="} as
the relation to be preserved by a window.
However the system can be tailored to preserve any reflexive, transitive
relation.
Details of how to declare a new relation for use with the system are
given in section~\ref{sec:rel}.

Each window holds a theorem.
To obtain the theorem held by the current window use the following command:
\begin{boxed}\begin{verbatim}
   WIN_THM : void -> thm
\end{verbatim}\end{boxed}\index{WIN\_THM@{\ptt WIN\_THM}|(}
Initially (before you have transformed the focus) this theorem 
will simply state that the original focus of the window is related to itself.
\begin{session}\begin{verbatim}
   #WIN_THM();;
   |- (A /\ B /\ C) /\ D ==> (A /\ B /\ C) /\ D
\end{verbatim}\end{session}\index{WIN\_THM@{\ptt WIN\_THM}|)}

\section{Transforming the Focus}

Once you have a window the next thing you want to do is transform it.
Each transformation of a focus $f_n$ to $f_{n+1}$ must be justified by a 
theorem of the following form:
\begin{alltt}
   \(\Gamma\) |- \(f\sb{n+1}\) \(R\) \(f\sb{n}\)
\end{alltt}
Where $\Gamma$ is some subset of the assumptions of the window, and
$R$\/ is the relation which is being preserved by the window.
The relation could, in fact, be any relation which the
system knows to be as strong as $R$.
The system already knows that equality is as strong as any reflexive relation.
For the definition of {\it stronger\/} see section~\ref{sec:rel}.

To take a theorem of the form above and use it to transform a window,
use the command:
\begin{boxed}\begin{verbatim}
   TRANSFORM_WIN : thm -> void
\end{verbatim}\end{boxed}\index{TRANSFORM\_WIN@{\ptt TRANSFORM\_WIN}}
To make life easier,
the following commands are provided for transforming the focus of a
window.
These commands automatically generate a theorem of the correct form and
use it to transform the window:\footnote{Other versions of rewriting
are described in chapter~\ref{chap:ref}.}
\begin{boxed}\begin{verbatim}
   MATCH_TRANSFORM_WIN: thm -> void
   REWRITE_WIN : thm list -> void
   PURE_REWRITE_WIN : thm list -> void
   CONVERT_WIN : conv -> void
   RULE_WIN : (thm -> thm) -> void
   THM_RULE_WIN : (thm -> thm) -> void
   FOC_RULE_WIN : (term -> thm) -> void
   TACTIC_WIN : tactic -> void
\end{verbatim}\end{boxed}\index{MATCH\_TRANSFORM\_WIN@{\ptt MATCH\_TRANSFORM\_WIN}}\index{REWRITE\_WIN@{\ptt REWRITE\_WIN}}\index{PURE\_REWRITE\_WIN@{\ptt PURE\_REWRITE\_WIN}}\index{CONVERT\_WIN@{\ptt CONVERT\_WIN}}\index{RULE\_WIN@{\ptt RULE\_WIN}}\index{THM\_RULE\_WIN@{\ptt THM\_RULE\_WIN}}\index{FOC\_RULE\_WIN@{\ptt FOC\_RULE\_WIN}}\index{TACTIC\_WIN@{\ptt TACTIC\_WIN}}
We shall stick to using rewriting in our examples because its function should
be familiar.
We can rewrite the focus of the window created in the
previous section with the assumption of that window.
\begin{session}\begin{verbatim}
   #PURE_REWRITE_WIN [ASSUME "~C"];;
       ! ~C
   ==> * (A /\ B /\ F) /\ D
   () : void

   #WIN_THM ();;
   ~C |- (A /\ B /\ F) /\ D ==> (A /\ B /\ C) /\ D
\end{verbatim}\end{session}

If you decide that the last thing you did was a mistake,
then you can use the \ml{UNDO} command to undo it.
\begin{boxed}\begin{verbatim}
   UNDO : void -> void
\end{verbatim}\end{boxed}\index{UNDO@{\ptt UNDO}}

\section{Opening subwindows}
If you wish to concentrate your attention on some subterm of the focus,
you should open a window on that subterm.
This is accomplished with the command:
\begin{boxed}\begin{verbatim}
   OPEN_WIN : path -> void
\end{verbatim}\end{boxed}\index{OPEN\_WIN@{\ptt OPEN\_WIN}|(}
\ml{OPEN\_WIN} takes as an argument a \ml{path} that describes the
position of the desired subterm within the focus.
A \ml{path}\index{path@{\ptt path}} is a list made up of the following
constructors: \ml{RATOR}, \ml{RAND} and \ml{BODY}.
You should think of using each element in the list to select
an ever decreasing subterm until the list is exhausted.

For example, if we wished to concentrate on the subterm \ml{"B \hand\ F"} in
the previous window, we should open a subwindow at \ml{[RATOR; RAND; RAND]}:
\begin{session}\begin{verbatim}
   #OPEN_WIN [RATOR; RAND; RAND];;
       ! ~C
       ! D
       ! A
   ==> * B /\ F
   () : void
\end{verbatim}\end{session}

A subwindow will have all the assumptions of the parent window,
plus any additional assumptions which follow from the context of the subwindow.
The one exception to this rule is when a window is opened inside the body of an
abstraction.
In this case, all assumptions with free occurrences of the variable bound
by the abstraction will be hidden.
(In the future this may be handled by renaming.)

The relation in the subwindow may not be the same as the relation in the
parent window.   The system will choose the weakest relation for the
subwindow which it knows will preserve the relation of the parent window.
To learn how the system makes these choices refer to section~\ref{sec:win}.

Having got a subwindow you will want to transform it, and then close it.
To close a subwindow, use the function:
\begin{boxed}\begin{verbatim}
   CLOSE_WIN : void -> void
\end{verbatim}\end{boxed}\index{CLOSE\_WIN@{\ptt CLOSE\_WIN}|(}
We continue our example by transforming the subwindow with rewriting,
and then closing it.
Once back in the parent window, we check the theorem proved so far.
\begin{session}\begin{verbatim}
   #REWRITE_WIN [];;
       ! ~C
       ! D
       ! A
   ==> * F
   () : void
   
   #CLOSE_WIN ();;
       ! ~C
   ==> * (A /\ F) /\ D
   () : void
   
   #WIN_THM ();;
   ~C |- (A /\ F) /\ D ==> (A /\ B /\ C) /\ D
\end{verbatim}\end{session}\index{CLOSE\_WIN@{\ptt CLOSE\_WIN}|)}

If opening a particular window proves to be a mistake,
you can return to the parent window with the \ml{UNDO\_WIN} command.
\begin{boxed}\begin{verbatim}
   UNDO_WIN : void -> void
\end{verbatim}\end{boxed}\index{UNDO\_WIN@{\ptt UNDO\_WIN}}
Alternatively, you can use the \ml{UNDO}\index{UNDO@{\ptt UNDO}} command
if the \ml{OPEN\_WIN}\index{OPEN\_WIN@{\ptt OPEN\_WIN}|)}
was the last command you made.

\section{Lemmas}\index{lemma|(}	\label{sec:lem}

The window stack can hold a set of theorems which are considered relevant
to the current problem.
The last parameter of the \ml{CREATE\_WIN} command is the initial list of
theorems which should be considered relevant to the window stack.
In section~\ref{sec:start} we created a window with an empty list of 
relevant theorems.

If the hypotheses of a theorem are a subset of the assumptions of a window,
then that theorem is said to be {\it applicable\/} in the context of that
window.
When a window is printed, the conclusions of those theorems held
by the stack that are applicable to the window are printed 
with the assumptions of the window.
Such conclusions are called the
{\it lemmas}\/ of the window.
Lemmas may be used in the same way as the assumptions.
We will refer to lemmas and assumptions collectively as the {\it context}
of a window.
When printed, lemmas are prefixed with
`\ml{|}'\index{"|@{{\ptt "|} (lemma prefix)}} rather than `\ml{!}' to
distinguish them from assumptions.

As an example,
suppose we wish to simplify the term \ml{"A \hand\ B"} given that we 
have a theorem \ml{a\_then\_b} which states that \ml{A |- B}.
We create a window stack which has a window with \ml{"A \hand\ B"} as its
focus, and which stores the theorem \ml{A |- B} in the stack as a
potentially relevant theorem.
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #BEGIN_STACK `lemma-ex` "(=) (A /\ B)" [] [a_then_b];;
   = * A /\ B
   () : void
\end{verbatim}\end{session}
If we now open a subwindow on \ml{"B"} we enter a context in which the
stored theorem is applicable.
We can then use the conclusion of the stored theorem to rewrite the focus
of the subwindow.
\begin{session}\begin{verbatim}
   #OPEN_WIN [RAND];;
     ! A
     | B
   = * B
   () : void
   
   #REWRITE_WIN [ASSUME "B:bool"];;
     ! A
     | B
   = * T
   () : void
   
   #CLOSE_WIN ();;
   = * A /\ T
   () : void
\end{verbatim}\end{session}

You can add more theorems to the set of relevant theorems during the course of
a proof by using the
\ml{ADD\_THEOREM}\index{ADD\_THEOREM@{\ptt ADD\_THEOREM}} command.
\begin{boxed}\begin{verbatim}
   ADD_THEOREM : thm -> void
\end{verbatim}\end{boxed}
You can also recover the list of theorems held by the window stack for
use with another proof by using the
\ml{LEMMA\_THMS}\index{LEMMA\_THMS@{\ptt LEMMA\_THMS}} command.
\begin{boxed}\begin{verbatim}
   LEMMA_THMS : void -> thm list
\end{verbatim}\end{boxed}\index{lemma|)}

\subsection{Windows on the Context}

Sometimes you might want to make use of a fact that follows indirectly from
the context of a window.
To allow this style of reasoning we provide a command for opening subwindows
on subterms in the context.
You can now open a window on some fact in the context and attempt to 
derive a new fact from it.
When you close such a window a theorem is added to the set of theorems
held by the window stack so that the fact you derived becomes a lemma.

The command to open a subwindow in the context is:
\begin{boxed}\begin{verbatim}
   OPEN_CONTEXT : term -> path -> void
\end{verbatim}\end{boxed}\index{OPEN\_CONTEXT@{\ptt OPEN\_CONTEXT}}
The first parameter is the term in the context you wish to open a window on,
the second is the path to the desired focus within that term.
More often than not, the path will be empty (denoting the entire expression).

For example, consider the window below:
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #PRINT_STACK ();;
       ! A = Z
       ! (A /\ B) /\ A
   ==> * (Z /\ B) /\ A
   () : void
\end{verbatim}\end{session}
If we open a subwindow on the first \ml{"A"} in the assumption
\ml{"(A \hand\ B) \hand\ A}, 
we can use the assumption \ml{"A = Z"} to rewrite the \ml{"A"} to a \ml{"Z"}.
The resulting lemma could then be used to simplify the focus to \ml{"T"}.
\begin{session}\begin{verbatim}
   #OPEN_CONTEXT "(A /\ B) /\ A" [RATOR; RAND; RATOR; RAND];;
       ! A = Z
       ! (A /\ B) /\ A
       ! A
       ! B
   <== * A
   () : void
\end{verbatim}\end{session}
Note that we are now preserving the relation \ml{"<=="},
this is because we are trying to derive a new fact that follows from 
the assumption we opened a subwindow on.
\begin{session}\begin{verbatim}
   #REWRITE_WIN [ASSUME "A:bool = Z:bool"];;
       ! A = Z
       ! (A /\ B) /\ A
       ! A
       ! B
   <== * Z
   () : void
   
   #CLOSE_WIN ();;
       ! A = Z
       ! (A /\ B) /\ A
       | (Z /\ B) /\ A
   ==> * (Z /\ B) /\ A
   () : void
\end{verbatim}\end{session}

\section{Conjectures}	\label{sec:con}

The window stack carries with it a set of goals, called 
{\it suppositions}\index{supposition},
which the user supposes to be true.
A supposition of the form \ml{P ?- C} means that the user believes that
\ml{"C"} follows from \ml{"P"}.
Initially the set of suppositions associated with the window stack is empty.
Suppositions can be added to the stack with the command:
\begin{boxed}\begin{verbatim}
   ADD_SUPPOSE : (goal -> void)
\end{verbatim}\end{boxed}\index{ADD\_SUPPOSE@{\ptt ADD\_SUPPOSE}}
The command \ml{CONJECTURE "C"} is a shorthand for adding a supposition with
conclusion \ml{"C"} and assumptions the same as those of the current window.
\begin{boxed}\begin{verbatim}
   CONJECTURE : (term -> void)
\end{verbatim}\end{boxed}\index{CONJECTURE@{\ptt CONJECTURE}}

If the premises of any supposition are a subset of the assumptions of a window,
then that supposition is said to be
{\it applicable}\index{applicable}\/ in the context of that
window.
When a window is printed, the conclusions of those suppositions which
are held by the stack and which are applicable are printed with the 
assumptions and lemmas of the window.
The conclusions of such suppositions are called the 
{\it conjectures}\index{conjectures}\/ of the
window.
Conjectures are part of the context of a window.
When printed, conjectures are prefixed with
`\ml{?}'\index{?@{{\ptt ?} (conjecture prefix)}} to distinguish them
from the other elements of the context.

Conjectures may be used like the other elements of the context, except once
used\index{conjectures!used} a conjecture must be proved.
Once a conjecture has been used, its prefix will change from `\ml{?}' to
`\ml{\$}'\index{\$@{{\ptt \$} (used conjecture prefix)}}.
If you have used a conjecture in a subwindow, and that conjecture is not
part of the context of the parent window,
or if the subwindow is inside the body of the abstraction and the variable
bound by the abstraction occurs free in the conjecture,
then that conjecture {\it must\/}
be proved before you can be allowed to close the subwindow.
Such conjectures are called {\it bad\/}
conjectures\index{conjectures!bad}.
Bad conjectures are prefixed with
`\ml{@}'\index{"@@{{\ptt "@} (bad conjecture prefix)}}.
A list of the bad conjectures of the current window can be obtained with 
the command:
\begin{boxed}\begin{verbatim}
   BAD_CONJECTURES : void -> term list
\end{verbatim}\end{boxed}\index{BAD\_CONJECTURES@{\ptt BAD\_CONJECTURES}}
All conjectures used at the very bottom of the window stack are considered bad
because they appear as extra assumptions in the theorem held by that window.

Consider the window below:
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #BEGIN_STACK `suppose-ex` "(=) ((A \/ ~A) \/ B)" [] [];;
   = * (A \/ ~A) \/ B
   () : void
\end{verbatim}\end{session}
If we assume that we can prove \ml{"A \hor\ \hnot A"},
we can simplify the focus, and then return to prove our assumption later.
\begin{session}\begin{verbatim}
   #CONJECTURE "A \/ ~A";;
     ? A \/ ~A
   = * (A \/ ~A) \/ B
   () : void
   
   #REWRITE_WIN [ASSUME "A \/ ~A"];;
     @ A \/ ~A
   = * T
   () : void

   #WIN_THM ();;
   A \/ ~A |- T = (A \/ ~A) \/ B
\end{verbatim}\end{session}

If you open a subwindow in the context of a window,
and in that subwindow you use a conjecture,
when you return to the parent window you may find that the conjecture is no
longer considered to have been used.
This is because the conjecture has {\it not\/} been used to transform the
focus of this window.
However, if you use the lemma generated by the subwindow,
all conjectures used in generating that lemma will then be
considered to have been used.

To remove a usage of a conjecture, you must introduce a lemma that is
the same as the conjecture.
You can do this by adding a theorem to the set of relevant theorems directly,
by deriving the desired lemma from the context
(using the conjecture to derive the required lemma will not work),
or by using the command \ml{ESTABLISH}\index{ESTABLISH@{\ptt ESTABLISH}}.
\begin{boxed}\begin{verbatim}
   ESTABLISH : term -> void
\end{verbatim}\end{boxed}
\ml{ESTABLISH "C"} opens a new subwindow with \ml{"C"} as its focus and
\ml{"==>"} as the relation it preserves.
If you can transform the focus of this subwindow to \ml{"T"} and then
close the window, \ml{"C"} will become a lemma in the parent window.

So, to continue our example, we must now prove the conjecture we have used:
\begin{session}\begin{verbatim}
#ESTABLISH "A \/ ~A";;
    ? A \/ ~A
==> * A \/ ~A
() : void

#REWRITE_WIN [EXCLUDED_MIDDLE];;
    ? A \/ ~A
==> * T
() : void

#CLOSE_WIN ();;
  | A \/ ~A
= * T
() : void

#WIN_THM ();;
|- T = (A \/ ~A) \/ B
\end{verbatim}\end{session}

\section{Window Stacks}

We have already used the
\ml{BEGIN\_STACK}\index{BEGIN\_STACK@{\ptt BEGIN\_STACK}} command
introduced in section~\ref{sec:start} to create a window stack.
It is possible to work with several window stacks at the same time.
When you create a new stack with
\ml{BEGIN\_STACK}\index{BEGIN\_STACK@{\ptt BEGIN\_STACK}}
it becomes the current stack.
You can set the current stack to another stack by using the
command \ml{SET\_STACK}\index{SET\_STACK@{\ptt SET\_STACK}}:
\begin{boxed}\begin{verbatim}
   SET_STACK : string -> void
\end{verbatim}\end{boxed}
The first parameter of 
\ml{SET\_STACK}\index{SET\_STACK@{\ptt SET\_STACK}} is the name of
the stack that you wish to be the current stack.

If you have finished working with a particular stack,
it can be destroyed with the 
\ml{END\_STACK}\index{END\_STACK@{\ptt END\_STACK}} command.
\begin{boxed}\begin{verbatim}
   END_STACK : string -> void
\end{verbatim}\end{boxed}
The first parameter of the 
\ml{END\_STACK}\index{END\_STACK@{\ptt END\_STACK}} command is the name
of the stack you wish to destroy.
It is possible, and in fact usual, to destroy the current stack, 
leaving yourself with no current stack.

The command \ml{CURRENT\_NAME}\index{CURRENT\_NAME@{\ptt CURRENT\_NAME}}
returns the name of the current stack, if there is one.
\begin{boxed}\begin{verbatim}
   CURRENT_NAME : string -> void
\end{verbatim}\end{boxed}
The \ml{ALL\_STACKS}\index{ALL\_STACKS@{\ptt ALL\_STACKS}} command
can be used to find out the names of all the stacks in the system.
\begin{boxed}\begin{verbatim}
   ALL_STACKS : void -> void
\end{verbatim}\end{boxed}

\subsection{The xlabel Library Component}

If you are running the HOL and the window system from within an Xterminal
(an X windows pseudo-terminal),
then the xlabel library component may be of help to you.
The xlabel library component will set the title bar of the Xterminal
to contain the name of the current stack, and maintain the title whenever the
the current stack is changed.
To load the xlabel component, first load the library as described in
section~\ref{sec:start}, then type the following:
\begin{hol}\begin{alltt}
	load_library `window:xlabel`;;
\end{alltt}\end{hol}

\section{Batch Proof}

Once you have completed a proof with the window system, you may wish to
reuse part or all of that proof.
Until now, the proof has been developed as a series of operations on a stack
of windows.
Proofs can be repeated noninteractively without using the window stack.
Each of the interactive commands we have seen so far
(except the undo and stack related commands)
has a batch equivalent.
The batch commands have the same name as their interactive
counterparts, except they are in lowercase.

A batch command to transform a window
takes the original window as an argument and returns the transformed window.
All such commands will have the basic type \ml{:window -> window}.
Batch analogues to commands which create subwindows
have an argument of the transformation function to apply to the subwindow.
They then take the original parent window as an argument,
open a subwindow in the parent,
apply the transformation function to the subwindow,
and close the subwindow,
returning the transformed parent window.
All of these commands will have the basic type 
\ml{:(window -> window) -> window -> window}.
The batch commands use of the \ML\ run-time stack 
mirrors the use of the window stack during interactive proof.

As an illustration of batch proof, we now repeat the first proof of
section~\ref{sec:start}.
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #let w1 = create_win "(==>) (A /\ (B /\ C))" ["~C"] [] [];;
   w1 = (|- A /\ B /\ C ==> A /\ B /\ C, ["~C"], [], []) : window
\end{verbatim}\end{session}
The \ml{create\_win} command creates a window with the specified 
relation and focus.   Its other parameters specify lists of assumptions
to make and theorems that might be relevant to the window.
\ml{create\_win} is the noninteractive analogue of \ml{BEGIN\_STACK}.
\begin{session}\begin{verbatim}
   #let w2 = ((pure_rewrite_win [ASSUME "~C"]) CB
   #          (open_win [RAND] (rewrite_win []))) w1;;
   w2 = (~C |- A /\ F ==> A /\ B /\ C, ["~C"], [], []) : window
   
   #win_thm w2;;
   ~C |- A /\ F ==> A /\ B /\ C
\end{verbatim}\end{session}
(Note that \ml{CB}\index{CB@{\ptt CB}} is new to release 2.0 of \HOL:
\ml{f CB g = g o f}.)
Since this particular combination of commands is quite common,
the one command \ml{transform} has been created for this situation.
\begin{boxed}\begin{verbatim}
   transform : (term -> term list -> thm list -> (window -> window) -> thm
\end{verbatim}\end{boxed}\index{transform@{\ptt transform}}
\ml{transform} creates a window, transforms it and returns the resulting
theorem.
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #transform "(==>) (A /\ (B /\ C))" ["~C"] []
   #          ((pure_rewrite_win [ASSUME "~C"]) CB
   #           (open_win [RAND] (rewrite_win [])));;
   ~C |- A /\ F ==> A /\ B /\ C
\end{verbatim}\end{session}

To interface between interactive and batch proof the following
functions are provided:
\begin{boxed}\begin{verbatim}
   TOP_WIN : void -> window
   APPLY_TRANSFORM : (window -> window) -> void
\end{verbatim}\end{boxed}\index{TOP\_WIN@{\ptt TOP\_WIN}}\index{APPLY\_TRANSFORM@{\ptt APPLY\_TRANSFORM}}
\ml{TOP\_WIN} returns the window on the top of the window stack.
\ml{APPLY\_TRANSFORM} applies a window transformation function to the top of
the stack.
All the interactive transformation commands can be described with
\ml{APPLY\_TRANSFORM}.
For example,
\begin{alltt}
   REWRITE_WIN thms \(=\) APPLY_TRANSFORM (rewrite_win thms)
\end{alltt}

\section{The tactic Library Component}

Most proof done with \HOL\ uses the subgoal package.
For most applications the subgoal package remains the most appropriate tool.
However it is possible to mix the two proof styles.
If you would like to use window inference from within the subgoal package
you should load the tactic library component as follows:
\begin{hol}\begin{alltt}
	load_library `window:tactic`;;
\end{alltt}\end{hol}

The tactic library component contains the following functions for 
mixing the window inference and subgoal proof styles:
\begin{boxed}\begin{verbatim}
   BEGIN_STACK_TAC : string -> path -> thm list -> tactic
   END_STACK_TAC : tactic
   open_TAC : path -> thm list -> (window -> window) -> tactic
\end{verbatim}\end{boxed}\index{BEGIN\_STACK\_TAC@{\ptt BEGIN\_STACK\_TAC}}\index{CLOSE\_STACK\_TAC@{\ptt CLOSE\_STACK\_TAC}}\index{open\_TAC@{\ptt open\_TAC}}
\ml{BEGIN\_STACK\_TAC} and \ml{END\_STACK\_TAC} are for interactive use only and
should be used to develop a proof.
Once developed, a proof can be repeated with \ml{open\_TAC}.
The idea behind these tactics is to open a window inside the current goal,
so as to transform some subterm of the goal.
The path parameter of both \ml{OPEN\_TAC} and \ml{open\_TAC} is the path
through the goal to the focus of the required subwindow.
The list of theorems is the list of theorems that might be relevant to
the proof.

Here is a simple interactive example.
Suppose we had as our current goal the term \ml{"A \hand\ B \hand\ F"}.
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #set_goal ([], "A /\ B /\ F");;
   "A /\ B /\ F"
   
   () : void
\end{verbatim}\end{session}
If we wanted to rewrite just the subterm \ml{"B \hand\ F"} to \ml{"F"} we
can do this by opening a window on the subterm.
\begin{session}\begin{verbatim}
   #expand (BEGIN_STACK_TAC `tac-ex` [RAND] []);;
   OK..
   ==> * B /\ F
   "A /\ B /\ F"
   
   () : void
\end{verbatim}\end{session}
Having opened at window on the desired subterm we can rewrite it without
effecting the remainder of the goal.
\begin{session}\begin{verbatim}
   #REWRITE_WIN [];;
   ==> * F
   () : void
\end{verbatim}\end{session}
The \ml{END\_STACK\_TAC} tactic then takes the reasoning done in the 
window stack and applies it to the goal.
\ml{END\_STACK\_TAC}, will not work if you have made any changes to the
goal since creating the stack.
\begin{session}\begin{verbatim}
   #expand (END_STACK_TAC `tac-ex`);;
   ==> * F
   OK..
   "A /\ F"
   
   () : void
\end{verbatim}\end{session}
The same example is repeated here with the window inference performed
noninteractively.
\setcounter{sessioncount}{1}
\begin{session}\begin{verbatim}
   #set_goal ([], "A /\ (B /\ F)");;
   "A /\ B /\ F"
   
   () : void
   
   #expand (open_TAC [RAND] [] (rewrite_win []));;
   OK..
   "A /\ F"
   
   () : void
\end{verbatim}\end{session}

\section{Adding New Window Rules}	\label{sec:win}

To allow the opening and closing of subwindows,
the system chains together several inference rules on behalf of the user.
These rules are called {\it window rules\/} and the system keeps them
in a data base together with some information about them.

The system has a full set of rules for opening and closing
subwindows on \HOL\ terms.
These rules are capable of preserving the following relations:
\ml{"="}, \ml{"==>"} and \ml{"<=="}.
The rules in the system exploit the contextual
information available when windowing on the positions 
marked with `\ml{\_}' in the following
terms: \ml{"\_\hand\_"}, \ml{"\_\hor\_"}, \ml{"\_==>\_"}, \ml{"\_<==\_"},
\ml{"\_=>\_|\_"}, \ml{"(\\\_.\_)\_"}, and \ml{let\_=\_in\_}.
However, if you would like the system to preserve other relations,
or exploit the contextual information available inside other terms,
then you will have to add some rules to the database.

Each window rule must be of type \ml{:term -> (thm -> thm)}.
A rule should take, the focus of the parent window and the theorem held
by the child window, and return the theorem required to transform the parent
window.
For example, the window rule \ml{IMP\_CONJ1\_CLOSE} as defined below is used
when opening a subwindow at \ml{"A"} in \ml{"A \hand\ B"} while preserving
\ml{"==>"} in the parent window.
\begin{verbatim}
          B |- A' ==> A
   ---------------------------  IMP_CONJ1_CLOSE "A /\ B" 
    |- (A' /\ B) ==> (A /\ B)
\end{verbatim}
Each rule in the system is packaged with the following information:
\begin{itemize}
	\item	The path from the focus of the parent window to the focus
		of the child window.
		In the case of \ml{IMP\_CONJ1\_CLOSE} this is 
		\ml{[RATOR; RAND]}.
	\item	A function from the focus of the parent window to \ml{bool}.
		The function is true iff the rule is applicable to the
		focus.
		\ml{IMP\_CONJ1\_CLOSE} only works on conjunctions,
		so it is stored with the function \ml{is\_conj}.
	\item	A function which takes the focus of the parent window and
		the relation that we want to preserve in the parent window,
		and returns the relation that this rule will preserve in
		the child window.
		\ml{IMP\_CONJ1\_CLOSE} always preserves \ml{"==>"} in the
		child window.
	\item	A function which takes the focus of the parent window and
		the relation that we want to preserve in the parent window,
		and returns the relation that this rule will preserve in
		the parent window.
		\ml{IMP\_CONJ1\_CLOSE} always preserves \ml{"==>"} in the
		parent window.
	\item	A function which takes the focus and assumptions of the
		parent window, and returns the assumptions of the 
		child window.

		The assumptions of a window are represented by a list of
		theorems each of which has just one hypothesis.
		An assumption {\it a}\/ is typically represented by the
		theorem \ml{\(a\) |- \(a\)}.
		However, consider a window with focus
		\ml{"\(a\) \hand\ \(b\) \hand\ \(c\)"}.
		If you were to open a subwindow at \ml{"\(a\)"} in such a 
		window, you might expect the subwindow to have two new
		assumptions, \ml{"\(b\)"} and \ml{"\(c\)"}.
		However a batch command would probably expect that when
		opening a window at the first operand of a conjunction, it
		would gain the second operand of the conjunction
		(namely \ml{"\(b\) \hand\ \(c\)"}) as an assumption.
		To avoid this a conflict of expectations, the following
		theorems should be added when opening the window:
		\ml{\(b\) \hand\ \(c\) |- \(b\)} and
		\ml{\(b\) \hand\ \(c\) |- \(c\)}.
		The system then knows that \ml{"\(b\) \hand\ \(c\)"} can
		be assumed true, and that from that it can derive the
		\ml{"\(b\)"} and \ml{"\(c\)"}.
		Only the conclusions of these theorems 
		(namely \ml{"\(b\)"} and \ml{"\(c\)"}) will be displayed as
		assumptions to the user during interactive proof.

	\item   A function which takes the focus of the parent window
		and returns the list of variables which appear
		bound in the parent window, but which are free in the
		child window.
		That is, if the window rule opens inside the body of 
		an abstraction, it returns the list of variables bound by
		the abstraction, otherwise the empty list is returned.
\end{itemize}
To add a window rule to the system, use the function
\ml{store\_rule}\index{store\_rule@{\ptt store\_rule}|(}.
\begin{boxed}\begin{verbatim}
   store_rule : window_rule -> void
\end{verbatim}\end{boxed}\index{store\_rule@{\ptt store\_rule}|)}
Where \ml{window\_rule} is defined as:
\begin{verbatim}
   lettype window_rule = (  path
                         #  (term -> bool)
                         #  (term -> term -> term)
                         #  (term -> term -> term)
                         #  (term -> ((thm list) -> (thm list)))
                         #  (term -> (term list))
                         #  (term -> (thm -> thm))
                         );;
\end{verbatim}\index{window\_rule@{\ptt window\_rule}}
Namely, a tuple of those components just described, and the window rule 
itself.
For example, \ml{IMP\_CONJ1\_CLOSE} was added to the system with the
following command:
\begin{verbatim}
   store_rule   (   [RATOR; RAND]
                ,   is_conj
                ,   (\foc.\rel. "==>")
                ,   (\foc.\rel. "==>")
                ,   (\foc.\hyps. (SMASH (ASSUME (rand foc)))@hyps)
                ,   (\foc. [])
                ,   IMP_CONJ1_CLOSE
                );;
\end{verbatim}
(Note that \ml{SMASH} is new inference rule introduced by the window library.
 \ml{SMASH} is similar to \ml{CONJUNCTS}.)

When opening a window it will usually be the case that there are several
possible lists of window rules which could have been chained together 
to open a window at the required position.
The system uses the following heuristics to decide which of two potential
lists of rules is the {\it better}:
\begin{enumerate}
	\item	The system considers the child window which would result from
		using each of possible lists of rules.
		\begin{itemize}	
			\item	If the relation required to be preserved by one
				child window is known to be weaker than that
				required by the other, the list of rules
				which produced the window with the weaker
				relation is chosen.
			\item	Otherwise, the list of rules which produced
				the child window with the most hypotheses is
				chosen.
		\end{itemize}
	\item	If step 1 can not distinguish between the lists of rules then
		the choice between them is somewhat arbitrary.
		In such a case the lists are compared one rule at
		a time until one is found which is regarded as being more
		{\it specific}\/ than the other.
		\begin{itemize}
			\item	Rules which follow a longer path are regarded as
				more specific.
			\item	Rules which preserve a weaker relation in the
				parent window are regarded as more specific.
			\item	Rules which preserve a weaker relation in the
				child window are regarded as more specific.
			\item	Rules which create more assumptions in the
				child window are regarded as more specific.
			\item	Rules which were more recently added to the
				system are regarded as more specific.
		\end{itemize}
\end{enumerate}

\section{Adding New Relations}	\label{sec:rel}

Before the window library can be used to preserve a relation, the
system must know that the relation is reflexive and transitive.
The system is already aware that the following relations are reflexive
and transitive: \ml{"="}, \ml{"==>"} and \ml{"<=="}.

To tell the system that some relation is reflexive and transitive, use
\ml{add\_relation}\index{add\_relation@{\ptt add\_relation}|(}.
\begin{boxed}\begin{verbatim}
   add_relation : (thm # thm) -> void
\end{verbatim}\end{boxed}
\ml{add\_relation} takes a pair of theorems, which should be of the same form
as \ml{EQ\_REFL} and \ml{EQ\_TRANS} and stores these theorems for use by
the system.
For example, to tell the system that implication was reflexive and transitive
we defined two theorems
\ml{IMP\_REFL\_THM}\index{IMP\_REFL\_THM@{\ptt IMP\_REFL\_THM}|(}
and
\ml{IMP\_TRANS\_THM}\index{IMP\_TRANS\_THM@{\ptt IMP\_TRANS\_THM}|(}
of the following form:
\begin{verbatim}
   IMP_REFL_THM = |- !x. x ==> x

   IMP_TRANS_THM = |- !x y z. (x ==> y) /\ (y ==> z) ==> x ==> z
\end{verbatim}
and then issued the command:
\begin{verbatim}
   add_relation (IMP_REFL_THM, IMP_TRANS_THM);;
\end{verbatim}\index{IMP\_TRANS\_THM@{\ptt IMP\_TRANS\_THM}|)}\index{IMP\_REFL\_THM@{\ptt IMP\_REFL\_THM}|)}\index{add\_relation@{\ptt add\_relation}|)}

\subsection{Relative Strengths}

We say that some relation, $r_1$,
is {\it stronger}\index{stronger}\/ than another relation, $r_2$, 
if whenever some $x$ and $y$ are related by $r_1$
they are also related by $r_2$.
Note that stronger is a reflexive relation.

If the system knows that $r_1$ is stronger than $r_2$ then
it will allow you use theorems of the form 
\begin{alltt}
   |- \(f\sb{n+1}\) \(r\sb{1}\) \(f\sb{n}\)
\end{alltt}
to transform the focus of a window which is supposed to be preserving
the relation $r_2$.
Furthermore, if you ask the system to open a subwindow 
in the focus of a window which is supposed to be preserving the relation
$r_2$, and the system has no window rule for that case, it can substitute
a window rule which preserves $r_1$.

Every relation used with the window library must be reflexive.
From this we can deduce that equality is stronger than any relation that can be
used with system.
The window library knows this, so,
when adding some new relation,
there is no need to state that equality is stronger than it.
However, if you plan on adding two new relations to the system,
say \ml{"r1"} and \ml{"r2"}, such that \ml{"r1"} is stronger than \ml{"r2"},
you will need to tell the system about that.

First you should prove the following theorem \ml{WEAKEN\_r1\_r2}:
\begin{verbatim}
    WEAKEN_r1_r2 = |- !x y. (x r1 y) ==> (x r2 y)
\end{verbatim}
then call
\ml{add\_weak}\index{add\_weak@{\ptt add\_weak}|(}
to add the theorem to the system:
\begin{boxed}\begin{verbatim}
   add_weak : thm -> void
\end{verbatim}\end{boxed}
as in:
\begin{verbatim}
   add_weak WEAKEN_r1_r2;;
\end{verbatim}\index{add\_weak@{\ptt add\_weak}|)}

\section{Future Changes}

Some changes to the window library are currently being considered.
These changes include:
\begin{itemize}
	\item	The window rules for opening inside the body of abstractions
		may be changed so that they rename
		bound variables rather than hiding assumptions in which
		the bound variables occur.
	\item	I may add the ability to weaken the premises of
		a supposition.
		This would be an alternative to compelling the user to prove
		used conjectures.
	\item	It may be possible to specify a path to a subterm with
		pattern matching.
	\item	Some functions which are currently considered {\it internal\/}
		to the system may be documented in future releases.
\end{itemize}

The window library is still work in progress.
It has been released to solicit comment as much as to provide a service.
As people begin to use the software I expect various infelicities to be brought
to light.
It is my intention to keep the interface fluid
for the first couple to releases so that I can capitalise on
the feedback I get from people's experiences with using it.
While I hope that the vast majority of the code is bug-free,
I will not be too surprised to learn otherwise.
If you do have a suggestion for improving the system, or find a bug, please
contact me.   I will endeavour to provide bug fixes as soon as possible.
When reporting a bug, please be sure to tell me which versions of the 
window inference system and \HOL\ you are using.
The constant \ml{window\_version} contains the version number of the window
system.
I can be contacted at:
\begin{center}
	\begin{tabular}{l@{\hspace{10mm}}ll}
		Jim Grundy				&			&								\\
		University of Cambridge	& phone:	&	+44$\;$223$\:$33$\,$4760	\\
		Computer Laboratory		& fax:		&	+44$\;$223$\:$33$\,$4678	\\
		New Museums Site		& telex:	&	CAMSPLG 81240				\\
		Pembroke Street			& email:	&	jg@cl.cam.ac.uk				\\
		Cambridge\ \ {\small CB}2 3{\small QG}	&	&						\\
		UNITED KINGDOM			&			&								\\
	\end{tabular}
\end{center}

\section{Bugs}

	Opening a window inside a \ml{let} expression will not work properly
		for \ml{let} expressions involving tuples of variables or
		which use the \ml{and} construct.

\section*{Acknowledgements}
	I would like to thank Andy Gordon, Mats Larsson, Laurent Thery and
		Joakim von Wright, all of whom have found bugs in earlier versions of
		the system, and suggested many improvements.