This repository has been archived by the owner on May 2, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.txt
334 lines (224 loc) · 11.6 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
This directory contains the current samizdat version of OLEG, specifically
src the source code (still needs SML/NJ 0.93)
bin linux binaries compiled from the above
examples some demo scripts
papers related old drafts of papers now changed beyond recognition
(and generally for the better)
emacs-hack.el not so much an oleg mode; more a nightmare of comint and
font-lock
Things you might like to know
(1) EMACS GADGETS
Try adjusting the code in emacs-hack.el to point to your oleg binary,
then run it when you start emacs (e.g. by pasting it into .emacs).
Now, when you've just loaded an oleg script, do M-x run-lego and it'll
start an oleg process for you. Moreover, the tab key in the script
buffer will send a line to the oleg process. More moreover, most things
will get coloured in properly.
It's not even Proof Lance Corporal, but it's better than a poke in the
eye.
By the way, if things start going really slowly, try watching in black
and white...
(2) LIBRARY
Er. Sorry about that. I can't quite remember how, but I seem to have
broken the module system at some point---it's incompatible in some way
with the labelling mechanism or something.
Anyhow, the library as was isn't so useful for oleg development. On
the other hand, you'll notice that each of the example files has the
same prelude. More or less. I guess it could be an include file.
(3) EXAMPLES
BasicProg.l demonstrates the basics of the exciting new programming
tactics
TypeCheck.l is the implementation of the typechecker from VfL version I
(the early funny one---see PAPERS)
TYPES03.l is the demo script used at TYPES 2003, in which we have
the joy of gcd
Exception.l is the code and correctness proof for my variation on the
theme of Hutton and Wright's compiler-with-exceptions;
as advertized in their paper
Unify.l if the code and correctness proof for first order unification
by structural recursion (see PAPERS)
(4) PAPERS
old-elim.ps is the original no-you-can't-fit-all-that-in-19-pages
version of EwaM, which attempts to be forthcoming about
no confusion and no cycle proofs, and has some moderately
provocative ideas about what the gadgets might be good
for; most of which got censored, in favour of doing one
job well...
view-I.ps is the earlier funnier (and shorter) version of VfL; whilst
anonymous referees provoked significant improvements
and much useful work on elaboration, I do feel that the
official version has lost (a) the emphasis on interactive
programming (like we do it in oleg) and (b) the feeling
of how much fun it is to work this way, rather than how
hard you have to work to make a machine believe in it...
unify.ps is actually quite close to the real thing, and
proof.ps is the correctness proof which nobody read, but is actually
quite cool; the Unify.l file follows this pretty closely
(5) EQUALITY
The Elim, KJunify and Program X tactics all use John Major equality,
but Qrepl (and its monster-in-the-basement chum Wave) still use
Martin-Lof equality. Also, some of the gadget-makers expect to find
M-L eq. So we need both. Sometimes we need to convert between the two.
Not so hard.
(6) GADGETS
The brackets (!...!) enclose tags---the codes oleg tactics use to refer
to constructions they exploit. The Generate tactic attempts to find a
provider for the construction with a given tag. The Label tactic
maps a tag to a given construction.
Gadget generation is no longer automatically triggered when you
declare an inductive datatype. Trigger it yourself, thus
Inductive [Nat : Type] Constructors
[zero : Nat]
[suc : {n:Nat}Nat];
Generate (!Nat cases!); (* the case analysis principle *)
Generate (!Nat eduardo!); (* the recursion principle *)
Note that generating `eduardo' relies on finding
Inductive [Unit : Type] Constructors [void : Unit];
Label (!unit!) Unit;
Label (!unit void!) void;
to provide the trivial memo structure.
The gadgets which prove no confusion still generate the M-L equality
version. Ugh! I never got around to automating the much simpler JM
construction, although you can find the template in the example
files. Here it is again
[Absurd = {T:Type}T];
Goal {x,y:Nat}Type;
Program NatNoConfStmt x y; (* compute matrix of statements *)
Program Elim (!Nat cases!) x;
Program Elim (!Nat cases!) y;
Program Refine {Phi:Type}Phi->Phi;
Program Refine Absurd;
Program Elim (!Nat cases!) y;
Program Refine Absurd;
Program Names y x;
Program Refine {Phi:Type}((x == y)->Phi)->Phi;
Program Save;
Goal {x,y:Nat}{q:x == y}{tg:Target q}NatNoConfStmt x y;
Program NatNoConf x y q tg; (* justify the injective diagonal *)
Program Elim (!JM elim!) q;
Program Elim (!Nat cases!) x;
Program Refine [Phi:Type][phi:Phi]phi;
Program Refine [Phi:Type][phi:(n == n)->Phi]phi (JMr n);
Program Save;
Label (!Nat noConf!) NatNoConf; (* tell KJunify *)
Er, also, the effect of
Label (!nat zero!) zero;
Label (!nat suc!) suc;
is to allow (!3!) to abbreviate suc (suc (suc zero)) and so on. Sadly
only on the input side.
(7) ELIMINATION
Elim rule target ... target;
eliminates with the given rule, after unifying the provided targets
with the expressions marked as {tg:Target exp} in the rule's type;
if the rule is not marked up in that way, Elim kind of guesses what
to do with the targets you provide (in such a way that regular _elim
rules are properly handled). Subgoal simplification by unification is
automatic.
(8) UNIFICATION
KJunify;
should actually be called JMunify
relies on you providing (!Blah noConf!) for each family Blah you need
to work with; see above recipe
(7) NAMING HYPOTHESES
Names x1 x2 x3 ...;
(re)names the hyps in the goal without intros-ing them; long overdue
(8) ABSTRACTION
Abst x exp;
abstracts every occurrence of exp from the goal as a new hyp called x;
can cope with exp living under a prefix of hyps---x goes as far left as
possible
AbstEq x q exp;
similar, but also keeps {q:x == exp} as a hyp; wot a larf!
Examples can be found in Exception.l and Unify.l
(9) REWRITING
Wave > lawsProof;
Wave < lawsProof;
Wave is a multiple rewriting tactic. lawsProof is a term of type
({x:X}... (Eq l[x...] r[x...])) # ... # ({x:X}... (Eq l[x...] r[x...]))
ie a tuple of universally quantified equations. Wave tries to
rewrite like billyo, following these laws, in the direction you
indicate. It's stupid, unsubtle (and potentially unsafe if you
choose dangerous laws). But it doesn't lie to the typechecker.
More safety is achievable via the gasoline-controlled version
Wave n > lawsProof;
Wave n < lawsProof;
which limits the number of iterations allowed.
Favourite applications include
Wave > (plusAbsorbsZero,plusAssociative);
Note the use of M-L Eq rather than JM ==. Also, Wave is not smart
enough to rewrite under hypotheses.
Examples in Unify.l
(10) PROGRAMMING
Thrilling new programming tools!
If your goal is
?0 : {x1:S1}...{xn:Sn}T
and you say
Program f x1 ... xn;
you turn your goal into a programming problem! The new Program Blah
tactics help you solve it! Read on...
(11) PROGRAMMING INFORMATION
After the execution of each Program Blah tactic, you get not only the
proof state, but the program state comprising
(*) the type signatures of the programs currently under development
(*) their code so far
(*) information local to the bit of code you're supposed to write next
All of this information is actually represented in the proof state,
which comprises goals of form
(*) {...}T_myFun p1 ... pn
the unsolved programming problems
(*) <myFun:{...}T>(myFun == [...]vomit[T_myFun goals])
the ghastly proof term, so far
(*) {...}U_myFun p1 ... pn
one for each lhs, solved or not
The program signatures are computed from the <myFun> goals; the
program code is computed by running the ghastly term so far for each
lhs given by the U_myFun goals.
By the way, T_myFun is just a frozen function which computes the
return type of your program. call_myFun and ret_myFun map between
the two in the obvious (but frozen way). U_myFun is just a frozen
function which computes a trivial Prop. Don't worry, they'll thaw
out later.
Program; (* with no args, note *)
attempts to generate and print the program state, if you've
lost it for some reason, eg hand-cranking a bit of the construction.
(12) PROGRAMMING TACTICS
Program Elim rule target;
splits a programming problem by rule on target;
ie does elimination on the given target with the given rule to both the
T_ goal and the U_ goal
Program Refine blah;
fills in blah as the right-hand side of the current goal;
ie solves the relevant T_ goal (having first tried to extract recursive
calls from T_ hypotheses); warning---sometimes the latter mechanism
commits to a T_ hyp too early, leaving unsolvable equations as subgoals
(hence the hand-cranking in gcd in TYPES03.l)
Program Names x1 ... xn;
renames pattern variables (often needed in induction-then-cases progs);
warning---sometimes muddles the goals up, leaving no programming problem
topmost, but nothing that Next can't cure.
Program Abst myFriend arg ... arg;
generates a programming problem for a helper function taking the given
args, which are usually existing pattern vars or some (var as exp),
where exp is an intermediate value you'd like abstracted, and var is
what it gets called; by a miracle of modern technology, the helper
function can still remember how to do recursive calls to the master
function.
(13) KEEPING A PROGRAM
Program Save;
should be called when you've filled in all the bits of program and
killed off any proof obligations apart from the <myFun> and U_ goals.
It unfreezes what it needs to solve these goals, then after QED, it
saves the big nasty term as the defined value of the function, freezes
it, and gives it (iota) reduction rules instead. Freeze/Unfreeze toggles
whether it's iota/delta reduction for that symbol.
(14) MYSTERIOUS Forget/KillRef PROBLEM
I've got some sort of bureaucratic cockup in the lego-state/proof-state/
twilight-zone, which means that retrograde steps sometimes throw away
too much (e.g. KillRef discarding the reduction rules you just saved,
or some such). I recommend ripping it all up and starting again.
Computers are fast. OK, it's still a pain. Undo in proof state is still
ok. Phew.
(15) SUPPORT
Choke. Cough. Splutter.
(16) HAVE FUN
No really, this is possible.