initial version

cleaned-up the sources of the ITP course
- remove internal notes
- remove exercise solutions
- remove KTH logo
- add Creative Commons license
This commit is contained in:
2019-11-11 10:22:43 +01:00
commit 3c35cc25c3
71 changed files with 35906 additions and 0 deletions

5
exercises/Makefile Executable file
View File

@ -0,0 +1,5 @@
all:
clean:
rm -f *Theory.sig *Theory.sml *.ui *.uo \#* *.toc *.aux *.ps *.log *.lof *.bbl *.blg *.hix *.tid *.tde *.out *~

82
exercises/README Normal file
View File

@ -0,0 +1,82 @@
This directory contains exercises that were used during a ITP Course
at KTH in Stockholm in 2017 (see
https://www.kth.se/social/group/interactive-theorem-/). These
exercises are intended to accompany the slides of this course that has
been made publicly available.
When working on the exercises, you don't need to read to the end of
the whole sheet before starting to work on an exercise. However, I
highly recommend reading all subquestions first. Some are easier, if
the have already been considered while working on previous
parts. Often there are hints at the very end of an exercise sheet. The
intention is that you work on exercise first without these hints. If
you have trouble, they provide some help. Usually it is a valuable
learning experience thinking about what is explained by the hints. So,
I really recomment to first attempt the exercises without the hints
first.
There are the following exercise sheets:
0) Background Questionaire (before lecture started)
This was handed out before the lecture even started. It's intention
was to get a feeling for the background of the students. It was
expected that students on average are able to solve half of the
questions within 1 h.
1) Exercise 1 (very beginning of Course)
This exercise asks students to set up their HOL environment and
practise using SML. It was handed out at the very beginning of the
course and does not require any knowledge from the course.
2) Exercise 2 (after Part 6, i.e. after forward proofs)
Learn basic usage of HOL and emacs. How to construct terms, simple
forward proofs and simple proof automation.
3) Exercise 3 (after part 9, i.e. after induction proofs)
Play around with simple backward proofs.
4) Exercise 4 (after part 11, i.e. good definitions)
Some simple proofs and definitions. The challange is how to structure your
proofs nicely. Moreover, this exercise requires some SML programming and
connects proofs and SML execution.
5) Exercise 5 (after part 12, i.e. deep/shallow embeddings, knowledge about simplifier from part 13 useful)
This exercise focuses on the effect of different definitions on
proofs. Moreover, more so than in exercise 4 students are required to
structure their development by defining own auxiliary definitions and
lemmata. Some proof ideas are, while still rather simple, not trivial.
This exercise can be solved without using the simplifier. However, the
simplifier can help a lot. Similarlish it is encouraged to really
learn how to use Metis for this exercise.
6) Exercise 6 (final project, after part 13, simplifier)
For organisational reasons, the final project was presented in
exercise 6, i.e. before exercise 7 and the end of the course. It
requires people to learn about part of HOL themselves, do a non
trivial formalisation and come up with some non trivial proofs.
Exercise 6 is intentend to take 3-4 times as much time as the other
exercises.
7) Exercise 7 (after part 14, advanced definitions)
Some exercises about advanced usages of the simplifier and how to use
inductive relations. It is very short, since people were in parallel
working already on their final project.

39
exercises/a2.dot Normal file
View File

@ -0,0 +1,39 @@
digraph G {
node_0 [label="0: '0'"]
node_2 [label="2: -"]
node_6 [label="6: '2'"]
node_10 [label="10: -"]
node_18 [label="18: '6'"]
node_10 -> node_18 [label="r"]
node_6 -> node_10 [label="r"]
node_2 -> node_6 [label="l"]
node_4 [label="4: -"]
node_12 [label="12: '4'"]
node_4 -> node_12 [label="l"]
node_8 [label="8: -"]
node_24 [label="24: '8'"]
node_8 -> node_24 [label="l"]
node_4 -> node_8 [label="r"]
node_2 -> node_4 [label="r"]
node_0 -> node_2 [label="l"]
node_1 [label="1: -"]
node_5 [label="5: -"]
node_13 [label="13: -"]
node_21 [label="21: '7'"]
node_13 -> node_21 [label="r"]
node_5 -> node_13 [label="l"]
node_9 [label="9: '3'"]
node_5 -> node_9 [label="r"]
node_1 -> node_5 [label="l"]
node_3 [label="3: '1'"]
node_11 [label="11: -"]
node_27 [label="27: '9'"]
node_11 -> node_27 [label="l"]
node_3 -> node_11 [label="l"]
node_7 [label="7: -"]
node_15 [label="15: '5'"]
node_7 -> node_15 [label="r"]
node_3 -> node_7 [label="r"]
node_1 -> node_3 [label="r"]
node_0 -> node_1 [label="r"]
}

781
exercises/a2.eps Normal file
View File

@ -0,0 +1,781 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: graphviz version 2.38.0 (20140413.2041)
%%Title: G
%%Pages: 1
%%BoundingBox: 36 36 559 428
%%EndComments
save
%%BeginProlog
/DotDict 200 dict def
DotDict begin
/setupLatin1 {
mark
/EncodingVector 256 array def
EncodingVector 0
ISOLatin1Encoding 0 255 getinterval putinterval
EncodingVector 45 /hyphen put
% Set up ISO Latin 1 character encoding
/starnetISO {
dup dup findfont dup length dict begin
{ 1 index /FID ne { def }{ pop pop } ifelse
} forall
/Encoding EncodingVector def
currentdict end definefont
} def
/Times-Roman starnetISO def
/Times-Italic starnetISO def
/Times-Bold starnetISO def
/Times-BoldItalic starnetISO def
/Helvetica starnetISO def
/Helvetica-Oblique starnetISO def
/Helvetica-Bold starnetISO def
/Helvetica-BoldOblique starnetISO def
/Courier starnetISO def
/Courier-Oblique starnetISO def
/Courier-Bold starnetISO def
/Courier-BoldOblique starnetISO def
cleartomark
} bind def
%%BeginResource: procset graphviz 0 0
/coord-font-family /Times-Roman def
/default-font-family /Times-Roman def
/coordfont coord-font-family findfont 8 scalefont def
/InvScaleFactor 1.0 def
/set_scale {
dup 1 exch div /InvScaleFactor exch def
scale
} bind def
% styles
/solid { [] 0 setdash } bind def
/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
/bold { 2 setlinewidth } bind def
/filled { } bind def
/unfilled { } bind def
/rounded { } bind def
/diagonals { } bind def
/tapered { } bind def
% hooks for setting color
/nodecolor { sethsbcolor } bind def
/edgecolor { sethsbcolor } bind def
/graphcolor { sethsbcolor } bind def
/nopcolor {pop pop pop} bind def
/beginpage { % i j npages
/npages exch def
/j exch def
/i exch def
/str 10 string def
npages 1 gt {
gsave
coordfont setfont
0 0 moveto
(\() show i str cvs show (,) show j str cvs show (\)) show
grestore
} if
} bind def
/set_font {
findfont exch
scalefont setfont
} def
% draw text fitted to its expected width
/alignedtext { % width text
/text exch def
/width exch def
gsave
width 0 gt {
[] 0 setdash
text stringwidth pop width exch sub text length div 0 text ashow
} if
grestore
} def
/boxprim { % xcorner ycorner xsize ysize
4 2 roll
moveto
2 copy
exch 0 rlineto
0 exch rlineto
pop neg 0 rlineto
closepath
} bind def
/ellipse_path {
/ry exch def
/rx exch def
/y exch def
/x exch def
matrix currentmatrix
newpath
x y translate
rx ry scale
0 0 1 0 360 arc
setmatrix
} bind def
/endpage { showpage } bind def
/showpage { } def
/layercolorseq
[ % layer color sequence - darkest to lightest
[0 0 0]
[.2 .8 .8]
[.4 .8 .8]
[.6 .8 .8]
[.8 .8 .8]
]
def
/layerlen layercolorseq length def
/setlayer {/maxlayer exch def /curlayer exch def
layercolorseq curlayer 1 sub layerlen mod get
aload pop sethsbcolor
/nodecolor {nopcolor} def
/edgecolor {nopcolor} def
/graphcolor {nopcolor} def
} bind def
/onlayer { curlayer ne {invis} if } def
/onlayers {
/myupper exch def
/mylower exch def
curlayer mylower lt
curlayer myupper gt
or
{invis} if
} def
/curlayer 0 def
%%EndResource
%%EndProlog
%%BeginSetup
14 default-font-family set_font
1 setmiterlimit
% /arrowlength 10 def
% /arrowwidth 5 def
% make sure pdfmark is harmless for PS-interpreters other than Distiller
/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
% make '<<' and '>>' safe on PS Level 1 devices
/languagelevel where {pop languagelevel}{1} ifelse
2 lt {
userdict (<<) cvn ([) cvn load put
userdict (>>) cvn ([) cvn load put
} if
%%EndSetup
setupLatin1
%%Page: 1 1
%%PageBoundingBox: 36 36 559 428
%%PageOrientation: Portrait
0 0 1 beginpage
gsave
36 36 523 392 boxprim clip newpath
1 1 set_scale 0 rotate 40 40 translate
% node_0
gsave
1 setlinewidth
0 0 0 nodecolor
245.85 366 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
232.85 362.3 moveto 26 (0: '0') alignedtext
grestore
% node_2
gsave
1 setlinewidth
0 0 0 nodecolor
185.85 279 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
176.35 275.3 moveto 19 (2: -) alignedtext
grestore
% node_0->node_2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 234.84 349.41 moveto
225.88 336.71 213.07 318.56 202.79 304.01 curveto
stroke
0 0 0 edgecolor
newpath 205.41 301.64 moveto
196.78 295.49 lineto
199.69 305.68 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 205.41 301.64 moveto
196.78 295.49 lineto
199.69 305.68 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
219.85 318.8 moveto 4 (l) alignedtext
grestore
% node_1
gsave
1 setlinewidth
0 0 0 nodecolor
287.85 279 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
278.35 275.3 moveto 19 (1: -) alignedtext
grestore
% node_0->node_1
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 253.95 348.61 moveto
259.99 336.38 268.36 319.44 275.27 305.46 curveto
stroke
0 0 0 edgecolor
newpath 278.48 306.85 moveto
279.77 296.34 lineto
272.21 303.75 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 278.48 306.85 moveto
279.77 296.34 lineto
272.21 303.75 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
269.85 318.8 moveto 5 (r) alignedtext
grestore
% node_6
gsave
1 setlinewidth
0 0 0 nodecolor
85.85 192 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
72.85 188.3 moveto 26 (6: '2') alignedtext
grestore
% node_2->node_6
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 169.78 264.34 moveto
153.52 250.53 128.21 229.01 109.63 213.21 curveto
stroke
0 0 0 edgecolor
newpath 111.76 210.43 moveto
101.87 206.62 lineto
107.23 215.77 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 111.76 210.43 moveto
101.87 206.62 lineto
107.23 215.77 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
141.85 231.8 moveto 4 (l) alignedtext
grestore
% node_4
gsave
1 setlinewidth
0 0 0 nodecolor
185.85 192 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
176.35 188.3 moveto 19 (4: -) alignedtext
grestore
% node_2->node_4
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 185.85 260.8 moveto
185.85 249.16 185.85 233.55 185.85 220.24 curveto
stroke
0 0 0 edgecolor
newpath 189.35 220.18 moveto
185.85 210.18 lineto
182.35 220.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 189.35 220.18 moveto
185.85 210.18 lineto
182.35 220.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
185.85 231.8 moveto 5 (r) alignedtext
grestore
% node_10
gsave
1 setlinewidth
0 0 0 nodecolor
31.85 105 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
18.85 101.3 moveto 26 (10: -) alignedtext
grestore
% node_6->node_10
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 75.69 175.01 moveto
67.77 162.55 56.63 145.01 47.56 130.74 curveto
stroke
0 0 0 edgecolor
newpath 50.28 128.48 moveto
41.96 121.92 lineto
44.37 132.23 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 50.28 128.48 moveto
41.96 121.92 lineto
44.37 132.23 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
62.85 144.8 moveto 5 (r) alignedtext
grestore
% node_18
gsave
1 setlinewidth
0 0 0 nodecolor
31.85 18 31.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
15.35 14.3 moveto 33 (18: '6') alignedtext
grestore
% node_10->node_18
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 31.85 86.8 moveto
31.85 75.16 31.85 59.55 31.85 46.24 curveto
stroke
0 0 0 edgecolor
newpath 35.35 46.18 moveto
31.85 36.18 lineto
28.35 46.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 35.35 46.18 moveto
31.85 36.18 lineto
28.35 46.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
31.85 57.8 moveto 5 (r) alignedtext
grestore
% node_12
gsave
1 setlinewidth
0 0 0 nodecolor
108.85 105 31.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
92.35 101.3 moveto 33 (12: '4') alignedtext
grestore
% node_4->node_12
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 172.43 176.19 moveto
160.62 163.15 143.22 143.95 129.61 128.92 curveto
stroke
0 0 0 edgecolor
newpath 132.19 126.56 moveto
122.89 121.5 lineto
127.01 131.26 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 132.19 126.56 moveto
122.89 121.5 lineto
127.01 131.26 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
152.85 144.8 moveto 4 (l) alignedtext
grestore
% node_8
gsave
1 setlinewidth
0 0 0 nodecolor
185.85 105 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
176.35 101.3 moveto 19 (8: -) alignedtext
grestore
% node_4->node_8
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 185.85 173.8 moveto
185.85 162.16 185.85 146.55 185.85 133.24 curveto
stroke
0 0 0 edgecolor
newpath 189.35 133.18 moveto
185.85 123.18 lineto
182.35 133.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 189.35 133.18 moveto
185.85 123.18 lineto
182.35 133.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
185.85 144.8 moveto 5 (r) alignedtext
grestore
% node_24
gsave
1 setlinewidth
0 0 0 nodecolor
180.85 18 31.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
164.35 14.3 moveto 33 (24: '8') alignedtext
grestore
% node_8->node_24
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 184.84 86.8 moveto
184.15 75.16 183.23 59.55 182.45 46.24 curveto
stroke
0 0 0 edgecolor
newpath 185.94 45.95 moveto
181.86 36.18 lineto
178.95 46.36 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 185.94 45.95 moveto
181.86 36.18 lineto
178.95 46.36 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
183.85 57.8 moveto 4 (l) alignedtext
grestore
% node_5
gsave
1 setlinewidth
0 0 0 nodecolor
287.85 192 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
278.35 188.3 moveto 19 (5: -) alignedtext
grestore
% node_1->node_5
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 287.85 260.8 moveto
287.85 249.16 287.85 233.55 287.85 220.24 curveto
stroke
0 0 0 edgecolor
newpath 291.35 220.18 moveto
287.85 210.18 lineto
284.35 220.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 291.35 220.18 moveto
287.85 210.18 lineto
284.35 220.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
287.85 231.8 moveto 4 (l) alignedtext
grestore
% node_3
gsave
1 setlinewidth
0 0 0 nodecolor
403.85 192 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
390.85 188.3 moveto 26 (3: '1') alignedtext
grestore
% node_1->node_3
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 305.47 265.09 moveto
324.71 250.99 355.74 228.25 377.8 212.09 curveto
stroke
0 0 0 edgecolor
newpath 380.07 214.77 moveto
386.06 206.03 lineto
375.93 209.12 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 380.07 214.77 moveto
386.06 206.03 lineto
375.93 209.12 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
352.85 231.8 moveto 5 (r) alignedtext
grestore
% node_13
gsave
1 setlinewidth
0 0 0 nodecolor
257.85 105 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
244.85 101.3 moveto 26 (13: -) alignedtext
grestore
% node_5->node_13
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 281.92 174.21 moveto
277.73 162.33 272.02 146.17 267.22 132.56 curveto
stroke
0 0 0 edgecolor
newpath 270.39 131.02 moveto
263.76 122.76 lineto
263.79 133.35 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 270.39 131.02 moveto
263.76 122.76 lineto
263.79 133.35 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
274.85 144.8 moveto 4 (l) alignedtext
grestore
% node_9
gsave
1 setlinewidth
0 0 0 nodecolor
330.85 105 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
317.85 101.3 moveto 26 (9: '3') alignedtext
grestore
% node_5->node_9
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 296.14 174.61 moveto
302.32 162.38 310.89 145.44 317.97 131.46 curveto
stroke
0 0 0 edgecolor
newpath 321.19 132.84 moveto
322.58 122.34 lineto
314.94 129.68 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 321.19 132.84 moveto
322.58 122.34 lineto
314.94 129.68 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
312.85 144.8 moveto 5 (r) alignedtext
grestore
% node_21
gsave
1 setlinewidth
0 0 0 nodecolor
262.85 18 31.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
246.35 14.3 moveto 33 (21: '7') alignedtext
grestore
% node_13->node_21
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 258.86 86.8 moveto
259.54 75.16 260.46 59.55 261.25 46.24 curveto
stroke
0 0 0 edgecolor
newpath 264.74 46.36 moveto
261.84 36.18 lineto
257.76 45.95 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 264.74 46.36 moveto
261.84 36.18 lineto
257.76 45.95 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
260.85 57.8 moveto 5 (r) alignedtext
grestore
% node_11
gsave
1 setlinewidth
0 0 0 nodecolor
403.85 105 27.1 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
390.85 101.3 moveto 26 (11: -) alignedtext
grestore
% node_3->node_11
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 403.85 173.8 moveto
403.85 162.16 403.85 146.55 403.85 133.24 curveto
stroke
0 0 0 edgecolor
newpath 407.35 133.18 moveto
403.85 123.18 lineto
400.35 133.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 407.35 133.18 moveto
403.85 123.18 lineto
400.35 133.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
403.85 144.8 moveto 4 (l) alignedtext
grestore
% node_7
gsave
1 setlinewidth
0 0 0 nodecolor
480.85 105 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
471.35 101.3 moveto 19 (7: -) alignedtext
grestore
% node_3->node_7
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 417.26 176.19 moveto
429.22 162.99 446.91 143.47 460.59 128.36 curveto
stroke
0 0 0 edgecolor
newpath 463.21 130.68 moveto
467.33 120.92 lineto
458.02 125.98 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 463.21 130.68 moveto
467.33 120.92 lineto
458.02 125.98 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
447.85 144.8 moveto 5 (r) alignedtext
grestore
% node_27
gsave
1 setlinewidth
0 0 0 nodecolor
400.85 18 31.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
384.35 14.3 moveto 33 (27: '9') alignedtext
grestore
% node_11->node_27
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 403.24 86.8 moveto
402.83 75.16 402.28 59.55 401.81 46.24 curveto
stroke
0 0 0 edgecolor
newpath 405.3 46.05 moveto
401.45 36.18 lineto
398.31 46.29 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 405.3 46.05 moveto
401.45 36.18 lineto
398.31 46.29 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
402.85 57.8 moveto 4 (l) alignedtext
grestore
% node_15
gsave
1 setlinewidth
0 0 0 nodecolor
482.85 18 31.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
466.35 14.3 moveto 33 (15: '5') alignedtext
grestore
% node_7->node_15
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 481.25 86.8 moveto
481.53 75.16 481.89 59.55 482.21 46.24 curveto
stroke
0 0 0 edgecolor
newpath 485.71 46.26 moveto
482.44 36.18 lineto
478.71 46.09 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 485.71 46.26 moveto
482.44 36.18 lineto
478.71 46.09 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
482.85 57.8 moveto 5 (r) alignedtext
grestore
endpage
showpage
grestore
%%PageTrailer
%%EndPage: 1
%%Trailer
end
restore
%%EOF

121
exercises/e1.tex Normal file
View File

@ -0,0 +1,121 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\input{../hol_commands.inc}
\title{Exercise 1}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 1
\webversion{}{\\\small{due Friday 28th April}}
\end{center}
\bigskip
\section{Setting up Environment}
We will use the HOL theorem prover\footnote{\url{https://hol-theorem-prover.org}}.
For the practical sessions you will need to be able to use HOL on your own machine. Therefore, please set up the following software.
\subsection{Standard ML}
You will need to have Standard ML available. Please install PolyML 5.6\footnote{webpage \url{http://www.polyml.org}}\footnote{download link \url{https://github.com/polyml/polyml/releases/tag/v5.6}} or later.
\subsection{HOL}
Please install a recent version of the HOL theorem prover. I recommend installing the most recent version from the git repository. If for some reason you don't want to do this, the latest release should be fine as well. Installation instructions can be found on HOL's webpage\footnote{see \url{https://hol-theorem-prover.org/\#get}}.
\subsection{Emacs}
In the lecture GNU Emacs\footnote{https://www.gnu.org/software/emacs/} will be used as a user-interface. Please install a recent version of Emacs. Please make sure you use Emacs and not XEmacs.
\subsection{HOL-Mode and SML mode}
We will use the \emph{hol-mode} for Emacs. It is distributed with HOL, but needs setting up in Emacs. Please set it up and familiarise yourself with its basic usage. Documentation can be found on HOL's webpage\footnote{see \url{https://hol-theorem-prover.org/hol-mode.html}}.
We will write SML programs all the time. Please install the SML mode\footnote{\url{https://elpa.gnu.org/packages/sml-mode.html}} to enable syntax highlighting for ML in Emacs.
Information on both the SML and the HOL mode can also be found in HOL's interaction
manual\footnote{\url{https://hol-theorem-prover.org/HOL-interaction.pdf}}.
\section{SML}
Let's refresh our knowledge about Standard ML. Moreover, these
exercises are aimed at getting familiar with Emacs and using the HOL
mode. So, please use Emacs with HOL mode as a user-interface and treat
HOL like a ML REPL.
To learn more about the Emacs mode, you can have a look at the HOL interaction manual.
If you need a brush-up on SML syntax, I recommend reading something compact like
\url{https://learnxinyminutes.com/docs/standard-ml/}. If you need more, the book
\emph{ML for the Working Programmer} by Prof.\ Larry Paulson is a good introduction.
\subsection{Our Own Lists}
Of course SML comes with a decent list library. However, as an exercise implement your own list datatype and implement the following list operations for your own datatype:
%
\begin{itemize}
\item \texttt{length}
\item \texttt{append} (\texttt{@})
\item \texttt{rev}
\item \texttt{revAppend}
\item \texttt{exists}
\end{itemize}
%
If you don't know what these functions should do, you can find documentation of the Standard ML Basis Library at e.\,g.\ \url{http://sml-family.org}.
In addition implement a function \texttt{replicate\ :\ 'a -> int -> 'a list}, which is supposed to
construct a list of the given length that only contains the given element. For example \texttt{replicate "a" 3} should return the list \texttt{["a", "a", "a"]}.
\begin{enumerate}
\item Prove with pen and paper that for your implementation
\texttt{append l [] = l} holds for all \texttt{l}.
\item Similarly, prove \texttt{$\forall$l1 l2.\ length (append l1 l2) = length l1 + length l2}.
\item There are strong connections between \texttt{append}, \texttt{revAppend} and \texttt{rev}.
One can for example define \texttt{revAppend} by \texttt{revAppend l1 l2 = append (rev l1) l2}.
Write down similar definitions for \texttt{rev} and \texttt{append} using only \texttt{revAppend}.
\end{enumerate}
\subsection{Making Change}
In the following, let's use the standard list library again. Write a
program that given the coins and notes you have in your wallet, lists
\emph{all} the possible ways to pay a certain amount. Represent the
coins you have as a list of integers. If a number occurs twice in
this list, you have two coins with this value. The result should be
returned in the form of a list of lists. For simplicity, the output
may contain duplicates.
An example implementation of the function
\texttt{make\_change\ :\ int list -> int -> int list list} should
shows for example the following outputs. Notice however, that the output of
your implementation is allowed to contain duplicates and use a different
order of the lists.
\begin{itemize}
\item \texttt{make\_change [5,2,2,1,1,1] 6 =}\\
\-\texttt{\ \ \ [[5, 1], [2, 2, 1, 1]]}
\item \texttt{make\_change [5,2,2,1,1,1] 15 = []}
\item \texttt{make\_change [10,5,5,5,2,2,1,1,1] 10 =}\\
\-\texttt{\ \ \ [[10], [5, 5], [5, 2, 2, 1], [5, 2, 1, 1, 1]]}
\end{itemize}
\bigskip
Write down as formally as you can some properties of \texttt{make\_change}. An example
property is
\begin{center}\texttt{
$\forall$cs n. n > sum cs $\Longrightarrow$ make\_change cs n = []}
\end{center}
where \texttt{sum} is defined by \texttt{val sum = foldl (op+) 0} and we assume that \texttt{cs} contains no number less than 0.
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

166
exercises/e2.tex Normal file
View File

@ -0,0 +1,166 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\input{../hol_commands.inc}
\title{Exercise 2}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 2
\webversion{}{\\\small{due Friday 5th May}}
\end{center}
\bigskip
\section{Self-Study}
\subsection{Emacs}
If you don't know Emacs well, familiarise yourself with its basic usage. Learn the key combinations for common operations like
opening a file, saving current buffer, closing buffer, switching between buffers, searching in a file, copy and paste text etc.
You might consider printing the \emph{Emacs Reference Card}\footnote{\url{https://www.gnu.org/software/emacs/refcards/pdf/refcard.pdf}} and putting
it next to your computer.
\subsection{HOL Documentation}
Familiarise yourself with how to get help about HOL.
\begin{itemize}
\item Build the various documentations in directory \texttt{Manual}. For this, call \texttt{make} in directory \texttt{HOL-HOME/Manual}. For building the manuals, \texttt{hol} and \texttt{Holmake} need to run.
Therefore make sure, \texttt{HOL-HOME/bin} is in your PATH.
\item Have a brief look at the various manuals in order to understand where which kind of information
can be found.
\item The lectures will cover the logic foundations of the HOL
theorem prover only very briefly and lightly. If you are interested in more
details, have a look at the \emph{Logic} manual. This is purely optional.
\item Familiarise yourself with the different ways to access the reference manual.
As an example read up on \texttt{MATCH\_MP} in the HTML reference manual, the PDF reference manual and the in-system help (type \texttt{help "MATCH\_MP"}).
\item Familiarise yourself with the different printing switches of HOL, in particular the ones in hol-mode's menu. Learn how to turn Unicode-output on/off, how to show assumptions of theorems and how to show type annotations.
\item Use \texttt{DB.match} and \texttt{DB.find} to find theorems stating \verb#A /\ A = A#. Use both the emacs-mode and the SML REPL. Look at the interface of \texttt{DB}.
\end{itemize}
\subsection{Holmake}
Learn about \texttt{Holmake} by reading description manual sections 7.3 - 7.3.4.
\subsection{Constructing Terms and Forward Proofs}
To deepen the knowledge about how to construct terms, how to program in HOL and how to perform
forward proofs, please look at the following HOL modules: \ml{FinalThm.sml}, \ml{FinalTerm.sml},
\ml{FinalType.sml}, \ml{Drule.sig}, \ml{Psyntax.sig}, \ml{boolSyntax.sig}, \ml{Lib.sig}.
\section{Terms}
\subsection{Free and Bound Vars}
List the free variables of the following terms:
\begin{itemize}
\item \verb#(\x. 2 + (7 * x) + y) z#
\item \verb#x + y + 2#
\item \verb#!x. x + 1 > x#
\item \verb#?x. x = y + 2#
\end{itemize}
\subsection{Alpha Equivalence}
Are the following pairs of terms alpha-equivalent? A simple mark on the sheet is a sufficient answer. Also take two colors and mark all occurences of free vars in one color and all occourences of bound vars in the other. Assume that \texttt{x}, \texttt{y}, \texttt{z}, \texttt{a} and \texttt{b} are variables. \bigskip
\begin{tabular}{@{$\ \ \bullet\ \ $}ll}
\verb#\x. x# & \verb#\y. y# \\
\verb#(\x. x) a# & \verb#(\y. y) a# \\
\verb#(\x. x) a# & \verb#(\y. y) b# \\
\verb#(\x. x)# & \verb#(\x. y)# \\
\verb#(\x y. x /\ y)# & \verb#(\y x. x /\ y)# \\
\verb#(\x y. x /\ y) a a# & \verb#(\y x. x /\ y) a a# \\
\verb#a /\ b# & \verb#a /\ b# \\
\verb#!x. x + 1 > x# & \verb#!y. y + 1 > y# \\
\verb#?x. x = y + 2# & \verb#?x. x = z + 2# \\
\verb#!y. ?x. x = y + 2# & \verb#!z. ?x. x = z + 2# \\
\end{tabular}
\subsection{Constructing Terms}
Write a SML function \ml{mk\_imp\_conj\_term :\ int -> term} that constructs for inputs $n$ greater 1 the term \verb#!A1 ... An. A1 ==> ... ==> An ==> (A1 /\ ... /\ An)#. If $n$ is not greater one, a \ml{HOL\_ERR} exception (use \ml{failwith}). You might want to read up on \ml{boolSyntax} for this exercise. You can use list-make-functions like \ml{mk\_list\_conj}, but also use non-list ones.
\section{Basic Forward Proofs}
\subsection{Commutativity of Conjunction}
Prove the lemma \verb#!A B. (A /\ B) <=> (B /\ A)# using only inferences presented in the lecture.
\subsection{Simplifying Conjunction}
Prove the lemmas \verb#!A. (A /\ ~A) <=> F# and \verb#!A B. (A /\ ~A) /\ B <=> F#.
\section{Writing Own Automation}
\subsection{Implications between Conjunctions}
Write a function \texttt{show\_big\_conj\_imp :\ term -> term -> thm} that assumes that both terms are conjunctions and tries to prove that the first one implies the second one. It should be clever enough to handle \texttt{T} and \texttt{F}.
\verb#show_big_conj_imp ``a /\ (b /\ a) /\ c`` ``c /\ T /\ a``# for example should succeed with \verb#|- (a /\ (b /\ a) /\ c) ==> (c /\ T /\ a)#. It should also be able to show \verb#|- (a /\ F) /\ c ==> d#. If the implication cannot be shown, the function \texttt{show\_big\_conj\_imp} should raise \texttt{HOL\_ERR}.
For this exercise it might be useful to read up on \texttt{Term.compare} and the red-black sets and maps in directory \texttt{portableML}.
\subsection{Equivalences between Conjunctions}
Use the function \texttt{show\_big\_conj\_imp} to now define a function \texttt{show\_big\_conj\_eq :\ term -> term -> thm} that tries to shows the equivalence between the input terms. If both input terms are alpha-equivalent, it should raise an \texttt{UNCHANGED} exception. If the equivalence cannot be proved, a \texttt{HOL\_ERR} exception should be raised.
\subsection{Duplicates in Conjunctions}
Use the function \texttt{show\_big\_conj\_eq} to implement a conversion \texttt{remove\_dups\_in\_conj\_CONV} that replaces duplicate appearances of a term in a large conjunction with \texttt{T}. Given the term \begin{center}\verb#a /\ (b /\ a) /\ c /\ b /\ a#
\end{center}
it should for example return the theorem
\begin{center}
\verb#|- (a /\ (b /\ a) /\ c /\ b /\ a) = (a /\ (b /\ T) /\ c /\ T /\ T)#.
\end{center}.
If no duplicates are found, \texttt{UNCHANGED} should be raised. If the input is not of type
\texttt{bool}, a \texttt{HOL\_ERR} should be raised.
\subsection{Contradictions in Conjunctions}
Use the function \texttt{show\_big\_conj\_eq} to implement a conversion \texttt{find\_contr\_in\_conj\_CONV} that searches for terms and their negations in a large conjunction. If such contradictions are found, the term should be converted to \texttt{F}.
Given the term \begin{center}\verb#a /\ (b /\ ~a) /\ c#
\end{center}
it should for example return the theorem
\begin{center}
\verb#|- (a /\ (b /\ ~a) /\ c) = F#.
\end{center}.
If no contradictions are found, \texttt{UNCHANGED} should be raised. If the input is not of type
\texttt{bool}, a \texttt{HOL\_ERR} should be raised.
\section{Squabbling Philosophers}
Recently keen historians were finally able to deduce where the less well-known ancient philosophers
Platon, Diogenes and Euklid came from (see background-questionnaire). However, in order to avoid being embarrassed by announcing some wrong result, they asked you to check their reasoning using HOL.
Can you help and show that Platon indeed came from Sparta?
\subsection{Download and Compile}
Get the file \texttt{philScript.sml}\webversion{}{ from the exercise repository\footnote{\url{https://gits-15.sys.kth.se/tuerk/ITP-exercises}}}. Compile it with \texttt{Holmake} to get a theory file. Read \texttt{philTheory.sig}.
\subsection{Proof}
Open the theory \texttt{philTheory} and prove \verb#Sp platon#. This is a simple first order logic problem. Therefore automated methods like resolution can solve it easily. HOL has such methods build in in the form of \eg the resolution based prover \ml{METIS}. For example,
\begin{center}
\verb#METIS_PROVE [PHIL_KNOWLEDGE] ``Sp platon``#
\end{center}
would already prove it. However, for learning, let us prove it via a low-level forward proof.
\begin{itemize}
\item Using the lemma \texttt{MONO\_NOT} and the inference rules \texttt{MATCH\_MP},
\texttt{SPEC} and \texttt{IMP\_TRANS} show the lemma \verb#|- ~(W p) ==> Sp p#.
\item Similarly show \verb#|- ~(B p) ==> At p#.
\item Assume \verb#At platon# and using this show the lemma \verb#[At platon] |- F# with
\texttt{MP} and \texttt{MATCH\_MP}. You will need many steps and many different lemmata.
\item Using \texttt{DISCH}, \texttt{NOT\_INTRO} and \texttt{MATCH\_MP} show \verb#Sp platon#.
\end{itemize}
Don't forget to turn printing of assumptions on in HOL or you will have a hard time figuring out what is going on.
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

65
exercises/e2Script.sml Normal file
View File

@ -0,0 +1,65 @@
open HolKernel Parse boolLib bossLib;
val _ = new_theory "e2";
val _ = Datatype `Philosopher = diogenes | platon | euklid`;
val Philosopher_nchotomy = DB.fetch "-" "Philosopher_nchotomy";
val Philosopher_distinct = DB.fetch "-" "Philosopher_distinct";
val PHIL_KNOWLEDGE = new_specification ("PHIL_KNOWLEDGE", ["At", "Sp", "W", "B"],
prove (``?At Sp W B.
(!p. (Sp p ==> B p)) /\
(!p. (At p ==> W p)) /\
(!p. ~(Sp p) \/ ~(At p)) /\
(!p. (Sp p) \/ (At p)) /\
((Sp platon) ==> ~(W diogenes)) /\
((Sp euklid) ==> ~(B diogenes)) /\
((At diogenes) ==> ~(B euklid)) /\
((At platon) ==> ~(W euklid))``,
Q.EXISTS_TAC `\p. Philosopher_CASE p F F T` THEN
Q.EXISTS_TAC `\p. Philosopher_CASE p T T F` THEN
Q.EXISTS_TAC `\p. Philosopher_CASE p F T T` THEN
Q.EXISTS_TAC `\p. Philosopher_CASE p T T F` THEN
SIMP_TAC (srw_ss()++DatatypeSimps.expand_type_quants_ss [``:Philosopher``]) []));
val PHIL_KNOWLEDGE_a = store_thm ("PHIL_KNOWLEDGE_a", ``!p. Sp p ==> B p``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_b = store_thm ("PHIL_KNOWLEDGE_b", ``!p. At p ==> W p``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_c = store_thm ("PHIL_KNOWLEDGE_b", ``!p. ~(Sp p) \/ ~(At p)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_c1 = store_thm ("PHIL_KNOWLEDGE_c1", ``!p. Sp p ==> ~(At p)``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_c2 = store_thm ("PHIL_KNOWLEDGE_c2", ``!p. At p ==> ~(Sp p)``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_d = store_thm ("PHIL_KNOWLEDGE_d", ``!p. (Sp p) \/ (At p)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_d1 = store_thm ("PHIL_KNOWLEDGE_d1", ``!p. ~(Sp p) ==> At p``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_d2 = store_thm ("PHIL_KNOWLEDGE_d2", ``!p. ~(At p) ==> Sp p``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_e = store_thm ("PHIL_KNOWLEDGE_e", ``(Sp platon) ==> ~(W diogenes)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_f = store_thm ("PHIL_KNOWLEDGE_f", ``(Sp euklid) ==> ~(B diogenes)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_g = store_thm ("PHIL_KNOWLEDGE_g", ``(At diogenes) ==> ~(B euklid)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_h = store_thm ("PHIL_KNOWLEDGE_g", ``(At platon) ==> ~(W euklid)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val _ = export_theory();

116
exercises/e3.tex Normal file
View File

@ -0,0 +1,116 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\input{../hol_commands.inc}
\title{Exercise 3}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 3
\webversion{}{\\\small{due Friday 12th May}}
\end{center}
\bigskip
\section{Self-Study}
\subsection{Tactics and Tacticals}
You should read background information on the tactics mentioned in the
lecture. For each of the tactics and tacticals mentioned on the
slides, read the entry in the description manual.
\subsection{hol-mode}
Carefully study the \texttt{Goalstack} submenu of hol-mode. Learn the keycodes to
set goals, expand tactics, undo the last tactic expansion, restart the current proof and
drop the current goal.
\subsection{num and list Theories}
We will use the natural number theory \texttt{numTheory} as well as the list theories
\texttt{listTheory} and \texttt{rich\_listTheory} a lot. Please familiarise yourself with
these HOL theories (e.\,g.\ by looking at their signature in the HTML version of the HOL Reference). I also recommend reading up on other common theories like \texttt{optionTheory}, \texttt{oneTheory} and \texttt{pairTheory}. These won't be needed for this weeks exercises, though.
\section{Backward Proofs}
Part of this exercise is searching for useful existing lemmata (\eg
useful rewrite rules). Another part is understanding the effect of
different rewrite rules and their combination. Even if you have
experience with using HOL, please refrain from using automated rewrite
tools that spoil these purposes and have not been covered in the
lecture yet. Please don't use HOL's simplifier and especially don't
use stateful simp-sets. Similarly, please don't use the compute lib
via \eg \texttt{EVAL\_TAC}.
For these exercise, it might be beneficial to open the modules \texttt{listTheory} and \texttt{rich\_listTheory} via \ml{open listTheory rich\_listTheory}. You will notice that when opening them a lot of definitions are printed. This can consume quite some time when opening many large theories. Play around with the hol-mode commands
\texttt{Send region to HOL - hide non-errors} and \texttt{Quite - hide output except errors} to avoid this printout and the associated waiting time.
\subsection{Replay Proofs from Lecture}
If you never did a tactical proof in HOL before, I recommend following the example interactive proofs from Part VIII.
Type them in your own HOL session, make the same mistakes shown in the lecture. Use hol-mode to control the goalStack via
commands like expand, back-up, set goal, drop goal. Get a feeling for how to interactively develop a tactical proof.
This exercise is optional. If you are confident enough, feel free to skip it.
\subsection{Formalise Induction Proofs from Exercise 1}
For exercise sheet 1, some simple properties of appending lists were proved with pen and paper via induction. Let's now try to prove them formally using HOL. Prove \hol{!l.\ l ++ [] = l} via induction using the definition of \hol{APPEND} (\hol{++}). Similarly, prove the associativity of \texttt{APPEND}, \ie prove \hol{!l1 l2 l3.\ l1 ++ (l2 ++ l3) = (l1 ++ l2) ++ l3}.
\subsection{Reverse}
In HOL, \texttt{revAppend} is called \hol{REV}. Using any useful lemmata you can find, prove
the lemma \hol{!l1 l2.\ LENGTH (REV l1 l2) = (LENGTH l1 + LENGTH l2)}. Now, let us as an exercise reprove the existing lemmata \hol{REVERSE\_REV} and \hol{REV\_REVERSE\_LEM}. This means, prove, first prove \hol{!l1 l2.\ REV l1 l2 = REVERSE l1 ++ l2}. Then prove \hol{!l.\ REVERSE l = REV l []} using this theorem. You should not use the theorems \texttt{REVERSE\_REV} or \texttt{REV\_REVERSE\_LEM} in these proofs.
\subsection{Length of Drop}
Prove \hol{!l1 l2.\ LENGTH (DROP (LENGTH l2) (l1 ++ l2)) = LENGTH l1} with induction, \ie
without using lemmata like \texttt{LENGTH\_DROP}. Do one proof with \texttt{Induct\_on} and a very similar proof with \texttt{Induct}. This is a bit tricky.
Please play around with the proof for some time. If you can't figure it out, look at the hints at the end of this exercise sheet.
\subsection{Making Change}
On exercise sheet 1, you were asked to implement a function \texttt{make\_change} in SML. Let's now define it in HOL and prove some properties. Define the function \texttt{MAKE\_CHANGE} in HOL via
\begin{verbatim}
val MAKE_CHANGE_def = Define `
(MAKE_CHANGE [] a = if (a = 0) then [[]] else []) /\
(MAKE_CHANGE (c::cs) a = (
(if (c <= a /\ 0 < a) then
(MAP (\l. c::l) (MAKE_CHANGE cs (a - c)))
else []) ++ (MAKE_CHANGE cs a)))`;
\end{verbatim}
Prove that \hol{!cs.\ MAKE\_CHANGE cs 0 = [[]]} and
\hol{!cs a l.\ MEM l (MAKE\_CHANGE cs a) ==> (SUM l = a)} hold.
\section{Hints}
\subsection{Length of Drop}
For proving \hol{!l1 l2.\ LENGTH (DROP (LENGTH l2) (l1 ++ l2)) = LENGTH l1} induction on
the structure of \hol{l2} is a good strategy. However, one needs to be careful that \hol{l1} stays
universally quantified. Expanding naively with \hol{GEN\_TAC >> Induct} will
remove the needed universal quantification of \hol{l1}.
To solve this, you can either use \hol{Induct\_on `l2`} or get rid of both universal quantifiers and then introduce them in a different order again. This is achieved by \hol{REPEAT GEN\_TAC >> SPEC\_TAC (``l1:'a list``, ``l1:'a list``) >> SPEC\_TAC (``l2:'a list``, ``l2:'a list``)}.
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

107
exercises/e3Script.sml Normal file
View File

@ -0,0 +1,107 @@
open HolKernel Parse boolLib bossLib;
open rich_listTheory arithmeticTheory
val _ = new_theory "e3";
``!l. APPEND l [] = l``
Induct >| [
REWRITE_TAC [APPEND],
ASM_REWRITE_TAC [APPEN]
])
open listTheory
val``!l1 l2. REV l1 l2 = REVERSE l1 ++ l2``
Induct >| [
REWRITE_TAC [REV_DEF, REVERSE, APPEND],
ASM_REWRITE_TAC [REVERSE, REV_DEF, APPEND_SNOC1]
])
``!l. REVERSE l = REV l []``
Induct >| [
REWRITE_TAC [REV_DEF, REVERSE],
ASM_REWRITE_TAC [REVERSE, REV_DEF]
])
``!l1 l2. LENGTH (DROP (LENGTH l2) (l1 ++ l2)) = LENGTH l1``
Induct >| [
REWRITE_TAC[LENGTH, APPEND, DROP_LENGTH_NIL],
Cases_on `l2` |> [
REWRITE_TAC[APPEND_NIL, LENGTH, DROP],
ASM_REWRITE_TAC[APPEND, LENGTH, DROP]
``!l1 l2. LENGTH (DROP (LENGTH l2) (l1 ++ l2)) = LENGTH l1``
REPEAT GEN_TAC >>
SPEC_TAC (``l1:'a list``, ``l1:'a list``) THEN
Induct_on `l2` >| [
REWRITE_TAC[LENGTH, DROP, APPEND_NIL],
Cases_on `l1` >| [
REWRITE_TAC[LENGTH, DROP, APPEND, DROP_LENGTH_NIL],
REPEAT GEN_TAC >>
REWRITE_TAC[LENGTH, DROP, APPEND] THEN
`t ++ h' :: l2 = (t ++ [h']) ++ l2` by REWRITE_TAC[APPEND, GSYM APPEND_ASSOC] >>
ASM_REWRITE_TAC[] >>
REWRITE_TAC[LENGTH_APPEND, LENGTH, ADD_CLAUSES]
]
])
val MAKE_CHANGE_def = Define `
(MAKE_CHANGE [] a = if (a = 0) then [[]] else []) /\
(MAKE_CHANGE (c::cs) a = (
(if (c <= a /\ 0 < a) then
(MAP (\l. c::l) (MAKE_CHANGE cs (a - c)))
else []) ++ (MAKE_CHANGE cs a)))`
val MAKE_CHANGE_PROP = prove(``!cs. MAKE_CHANGE cs 0 = [[]]``,
Induct >| [
REWRITE_TAC[MAKE_CHANGE_def],
ASM_REWRITE_TAC[MAKE_CHANGE_def, prim_recTheory.LESS_REFL, APPEND]
])
val MAKE_CHANGE_PROP1 = prove (``!cs a l.
MEM l (MAKE_CHANGE cs a) ==> (SUM l = a)``,
Induct >| [
REPEAT GEN_TAC >>
REWRITE_TAC[MAKE_CHANGE_def] >>
Cases_on `a = 0` >> (
ASM_REWRITE_TAC[MEM] THEN
REPEAT STRIP_TAC THEN
ASM_REWRITE_TAC[SUM]
),
REPEAT GEN_TAC >>
ASM_REWRITE_TAC [MAKE_CHANGE_def, MEM_APPEND, DISJ_IMP_THM] >>
Cases_on `h <= a /\ 0 < a` >| [
ASM_REWRITE_TAC[MEM_MAP] THEN
BETA_TAC THEN
REPEAT STRIP_TAC THEN
`SUM y = (a - h)` by METIS_TAC[] >>
ASM_REWRITE_TAC [SUM] >>
DECIDE_TAC,
ASM_REWRITE_TAC[MEM]
]
]);
val _ = export_theory();

View File

@ -0,0 +1,24 @@
signature dot_graphsLib =
sig
type array_graph
(* binary for running dot *)
val dot_binary : string ref;
(* a fresh, empty one *)
val new_array_graph : array_graph
(* add a node to a graph with number n and the term option content *)
val add_node : array_graph -> int -> Abbrev.term option -> array_graph
(* adds a link between two nodes in the graph *)
val add_node_link : array_graph -> int -> int -> string -> array_graph
(* Various outputs *)
val print_graph : array_graph -> unit
val graph_to_string : array_graph -> string
val show_graph : array_graph -> unit
val write_graph_to_dot_file : array_graph -> string -> unit
val write_graph_to_png_file : array_graph -> string -> unit
end

View File

@ -0,0 +1,62 @@
structure dot_graphsLib :> dot_graphsLib =
struct
open HolKernel Parse
datatype array_graph = AG of string
val new_array_graph = AG "";
(* Auxiliary functions *)
fun AG_add (AG s) s' = AG (s ^ " " ^ s' ^ "\n")
fun node_name n = ("node_"^(int_to_string n))
(* create a new node with number n and value v in graph ag *)
fun add_node ag (n:int) (v : term option) = let
val n_s = node_name n;
val v_s = case v of NONE => "-"
| SOME t => "'" ^ (term_to_string t) ^ "'"
val new_s = (n_s ^ " [label=\"" ^ (int_to_string n) ^": "^v_s^"\"]")
in
AG_add ag new_s
end
(* Add a link between nodes n1 and n2 *)
fun add_node_link ag (n1:int) (n2 : int) (label : string) = let
val new_s = (node_name n1) ^ " -> " ^ (node_name n2) ^ " [label=\""^label^"\"]";
in
AG_add ag new_s
end
fun graph_to_string (AG s) = "digraph G {\n" ^ s ^ "}\n\n"
fun print_graph ag = (TextIO.print (graph_to_string ag))
fun write_graph_to_dot_file ag file_name = let
val os = TextIO.openOut file_name;
val _ = TextIO.output (os, graph_to_string ag);
val _ = TextIO.closeOut os
in
()
end
val dot_binary = ref "/usr/bin/dot";
fun show_graph ag = let
val p = Unix.execute (!dot_binary, ["-Tx11"])
val os = Unix.textOutstreamOf p
val _ = TextIO.output (os, graph_to_string ag)
val _ = TextIO.closeOut os
in
()
end
fun write_graph_to_png_file ag filename = let
val p = Unix.execute (!dot_binary, ["-Tpng", "-o", filename])
val os = Unix.textOutstreamOf p
val _ = TextIO.output (os, graph_to_string ag)
val _ = TextIO.closeOut os
in
()
end
end

View File

@ -0,0 +1,116 @@
structure e4_arraysLib :> e4_arraysLib =
struct
open HolKernel Parse bossLib e4_arraysTheory dot_graphsLib
(* Example
val ag = let
val ag = new_array_graph
val ag = add_node ag 1 NONE
val ag = add_node ag 2 NONE
val ag = add_node ag 3 NONE
val ag = add_node ag 4 (SOME ``A /\ B``)
val ag = add_node ag 5 NONE
val ag = add_node_link ag 1 2 "a";
val ag = add_node_link ag 1 3 "b";
val ag = add_node_link ag 3 4 "c";
val ag = add_node_link ag 4 5 "d";
in
ag
end
val _ = (dot_binary := "/usr/bin/dot");
val _ = print_graph ag
val _ = show_graph ag
*)
fun simple_array n = let
val n_t = numSyntax.term_of_int n
val thm = EVAL ``FOLDL (\a n. UPDATE n a n) EMPTY_ARRAY (COUNT_LIST ^n_t)``
in
rhs (concl thm)
end
fun sparse_array n = let
val n_t = numSyntax.term_of_int n
val thm = EVAL ``FOLDL (\a n. UPDATE n a (n*3)) EMPTY_ARRAY (COUNT_LIST ^n_t)``
in
rhs (concl thm)
end
val a1 = simple_array 10;
val a2 = sparse_array 10;
val a3 = simple_array 20;
val a4 = simple_array 100;
fun is_array_leaf t = same_const t ``Leaf``
fun dest_array_node t = let
val (c, args) = strip_comb t
val _ = if (same_const c ``Node``) then () else fail()
val vo = SOME (optionSyntax.dest_some (el 2 args)) handle HOL_ERR _ => NONE
in
(el 1 args, vo, el 3 args)
end
val is_array_node = can dest_array_node
fun graph_of_array_aux ag level suff t =
if (is_array_leaf t) then (NONE, ag) else
let
val (l, vo, r) = dest_array_node t
val n = level + suff
val m = n - 1;
val ag = add_node ag m vo
val (l_n, ag) = graph_of_array_aux ag (level*2) n l
val ag = case l_n of NONE => ag
| SOME ln => add_node_link ag m ln "l"
val (r_n, ag) = graph_of_array_aux ag (level*2) suff r
val ag = case r_n of NONE => ag
| SOME rn => add_node_link ag m rn "r"
in
(SOME m, ag)
end handle HOL_ERR _ => (NONE, ag)
fun graph_of_array t =
snd (graph_of_array_aux new_array_graph 1 0 t)
show_graph (graph_of_array a1)
show_graph (graph_of_array a2)
print_graph (graph_of_array a1)
EVAL ``num2boolList 5``
a1
Node
(Node (Node Leaf (SOME 6) Leaf)
(SOME 2)
(Node Leaf (SOME 5) Leaf))
(SOME 0)
(Node
(Node Leaf (SOME 4) (Node Leaf (SOME 9) Leaf))
(SOME 1)
(Node (Node Leaf (SOME 8) Leaf) (SOME 3)
(Node Leaf (SOME 7) Leaf)))
end
print_graph (graph_of_array a2);
show_graph (graph_of_array (simple_array 15));

View File

@ -0,0 +1,235 @@
open HolKernel Parse boolLib bossLib;
val _ = new_theory "e4_arrays";
(**************************************************)
(* Provided part *)
(**************************************************)
val num2boolList_def = Define `
(num2boolList 0 = []) /\
(num2boolList 1 = []) /\
(num2boolList n = (EVEN n) :: num2boolList (n DIV 2))`
(* The resulting definition is hard to apply and
rewriting with it loops easily. So let's provide
a decent lemma capturing the semantics *)
val num2boolList_REWRS = store_thm ("num2boolList_REWRS",
``(num2boolList 0 = []) /\
(num2boolList 1 = []) /\
(!n. 2 <= n ==> ((num2boolList n = (EVEN n) :: num2boolList (n DIV 2))))``,
REPEAT STRIP_TAC >| [
METIS_TAC[num2boolList_def],
METIS_TAC[num2boolList_def],
`n <> 0 /\ n <> 1` by DECIDE_TAC >>
METIS_TAC[num2boolList_def]
]);
(* It is aslo useful to show when the list is empty *)
val num2boolList_EQ_NIL = store_thm ("num2boolList_EQ_NIL",
``!n. (num2boolList n = []) <=> ((n = 0) \/ (n = 1))``,
GEN_TAC >> EQ_TAC >| [
REPEAT STRIP_TAC >>
CCONTR_TAC >>
FULL_SIMP_TAC list_ss [num2boolList_REWRS],
REPEAT STRIP_TAC >> (
ASM_SIMP_TAC std_ss [num2boolList_REWRS]
)
]);
(* Now the awkward arithmetic part. Let's show that num2boolList is injective *)
(* For demonstration, let's define our own induction theorem *)
val MY_NUM_INDUCT = store_thm ("MY_NUM_INDUCT",
``!P. P 1 /\ (!n. (2 <= n /\ (!m. (m < n /\ m <> 0) ==> P m)) ==> P n) ==> (!n. n <> 0 ==> P n)``,
REPEAT STRIP_TAC >>
completeInduct_on `n` >>
Cases_on `n` >> FULL_SIMP_TAC arith_ss [] >>
Cases_on `n'` >> ASM_SIMP_TAC arith_ss [])
val num2boolList_INJ = store_thm ("num2boolList_INJ",
``!n. n <> 0 ==> !m. m <> 0 ==> (num2boolList n = num2boolList m) ==> (n = m)``,
HO_MATCH_MP_TAC MY_NUM_INDUCT >>
CONJ_TAC >- (
SIMP_TAC list_ss [num2boolList_REWRS, num2boolList_EQ_NIL]
) >>
GEN_TAC >> STRIP_TAC >> GEN_TAC >> STRIP_TAC >>
Cases_on `m = 1` >- (
ASM_SIMP_TAC list_ss [num2boolList_REWRS]
) >>
ASM_SIMP_TAC list_ss [num2boolList_REWRS] >>
REPEAT STRIP_TAC >>
`n DIV 2 = m DIV 2` by (
`(m DIV 2 <> 0) /\ (n DIV 2 <> 0) /\ (n DIV 2 < n)` suffices_by METIS_TAC[] >>
ASM_SIMP_TAC arith_ss [arithmeticTheory.NOT_ZERO_LT_ZERO,
arithmeticTheory.X_LT_DIV]
) >>
`n MOD 2 = m MOD 2` by (
ASM_SIMP_TAC std_ss [arithmeticTheory.MOD_2]
) >>
`0 < 2` by DECIDE_TAC >>
METIS_TAC[arithmeticTheory.DIVISION]);
(* Shifting the keys by one is trivial and by this we get rid of the
preconditions of the injectivity theorem *)
val num2arrayIndex_def = Define `num2arrayIndex n = (num2boolList (SUC n))`
val num2arrayIndex_INJ = store_thm ("num2arrayIndex_INJ",
``!n m. (num2arrayIndex n = num2arrayIndex m) <=> (n = m)``,
SIMP_TAC list_ss [num2arrayIndex_def] >>
METIS_TAC [numTheory.NOT_SUC, num2boolList_INJ, numTheory.INV_SUC]);
(* Now let's define the inverse operation *)
val boolList2num_def = Define `
(boolList2num [] = 1) /\
(boolList2num (F::idx) = 2 * boolList2num idx + 1) /\
(boolList2num (T::idx) = 2 * boolList2num idx)`
(* We can show that the inverse is never 0 ... *)
val boolList2num_GT_0 = prove (``!idx. 0 < boolList2num idx``,
Induct >- SIMP_TAC arith_ss [boolList2num_def] >>
Cases >> ASM_SIMP_TAC arith_ss [boolList2num_def]);
(* ... so we can subtract 1 for the index shift *)
val arrayIndex2num_def = Define `arrayIndex2num idx = PRE (boolList2num idx)`
(* Now a fiddly prove that we indeed defined the inverse *)
val boolList2num_inv = prove (``!idx. num2boolList (boolList2num idx) = idx``,
Induct >- (
SIMP_TAC arith_ss [boolList2num_def, num2boolList_REWRS]
) >>
`0 < boolList2num idx` by METIS_TAC[boolList2num_GT_0] >>
`0 < 2` by DECIDE_TAC >>
Cases >| [
`!x. (2 * x) MOD 2 = 0` by
METIS_TAC[arithmeticTheory.MOD_EQ_0, arithmeticTheory.MULT_COMM] >>
`!x. (2 * x) DIV 2 = x` by
METIS_TAC[arithmeticTheory.MULT_DIV, arithmeticTheory.MULT_COMM] >>
ASM_SIMP_TAC list_ss [boolList2num_def, num2boolList_REWRS,
arithmeticTheory.EVEN_MOD2],
`!x y. (2 * x + y) MOD 2 = (y MOD 2)` by
METIS_TAC[arithmeticTheory.MOD_TIMES, arithmeticTheory.MULT_COMM] >>
`!x y. (2 * x + y) DIV 2 = x + y DIV 2` by
METIS_TAC[arithmeticTheory.ADD_DIV_ADD_DIV, arithmeticTheory.MULT_COMM] >>
ASM_SIMP_TAC list_ss [boolList2num_def, num2boolList_REWRS,
arithmeticTheory.EVEN_MOD2]
]);
(* Shifting is easy then *)
val arrayIndex2num_inv = store_thm ("arrayIndex2num_inv",
``!idx. num2arrayIndex (arrayIndex2num idx) = idx``,
GEN_TAC >>
REWRITE_TAC[num2arrayIndex_def, arrayIndex2num_def] >>
`0 < boolList2num idx` by METIS_TAC[boolList2num_GT_0] >>
FULL_SIMP_TAC arith_ss [arithmeticTheory.SUC_PRE] >>
ASM_SIMP_TAC std_ss [boolList2num_inv]);
(* It is also very easy to derive other useful properties. *)
val num2arrayIndex_inv = store_thm ("num2arrayIndex_inv",
``!n. arrayIndex2num (num2arrayIndex n) = n``,
METIS_TAC[ num2arrayIndex_INJ, arrayIndex2num_inv]);
val arrayIndex2num_INJ = store_thm ("arrayIndex2num_INJ",
``!idx1 idx2. (arrayIndex2num idx1 = arrayIndex2num idx2) <=> (idx1 = idx2)``,
METIS_TAC[ num2arrayIndex_INJ, arrayIndex2num_inv]);
(* A rewrite for the top-level inverse might be handy *)
val num2arrayIndex_REWRS = store_thm ("num2arrayIndex_REWRS", ``
!n. num2arrayIndex n =
if (n = 0) then [] else
ODD n :: num2arrayIndex ((n - 1) DIV 2)``,
REWRITE_TAC[num2arrayIndex_def] >>
Cases >> SIMP_TAC arith_ss [num2boolList_REWRS] >>
SIMP_TAC arith_ss [arithmeticTheory.ODD, arithmeticTheory.EVEN,
arithmeticTheory.ODD_EVEN] >>
`(!x r. (2 * x + r) DIV 2 = x + r DIV 2) /\ (!x. (2*x) DIV 2 = x)` by (
`0 < 2` by DECIDE_TAC >>
METIS_TAC[arithmeticTheory.ADD_DIV_ADD_DIV, arithmeticTheory.MULT_COMM,
arithmeticTheory.MULT_DIV]
) >>
Cases_on `EVEN n'` >> ASM_REWRITE_TAC[] >| [
`?m. n' = 2* m` by METIS_TAC[arithmeticTheory.EVEN_ODD_EXISTS] >>
ASM_SIMP_TAC arith_ss [arithmeticTheory.ADD1],
`?m. n' = SUC (2* m)` by METIS_TAC[arithmeticTheory.EVEN_ODD_EXISTS,
arithmeticTheory.ODD_EVEN] >>
ASM_SIMP_TAC arith_ss [arithmeticTheory.ADD1]
]);
(**************************************************)
(* YOU SHOULD WORK FROM HERE ON *)
(**************************************************)
(* TODO: Define a datatype for arrays storing values of type 'a. *)
val _ = Datatype `array = DUMMY 'a`
(* TODO: Define a new, empty array *)
val EMPTY_ARRAY_def = Define `EMPTY_ARRAY : 'a array = ARB`
(* TODO: define ILOOKUP, IUPDATE and IREMOVE *)
val IUPDATE_def = Define `IUPDATE (v : 'a) (a : 'a array) (k : bool list) = a:'a array`
val ILOOKUP_def = Define `ILOOKUP (a : 'a array) (k : bool list) = NONE:'a option`
val IREMOVE_def = Define `IREMOVE (a : 'a array) (k : bool list) = a:'a array`
(* With these, we can define the lifted operations *)
val LOOKUP_def = Define `LOOKUP a n = ILOOKUP a (num2arrayIndex n)`
val UPDATE_def = Define `UPDATE v a n = IUPDATE v a (num2arrayIndex n)`
val REMOVE_def = Define `REMOVE a n = IREMOVE a (num2arrayIndex n)`
(* TODO: show a few properties *)
val LOOKUP_EMPTY = store_thm ("LOOKUP_EMPTY",
``!k. LOOKUP EMPTY_ARRAY k = NONE``,
cheat);
val LOOKUP_UPDATE = store_thm ("LOOKUP_UPDATE",
``!v n n' a. LOOKUP (UPDATE v a n) n' =
(if (n = n') then SOME v else LOOKUP a n')``,
cheat);
val LOOKUP_REMOVE = store_thm ("LOOKUP_REMOVE",
``!n n' a. LOOKUP (REMOVE a n) n' =
(if (n = n') then NONE else LOOKUP a n')``,
cheat);
val UPDATE_REMOVE_EQ = store_thm ("UPDATE_REMOVE_EQ", ``
(!v1 v2 n a. UPDATE v1 (UPDATE v2 a n) n = UPDATE v1 a n) /\
(!v n a. UPDATE v (REMOVE a n) n = UPDATE v a n) /\
(!v n a. REMOVE (UPDATE v a n) n = REMOVE a n)
``,
cheat);
val UPDATE_REMOVE_NEQ = store_thm ("UPDATE_REMOVE_NEQ", ``
(!v1 v2 a n1 n2. n1 <> n2 ==>
((UPDATE v1 (UPDATE v2 a n2) n1) = (UPDATE v2 (UPDATE v1 a n1) n2))) /\
(!v a n1 n2. n1 <> n2 ==>
((UPDATE v (REMOVE a n2) n1) = (REMOVE (UPDATE v a n1) n2))) /\
(!a n1 n2. n1 <> n2 ==>
((REMOVE (REMOVE a n2) n1) = (REMOVE (REMOVE a n1) n2)))``,
cheat);
val _ = export_theory();

174
exercises/e4.tex Normal file
View File

@ -0,0 +1,174 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\usepackage{graphicx}
\input{../hol_commands.inc}
\title{Exercise 4}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 4
\webversion{}{\\\small{due Wednesday 24th May}}
\end{center}
\bigskip
\section{Functional Arrays}
Arrays are not easily available in pure functional programs. However,
one can easily encode finite maps with natural numbers as keys. One
such finite map implementation is known as \emph{functional arrays}.
Functional arrays are binary trees that use the binary representation
of the key to determine the position in the tree. As a result, the
trees are always balanced. This is illustrated by the following picture:
\begin{center}
\includegraphics[width=14cm]{func_array.eps}
\end{center}
The nodes in this tree are annotated with the both the decimal and the binary representation of
their keys. The root node is for key 1, key 0 is not allowed. All values in
the right subtree are even, all in the left odd. This means that the last digit is
always 0 or always 1. We then continue with this scheme recursively. At level 2 we look at the
second bit, level 3 looks at the third bit and so on.
Navigating to the node for key $k$ can easily be implemented recursively. We check whether
$k$ is 1. If so, we look at the root node of our tree. Otherwise, we check whether $k$ is even.
If it is, we search for key $k\ \textit{DIV}\ 2$ in the right subtree, otherwise we look for
$k\ \textit{DIV}\ 2$ in the left subtree. Another way of describing the procedure is that we
always look at the last bit. If we see 0, we go to the right subtree, if we see 1 we go to the left subtree. We then throw the last bit away and continue. Once we reach the number 1, we stop.
\bigskip
Let's implement functional arrays in HOL. Please use the file
\texttt{e4\_arraysScript.sml} for this purpose. It contains auxiliary
definitions and some outline. Please read all of the exercise sheet
(except perhaps the hints section) before you start working.
\subsection{Datatype}
Define a datatype for functional arrays. This should be a binary tree type with leafs and nodes.
Leafs don't store any information. Each node should have a left and a right subtree as well as perhaps a value. Some keys might have a value stored, other not. So, please use an option type here.
In C one would have nodes with a left- and right subtree pointer. NULL values in these pointers would indicate that we don't have a subtree. This role of NULL pointers is in our functional implementation taken by leafs. Notice that leafs are not shown in the picture above. Each node in the last row above has implicitly a left and a right subtree, which are leafs.
\subsection{Implement Basic Operations}
Let's now implement a lookup, an update, a remove operation as well as a constant for empty arrays.
Checking the bits of the key directly in the recursive definitions of these operations is fiddly.
One has to reason about arithmetic a lot and deal with some awkward termination conditions.
Therefore, I took already care for you of this fiddly part. The function \hol{num2arrayIndex} takes
a key and returns an array index. An array index is encoded as a list of booleans. If the list is empty, we should stop at the current node. If it starts with \texttt{F} we should look at the left subtree, if it is \texttt{T} at the right one. There is also an inverse operation \hol{arrayIndex2num} as well as a few lemmata. Notice, that \hol{num2arrayIndex} adds implicitly 1 to the number before
looking at the bits. Thus, we can handle 0 and don't need a special case.
\subsubsection{\texttt{EMPTY\_ARRAY}}
Define a constant \texttt{EMPTY\_ARRAY} that represents an array, which has no values stored in it at all.
\subsubsection{\texttt{UPDATE} and \texttt{REMOVE}}
Define an update function. Start with defining a function \texttt{IUPDATE v a idx} that updates array \texttt{a} to contain \texttt{v} for index \texttt{idx}. It should return the updated array. Then use the definition of \texttt{UPDATE} already present in the theory to lift this definition to keys that are natural numbers.
Similarish define a function \texttt{REMOVE a idx} that removes the value stored for index \texttt{idx} from array \texttt{a}. No value should be stored for this index in the resulting array.
The remove and update functions are very similar. It is beneficial to define a generalised update function that takes an optional value argument. If a value is provided, the current value is updated with it. If no value is provided, the current one is removed.
\subsection{Test your definition}
Use \texttt{EVAL} to test whether your definitions work as expected.
\subsection{Visualise Trees}
To install HOL, you needed to install the graphviz tool
(\url{http://www.graphviz.org/}). Let's use this tool to visualise your trees.
I already coded an auxiliary library to communicate with graphviz. You need to
write syntax functions for your array type. I recommend having a look at the implementation
of an existing syntax library like \texttt{optionSyntax}. Then code functions
\begin{itemize}
\item \texttt{is\_array\_leaf :\ term -> bool}
\item \texttt{is\_array\_node :\ term -> bool}
\item \texttt{dest\_array\_node :\ term -> (term * term option * term)}
\end{itemize}
Use the provided library \texttt{dot\_graphLib} to visualise your
arrays. Some example code is provided in
\texttt{e4\_arraysLib.sml}. Familiarise yourself with this code. The
example array \texttt{a2} should have for $n < 10$ the value $n$
stored at key $3*n$ all other keys have no value stored. When you
visualise \texttt{a2} the result should look as follows:
\begin{center}
\includegraphics[width=14cm]{a2.eps}
\end{center}
This is a good test of whether your \texttt{UPDATE} works as expected. Feel free however, to
delay this exercise till after the proofs, if you prefer that.
\subsubsection{\texttt{LOOKUP}}
Define a lookup function. Similar to \texttt{UPDATE} define \texttt{ILOOKUP} on indexes first and
then lift it to numbers. \texttt{LOOKUP a k} should return \texttt{SOME v} iff value \texttt{v} is
stored for key \texttt{k} and \texttt{NONE} if no value is stored.
\subsection{Test your definition}
Use \texttt{EVAL} to test whether your definition of \texttt{LOOKUP} works as expected.
\subsection{Basic Properties}
Show that you indeed implemented a finite map datastructure. For this purpose fill in the missing
proofs in \texttt{e4\_arraysScript.sml}. Make sure that the resulting theory compiles and can be loaded by \texttt{e4\_arraysLib.sml}.
You should prove the following properties:
\begin{enumerate}
\item \texttt{!k.\ LOOKUP EMPTY\_ARRAY k = NONE}
\item \texttt{!v n n' a.\ LOOKUP (UPDATE v a n) n' =\\
\-\qquad (if (n = n') then SOME v else LOOKUP a n')}
\item \texttt{!n n' a.\ LOOKUP (REMOVE a n) n' = (if (n = n') then NONE else LOOKUP a n')}
\item \texttt{!v1 v2 n a.\ UPDATE v1 (UPDATE v2 a n) n = UPDATE v1 a n}
\item \texttt{!v n a.\ UPDATE v (REMOVE a n) n = UPDATE v a n}
\item \texttt{!v n a.\ REMOVE (UPDATE v a n) n = REMOVE a n}
\item \texttt{!v1 v2 a n1 n2.\ n1 <> n2 ==>\\\-\qquad
((UPDATE v1 (UPDATE v2 a n2) n1) = (UPDATE v2 (UPDATE v1 a n1) n2))}
\item \texttt{!v a n1 n2.\ n1 <> n2 ==>\\\-\qquad
((UPDATE v (REMOVE a n2) n1) = (REMOVE (UPDATE v a n1) n2))}
\item \texttt{!a n1 n2.\ n1 <> n2 ==>\\\-\qquad
((REMOVE (REMOVE a n2) n1) = (REMOVE (REMOVE a n1) n2))}
\end{enumerate}
\section{Hints}
If you perform your proofs naively, you need a lot of case-splits and everything gets
very lengthy. It is beneficial to use many auxiliary definitions and use them and many tiny
lemmata about them to avoid case-splits. It might for example be beneficial to introduce auxiliary
functions \texttt{VAL\_OF\_ROOT} and \texttt{GEN\_GET\_SUBARRAY} and derive the following properties:
\begin{itemize}
\item \texttt{!a. ILOOKUP a [] = VAL\_OF\_ROOT a}
\item \texttt{!a i idx.\ ILOOKUP a (i::idx) = ILOOKUP (GEN\_GET\_SUBARRAY i a) idx}
\end{itemize}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

View File

@ -0,0 +1,11 @@
val IS_WEAK_SUBLIST_REC_def = Define `
(IS_WEAK_SUBLIST_REC (l1 : 'a list) ([]:'a list) = T) /\
(IS_WEAK_SUBLIST_REC [] (_::_) = F) /\
(IS_WEAK_SUBLIST_REC (y::ys) (x::xs) = (
(x = y) /\ IS_WEAK_SUBLIST_REC ys xs) \/ (IS_WEAK_SUBLIST_REC ys (x::xs)))`;
val FILTER_BY_BOOLS_def = Define `
FILTER_BY_BOOLS bl l = MAP SND (FILTER FST (ZIP (bl, l)))`
val IS_WEAK_SUBLIST_FILTER_def = Define `IS_WEAK_SUBLIST_FILTER l1 l2 =
?(bl : bool list). (LENGTH bl = LENGTH l1) /\ (l2 = FILTER_BY_BOOLS bl l1)`

View File

@ -0,0 +1,185 @@
open HolKernel Parse boolLib bossLib;
val _ = new_theory "e5";
open listTheory rich_listTheory arithmeticTheory
(**************)
(* Question 1 *)
(**************)
(*--- 1.1 --- *)
(* TODO: Fill in a proper definition *)
val IS_WEAK_SUBLIST_REC_def = Define `IS_WEAK_SUBLIST_REC (l1 : 'a list) (l2 : 'a list) = T`
(* Some tests *)
val test1 = EVAL ``IS_WEAK_SUBLIST_REC [1;2;3;4;5;6;7] [2;5;6]``;
val test2 = EVAL ``IS_WEAK_SUBLIST_REC [1;2;3;4;5;6;7] [2;6;5]``;
val test3 = EVAL ``IS_WEAK_SUBLIST_REC [1;2;3;4;5;6;7] [2;5;6;8]``;
(* TODO: at least 2 sanity check lemmata *)
(*--- 1.2 --- *)
(* TODO: fill in Definition *)
val IS_WEAK_SUBLIST_FILTER_def = Define `IS_WEAK_SUBLIST_FILTER (l1 : 'a list) (l2 : 'a list) = T`
(* TODO: at least 2 sanity check lemmata *)
(*--- 1.3 --- *)
(* TODO: Prove of auxiliary lemmata *)
val IS_WEAK_SUBLIST_EQUIV = store_thm ("IS_WEAK_SUBLIST_EQUIV",
``IS_WEAK_SUBLIST_REC = IS_WEAK_SUBLIST_FILTER``,
REWRITE_TAC[FUN_EQ_THM] >>
CONV_TAC (RENAME_VARS_CONV ["l1", "l2"]) >>
cheat)
(*--- 1.4 --- *)
(* TODO: Prove of auxiliary lemmata and perhaps reorder lemmata below *)
val IS_WEAK_SUBLIST_REC_APPEND_EXTEND_LEFT = store_thm ("IS_WEAK_SUBLIST_REC_APPEND_EXTEND_LEFT",
``!l1a l1 l1b l2. IS_WEAK_SUBLIST_REC l1 l2 ==> IS_WEAK_SUBLIST_REC (l1a ++ l1 ++ l1b) l2``,
cheat);
val IS_WEAK_SUBLIST_REC_APPEND = store_thm ("IS_WEAK_SUBLIST_REC_APPEND_EXTEND_LEFT",
``!l1a l1b l2a l2b. IS_WEAK_SUBLIST_REC l1a l2a ==>
IS_WEAK_SUBLIST_REC l1b l2b ==>
IS_WEAK_SUBLIST_REC (l1a ++ l1b) (l2a ++ l2b)``,
cheat);
val IS_WEAK_SUBLIST_REC_REFL = store_thm ("IS_WEAK_SUBLIST_REC_REFL",
``!l. IS_WEAK_SUBLIST_REC l l``,
cheat);
val IS_WEAK_SUBLIST_REC_TRANS = store_thm ("IS_WEAK_SUBLIST_REC_TRANS",
``!l1 l2 l3. IS_WEAK_SUBLIST_REC l1 l2 ==>
IS_WEAK_SUBLIST_REC l2 l3 ==>
IS_WEAK_SUBLIST_REC l1 l3``,
cheat);
val IS_WEAK_SUBLIST_REC_ANTISYM = store_thm ("IS_WEAK_SUBLIST_REC_ANTISYM",
``!l1 l2. IS_WEAK_SUBLIST_REC l1 l2 ==>
IS_WEAK_SUBLIST_REC l2 l1 ==>
(l1 = l2)``,
cheat);
val IS_WEAK_SUBLIST_FILTER_APPEND_EXTEND_LEFT = store_thm ("IS_WEAK_SUBLIST_FILTER_APPEND_EXTEND_LEFT",
``!l1a l1 l1b l2. IS_WEAK_SUBLIST_FILTER l1 l2 ==> IS_WEAK_SUBLIST_FILTER (l1a ++ l1 ++ l1b) l2``,
cheat);
val IS_WEAK_SUBLIST_FILTER_APPEND = store_thm ("IS_WEAK_SUBLIST_FILTER_APPEND_EXTEND_LEFT",
``!l1a l1b l2a l2b. IS_WEAK_SUBLIST_FILTER l1a l2a ==>
IS_WEAK_SUBLIST_FILTER l1b l2b ==>
IS_WEAK_SUBLIST_FILTER (l1a ++ l1b) (l2a ++ l2b)``,
cheat);
val IS_WEAK_SUBLIST_FILTER_REFL = store_thm ("IS_WEAK_SUBLIST_FILTER_REFL",
``!l. IS_WEAK_SUBLIST_FILTER l l``,
cheat);
val IS_WEAK_SUBLIST_FILTER_TRANS = store_thm ("IS_WEAK_SUBLIST_FILTER_TRANS",
``!l1 l2 l3. IS_WEAK_SUBLIST_FILTER l1 l2 ==>
IS_WEAK_SUBLIST_FILTER l2 l3 ==>
IS_WEAK_SUBLIST_FILTER l1 l3``,
cheat);
val IS_WEAK_SUBLIST_FILTER_ANTISYM = store_thm ("IS_WEAK_SUBLIST_FILTER_ANTISYM",
``!l1 l2. IS_WEAK_SUBLIST_FILTER l1 l2 ==>
IS_WEAK_SUBLIST_FILTER l2 l1 ==>
(l1 = l2)``,
cheat);
(**************)
(* Question 2 *)
(**************)
val sh_true_def = Define `sh_true = T`;
val sh_var_def = Define `sh_var (v:bool) = v`;
val sh_not_def = Define `sh_not b = ~b`;
val sh_and_def = Define `sh_and b1 b2 = (b1 /\ b2)`;
val sh_or_def = Define `sh_or b1 b2 = (b1 \/ b2)`;
val sh_implies_def = Define `sh_implies b1 b2 = (b1 ==> b2)`;
val _ = Datatype `bvar = BVar num`
val _ = Datatype `prop = d_true | d_var bvar | d_not prop
| d_and prop prop | d_or prop prop
| d_implies prop prop`;
val _ = Datatype `var_assignment = BAssign (bvar -> bool)`
val VAR_VALUE_def = Define `VAR_VALUE (BAssign a) v = (a v)`
val PROP_SEM_def = Define `
(PROP_SEM a d_true = T) /\
(PROP_SEM a (d_var v) = VAR_VALUE a v) /\
(PROP_SEM a (d_not p) = ~(PROP_SEM a p)) /\
(PROP_SEM a (d_and p1 p2) = (PROP_SEM a p1 /\ PROP_SEM a p2)) /\
(PROP_SEM a (d_or p1 p2) = (PROP_SEM a p1 \/ PROP_SEM a p2)) /\
(PROP_SEM a (d_implies p1 p2) = (PROP_SEM a p1 ==> PROP_SEM a p2))`
(* TODO Work on question 2 *)
(**************)
(* Question 3 *)
(**************)
val expunge_def =
Define
`(expunge x [] = [])
/\ (expunge x (h::t) = if x=h then expunge x t else h::expunge x t)`;
val min_def =
Define
`(min [] m = m)
/\ (min (h::t) m = if m <= h then min t m else min t h)`;
val minsort_defn =
Hol_defn "minsort"
`(minsort [] = [])
/\ (minsort (h::t) =
let m = min t h
in
m::minsort (expunge m (h::t)))`;
(* TODO: prove some auxiliary lemmata and fill in termination proof *)
(* For interactive use
Defn.tgoal minsort_defn
*)
val (minsort_def, minsort_ind) = Defn.tprove (minsort_defn,
WF_REL_TAC `TODO` >>
cheat);
val _ = export_theory();

184
exercises/e5.tex Normal file
View File

@ -0,0 +1,184 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\usepackage{graphicx}
\input{../hol_commands.inc}
\title{Exercise 5}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 5
\webversion{}{\\\small{due Friday 26th May (except 1.3 and 1.4)\\ 1.3 and 1.4 due Friday 2nd June}}
\end{center}
\bigskip
\section{Multiple Definitions / Formal Sanity}
\ml{rich\_listTheory} provides a predicate \hol{IS\_SUBLIST}. It checks whether
a list appears somewhere as part of another list:
\begin{center}
\begin{verbatim}
|- !l1 l2. IS_SUBLIST l1 l2 <=> ?l l'. l1 = l ++ (l2 ++ l')
\end{verbatim}
\end{center}
Define a weaker version of such a predicate called \hol{IS\_WEAK\_SUBLIST} that allows additional elements between
the elements of \texttt{l2}. So, for example \hol{IS\_WEAK\_SUBLIST [1;2;3;4;5;6;7] [2;5;6]} should hold. In contrast the statements \hol{IS\_WEAK\_SUBLIST [1;2;3;4;5;6;7] [2;6;5]} or \hol{IS\_WEAK\_SUBLIST [1;2;3;4;5;6;7] [2;5;6;8]} do not hold. Another way of describing the semantics of \hol{IS\_WEAK\_SUBLIST l1 l2} is saying that one can get \texttt{l2} by removing elements from \hol{l1} while keeping the order.
\subsection{Recursive Definition}
Define \hol{IS\_WEAK\_SUBLIST} recursively using \hol{Define}. Name your function \hol{IS\_WEAK\_SUBLIST\_REC}. Test this definition via \hol{EVAL} and prove at least 2 sanity check lemmata, which do not coincide with the lemmata you are asked to show below.
\subsection{Filter Definition}
Define a version of \hol{IS\_WEAK\_SUBLIST} called \hol{IS\_WEAK\_SUBLIST\_FILTER} using the existing list function \hol{FILTER}. You might want to use \hol{ZIP}, \hol{MAP}, \hol{FST} and \hol{SND} as well. The idea is to check for the existence of a list of booleans of the same length as \hol{l1}, zip this list with \hol{l1} and filter. You probably want to introduce auxiliary definitions before defining \hol{IS\_WEAK\_SUBLIST\_FILTER}.
The resulting definition is not executable via \hol{EVAL}. Anyhow, show at least 2 sanity check lemmata, which do not coincide with the lemmata you are asked to show below.
\subsection{Equivalence Proof}
Show \hol{IS\_WEAK\_SUBLIST\_REC = IS\_WEAK\_SUBLIST\_FILTER}. You might want to prove various auxiliary lemmata first. You might want to use among other things \hol{FUN\_EQ\_THM} and the list function \texttt{REPLICATE}.
\subsection{Properties}
Show the following properties of \texttt{IS\_WEAK\_SUBLIST\_REC} and \texttt{IS\_WEAK\_SUBLIST\_FILTER}. This means that for each property stated below in terms of \texttt{IS\_WEAK\_SUBLIST} you should prove one lemma using \texttt{IS\_WEAK\_SUBLIST\_REC} and another lemma using \texttt{IS\_WEAK\_SUBLIST\_FILTER}. Don't use the fact that both functions are equal. The point of this exercise is partly to demonstrate the impact of different definitions on proofs. You might of course use previously proved lemmata to prove additional ones.
\begin{enumerate}
\item \hol{!l1a l1 l1b l2.\ IS\_WEAK\_SUBLIST l1 l2 ==>\\
\-\qquad IS\_WEAK\_SUBLIST (l1a ++ l1 ++ l1b) l2}
\item \hol{!l1a l1b l2a l2b.\ IS\_WEAK\_SUBLIST l1a l2a ==> IS\_WEAK\_SUBLIST l1b l2b ==>\\
\-\qquad IS\_WEAK\_SUBLIST (l1a ++ l1b) (l2a ++ l2b)}
\item \hol{!l.\ IS\_WEAK\_SUBLIST l l}
\item \hol{!l1 l2 l3.\ IS\_WEAK\_SUBLIST l1 l2 ==> IS\_WEAK\_SUBLIST l2 l3 ==>\\
\-\qquad IS\_WEAK\_SUBLIST l1 l3}
\item \hol{!l1 l2.\ IS\_WEAK\_SUBLIST l1 l2 ==> IS\_WEAK\_SUBLIST l2 l1 ==> (l1 = l2)}
\end{enumerate}
\section{Deep and Shallow Embeddings}
As seen in the lecture let's define a deep and a shallow embedding of
propositional logic. Use the names and definitions from the lecture
notes. Add a definition stating that two propositional formulas are
equivalent, iff their semantics coincides for all variable
assignments, \ie
\begin{center}
\verb#PROP_IS_EQUIV p1 p2 <=> (!a. PROP_SEM a p1 = PROP_SEM a p2)#
\end{center}
\subsection{Syntax for propositional formulas}
Define in SML syntax functions for all shallowly embedded propositional formulas.
Define for each constructor a make - function, a destructor and a check.
For \hol{sh\_and} I would like to have for example
\begin{itemize}
\item \hol{mk\_sh\_and :\ term -> term -> term},
\item \hol{dest\_sh\_and :\ term -> (term * term)} and
\item \hol{is\_sh\_and :\ term -> bool}.
\end{itemize}
Define a check \hol{is\_sh\_prop :\ term -> bool} that checks whether
a term is a shallowly embedded propositional formula.
\subsection{Getting Rid of Conjunction and Implication}
Define a function in HOL \hol{PROP\_CONTAINS\_NO\_AND\_IMPL : prop -> bool} that checks whether a propositional
formula contains no conjunction and implication operators. Define a similar function \hol{sh\_prop\_contains\_no\_and\_impl} in SML that checks the same property for shallowly embedded formulas.
Define a function \hol{PROP\_REMOVE\_AND\_IMPL} in HOL that removes all conjunctions and implications
from a propositional formula and returns an equivalent one. Prove these properties, \ie prove
\begin{itemize}
\item \verb#!p. PROP_IS_EQUIV (PROP_REMOVE_AND_IMPL p) p#
\item \verb#!p. PROP_CONTAINS_NO_AND_IMPL (PROP_REMOVE_AND_IMPL p)#
\end{itemize}
Implement a similar function \hol{sh\_prop\_remove\_and\_impl :\ term -> thm} in SML that performs the same operation on the shallow embedding and returns a theorem stating that the input term is equal to a version without conjunctions and implications. The SML version is allowed to fail, if the input term does not satisfy \hol{is\_sh\_prop}.
Notice, that \hol{PROP\_REMOVE\_AND\_IMPL} is a verified function, whereas
\hol{sh\_prop\_remove\_and\_impl} is a verifying one.
\section{Fancy Function Definitions}
In the lecture the termination proof for quicksort was briefly discussed.
As an exercise, let's define \hol{minsort}. This function \hol{minsort} sorts
a list of natural numbers, by always searching a minimal element of the list,
put it in front of the list a recursively sort the rest of this list. In HOL,
it can be defined as
\begin{verbatim}
val expunge_def =
Define
`(expunge x [] = [])
/\ (expunge x (h::t) = if x=h then expunge x t else h::expunge x t)`;
val min_def =
Define
`(min [] m = m)
/\ (min (h::t) m = if m <= h then min t m else min t h)`;
val minsort_defn =
Hol_defn "minsort"
`(minsort [] = [])
/\ (minsort (h::t) =
let m = min t h
in
m::minsort (expunge m (h::t)))`;
\end{verbatim}
Notice, that TFL (\ie \hol{Define}) is not able to show automatically
that \hol{minsort} is terminating. You need to do this manually. Show
auxiliary lemmata about \hol{min} and \hol{expunge} and use them with
\hol{Defn.tprove} (and \hol{Defn.tgoal}) to show that \hol{minsort}
terminates.
\clearpage
\section{Hints}
\subsection{Definition of \hol{IS\_WEAK\_SUBLIST}}
\hol{IS\_WEAK\_SUBLIST\_REC} and \hol{IS\_WEAK\_SUBLIST\_FILTER} can be defined by
\begin{verbatim}
val IS_WEAK_SUBLIST_REC_def = Define `
(IS_WEAK_SUBLIST_REC (l1 : 'a list) ([]:'a list) = T) /\
(IS_WEAK_SUBLIST_REC [] (_::_) = F) /\
(IS_WEAK_SUBLIST_REC (y::ys) (x::xs) = (
(x = y) /\ IS_WEAK_SUBLIST_REC ys xs) \/ (IS_WEAK_SUBLIST_REC ys (x::xs)))`;
val FILTER_BY_BOOLS_def = Define `
FILTER_BY_BOOLS bl l = MAP SND (FILTER FST (ZIP (bl, l)))`
val IS_WEAK_SUBLIST_FILTER_def = Define `IS_WEAK_SUBLIST_FILTER l1 l2 =
?(bl : bool list). (LENGTH bl = LENGTH l1) /\ (l2 = FILTER_BY_BOOLS bl l1)`
\end{verbatim}
\subsection{Termination of \hol{minsort}}
\hol{minsort} is an example of the TFL library. You can find a termination proof in the HOL sources. However, really try to prove termination yourself first. Before you start looking up the proof, here a few hints:
\begin{itemize}
\item The main idea is that the length of \hol{expunge m (h::t)} is shorter than the length of \hol{h::t}, \ie start your termination proof with \hol{WF\_REL\_TAC LENGTH}.
\item show the lemma \hol{!x xs.\ LENGTH (expunge x xs) <= LENGTH xs}
\item show the lemma \hol{!x xs.\ MEM x xs ==> LENGTH (expunge x xs) < LENGTH xs}
\item show the lemma \hol{!x xs.\ MEM (min xs x) (x::xs)}
\end{itemize}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

125
exercises/e6.tex Normal file
View File

@ -0,0 +1,125 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\usepackage{graphicx}
\input{../hol_commands.inc}
\title{Exercise 6}
\def\ttwebflag{}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 6
\webversion{}{\\\small{due Friday 2nd June}}
\end{center}
\bigskip
\webversion{}{
\section{Exercise 5}
Please finish question 1.3 and 1.4 from exercise 5. You might find the simplifier helpful.
\section{Final Project}
We have 3 more weeks to go on the lecture. For the last 3 weeks, I would like to set a small project to solve for everyone. There will be a default project (see below). However, if you want you can also propose your own project. This has to be approved by me, before you can start working on it. It should satisfy the following requirements:
\begin{itemize}
\item You should build a formal model of some description. This description can \eg be a natural language text or some computer program.
\item You should test your model against the description / implementation.
\item You should prove some interesting properties.
\item It should be do-able in a reasonable amount of time (ideally 3 weeks). You have to either convince me that it is doable in 3 weeks or worth both your and my additional time.
\end{itemize}
Please read the default project proposal below. Either decide to do this project or think of an alternative final project. In any case, discuss your choice with me. \webversion{}{\textbf{Whoever has not discussed a final project with me by June 2nd will be forced to do the default project.}}
\clearpage
}
\webversion{\section{Final Project}}{\section{Default Project - Regular Expressions in HOL}}
There is a fun paper on regular expressions: \emph{A Play on Regular
Expressions} by Sebastian Fischer, Frank Huch and Thomas Wilke
published as a functional pearl at ICFP 2010
(\url{http://www-ps.informatik.uni-kiel.de/~sebf/pub/regexp-play.html}).
In this paper an implementation of marked regular expressions in
Haskell is described. The task is to formalise the simple parts of
this work in HOL, verify the correctness of the implementation and
export trustworthy code into an SML library.
You should develop this project such that (in theory) it could be
added to the examples directory of HOL. Therefore, I want you to
create a git-repository for your project\webversion{}{ and give me access to it}. You
should create one or more HOL-theories that can be compiled by
Holmake. There will be multiple SML files as well. These should
compile decently and have a signature. Please provide a selftest for
your development. Write decent documentation. There should be a (very
short) \texttt{README} as well as sufficient comments in the code.
\subsection{Basic Regular Expression Semantics}
Read Act 1, Scene 1. Implement the \texttt{Reg} datatype in HOL. Like later in the paper,
replace the type \texttt{Char} with a free type variable \texttt{'a}. The intention is to define
regular expressions on lists of type \texttt{'a}. Define a function \texttt{language\_of :\ 'a Reg -> ('a list) set} that returns the language accepted by a regular expression. The definition of
\texttt{language\_of} should be as clean and simple as possible. It does not need to be executable.
\subsection{Executable Semantics}
Now define the function \texttt{accept} in HOL. While doing so replace the type \texttt{String} with \texttt{'a list} to match the changes to \texttt{Reg}. You will need to implement the auxiliary functions \texttt{parts} and \texttt{split}. Test your definitions and apply formal sanity checks.
\subsection{Code Extraction and Conformance Testing}
Familiarise yourself with \texttt{EmitML}. Use it to extract your datatype \texttt{Reg} and the function \texttt{accept} to ML. Test \texttt{accept} against the regular expression implementation in \texttt{regexpMatch.sml} that comes with HOL.
\texttt{EmitML} has not been discussed in the lecture and is not well documented. Part of this challenge is to find information for yourself about HOL libraries and learn from examples and source code.
\subsection{Correctness Proof}
Prove that \texttt{accept} and \texttt{language\_of} agree with each other, \ie prove the statement \texttt{!r w.\ accept r w <=> w IN (language\_of r)}.
\subsection{Marked Regular Expressions}
Continue reading the paper. Act 1, Scene 2 is interesting, but we are here not interested in weights. Instead focus in Act 2, Scene 1. Implement a datatype for marked regular expressions called \texttt{MReg}. Use first the simple version with caching the values of \texttt{empty} and \texttt{final}. Provide a function \texttt{MARK\_REG :\ 'a Reg -> 'a MReg} that turns a regular expression into a marked expression without any marks set. Implement a function \texttt{acceptM :\ 'a MReg -> 'a list -> bool} following the idea of the \texttt{accept} function in the paper.
Test your definitions and perform formal sanity checks.
\subsection{Correctness Proof Marked Regular Expressions}
Show that \texttt{acceptM} is correct, \ie show
\texttt{!r w.\ acceptM (MARK\_REG r) w <=> w IN (language\_of r)}.
\subsection{Cached Marked Regular Expressions}
Now let's also implement the caching of \texttt{empty} and \texttt{final}. Call the resulting datatypes \texttt{CMReg}. It is tempting to define mutually recursive types \texttt{CMReg} and \texttt{CMRe} as in the paper. However, HOL's automation won't work well on such a type, so I advice manually encoding a cache (\ie adding extra boolean arguments to the constructors of \texttt{MReg}). Write a function \texttt{CACHE\_REG :\ 'a MReg -> 'a CMReg} that turns a marked regular expression into a cached marked one with valid caches. Implement a function \texttt{acceptCM :\ 'a CMReg -> 'a list -> bool} that is similar to \texttt{acceptM}, but more efficient due to using the caches.
Test your definitions and perform formal sanity checks. As part of formal sanity,
define a well-formedness predicate for cached marked regular expressions stating that the cached values for \texttt{empty} and \texttt{final} are correct.
Moreover, define the inverse function \texttt{UNCACHE\_REG :\ 'a CMReg -> 'a MReg} of \texttt{CACHE\_REG} and show that these functions are really inverses.
\subsection{Correctness Proof Caches}
Show that \texttt{acceptCM} is correct, \ie show
\texttt{!r w.\ acceptCM (CACHE\_REG (MARK\_REG r)) w <=> w IN (language\_of r)}.
\subsection{SML Library}
Use \texttt{EmitML} to extract your code to SML. Provide an interface for regular expressions on strings. The interface should contain a type for regular expression on strings similar to \texttt{char Reg}. It should provide a function \texttt{match} that checks whether such a regular expression matches a given string. Build 4 instances of this interface, one with the regular expression library \texttt{regexpMatch.sml} and ones for \texttt{accept}, \texttt{acceptM} and \texttt{acceptCM}. Write some simple tests and run them against all these instantiations (\eg via a functor). Perform some simple performance measurements.
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

70
exercises/e7.tex Normal file
View File

@ -0,0 +1,70 @@
\documentclass[a4paper,10pt,oneside]{scrartcl}
\usepackage[utf8]{inputenc}
\usepackage[a4paper]{geometry}
\usepackage{hyperref}
\usepackage{url}
\usepackage{color}
\usepackage{amsfonts}
\usepackage{graphicx}
\input{../hol_commands.inc}
\title{Exercise 7}
\begin{document}
\begin{center}
\usekomafont{sectioning}\usekomafont{part}ITP Exercise 7
\end{center}
\bigskip
\webversion{}{
\section{Final Project}
You should all have started working on your final project by now. The last lecture will take place Monday, 12th June. Practical sessions will continue till 23rd June. There will be an additional practical session on 19 June during the slot normally used for the lecture. The final project is at the very latest due on the 23rd. If other agreements have been reached in person, these take precedence. Despite the late deadline, you are still required to turn up to at least one practical session each week. I highly recommend attending more than one each week.
}
\section{Exercise 7}
\webversion{}{Since you are working on the final project, exercise 7 is optional. You are not required to
work it and there is no deadline.}
\subsection{Advanced Definition Principles}
Define the reflexive, transitive closure of a relation using 3 different methods as shown below.
\hol{RTC\_REL} is defining it using the inductive relation library. \hol{RTC\_DIRECT} is
using a simple higher order logic definition and \hol{RTC\_REC} uses recursion on natural numbers to define it. Show that all three definitions are defining the same function, \ie show
\hol{(RTC\_REL = RTC\_DIRECT) \holAnd{} (RTC\_REL = RTC\_REC) \holAnd{} (RTC\_REC = RTC\_DIRECT)}.
\begin{verbatim}
val (RTC_REL_rules, RTC_REL_ind, RTC_REL_cases) = Hol_reln `
(!x y. R x y ==> RTC_REL R x y) /\
(!x. RTC_REL R x x) /\
(!x y z. RTC_REL R x y /\ RTC_REL R y z ==> RTC_REL R x z)`
val RTC_DIRECT_def = new_definition ("RTC_DIRECT",
``RTC_DIRECT R = \(a:'a) (b:'a). !P.
((!x. P x x) /\ (!x y. R x y ==> P x y) /\
(!x y z. (P x y /\ P y z) ==> P x z)) ==>
(P a b)``);
val RTC_REC_NUM_def = Define `
(RTC_REC_NUM 0 R x y <=> (x = y)) /\
(RTC_REC_NUM (SUC n) R x y <=> (?z. R x z /\ RTC_REC_NUM n R z y))`
val RTC_REC_def = Define `
RTC_REC R x y = ?n. RTC_REC_NUM n R x y`;
\end{verbatim}
\subsection{Simplifier}
Dig out the code for \texttt{find\_contr\_in\_conj\_CONV} your wrote for execise 2, section 4.4. Create a simpset-fragment containing this conversion and use it on several examples.
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:

32
exercises/func_array.dot Normal file
View File

@ -0,0 +1,32 @@
digraph G {
node_0 [label="1: 1"]
node_2 [label="3: 11"]
node_1 [label="2: 10"]
node_6 [label="7: 111"]
node_5 [label="6: 110"]
node_4 [label="5: 101"]
node_3 [label="4: 100"]
node_14 [label="15: 1111"]
node_13 [label="14: 1110"]
node_12 [label="13: 1101"]
node_11 [label="12: 1100"]
node_10 [label="11: 1011"]
node_9 [label="10: 1010"]
node_8 [label="9: 1001"]
node_7 [label="8: 1000"]
node_1 -> node_3 [label="r"]
node_1 -> node_5 [label="l"]
node_0 -> node_2 [label="l"]
node_0 -> node_1 [label="r"]
node_2 -> node_4 [label="r"]
node_2 -> node_6 [label="l"]
node_3 -> node_11 [label="l"]
node_3 -> node_7 [label="r"]
node_4 -> node_12 [label="l"]
node_4 -> node_8 [label="r"]
node_5 -> node_13 [label="l"]
node_5 -> node_9 [label="r"]
node_6 -> node_10 [label="r"]
node_6 -> node_14 [label="l"]
}

653
exercises/func_array.eps Normal file
View File

@ -0,0 +1,653 @@
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: graphviz version 2.38.0 (20140413.2041)
%%Title: G
%%Pages: 1
%%BoundingBox: 36 36 826 341
%%EndComments
save
%%BeginProlog
/DotDict 200 dict def
DotDict begin
/setupLatin1 {
mark
/EncodingVector 256 array def
EncodingVector 0
ISOLatin1Encoding 0 255 getinterval putinterval
EncodingVector 45 /hyphen put
% Set up ISO Latin 1 character encoding
/starnetISO {
dup dup findfont dup length dict begin
{ 1 index /FID ne { def }{ pop pop } ifelse
} forall
/Encoding EncodingVector def
currentdict end definefont
} def
/Times-Roman starnetISO def
/Times-Italic starnetISO def
/Times-Bold starnetISO def
/Times-BoldItalic starnetISO def
/Helvetica starnetISO def
/Helvetica-Oblique starnetISO def
/Helvetica-Bold starnetISO def
/Helvetica-BoldOblique starnetISO def
/Courier starnetISO def
/Courier-Oblique starnetISO def
/Courier-Bold starnetISO def
/Courier-BoldOblique starnetISO def
cleartomark
} bind def
%%BeginResource: procset graphviz 0 0
/coord-font-family /Times-Roman def
/default-font-family /Times-Roman def
/coordfont coord-font-family findfont 8 scalefont def
/InvScaleFactor 1.0 def
/set_scale {
dup 1 exch div /InvScaleFactor exch def
scale
} bind def
% styles
/solid { [] 0 setdash } bind def
/dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
/dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
/invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
/bold { 2 setlinewidth } bind def
/filled { } bind def
/unfilled { } bind def
/rounded { } bind def
/diagonals { } bind def
/tapered { } bind def
% hooks for setting color
/nodecolor { sethsbcolor } bind def
/edgecolor { sethsbcolor } bind def
/graphcolor { sethsbcolor } bind def
/nopcolor {pop pop pop} bind def
/beginpage { % i j npages
/npages exch def
/j exch def
/i exch def
/str 10 string def
npages 1 gt {
gsave
coordfont setfont
0 0 moveto
(\() show i str cvs show (,) show j str cvs show (\)) show
grestore
} if
} bind def
/set_font {
findfont exch
scalefont setfont
} def
% draw text fitted to its expected width
/alignedtext { % width text
/text exch def
/width exch def
gsave
width 0 gt {
[] 0 setdash
text stringwidth pop width exch sub text length div 0 text ashow
} if
grestore
} def
/boxprim { % xcorner ycorner xsize ysize
4 2 roll
moveto
2 copy
exch 0 rlineto
0 exch rlineto
pop neg 0 rlineto
closepath
} bind def
/ellipse_path {
/ry exch def
/rx exch def
/y exch def
/x exch def
matrix currentmatrix
newpath
x y translate
rx ry scale
0 0 1 0 360 arc
setmatrix
} bind def
/endpage { showpage } bind def
/showpage { } def
/layercolorseq
[ % layer color sequence - darkest to lightest
[0 0 0]
[.2 .8 .8]
[.4 .8 .8]
[.6 .8 .8]
[.8 .8 .8]
]
def
/layerlen layercolorseq length def
/setlayer {/maxlayer exch def /curlayer exch def
layercolorseq curlayer 1 sub layerlen mod get
aload pop sethsbcolor
/nodecolor {nopcolor} def
/edgecolor {nopcolor} def
/graphcolor {nopcolor} def
} bind def
/onlayer { curlayer ne {invis} if } def
/onlayers {
/myupper exch def
/mylower exch def
curlayer mylower lt
curlayer myupper gt
or
{invis} if
} def
/curlayer 0 def
%%EndResource
%%EndProlog
%%BeginSetup
14 default-font-family set_font
1 setmiterlimit
% /arrowlength 10 def
% /arrowwidth 5 def
% make sure pdfmark is harmless for PS-interpreters other than Distiller
/pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
% make '<<' and '>>' safe on PS Level 1 devices
/languagelevel where {pop languagelevel}{1} ifelse
2 lt {
userdict (<<) cvn ([) cvn load put
userdict (>>) cvn ([) cvn load put
} if
%%EndSetup
setupLatin1
%%Page: 1 1
%%PageBoundingBox: 36 36 826 341
%%PageOrientation: Portrait
0 0 1 beginpage
gsave
36 36 790 305 boxprim clip newpath
1 1 set_scale 0 rotate 40 40 translate
% node_0
gsave
1 setlinewidth
0 0 0 nodecolor
424.25 279 27 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
413.25 275.3 moveto 22 (1: 1) alignedtext
grestore
% node_2
gsave
1 setlinewidth
0 0 0 nodecolor
273.25 192 28.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
259.25 188.3 moveto 28 (3: 11) alignedtext
grestore
% node_0->node_2
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 404.19 266.71 moveto
378.17 252.06 332.54 226.38 302.61 209.53 curveto
stroke
0 0 0 edgecolor
newpath 304.3 206.46 moveto
293.87 204.61 lineto
300.86 212.56 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 304.3 206.46 moveto
293.87 204.61 lineto
300.86 212.56 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
358.25 231.8 moveto 4 (l) alignedtext
grestore
% node_1
gsave
1 setlinewidth
0 0 0 nodecolor
493.25 192 28.7 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
479.25 188.3 moveto 28 (2: 10) alignedtext
grestore
% node_0->node_1
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 436.58 262.8 moveto
447.11 249.83 462.42 230.97 474.48 216.12 curveto
stroke
0 0 0 edgecolor
newpath 477.2 218.32 moveto
480.78 208.35 lineto
471.76 213.91 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 477.2 218.32 moveto
480.78 208.35 lineto
471.76 213.91 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
463.25 231.8 moveto 5 (r) alignedtext
grestore
% node_6
gsave
1 setlinewidth
0 0 0 nodecolor
144.25 105 33.29 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
126.75 101.3 moveto 35 (7: 111) alignedtext
grestore
% node_2->node_6
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 254.21 178.46 moveto
232.86 164.39 198 141.42 173.25 125.11 curveto
stroke
0 0 0 edgecolor
newpath 174.91 122.02 moveto
164.64 119.44 lineto
171.06 127.86 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 174.91 122.02 moveto
164.64 119.44 lineto
171.06 127.86 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
217.25 144.8 moveto 4 (l) alignedtext
grestore
% node_4
gsave
1 setlinewidth
0 0 0 nodecolor
273.25 105 33.29 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
255.75 101.3 moveto 35 (5: 101) alignedtext
grestore
% node_2->node_4
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 273.25 173.8 moveto
273.25 162.16 273.25 146.55 273.25 133.24 curveto
stroke
0 0 0 edgecolor
newpath 276.75 133.18 moveto
273.25 123.18 lineto
269.75 133.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 276.75 133.18 moveto
273.25 123.18 lineto
269.75 133.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
273.25 144.8 moveto 5 (r) alignedtext
grestore
% node_5
gsave
1 setlinewidth
0 0 0 nodecolor
493.25 105 33.29 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
475.75 101.3 moveto 35 (6: 110) alignedtext
grestore
% node_1->node_5
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 493.25 173.8 moveto
493.25 162.16 493.25 146.55 493.25 133.24 curveto
stroke
0 0 0 edgecolor
newpath 496.75 133.18 moveto
493.25 123.18 lineto
489.75 133.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 496.75 133.18 moveto
493.25 123.18 lineto
489.75 133.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
493.25 144.8 moveto 4 (l) alignedtext
grestore
% node_3
gsave
1 setlinewidth
0 0 0 nodecolor
646.25 105 33.29 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
628.75 101.3 moveto 35 (4: 100) alignedtext
grestore
% node_1->node_3
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 513.88 179.54 moveto
539.9 165.08 584.88 140.09 615.09 123.31 curveto
stroke
0 0 0 edgecolor
newpath 616.92 126.3 moveto
623.96 118.38 lineto
613.52 120.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 616.92 126.3 moveto
623.96 118.38 lineto
613.52 120.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
579.25 144.8 moveto 5 (r) alignedtext
grestore
% node_14
gsave
1 setlinewidth
0 0 0 nodecolor
42.25 18 42.49 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
17.75 14.3 moveto 49 (15: 1111) alignedtext
grestore
% node_6->node_14
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 126.94 89.58 moveto
110.97 76.27 87.03 56.32 68.66 41.01 curveto
stroke
0 0 0 edgecolor
newpath 70.59 38.07 moveto
60.67 34.35 lineto
66.11 43.44 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 70.59 38.07 moveto
60.67 34.35 lineto
66.11 43.44 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
100.25 57.8 moveto 4 (l) alignedtext
grestore
% node_10
gsave
1 setlinewidth
0 0 0 nodecolor
144.25 18 42.49 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
119.75 14.3 moveto 49 (11: 1011) alignedtext
grestore
% node_6->node_10
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 144.25 86.8 moveto
144.25 75.16 144.25 59.55 144.25 46.24 curveto
stroke
0 0 0 edgecolor
newpath 147.75 46.18 moveto
144.25 36.18 lineto
140.75 46.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 147.75 46.18 moveto
144.25 36.18 lineto
140.75 46.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
144.25 57.8 moveto 5 (r) alignedtext
grestore
% node_13
gsave
1 setlinewidth
0 0 0 nodecolor
442.25 18 42.49 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
417.75 14.3 moveto 49 (14: 1110) alignedtext
grestore
% node_5->node_13
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 483.41 87.61 moveto
476.05 75.34 465.85 58.34 457.44 44.32 curveto
stroke
0 0 0 edgecolor
newpath 460.37 42.4 moveto
452.22 35.63 lineto
454.37 46 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 460.37 42.4 moveto
452.22 35.63 lineto
454.37 46 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
471.25 57.8 moveto 4 (l) alignedtext
grestore
% node_9
gsave
1 setlinewidth
0 0 0 nodecolor
544.25 18 42.49 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
519.75 14.3 moveto 49 (10: 1010) alignedtext
grestore
% node_5->node_9
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 503.08 87.61 moveto
510.44 75.34 520.64 58.34 529.05 44.32 curveto
stroke
0 0 0 edgecolor
newpath 532.13 46 moveto
534.27 35.63 lineto
526.12 42.4 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 532.13 46 moveto
534.27 35.63 lineto
526.12 42.4 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
522.25 57.8 moveto 5 (r) alignedtext
grestore
% node_12
gsave
1 setlinewidth
0 0 0 nodecolor
246.25 18 42.49 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
221.75 14.3 moveto 49 (13: 1101) alignedtext
grestore
% node_4->node_12
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 267.91 87.21 moveto
264.16 75.41 259.07 59.38 254.77 45.82 curveto
stroke
0 0 0 edgecolor
newpath 258.03 44.52 moveto
251.66 36.05 lineto
251.35 46.64 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 258.03 44.52 moveto
251.66 36.05 lineto
251.35 46.64 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
262.25 57.8 moveto 4 (l) alignedtext
grestore
% node_8
gsave
1 setlinewidth
0 0 0 nodecolor
344.25 18 37.89 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
323.25 14.3 moveto 42 (9: 1001) alignedtext
grestore
% node_4->node_8
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 286.27 88.41 moveto
296.84 75.75 311.94 57.68 324.08 43.15 curveto
stroke
0 0 0 edgecolor
newpath 327.1 44.99 moveto
330.82 35.07 lineto
321.73 40.5 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 327.1 44.99 moveto
330.82 35.07 lineto
321.73 40.5 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
313.25 57.8 moveto 5 (r) alignedtext
grestore
% node_11
gsave
1 setlinewidth
0 0 0 nodecolor
646.25 18 42.49 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
621.75 14.3 moveto 49 (12: 1100) alignedtext
grestore
% node_3->node_11
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 646.25 86.8 moveto
646.25 75.16 646.25 59.55 646.25 46.24 curveto
stroke
0 0 0 edgecolor
newpath 649.75 46.18 moveto
646.25 36.18 lineto
642.75 46.18 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 649.75 46.18 moveto
646.25 36.18 lineto
642.75 46.18 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
646.25 57.8 moveto 4 (l) alignedtext
grestore
% node_7
gsave
1 setlinewidth
0 0 0 nodecolor
744.25 18 37.89 18 ellipse_path stroke
0 0 0 nodecolor
14 /Times-Roman set_font
723.25 14.3 moveto 42 (8: 1000) alignedtext
grestore
% node_3->node_7
gsave
1 setlinewidth
0 0 0 edgecolor
newpath 663.32 89.19 moveto
678.72 75.83 701.59 55.99 719.09 40.82 curveto
stroke
0 0 0 edgecolor
newpath 721.45 43.4 moveto
726.71 34.21 lineto
716.86 38.12 lineto
closepath fill
1 setlinewidth
solid
0 0 0 edgecolor
newpath 721.45 43.4 moveto
726.71 34.21 lineto
716.86 38.12 lineto
closepath stroke
0 0 0 edgecolor
14 /Times-Roman set_font
701.25 57.8 moveto 5 (r) alignedtext
grestore
endpage
showpage
grestore
%%PageTrailer
%%EndPage: 1
%%Trailer
end
restore
%%EOF

65
exercises/philScript.sml Normal file
View File

@ -0,0 +1,65 @@
open HolKernel Parse boolLib bossLib;
val _ = new_theory "phil";
val _ = Datatype `Philosopher = diogenes | platon | euklid`;
val Philosopher_nchotomy = DB.fetch "-" "Philosopher_nchotomy";
val Philosopher_distinct = DB.fetch "-" "Philosopher_distinct";
val PHIL_KNOWLEDGE = new_specification ("PHIL_KNOWLEDGE", ["At", "Sp", "W", "B"],
prove (``?At Sp W B.
(!p. (Sp p ==> B p)) /\
(!p. (At p ==> W p)) /\
(!p. ~(Sp p) \/ ~(At p)) /\
(!p. (Sp p) \/ (At p)) /\
((Sp platon) ==> ~(W diogenes)) /\
((Sp euklid) ==> ~(B diogenes)) /\
((At diogenes) ==> ~(B euklid)) /\
((At platon) ==> ~(W euklid))``,
Q.EXISTS_TAC `\p. Philosopher_CASE p F F T` THEN
Q.EXISTS_TAC `\p. Philosopher_CASE p T T F` THEN
Q.EXISTS_TAC `\p. Philosopher_CASE p F T T` THEN
Q.EXISTS_TAC `\p. Philosopher_CASE p T T F` THEN
SIMP_TAC (srw_ss()++DatatypeSimps.expand_type_quants_ss [``:Philosopher``]) []));
val PHIL_KNOWLEDGE_a = store_thm ("PHIL_KNOWLEDGE_a", ``!p. Sp p ==> B p``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_b = store_thm ("PHIL_KNOWLEDGE_b", ``!p. At p ==> W p``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_c = store_thm ("PHIL_KNOWLEDGE_c", ``!p. ~(Sp p) \/ ~(At p)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_c1 = store_thm ("PHIL_KNOWLEDGE_c1", ``!p. Sp p ==> ~(At p)``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_c2 = store_thm ("PHIL_KNOWLEDGE_c2", ``!p. At p ==> ~(Sp p)``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_d = store_thm ("PHIL_KNOWLEDGE_d", ``!p. (Sp p) \/ (At p)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_d1 = store_thm ("PHIL_KNOWLEDGE_d1", ``!p. ~(Sp p) ==> At p``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_d2 = store_thm ("PHIL_KNOWLEDGE_d2", ``!p. ~(At p) ==> Sp p``,
PROVE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_e = store_thm ("PHIL_KNOWLEDGE_e", ``(Sp platon) ==> ~(W diogenes)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_f = store_thm ("PHIL_KNOWLEDGE_f", ``(Sp euklid) ==> ~(B diogenes)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_g = store_thm ("PHIL_KNOWLEDGE_g", ``(At diogenes) ==> ~(B euklid)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val PHIL_KNOWLEDGE_h = store_thm ("PHIL_KNOWLEDGE_h", ``(At platon) ==> ~(W euklid)``,
REWRITE_TAC[PHIL_KNOWLEDGE]);
val _ = export_theory();