├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── stlc
├── Makefile
├── doc
│ ├── Hutton
│ │ ├── Base.agda
│ │ └── Constant.agda
│ ├── Makefile
│ ├── background.tex
│ └── hutton.agda-lib
├── examples
│ ├── hid.stlc
│ ├── silly.stlc
│ └── swap2.stlc
└── src
│ ├── Data
│ ├── List
│ │ └── Relation
│ │ │ └── Unary
│ │ │ └── All
│ │ │ └── Extras.agda
│ └── Map.agda
│ ├── Eval.agda
│ ├── Language.agda
│ ├── LetInline.agda
│ ├── Main.agda
│ ├── Parse.agda
│ ├── Pipeline.agda
│ ├── Print.agda
│ ├── Scopecheck.agda
│ ├── System
│ └── Environment.agda
│ ├── Typecheck.agda
│ ├── Types.agda
│ └── stlc.agda-lib
└── travis
├── install_agda.sh
└── libraries-2.5.4.2
/.gitignore:
--------------------------------------------------------------------------------
1 | *.agdai
2 | *~
3 | *MAlonzo/
4 | *.aux
5 | *.log
6 | *.nav
7 | *.out
8 | *.snm
9 | *.toc
10 | *.fdb_latexmk
11 | *.fls
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: C
2 | sudo: false
3 |
4 | branches:
5 | only:
6 | - master
7 |
8 | addons:
9 | apt:
10 | packages:
11 | - cabal-install-2.0
12 | - ghc-8.2.2
13 | sources:
14 | - hvr-ghc
15 |
16 | cache:
17 | directories:
18 | - $HOME/.cabal/
19 | - $HOME/.ghc/
20 |
21 | install:
22 | - export PATH=$HOME/.cabal/bin:/opt/ghc/8.2.2/bin:/opt/cabal/2.0/bin:$PATH
23 | - cd travis/
24 | - travis_wait 50 ./install_agda.sh
25 |
26 | script:
27 | - cd ../stlc/
28 | - make
29 | - cd src/
30 | - agda --html Main.agda
31 | - cd ../../
32 | - mkdir -p stlc/
33 | - mv stlc/src/html/* stlc/
34 |
35 | after_success:
36 | # uploading to gh-pages
37 | - git init
38 | - git config --global user.name "Travis CI bot"
39 | - git config --global user.email "travis-ci-bot@travis.fake"
40 | - git remote add upstream https://$GH_TOKEN@github.com/gallais/agdarky.git &>/dev/null
41 | - git fetch upstream && git reset upstream/gh-pages
42 | - git add -f \*.html \*.css
43 | - git commit -m "Automatic HTML update via Travis"
44 | - git push -q upstream HEAD:gh-pages &>/dev/null;
45 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # agdarky
2 | Agda suffices: software written from A to Z in Agda
3 |
--------------------------------------------------------------------------------
/stlc/Makefile:
--------------------------------------------------------------------------------
1 | AGDA=agda
2 |
3 | all: executable tests
4 |
5 | executable:
6 | cd src/ && ${AGDA} --compile-dir=.. -c Main.agda
7 |
8 | tests:
9 | ./Main examples/silly.stlc
10 | ./Main examples/swap2.stlc
11 | ./Main examples/hid.stlc
12 |
--------------------------------------------------------------------------------
/stlc/doc/Hutton/Base.agda:
--------------------------------------------------------------------------------
1 | module Hutton.Base where
2 |
3 | open import Data.Unit
4 | open import Data.List.Base as List
5 | open import Generic.Syntax
6 |
7 | ------------------------------------------------------------------------
8 | -- SYNTAX: description in the universe of syntaxes with binding
9 |
10 | -- Hutton's Razor: the smallest language needed to demonstrate a feature
11 | -- Here we take: H = x | H + H
12 |
13 | hutton : Desc ⊤
14 |
15 | -- hutton is a description of a language where the notion of type is unit (⊤)
16 | -- aka. there is no typing information
17 |
18 | hutton = `X [] _ (`X [] _ (`∎ _))
19 |
20 | -- it declares one constructor
21 | -- (for the _+_ operator)
22 |
23 | -- _+_ takes two subterms
24 | -- (declared using the constructor `X)
25 |
26 | -- both of which live in the same context
27 | -- (the extension is the empty list [])
28 |
29 | -- both of which don't have an interesting type
30 | -- (_ is filled in by Agda: ⊤'s only value is tt)
31 |
32 | -- And the return type of that constructor is not interesting
33 | -- (again: this is an untyped language)
34 |
35 | open import Data.Product
36 | open import Relation.Binary.PropositionalEquality
37 |
38 | -- We can use pattern synonyms to hide the fact we are using a universe of
39 | -- syntaxes with binding
40 |
41 | pattern add' l r = (l , r , refl)
42 | pattern add l r = `con (add' l r)
43 |
44 | -- They can be used on the RHS
45 |
46 | double : TM hutton _ → TM hutton _
47 | double x = add x x
48 |
49 | -- But also on the LHS:
50 |
51 | right : ∀ {Γ} → Tm hutton _ _ Γ → Tm hutton _ _ Γ
52 | right (add l r) = r
53 | right (`var x) = `var x
54 |
55 | -- We discover here the notion of variables: syntaxes with binding are
56 | -- automatically endowed with variables.
57 |
58 | ------------------------------------------------------------------------
59 | -- SEMANTICS: scope-and-type preserving fold-like traversal
60 |
61 | open import Data.Nat.Base
62 | open import var
63 | open import environment
64 | open import Generic.Semantics
65 |
66 | -- The notion of values for a Semantics are always scoped. This way we
67 | -- can write type-and-scope preserving traversals
68 |
69 | Value : ⊤ ─Scoped
70 | Value _ _ = ℕ
71 |
72 | Eval : Sem -- a semantics
73 | hutton -- for terms in hutton's razor
74 | Value -- where variables are assigned a Value
75 | Value -- and the overall computation returns a Value
76 |
77 | -- In general for a traversal on a syntax with binding to be scope preversing,
78 | -- we need to be able to embed the scoped values assigned to variables into
79 | -- larger contexts. This allows us to go under binder.
80 | -- Here Value is scope independent. As such it is trivially thinnable (i.e.
81 | -- stable under scope extensions).
82 | Sem.th^𝓥 Eval = λ v ρ → v
83 |
84 | -- When we look up the value associated to a variable, we need to return
85 | -- something which has the type of the overall computation. Here they match
86 | -- up so we can use the identity function
87 | Sem.var Eval = λ n → n
88 |
89 | -- Finally we have to define an algebra which interprets every constructor
90 | -- provided that the subterms already have been interpreted. Here we transform
91 | -- the syntactic construct add into the addition on natural numbers
92 | Sem.alg Eval = λ where
93 | (add' l r) → l + r
94 |
95 | -- We can evaluate terms by giving an interpretation to each of their variables
96 | eval : ∀ (n : ℕ) → let Γ = List.replicate n _ in (Γ ─Env) Value [] → Tm hutton _ _ Γ → ℕ
97 | eval n ρ t = Sem.sem Eval ρ t
98 |
99 | open import Relation.Binary.PropositionalEquality
100 |
101 | -- x₀ + x₁ ≡ 12 under the assumption that x₀ = 4 and x₁ = 8
102 |
103 | _ : eval 2 (ε ∙ 4 ∙ 8) (add (`var z) (`var (s z)))
104 | ≡ 12
105 | _ = refl
106 |
--------------------------------------------------------------------------------
/stlc/doc/Hutton/Constant.agda:
--------------------------------------------------------------------------------
1 | module Hutton.Constant where
2 |
3 | open import Data.Unit
4 | open import Data.List.Base as List
5 | open import Data.Nat.Base
6 | open import Generic.Syntax
7 |
8 | ------------------------------------------------------------------------
9 | -- SYNTAX: description in the universe of syntaxes with binding
10 |
11 | -- Hutton's Razor reloaded
12 | -- This time we take: H = x | n | H + H
13 | -- where n is a natural number
14 |
15 | data Tag : Set where
16 | Add Lit : Tag
17 |
18 | hutton : Desc ⊤
19 |
20 | -- it uses a Tag to distinguish two constructors:
21 | -- the _+_ operator we have already seen
22 | -- and a constructor for literals
23 |
24 | hutton = `σ Tag λ where
25 | Add → `X [] _ (`X [] _ (`∎ _))
26 | Lit → `σ ℕ λ _ → `∎ _
27 |
28 | -- `σ is used in one case to offer a choice of construtors and in another
29 | -- to store a value in a constructor.
30 |
31 | open import Data.Product
32 | open import Relation.Binary.PropositionalEquality
33 |
34 | -- We can once more introduce pattern synonyms to hide the fact that we
35 | -- are using an encoding
36 |
37 | pattern add' l r = (Add , l , r , refl)
38 | pattern add l r = `con (add' l r)
39 |
40 | double : TM hutton _ → TM hutton _
41 | double x = add x x
42 |
43 | pattern lit' n = (Lit , n , refl)
44 | pattern lit n = `con (lit' n)
45 |
46 | five : TM hutton _
47 | five = lit 5
48 |
49 | ------------------------------------------------------------------------
50 | -- SEMANTICS: scope-and-type preserving fold-like traversal
51 |
52 | -- We can once more define our language's denotational semantics
53 |
54 | open import Data.Nat.Base
55 | open import var
56 | open import environment
57 | open import Generic.Semantics
58 |
59 | Value : ⊤ ─Scoped
60 | Value _ _ = ℕ
61 |
62 | -- It is essentially the same except for the new lit' case we had to add.
63 |
64 | Eval : Sem hutton Value Value
65 | Sem.th^𝓥 Eval = λ v ρ → v
66 | Sem.var Eval = λ n → n
67 | Sem.alg Eval = λ where
68 | (add' l r) → l + r
69 | (lit' n) → n
70 |
71 | eval : TM hutton _ → ℕ
72 | eval = Sem.closed Eval
73 |
74 | -- 5 + 5 ≡ 10
75 |
76 | _ : eval (double five) ≡ 10
77 | _ = refl
78 |
79 | ------------------------------------------------------------------------
80 |
81 | -- But we can also have more subtle semantics e.g. constant folding:
82 | -- where values are now terms of the language itself.
83 |
84 | open import Generic.Semantics.Syntactic
85 |
86 | Fold : Sem hutton (Tm hutton _) (Tm hutton _)
87 | Sem.th^𝓥 Fold = th^Tm -- generic lemma: terms are always thinnable
88 | Sem.var Fold = λ t → t -- values and result are the same type
89 | Sem.alg Fold = λ where
90 | -- Here is the interesting part: we are simplifying the terms.
91 | -- Note that the subterms l and r in the pattern (add' l r) have
92 | -- already been simplified.
93 | (add' (lit 0) t) → t
94 | (add' t (lit 0)) → t
95 | (add' (lit m) (lit n)) → lit (m + n)
96 | (add' t u) → add t u
97 | (lit' n) → lit n
98 |
99 | fold : ∀ n → let Γ = List.replicate n _ in Tm hutton _ _ Γ → Tm hutton _ _ Γ
100 | fold n = Sem.sem Fold (pack `var)
101 |
102 | -- (0 + (x₂ + 0)) + (3 + 4) ≡ x₂ + 7
103 |
104 | _ : fold 3 (add (add (lit 0) (add (`var (s (s z))) (lit 0)))
105 | (add (lit 3) (lit 4)))
106 | ≡ add (`var (s (s z))) (lit 7)
107 | _ = refl
108 |
109 | -- Or even more subtle ones where we collapse *all* constants and quotient
110 | -- the tree modulo associativity
111 |
112 | -- Values are then a constant together with a list of variables read from left
113 | -- to right in the tree:
114 |
115 | record Essence (_ : ⊤) (Γ : List ⊤) : Set where
116 | constructor _:+_
117 | field literal : ℕ
118 | variables : List (Var _ Γ)
119 |
120 | -- Variables are interpreted as themselves and the computation delivers the
121 | -- 'essence' of a computation.
122 |
123 | Simpl : Sem hutton Var Essence
124 | Sem.th^𝓥 Simpl = th^Var -- Variables are always thinnable (≈ renaming)
125 | Sem.var Simpl = λ s → (0 :+ (s ∷ [])) -- Their essence is the singleton list
126 | Sem.alg Simpl = λ where
127 | -- The addition of two essences yields a new one by:
128 | -- taking the sum of both literals
129 | -- appending the lists of variables (while respecting the left to right ordering)
130 | (add' (m :+ xs) (n :+ ys)) → (m + n) :+ (xs ++ ys)
131 | -- The essence of a literal is its value together with the empty list of variables
132 | (lit' n) → n :+ []
133 |
134 | open import Function
135 |
136 | simplify : ∀ n → let Γ = List.replicate n _ in Tm hutton _ _ Γ → Tm hutton _ _ Γ
137 | simplify Γ t = case Sem.sem Simpl (pack (λ v → v)) t of λ where
138 | -- we clean up after ourselves: if the literal is 0,
139 | -- we don't bother returning it
140 | (0 :+ (x ∷ xs)) → List.foldl cons (`var x) xs
141 | (n :+ xs) → List.foldl cons (lit n) xs
142 |
143 | where cons = λ t v → add t (`var v)
144 |
145 |
146 | -- (3 + (x₀ + x₁)) + (x₂ + (2 + 12)) ≡ 15 + x₀ + x₁ + x₂
147 |
148 | _ : simplify 3 (add (add (lit 3) (add (`var z) (`var (s z))))
149 | (add (`var (s (s z))) (add (lit 2) (lit 10))))
150 | ≡ add (add (add (lit 15) (`var z)) (`var (s z))) (`var (s (s z)))
151 | _ = refl
152 |
153 | -- ((x₀ + 0) + x₁) + (x₂ + (x₀ + x₀)) ≡ x₀ + x₁ + x₂ + x₀ + x₀
154 |
155 | _ : simplify 3 (add (add (add (`var z) (lit 0)) (`var (s z)))
156 | (add (`var (s (s z))) (add (`var z) (`var z))))
157 | ≡ add (add (add (add (`var z)
158 | (`var (s z)))
159 | (`var (s (s z))))
160 | (`var z))
161 | (`var z)
162 | _ = refl
163 |
164 |
165 |
166 | -- But all of this is really language specific...
167 |
--------------------------------------------------------------------------------
/stlc/doc/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | latexmk -pdf background.tex
3 |
4 | clean:
5 | rm *.aux *.log *.nav *.out *.snm *.toc *.fdb_latexmk *.fls *.pdf
6 |
--------------------------------------------------------------------------------
/stlc/doc/background.tex:
--------------------------------------------------------------------------------
1 | \documentclass{beamer}
2 | \newcommand{\codehere}[1]{
3 | \begin{center}
4 | {\large[#1.agda]}
5 | \end{center}
6 | }
7 |
8 | \begin{document}
9 |
10 | \author{Guillaume ALLAIS
11 | \\ University of Strathclyde
12 | \\ guillaume.allais@strath.ac.uk}
13 | \title{Scrap Your DSL Boilerplate\\
14 | With a Universe of Syntaxes With Binding}
15 | \institute{CoCoDo 2019}
16 | \date{April 2nd, 2019}
17 |
18 | \begin{frame}
19 | \maketitle
20 | \end{frame}
21 |
22 | \begin{frame}{Quick Presentation}
23 | \begin{itemize}
24 | \item Background in Interactive Theorem Provers
25 | \item (User and) Developer of Agda and its standard library
26 | \begin{itemize}
27 | \item \url{https://github.com/agda/agda}
28 | \item \url{https://github.com/agda/agda-stdlib}
29 | \end{itemize}
30 | \item Excited about \emph{running} correct by construction code
31 | \end{itemize}
32 | \end{frame}
33 |
34 | \begin{frame}{Don't hesitate to ask questions}
35 | \end{frame}
36 |
37 | \begin{frame}{Background of this Work}
38 |
39 | \begin{itemize}
40 | \item Theoretic: DSLs with Strong invariants
41 | \uncover<2->
42 | {
43 | \begin{itemize}
44 | \item Universe of Syntaxes with Binding
45 | \item Type and Scope Preserving Programs and their Proofs
46 | \item Not in: Resource-Aware Type Systems (Linear Logic)
47 | \end{itemize}
48 | }
49 | \medskip
50 | \item Practical: User Interactions
51 | \uncover<3->
52 | {
53 | \begin{itemize}
54 | \item Total Parser Combinators
55 | \item Not in (yet): Declarative Hierarchical Command Line Interfaces
56 | \item Not in (yet): Sized IO
57 | \end{itemize}
58 | }
59 | \end{itemize}
60 | \end{frame}
61 |
62 | \begin{frame}{Intro to Agda: Description}
63 | Agda is:
64 | \begin{itemize}
65 | \item pure
66 | \begin{itemize}
67 | \item No undocumented side effects
68 | \item No undocumented mutations
69 | \uncover<2->{\item No undocumented non-termination}
70 | \end{itemize}
71 | \item functional
72 | \begin{itemize}
73 | \item first class functions
74 | \item powerful notion of inductive families (GADTs++)
75 | \end{itemize}
76 | \item dependently typed
77 | \begin{itemize}
78 | \item Types can (mention / be) arbitrary terms
79 | \end{itemize}
80 | \item<1> total
81 | \end{itemize}
82 |
83 | \end{frame}
84 |
85 | \begin{frame}{Intro to Agda: Interactive Programming}
86 | \codehere{Gentle}
87 | \end{frame}
88 |
89 | \begin{frame}{Warming up: Hutton's Razor(s)}
90 | \href{run:Hutton/Base.agda}{Hutton.Base}
91 | \href{run:Hutton/Constant.agda}{Hutton.Constant}
92 | \end{frame}
93 |
94 | \begin{frame}{Generic Pass: Let-inlining}
95 | \href{run:/home/gallais/projects/generic-syntax/src/Generic/Syntax/LetBinder.agda}{Let Binders}
96 | \newline
97 | \href{run:/home/gallais/projects/generic-syntax/src/Generic/Semantics/Elaboration/LetBinder.agda}{Elaboration}
98 | \end{frame}
99 |
100 | \begin{frame}{Generic Pass: Let-inlining, II}
101 | \begin{itemize}
102 | \item Either: IR with usage counting for variables
103 | \newline
104 | \href{run:/home/gallais/projects/generic-syntax/src/Generic/Syntax/LetCounter.agda}{Let Counters}
105 | \newline
106 | \href{run:/home/gallais/projects/generic-syntax/src/Generic/Semantics/Elaboration/LetCounter.agda}{Elaboration}
107 |
108 | \item Or: Different IR with usage information ("co-deBruijn")
109 | \end{itemize}
110 | \end{frame}
111 |
112 | \begin{frame}{Going Further: Intro to Type Theory / Agda}
113 |
114 | \begin{itemize}
115 | \item The Little Typer (\url{http://www.thelittletyper.com/})
116 | \item Verified Functional Programming in Agda (\url{https://dl.acm.org/citation.cfm?id=2841316})
117 | \item Programming Language Foundations in Agda (\url{https://plfa.github.io/})
118 | \end{itemize}
119 | \end{frame}
120 |
121 | \begin{frame}{Going Further: This Tutorial's Dependencies}
122 |
123 | \begin{itemize}
124 | \item Theory:
125 | \begin{itemize}
126 | \item Type-and-scope safe programs and their proofs (\url{https://dl.acm.org/citation.cfm?id=3018613})
127 | \item A type and scope safe universe of syntaxes with binding: their semantics and proofs (\url{https://dl.acm.org/citation.cfm?id=3236785})
128 |
129 | \item Generic Syntax library (\url{https://github.com/gallais/generic-syntax})
130 | \end{itemize}
131 | \item User Interactions:
132 | \begin{itemize}
133 | \item agdarsec -- Total Parser Combinators (\url{https://gallais.github.io/pdf/agdarsec18.pdf})
134 | \item agdARGS -- Declarative Hierarchical Command Line Interfaces (\url{https://gallais.github.io/pdf/TTT-2017.pdf})
135 | \end{itemize}
136 | \end{itemize}
137 | \end{frame}
138 | \end{document}
139 |
--------------------------------------------------------------------------------
/stlc/doc/hutton.agda-lib:
--------------------------------------------------------------------------------
1 | name: stlc
2 | include: .
3 | depend: standard-library
4 | , agdarsec
5 | , generic-syntax
6 |
--------------------------------------------------------------------------------
/stlc/examples/hid.stlc:
--------------------------------------------------------------------------------
1 | def idh : ('a → 'a) → ('a → 'a) = λf.λx. f x
2 | def id : ('a → 'a) = λx.x
3 | have idh id
4 |
5 |
--------------------------------------------------------------------------------
/stlc/examples/silly.stlc:
--------------------------------------------------------------------------------
1 | def id : 'a -> 'a = \x. x
2 | def un : 'a -> 'b -> 'a = \x.\y.id (let y = x in y)
3 | def deux : 'a -> 'b -> 'b = \x. \y .y
4 | have un
5 |
--------------------------------------------------------------------------------
/stlc/examples/swap2.stlc:
--------------------------------------------------------------------------------
1 | def swapab : ('a * 'b) -> ('b * 'a) = \p. (snd p, fst p)
2 | def swapba : ('b * 'a) -> ('a * 'b) = \p. (snd p, fst p)
3 | have (\p. swapba (swapab p) : ('a * 'b) -> ('a * 'b))
4 |
--------------------------------------------------------------------------------
/stlc/src/Data/List/Relation/Unary/All/Extras.agda:
--------------------------------------------------------------------------------
1 | module Data.List.Relation.Unary.All.Extras where
2 |
3 | open import Data.List.Base as List
4 | open import Data.List.All as Listₚ
5 | open import Data.Product
6 | open import Function
7 | open import Relation.Unary
8 |
9 | module _ {a p} {A : Set a} {P : Pred A p} where
10 |
11 | fromList : (xs : List (∃ P)) → All P (List.map proj₁ xs)
12 | fromList [] = []
13 | fromList ((x , p) ∷ xps) = p ∷ fromList xps
14 |
15 | toList : ∀ {xs} → All P xs → List (∃ P)
16 | toList [] = []
17 | toList (px ∷ pxs) = (-, px) ∷ toList pxs
18 |
19 | self : ∀ {a} {A : Set a} {xs : List A} → All (const A) xs
20 | self = Listₚ.tabulate (λ {x} _ → x)
21 |
--------------------------------------------------------------------------------
/stlc/src/Data/Map.agda:
--------------------------------------------------------------------------------
1 | module Data.Map where
2 |
3 | open import Data.Bool
4 | open import Data.Product
5 | open import Data.List as List
6 | open import Data.Maybe
7 | open import Function
8 |
9 | open import Relation.Nullary
10 | open import Relation.Nullary.Decidable
11 | open import Relation.Binary
12 | open import Relation.Binary.PropositionalEquality
13 |
14 | module Map {A : Set} (eq? : Decidable {A = A} _≡_) (B : Set) where
15 |
16 | Map : Set
17 | Map = List (A × B)
18 |
19 | RMap : Set
20 | RMap = List (B × A)
21 |
22 | empty : Map
23 | empty = []
24 |
25 | set : A → B → Map → Map
26 | set a b mp = (a , b) ∷ mp
27 |
28 | assoc : A → Map → Maybe B
29 | assoc a = flip foldr nothing $ uncurry $ λ a′ b ih →
30 | if ⌊ eq? a a′ ⌋ then just b else ih
31 |
32 | invert : Map → RMap
33 | invert = List.map swap
34 |
--------------------------------------------------------------------------------
/stlc/src/Eval.agda:
--------------------------------------------------------------------------------
1 | module Eval where
2 |
3 | open import Data.Nat.Base using (ℕ)
4 | open import Data.List.Base using (List; [])
5 | open import Data.Product as Prod
6 | open import Function
7 | open import Relation.Unary renaming (_⇒_ to _⟶_)
8 | open import var
9 | open import environment
10 | open import Generic.Syntax
11 | open import Generic.Semantics
12 | open import Generic.Semantics.Syntactic using (th^Tm)
13 | open import Language; open Internal
14 | open import Text.Parser.Position
15 |
16 | Model' : Type ℕ → List (Mode × Type ℕ) → Set
17 | Model' (α k) Γ = Position × Typed (Infer , α k) Γ
18 | Model' (σ ⊗ τ) Γ = Position × Model' σ Γ × Model' τ Γ
19 | Model' (σ ⇒ τ) Γ = Position × □ (Model' σ ⟶ Model' τ) Γ
20 |
21 | Model : (Mode × Type ℕ) ─Scoped
22 | Model (m , σ) = Model' σ
23 |
24 | th^Model' : ∀ {σ} → Thinnable (Model' σ)
25 | th^Model' {α k} (r , t) ρ = r , th^Tm t ρ
26 | th^Model' {σ ⇒ τ} (r , f) ρ = r , th^□ f ρ
27 | th^Model' {σ ⊗ τ} (r , a , b) ρ = r , th^Model' a ρ , th^Model' b ρ
28 |
29 | Eval : ∀ {P} → Sem (internal P) Model Model
30 | Sem.th^𝓥 Eval = th^Model'
31 | Sem.var Eval = id
32 | Sem.alg Eval = λ where
33 | (r , `λ' b) → r , λ inc v → b inc (ε ∙ v)
34 | (r , f `$' t) → extract (proj₂ f) t
35 | (r , `fst' t) → proj₁ $ proj₂ t
36 | (r , `snd' t) → proj₂ $ proj₂ t
37 | (r , a `,' b) → (r , a , b)
38 | (r , t `∶' σ) → t
39 | (r , `-' t) → t
40 | (r , `let' e `in t) → extract t (ε ∙ e)
41 |
42 | reify : ∀ σ → ∀[ Model' σ ⟶ Typed (Check , σ) ]
43 | reflect : ∀ σ → ∀[ const Position ⟶ Typed (_ , σ) ⟶ Model' σ ]
44 |
45 | reify (α k) (r , t) = r >`- t
46 | reify (σ ⇒ τ) (r , t) = r >`λ reify τ (t extend (reflect σ r (`var z)))
47 | reify (σ ⊗ τ) (r , a , b) = r >[ reify σ a `, reify τ b ]
48 |
49 | reflect (α k) r t = r , t
50 | reflect (σ ⊗ τ) r t = r , reflect σ r (r >`fst t) , reflect τ r (r >`snd t)
51 | reflect (σ ⇒ τ) r t = r , λ inc v → reflect τ r (r >[ th^Tm t inc `$ reify σ v ])
52 |
53 | norm : ∀ {P m σ} → Internal P (m , σ) [] → Typed (Check , σ) []
54 | norm = reify _ ∘′ Sem.closed Eval
55 |
--------------------------------------------------------------------------------
/stlc/src/Language.agda:
--------------------------------------------------------------------------------
1 | module Language where
2 |
3 | open import Data.Unit
4 | open import Data.Empty
5 | open import Data.Product as Prod
6 | open import Data.Nat
7 | open import Data.List as List using (List; []; _∷_)
8 | open import Data.List.All -- important for the pattern synonyms!
9 | open import Data.String as String using (String; _++_)
10 | open import Function
11 | open import Function.Equivalence
12 | open import Relation.Nullary
13 | open import Relation.Nullary.Decidable as RNDec
14 | open import Relation.Nullary.Product
15 | open import Relation.Binary using (Decidable)
16 | open import Relation.Binary.PropositionalEquality
17 |
18 | open import var using (z; s; _─Scoped)
19 | open import environment
20 | open import Generic.Syntax
21 | open import Generic.AltSyntax
22 | open import Generic.Semantics.Syntactic using (sub)
23 | open import Text.Parser.Position as Position using (Position; _∶_; start)
24 |
25 | infixr 6 _⇒_
26 | infixr 7 _⊗_
27 | data Type (A : Set) : Set where
28 | α : A → Type A
29 | _⊗_ : (σ τ : Type A) → Type A
30 | _⇒_ : (σ τ : Type A) → Type A
31 |
32 | show : Type String → String
33 | pshow : Type String → String
34 |
35 | show (α str) = "'" ++ str
36 | show (σ ⊗ τ) = pshow σ ++ " * " ++ show τ
37 | show (σ ⇒ τ) = pshow σ ++ " → " ++ show τ
38 |
39 | pshow σ@(α _) = show σ
40 | pshow σ@(_ ⊗ _) = "(" ++ show σ ++ ")"
41 | pshow σ@(_ ⇒ _) = "(" ++ show σ ++ ")"
42 |
43 | data Mode : Set where
44 | Infer Check : Mode
45 |
46 | eqdecMode : Decidable {A = Mode} _≡_
47 | eqdecMode Infer Infer = yes refl
48 | eqdecMode Infer Check = no (λ ())
49 | eqdecMode Check Infer = no (λ ())
50 | eqdecMode Check Check = yes refl
51 |
52 | module _ {A : Set} where
53 |
54 | α-equivalence : {a₁ a₂ : A} → (a₁ ≡ a₂) ⇔ (α a₁ ≡ α a₂)
55 | α-equivalence = equivalence (cong α) (λ where refl → refl)
56 |
57 | ⇒-equivalence : {σ₁ σ₂ τ₁ τ₂ : Type A} →
58 | (σ₁ ≡ σ₂ × τ₁ ≡ τ₂) ⇔ (σ₁ ⇒ τ₁ ≡ σ₂ ⇒ τ₂)
59 | ⇒-equivalence = equivalence (uncurry (cong₂ _⇒_)) (λ where refl → refl , refl)
60 |
61 | ⊗-equivalence : {σ₁ σ₂ τ₁ τ₂ : Type A} →
62 | (σ₁ ≡ σ₂ × τ₁ ≡ τ₂) ⇔ (σ₁ ⊗ τ₁ ≡ σ₂ ⊗ τ₂)
63 | ⊗-equivalence = equivalence (uncurry (cong₂ _⊗_)) (λ where refl → refl , refl)
64 |
65 | module _ {A : Set} (eq : Decidable {A = A} _≡_) where
66 |
67 | eqdecType : Decidable {A = Type A} _≡_
68 | eqdecType (α a₁) (α a₂) = RNDec.map α-equivalence (eq a₁ a₂)
69 | eqdecType (σ₁ ⊗ τ₁) (σ₂ ⊗ τ₂) =
70 | RNDec.map ⊗-equivalence (eqdecType σ₁ σ₂ ×-dec eqdecType τ₁ τ₂)
71 | eqdecType (σ₁ ⇒ τ₁) (σ₂ ⇒ τ₂) =
72 | RNDec.map ⇒-equivalence (eqdecType σ₁ σ₂ ×-dec eqdecType τ₁ τ₂)
73 |
74 | eqdecType (α _) (_ ⇒ _) = no (λ ())
75 | eqdecType (_ ⇒ _) (α _) = no (λ ())
76 | eqdecType (α _) (_ ⊗ _) = no (λ ())
77 | eqdecType (_ ⊗ _) (α _) = no (λ ())
78 | eqdecType (_ ⊗ _) (_ ⇒ _) = no (λ ())
79 | eqdecType (_ ⇒ _) (_ ⊗ _) = no (λ ())
80 |
81 | data `Bidi (P : Set) : Set where
82 | Cut App Fst Snd : `Bidi P
83 | Lam Prd Emb : `Bidi P
84 | Let : {p : P} → `Bidi P
85 |
86 | -- Throwing in some useful combinators
87 |
88 | module _ {I : Set} where
89 |
90 | `κ_`×_ : Set → Desc I → Desc I
91 | `κ A `× d = `σ A $ const d
92 |
93 | Located : Desc I → Desc I
94 | Located d = `κ Position `× d
95 |
96 | module Surface where
97 |
98 | -- I'm adding useless `κ_`×_ parts to keep the layout the
99 | -- same between surface and internal. This will allow us to
100 | -- use the same pattern synonyms for both!
101 | surface : Set → Desc Mode
102 | surface A = Located $ `σ (`Bidi ⊤) $ λ where
103 | Cut → `κ Type A `× `X [] Check (`∎ Infer)
104 | App → `κ ⊤ `× `X [] Infer (`X [] Check (`∎ Infer))
105 | Fst → `κ ⊤ `× `X [] Infer (`∎ Infer)
106 | Snd → `κ ⊤ `× `X [] Infer (`∎ Infer)
107 | Lam → `κ ⊤ `× `X (Infer ∷ []) Check (`∎ Check)
108 | Prd → `κ ⊤ `× `X [] Check (`X [] Check (`∎ Check))
109 | Emb → `κ ⊤ `× `X [] Infer (`∎ Check)
110 | Let → `κ ⊤ `× `X [] Infer (`X (Infer ∷ []) Check (`∎ Check))
111 |
112 |
113 | Parsed : Mode → Set
114 | Parsed = Raw Position (surface String) _
115 |
116 | Scoped : Mode → List Mode → Set
117 | Scoped = Tm (surface ℕ) _
118 |
119 |
120 | module Internal where
121 |
122 | internal : (P : Set) → Desc (Mode × Type ℕ)
123 | internal P = Located $ `σ (`Bidi P) $ λ where
124 | Cut → `σ (Type ℕ) $ λ σ →
125 | `X [] (Check , σ) (`∎ (Infer , σ))
126 | App → `σ (Type ℕ × Type ℕ) $ uncurry $ λ σ τ →
127 | `X [] (Infer , σ ⇒ τ) (`X [] (Check , σ) (`∎ (Infer , τ)))
128 | Fst → `σ (Type ℕ × Type ℕ) $ uncurry $ λ σ τ →
129 | `X [] (Infer , σ ⊗ τ) (`∎ (Infer , σ))
130 | Snd → `σ (Type ℕ × Type ℕ) $ uncurry $ λ σ τ →
131 | `X [] (Infer , σ ⊗ τ) (`∎ (Infer , τ))
132 | Lam → `σ (Type ℕ × Type ℕ) $ uncurry $ λ σ τ →
133 | `X ((Infer , σ) ∷ []) (Check , τ) (`∎ (Check , σ ⇒ τ))
134 | Prd → `σ (Type ℕ × Type ℕ) $ uncurry $ λ σ τ →
135 | `X [] (Check , σ) (`X [] (Check , τ) (`∎ (Check , σ ⊗ τ)))
136 | Emb → `σ (Type ℕ) $ λ σ →
137 | `X [] (Infer , σ) (`∎ (Check , σ))
138 | Let → `σ (Type ℕ × Type ℕ) $ uncurry $ λ σ τ →
139 | `X [] (Infer , σ) (`X ((Infer , σ) ∷ []) (Check , τ) (`∎ (Check , τ)))
140 |
141 | Internal : (P : Set) → (Mode × Type ℕ) ─Scoped
142 | Internal P = Tm (internal P) _
143 |
144 | getPosition : ∀ {P σ Γ} → Internal P σ Γ → Position
145 | getPosition (`var _) = start
146 | getPosition (`con (r , _)) = r
147 |
148 | typed = internal ⊤
149 |
150 | Typed : (Mode × Type ℕ) ─Scoped
151 | Typed = Tm typed _
152 |
153 | letfree = internal ⊥
154 |
155 | LetFree : (Mode × Type ℕ) ─Scoped
156 | LetFree = Tm letfree _
157 |
158 | erase : ∀ {X σ Γ} → ⟦ letfree ⟧ X σ Γ → ⟦ typed ⟧ X σ Γ
159 | erase (r , Cut , p) = r , Cut , p
160 | erase (r , App , p) = r , App , p
161 | erase (r , Fst , p) = r , Fst , p
162 | erase (r , Snd , p) = r , Snd , p
163 | erase (r , Lam , p) = r , Lam , p
164 | erase (r , Emb , p) = r , Emb , p
165 | erase (r , Prd , p) = r , Prd , p
166 | erase (r , Let {} , p)
167 |
168 | data LetView {X Γ} : ∀ {σ} → ⟦ typed ⟧ X σ Γ → Set where
169 | Let : ∀ r {σ τ} e b → LetView (r , Let , (σ , τ) , e , b , refl)
170 | ¬Let : ∀ {σ} (t : ⟦ letfree ⟧ X σ Γ) → LetView (erase t)
171 |
172 | letView : ∀ {X Γ σ} (t : ⟦ typed ⟧ X σ Γ) → LetView t
173 | letView (r , Cut , p) = ¬Let (r , Cut , p)
174 | letView (r , App , p) = ¬Let (r , App , p)
175 | letView (r , Fst , p) = ¬Let (r , Fst , p)
176 | letView (r , Snd , p) = ¬Let (r , Snd , p)
177 | letView (r , Lam , p) = ¬Let (r , Lam , p)
178 | letView (r , Emb , p) = ¬Let (r , Emb , p)
179 | letView (r , Prd , p) = ¬Let (r , Prd , p)
180 | letView (r , Let , _ , e , b , refl) = Let r e b
181 |
182 | -- Traditional pattern synonyms (usable on the LHS only)
183 | pattern _`∶'_ t σ = (Cut , σ , t , refl)
184 | pattern _`∶_ t σ = `con (_ , t `∶' σ)
185 | pattern _`$'_ f t = (App , _ , f , t , refl)
186 | pattern _`$_ f t = `con (_ , f `$' t)
187 | pattern `fst'_ e = (Fst , _ , e , refl)
188 | pattern `fst_ e = `con (_ , `fst' e)
189 | pattern `snd'_ e = (Snd , _ , e , refl)
190 | pattern `snd_ e = `con (_ , `snd' e)
191 | pattern `λ'_ b = (Lam , _ , b , refl)
192 | pattern `λ_ b = `con (_ , `λ' b)
193 | pattern `λ'_↦_ x b = (_ , Lam , _ , (x ∷ [] , b) , refl)
194 | pattern `λ_↦_ x b = `con (`λ' x ↦ b)
195 | pattern _`,'_ a b = (Prd , _ , a , b , refl)
196 | pattern _`,_ a b = `con (_ , a `,' b)
197 | pattern `let'_`in_ e b = (Let , _ , e , b , refl)
198 | pattern `let_`in_ e b = `con (_ , `let' e `in b)
199 | pattern `-'_ t = (Emb , _ , t , refl)
200 | pattern `-_ t = `con (_ , `-' t)
201 |
202 | -- Position-aware pattern synonyms (usable both on the LHS and RHS)
203 | pattern _>[_`∶'_] r t σ = (r , Cut , σ , t , refl)
204 | pattern _>[_`∶_] r t σ = `con (r >[ t `∶' σ ])
205 | pattern _>[_`$'_] r f t = (r , App , _ , f , t , refl)
206 | pattern _>[_`$_] r f t = `con (r >[ f `$' t ])
207 | pattern _>`fst'_ r e = (r , Fst , _ , e , refl)
208 | pattern _>`fst_ r e = `con (r >`fst' e)
209 | pattern _>`snd'_ r e = (r , Snd , _ , e , refl)
210 | pattern _>`snd_ r e = `con (r >`snd' e)
211 | pattern _>`λ'_ r b = (r , Lam , _ , b , refl)
212 | pattern _>`λ_ r b = `con (r >`λ' b)
213 | pattern _>[_`,'_] r a b = (r , Prd , _ , a , b , refl)
214 | pattern _>[_`,_] r a b = `con (r >[ a `,' b ])
215 | pattern _>`let'_`in_ r e b = (r , Let , _ , e , b , refl)
216 | pattern _>`let_`in_ r e b = `con (r >`let' e `in b)
217 | pattern _>`-'_ r t = (r , Emb , _ , t , refl)
218 | pattern _>`-_ r t = `con (r >`-' t)
219 |
220 | pattern _>`λ'_↦_ r x b = (r , Lam , _ , (x ∷ [] , b) , refl)
221 | pattern _>`λ_↦_ r x b = `con (r >`λ' x ↦ b)
222 | pattern _>`let'_↦_`in_ r x e b = (r , Let , _ , e , (x ∷ [] , b) , refl)
223 | pattern _>`let_↦_`in_ r x e b = `con (r >`let' x ↦ e `in b)
224 |
225 | -- Examples of terms of differnent languages using the same pattern synonyms
226 | -- Here we use `start' as a placeholder for positions
227 |
228 | _ : Surface.Scoped Check []
229 | _ = start >`λ (start >`- `var z)
230 |
231 | _ : ∀ {σ} → Internal.Typed (Check , σ ⇒ σ) []
232 | _ = start >`λ (start >`- `var z)
233 |
234 | toCheck : ∀ {m σ Γ} → Internal.Typed (m , σ) Γ → Internal.Typed (Check , σ) Γ
235 | toCheck {Infer} t = Internal.getPosition t >`- t
236 | toCheck {Check} t = t
237 |
238 | toInfer : ∀ {m σ Γ} → Internal.Typed (m , σ) Γ → Internal.Typed (Infer , σ) Γ
239 | toInfer {Infer} t = t
240 | toInfer {Check} t = Internal.getPosition t >[ t `∶ _ ]
241 |
242 | infersOf : List (Type ℕ) → List (Mode × Type ℕ)
243 | infersOf = List.map (Infer ,_)
244 |
245 | data Definitions : List (Type ℕ) → Set
246 | record Definition {ds} (p : Definitions ds) : Set
247 |
248 | infixl 11 _>_∶_≔_ _∶_≔_
249 | record Definition {ds} p where
250 | constructor _>_∶_≔_
251 | field pos : Position
252 | name : String
253 | type : Type ℕ
254 | term : Internal.Typed (Check , type) (infersOf ds)
255 |
256 | pattern _∶_≔_ x σ t = _ > x ∶ σ ≔ t
257 |
258 | infixl 10 _&_
259 | data Definitions where
260 | [] : Definitions []
261 | _&_ : ∀ {ds} (p : Definitions ds) (d : Definition p) →
262 | Definitions (Definition.type d ∷ ds)
263 |
264 | modes : ∀ {Γ} → Definitions Γ → List Mode
265 | modes {Γ} _ = List.map (const Infer) Γ
266 |
267 | names : ∀ {Γ} (ds : Definitions Γ) → All (const String) (modes ds)
268 | names [] = []
269 | names (ds & d) = Definition.name d ∷ names ds
270 |
271 | toEnv : ∀ {Γ} → Definitions Γ → (infersOf Γ ─Env) Internal.Typed []
272 | toEnv [] = ε
273 | toEnv (Γ & r > _ ∶ σ ≔ d) = let ρ = toEnv Γ in ρ ∙ sub ρ (r >[ d `∶ σ ])
274 |
275 | Expression : Type ℕ ─Scoped
276 | Expression σ Γ = Internal.Typed (Infer , σ) (infersOf Γ)
277 |
278 |
279 | toLets : ∀ {σ Γ} → Definitions Γ →
280 | Internal.Typed (Check , σ) (infersOf Γ) → Internal.Typed (Check , σ) []
281 | toLets [] e = e
282 | toLets (ds & d) e = toLets ds $ Definition.pos d
283 | >`let toInfer (Definition.term d)
284 | `in e
285 |
286 | infix 9 _&&_
287 | data Program : Set where
288 | _&&_ : ∀ {σ Γ} → Definitions Γ → Expression σ Γ → Program
289 |
290 | pattern assuming_have_ defs expr = defs && expr
291 |
292 | {-
293 | -- Can't quite write this: we would have to also write down the position of each node
294 |
295 | _ : Program
296 | _ = let nat = α 0 ⇒ (α 0 ⇒ α 0) ⇒ α 0 in assuming []
297 | & "id" ∶ nat ⇒ nat ≔ `λ `- `var z
298 | & "zero" ∶ nat ≔ `λ `λ `- `var (s z)
299 | & "suc" ∶ nat ⇒ nat ≔ `λ `λ `λ `- (`var z
300 | `$ (`- ((`var (s (s z))
301 | `$ (`- (`var (s z))))
302 | `$ (`- (`var z)))))
303 | have `var (s (s z)) `$ (`- (`var z `$ (`- (`var z `$ (`- `var (s z))))))
304 | -}
305 |
--------------------------------------------------------------------------------
/stlc/src/LetInline.agda:
--------------------------------------------------------------------------------
1 | module LetInline where
2 |
3 | open import Data.List.Base
4 | open import Data.Product
5 | open import environment
6 | open import Language
7 | open import Generic.Semantics
8 | open import Generic.Semantics.Syntactic
9 | open import Function
10 |
11 | open Internal
12 |
13 | LetInline : Sem typed LetFree LetFree
14 | Sem.th^𝓥 LetInline = th^Tm
15 | Sem.var LetInline = id
16 | Sem.alg LetInline = λ t → case letView t of λ where
17 | (Let r e b) → extract b (ε ∙ e)
18 | (¬Let p) → Sem.alg Substitution p
19 |
20 | let-inline : ∀ {σ} → Typed σ [] → LetFree σ []
21 | let-inline = Sem.closed LetInline
22 |
--------------------------------------------------------------------------------
/stlc/src/Main.agda:
--------------------------------------------------------------------------------
1 | module Main where
2 |
3 | open import Data.List.Base using ([]; _∷_)
4 | open import Data.Sum.Base
5 | open import Data.Product
6 | open import Data.String.Base
7 | open import Function
8 |
9 | open import System.Environment
10 | open import IO
11 | open import Codata.Musical.Notation
12 |
13 | import Types
14 | open import Pipeline
15 | open import Print
16 |
17 | main = run $
18 | ♯ getArgs >>= λ where
19 | [] → ♯ (return _)
20 | (fp ∷ _) → ♯ (♯ readFiniteFile fp >>= λ str →
21 | ♯ putStrLn ([ Types.show , unlines3 ]′ (pipeline str)))
22 |
23 | where unlines3 = λ where (a , b , c) → a ++ "\n" ++ b ++ "\n" ++ c
24 |
--------------------------------------------------------------------------------
/stlc/src/Parse.agda:
--------------------------------------------------------------------------------
1 | module Parse where
2 |
3 | open import Level
4 | open import Data.Unit using (⊤)
5 | open import Data.Bool.Base using (Bool; true; false)
6 | open import Data.Nat.Properties using (≤-refl)
7 | open import Data.Empty
8 | open import Data.Product
9 |
10 | open import Data.Maybe
11 | open import Data.Bool using (if_then_else_)
12 | open import Data.Char as Char using (Char; isSpace; isAlpha)
13 | open import Data.String as String using (String; toList)
14 | import Data.String.Unsafe as String
15 | open import Data.Sum.Base using (_⊎_; inj₁; inj₂; [_,_]′)
16 | open import Data.List.Base as List using (List; []; _∷_)
17 | open import Data.List.NonEmpty as List⁺ using (List⁺; _∷_)
18 | open import Data.Vec as Vec using (Vec)
19 | open import Function
20 |
21 | open import Category.Monad
22 |
23 | open import Induction.Nat.Strong as INS
24 |
25 | open import Data.Nat.Base using (ℕ)
26 | open import Data.Subset
27 | open import Data.List.Sized.Interface
28 | open import Relation.Binary using (Decidable)
29 | open import Relation.Binary.PropositionalEquality
30 | open import Relation.Binary.PropositionalEquality.Decidable
31 | open import Relation.Nullary
32 | open import Relation.Nullary.Decidable using (map′)
33 | open import Relation.Unary using (IUniversal) renaming (_⇒_ to _⟶_)
34 |
35 | open import Text.Parser.Types
36 | open import Text.Parser.Position
37 | open import Text.Parser.Combinators hiding (_>>=_)
38 | open import Text.Parser.Monad
39 |
40 | open import Generic.AltSyntax
41 |
42 | open import Language
43 | open Surface
44 | open import Types
45 |
46 | module ParserM = Agdarsec (Error String) ⊥ (record { into = At_ParseError ∘′ proj₁ })
47 | open ParserM
48 |
49 | data Tok : Set where
50 | ID : String → Tok
51 | ARR PRD : Tok
52 | DEF HVE : Tok
53 | LET EQ IN : Tok
54 | LAM DOT : Tok
55 | FST SND : Tok
56 | LPAR COL COM RPAR : Tok
57 |
58 | _≟_ : Decidable {A = Tok} _≡_
59 | ID x ≟ ID y = map′ (cong ID) (λ where refl → refl) (x String.≟ y)
60 | ARR ≟ ARR = yes refl
61 | PRD ≟ PRD = yes refl
62 | DEF ≟ DEF = yes refl
63 | HVE ≟ HVE = yes refl
64 | LET ≟ LET = yes refl
65 | EQ ≟ EQ = yes refl
66 | IN ≟ IN = yes refl
67 | LAM ≟ LAM = yes refl
68 | DOT ≟ DOT = yes refl
69 | FST ≟ FST = yes refl
70 | SND ≟ SND = yes refl
71 | LPAR ≟ LPAR = yes refl
72 | COL ≟ COL = yes refl
73 | COM ≟ COM = yes refl
74 | RPAR ≟ RPAR = yes refl
75 | _ ≟ _ = no p where postulate p : _
76 |
77 | Token : Set
78 | Token = Position × Tok
79 |
80 | keywords : List⁺ (String × Tok)
81 | keywords = ("→" , ARR)
82 | ∷ ("->" , ARR)
83 | ∷ ("*" , PRD)
84 | ∷ ("λ" , LAM)
85 | ∷ ("\\" , LAM)
86 | ∷ (":" , COL)
87 | ∷ ("let" , LET)
88 | ∷ ("in" , IN)
89 | ∷ ("fst" , FST)
90 | ∷ ("snd" , SND)
91 | ∷ ("def" , DEF)
92 | ∷ ("have", HVE)
93 | ∷ []
94 |
95 | breaking : Char → ∃ λ b → if b then Maybe Tok else Lift _ ⊤
96 | breaking c = case c of λ where
97 | '(' → true , just LPAR
98 | ')' → true , just RPAR
99 | '.' → true , just DOT
100 | ',' → true , just COM
101 | '=' → true , just EQ
102 | c → if isSpace c then true , nothing else false , _
103 |
104 | open import Text.Lexer keywords breaking ID using (tokenize)
105 |
106 | instance
107 | _ = ParserM.monadZero
108 | _ = ParserM.monadPlus
109 | _ = ParserM.monad
110 |
111 | P = ParserM.param Token (Vec Token) λ where (p , _) _ → Value (_ , p , [])
112 |
113 | theTok : Tok → ∀[ Parser P Token ]
114 | theTok t = maybeTok $ λ where
115 | tok@(p , t') → case t ≟ t' of λ where
116 | (yes eq) → just tok
117 | (no ¬eq) → nothing
118 |
119 | name : ∀[ Parser P String ]
120 | name = maybeTok λ where (p , ID str) → just str; _ → nothing
121 |
122 | parens : ∀ {A} → ∀[ □ Parser P A ⟶ Parser P A ]
123 | parens □p = theTok LPAR &> □p <& box (theTok RPAR)
124 |
125 | type : ∀[ Parser P (Type String) ]
126 | type = fix _ $ λ rec →
127 | let varlike str = case String.toList str of λ where
128 | ('\'' ∷ nm) → just (String.fromList nm)
129 | _ → nothing
130 | in chainr1 (α <$> guardM varlike name <|> parens rec)
131 | (box $ (_⇒_ <$ theTok ARR) <|> _⊗_ <$ theTok PRD)
132 |
133 | record Bidirectional n : Set where
134 | field infer : Parser P (Parsed Infer) n
135 | check : Parser P (Parsed Check) n
136 | open Bidirectional
137 |
138 | bidirectional : ∀[ Bidirectional ]
139 | bidirectional = fix Bidirectional $ λ rec →
140 | let □check = INS.map check rec
141 | □infer = INS.map infer rec
142 | var = uncurry (flip `var) <$> (guard (List.all isAlpha ∘′ toList) name <&M> getPosition)
143 | cut = (λ where ((t , (p , _)) , σ) → p >[ t `∶ σ ])
144 | <$> (theTok LPAR
145 | &> □check <&> box (theTok COL) <&> box (commit type)
146 | <& box (theTok RPAR))
147 | app = (λ where (p , c) e → p >[ e `$ c ]) <$>
148 | (getPosition ((uncurry _>`-_ <$> (getPosition var))
149 | <|> parens □check))
150 |
151 | proj = (λ where ((p , t) , e) → [ const (p >`fst e) , const (p >`snd e) ]′ t)
152 | <$> (getPosition (theTok FST <⊎> theTok SND)
153 | <&> box (var <|> parens □infer))
154 | infer = iterate (var <|> cut <|> proj <|> parens (INS.map commit □infer))
155 | (box app)
156 | lam = (λ where ((p , x) , c) → p >`λ x ↦ c)
157 | <$> (theTok LAM &> box (getPosition name)
158 | <&> box (theTok DOT &> INS.map commit □check))
159 | letin = (λ where (((p , x) , e) , c) → p >`let x ↦ e `in c)
160 | <$> (theTok LET &> box (getPosition name)
161 | <&> box (theTok EQ &> INS.map commit □infer)
162 | <&> box (theTok IN &> INS.map commit □check)
163 | )
164 |
165 | paredc = (λ p → let (c , r) = p; cons c = uncurry (_>[ c `,_]) in
166 | [ cons c ∘′ List⁺.foldr₁ (λ where (p , c) → (p ,_) ∘′ cons c)
167 | , const c ]′ r) <$>
168 | -- opening parenthesis
169 | ((theTok LPAR &> □check) <&> box (
170 | -- followed by either
171 | -- either a list of other values
172 | (list⁺ ((getPosition INS.map commit □check)
173 | <& box (theTok RPAR))
174 | -- or a closing parenthesis
175 | <⊎> theTok RPAR
176 | ))
177 | emb = uncurry _>`-_ <$> (getPosition infer)
178 | check = lam <|> letin <|> emb
179 | in record { infer = infer <|> parens (INS.map commit □infer)
180 | ; check = check <|> paredc
181 | }
182 |
183 | definitions : ∀[ Parser P (List⁺ (Position × String × Type String × Parsed Check)) ]
184 | definitions = list⁺ $ getPosition
185 | box (name
187 | <&> box (theTok COL
188 | &> box (type
189 | <&> box (theTok EQ
190 | &> box (check bidirectional)))))
191 |
192 | program : ∀[ Parser P (List⁺ (Position × String × Type String × Parsed Check)
193 | × Parsed Infer) ]
194 | program = definitions <&> box (theTok HVE &> box (infer bidirectional))
195 |
196 | parse : String → Types.Result String
197 | (List⁺ (Position × String × Type String × Parsed Check) × Parsed Infer)
198 | parse str = result inj₁ inj₁ (inj₂ ∘′ Success.value ∘′ proj₁)
199 | $′ runParser program ≤-refl input (start , [])
200 | where input = Vec.fromList $ tokenize str
201 |
202 | open import Agda.Builtin.Equality
203 |
204 | _ : tokenize "(λ x . 1 : `a → `a)"
205 | ≡ (0 ∶ 0 , LPAR)
206 | ∷ (0 ∶ 1 , LAM)
207 | ∷ (0 ∶ 3 , ID "x")
208 | ∷ (0 ∶ 5 , DOT)
209 | ∷ (0 ∶ 7 , ID "1")
210 | ∷ (0 ∶ 9 , COL)
211 | ∷ (0 ∶ 11 , ID "`a")
212 | ∷ (0 ∶ 14 , ARR)
213 | ∷ (0 ∶ 16 , ID "`a")
214 | ∷ (0 ∶ 18 , RPAR)
215 | ∷ []
216 | _ = refl
217 |
218 | _ : parse "def ida : 'a → 'a = λ x . x
219 | \ \def idb : 'a → 'a = λ y . ida y
220 | \ \have idb"
221 | ≡ (inj₂ (((start , "ida" , _ , `λ "x" ↦ (`- `var (0 ∶ 27) "x"))
222 | ∷ (record { line = 0 ; offset = 27 } , "idb" , _ , `λ "y" ↦ `- (`var _ "ida" `$ (`- `var (1 ∶ 31) "y")))
223 | ∷ []
224 | ) , `var (2 ∶ 5) "idb"
225 | ))
226 | _ = refl
227 |
228 | _ : parse "def thd : ('a * 'b * 'c) -> 'c = λ p. fst (fst p)
229 | \ \have thd"
230 | ≡ inj₂ (((start , "thd" , (α "a" ⊗ (α "b" ⊗ α "c")) ⇒ α "c"
231 | , `λ "p" ↦ `- `fst `fst `var (0 ∶ 48) "p"
232 | )
233 | ∷ []
234 | )
235 | , `var (1 ∶ 5) "thd"
236 | )
237 | _ = refl
238 |
239 | _ : parse "def swap : ('a * 'b) → ('b * 'a) = λp. (snd p, fst p, snd p)
240 | \ \have swap"
241 | ≡ inj₂ ((start , "swap" , (α "a" ⊗ α "b") ⇒ (α "b" ⊗ α "a")
242 | , (0 ∶ 35) >`λ "p" ↦ ((`- `snd `var (0 ∶ 44) "p")
243 | `, ((`- `fst `var (0 ∶ 51) "p")
244 | `, (`- `snd `var (0 ∶ 58) "p")))
245 | )
246 | ∷ []
247 | , `var (1 ∶ 5) "swap"
248 | )
249 | _ = refl
250 |
251 | _ : tokenize "(λ x . x : `a → `a)"
252 | ≡ (start , LPAR)
253 | ∷ (0 ∶ 1 , LAM)
254 | ∷ (0 ∶ 3 , ID "x")
255 | ∷ (0 ∶ 5 , DOT)
256 | ∷ (0 ∶ 7 , ID "x")
257 | ∷ (0 ∶ 9 , COL)
258 | ∷ (0 ∶ 11 , ID "`a")
259 | ∷ (0 ∶ 14 , ARR)
260 | ∷ (0 ∶ 16 , ID "`a")
261 | ∷ (0 ∶ 18 , RPAR)
262 | ∷ []
263 | _ = refl
264 |
--------------------------------------------------------------------------------
/stlc/src/Pipeline.agda:
--------------------------------------------------------------------------------
1 | module Pipeline where
2 |
3 | open import Data.Product
4 | open import Data.String
5 | open import Data.Sum
6 | open import Data.List.Base as List
7 | import Data.List.NonEmpty as List⁺
8 | open import Data.List.All
9 | open import Data.List.All.Properties
10 | open import Data.List.Relation.Unary.All.Extras as Allₑ
11 | open import Text.Parser.Position
12 | open import Function
13 | open import Relation.Binary.PropositionalEquality
14 |
15 | open import var using (z; s)
16 | import environment as E
17 | open import Generic.Syntax using (`var)
18 | open import Generic.Semantics.Syntactic using (sub)
19 | open import Language; open Surface
20 | open import Types
21 | open import Parse
22 | open import Scopecheck
23 | open import Typecheck
24 | open import LetInline
25 | open import Eval
26 | open import Print
27 |
28 | open import Category.Monad
29 |
30 | open Compiler
31 |
32 | module _ where
33 |
34 | open RawMonad (Compiler.monad String)
35 |
36 | declarations : List (Position × String × Type String × Parsed Check) →
37 | ∀ {Γ} → Definitions Γ → Compiler String (∃ Definitions)
38 | declarations [] p = pure $ -, p
39 | declarations ((r , str , sig , decl) ∷ decls) p = do
40 | scoped ← scopecheck p decl
41 | σ ← liftState $ cleanupType sig
42 | typed ← ppCompiler $ liftResult $ type- Check _ scoped (map⁺ Allₑ.self) σ
43 | let x = r > str ∶ σ ≔ subst (Internal.Typed _) (eq^fromTyping _) typed
44 | declarations decls (p & x)
45 |
46 | declaration : ∀ {Γ} → Definitions Γ → Parsed Infer →
47 | Compiler String (∃ λ σ → Expression σ Γ)
48 | declaration {Γ} p d = do
49 | scoped ← scopecheck p d
50 | (σ , typed) ← ppCompiler $ liftResult $ type- Infer Γ scoped (map⁺ self)
51 | pure (σ , subst (Internal.Typed _) (eq^fromTyping _) typed)
52 |
53 | toProgram : String → Compiler String Program
54 | toProgram str = do
55 | (decls , expr) ← liftResult $ parse str
56 | (Γ , defs) ← declarations (List⁺.toList decls) []
57 | (σ , eval) ← declaration defs expr
58 | pure $ assuming defs have eval
59 |
60 | pipeline : String → Error String ⊎ (String × String × String)
61 | pipeline str = Compiler.run $ do
62 | (defs && eval) ← toProgram str
63 | let lets = toLets defs (toCheck eval)
64 | let unlets = let-inline lets
65 | let val = norm unlets
66 | rm ← Map.invert <$> getMap
67 | pure $ print lets rm
68 | , print unlets rm
69 | , print val rm
70 |
71 | open import Agda.Builtin.Equality
72 |
73 | _ : Compiler.run (toProgram "def id : 'a → 'a = λx. x
74 | \ \def deux : 'a → 'b → 'b = λx. λy.y
75 | \ \have id")
76 | ≡ inj₂ (assuming []
77 | & "id" ∶ α 0 ⇒ α 0 ≔ `λ `- `var z
78 | & "deux" ∶ α 0 ⇒ α 1 ⇒ α 1 ≔ `λ `λ `- `var z
79 | have `var (s z))
80 | _ = refl
81 |
82 | -- normalisation test
83 |
84 | _ : pipeline "def idh : ('a → 'a) → ('a → 'a) = λf.λx. f x
85 | \ \def id : ('a → 'a) = λx.x
86 | \ \have idh id"
87 | ≡ inj₂ ("let c = (λa.λb.a b : (`a → `a) → `a → `a) in \
88 | \let e = (λd.d : `a → `a) in \
89 | \c e"
90 | , "(λa.λb.a b : (`a → `a) → `a → `a) (λc.c : `a → `a)"
91 | , "λa.a")
92 | _ = refl
93 |
--------------------------------------------------------------------------------
/stlc/src/Print.agda:
--------------------------------------------------------------------------------
1 | module Print where
2 |
3 | open import Data.Bool using (true; false; if_then_else_; _∧_)
4 | open import Data.Nat as Nat
5 | import Data.Nat.Show as NShow
6 | open import Data.String
7 | open import Data.Char
8 | open import Data.Char.Unsafe
9 | open import Data.Product
10 | open import Data.Maybe
11 | open import Data.List.Base as List using ([])
12 | open import Function
13 |
14 | open import var
15 | open import environment
16 | import Generic.Semantics.Printing as Printing
17 |
18 | open import Language
19 | open Internal
20 |
21 | import Data.Map as M
22 | private
23 | module Map = M.Map Nat._≟_ String
24 | open Map using (Map)
25 |
26 | type : Type ℕ → Map → String
27 | type (α k) mp = maybe ("`" ++_) (NShow.show k) (Map.assoc k mp)
28 | type (σ@(α _) ⇒ τ) mp = type σ mp ++ " → " ++ type τ mp
29 | type (σ ⇒ τ) mp = "(" ++ type σ mp ++ ") → " ++ type τ mp
30 | type (σ@(α _) ⊗ τ) mp = type σ mp ++ " * " ++ type τ mp
31 | type (σ ⊗ τ) mp = "(" ++ type σ mp ++ ") * " ++ type τ mp
32 |
33 | print : ∀ {P mσ} → Internal P mσ [] → Map → String
34 | print t mp = Printing.print display t where
35 |
36 | display = Printing.mkD $ λ where
37 | (p , t `∶' σ) → "(" ++ t ++ " : " ++ type σ mp ++ ")"
38 | (p , f `$' t) → f ++ " " ++ parens? t
39 | (p , `fst' e) → "fst " ++ parens? e
40 | (p , `snd' e) → "snd " ++ parens? e
41 | (p , `λ' (x , b)) → "λ" ++ lookup x z ++ "." ++ b
42 | (p , a `,' b) → "(" ++ a ++ ", " ++ b ++ ")"
43 | (p , `let' e `in (x , b)) → "let " ++ lookup x z ++ " = " ++ e ++ " in " ++ b
44 | (p , `-' t) → t
45 |
46 |
47 | where parens? : String → String
48 | parens? t = let cs = toList t in
49 | if maybe′ ('(' ==_) true (List.head cs)
50 | ∧ maybe′ (')' ==_) true (List.head (List.reverse cs)) then t
51 | else if List.any isSpace cs then "(" ++ t ++ ")" else t
52 |
--------------------------------------------------------------------------------
/stlc/src/Scopecheck.agda:
--------------------------------------------------------------------------------
1 | module Scopecheck where
2 |
3 | open import Data.Product as Product
4 | open import Data.Nat
5 | open import Data.String
6 | open import Data.String.Unsafe as String
7 | open import Data.Maybe.Base using (Maybe; nothing; just; maybe′)
8 | open import Data.Sum.Base as Sum using (inj₁; inj₂; [_,_]′)
9 | open import Data.List as List using ([])
10 | open import Data.List.All as All using (All)
11 | open import Data.List.All.Properties
12 | open import Function
13 |
14 | open import Category.Monad
15 | open import Category.Monad.State
16 |
17 | open import Generic.Syntax
18 | open import Generic.AltSyntax
19 |
20 | open import Text.Parser.Position
21 |
22 | open import Language
23 | open Surface
24 | open import Types
25 |
26 | module _ where
27 |
28 | M = State (Map × ℕ)
29 | open RawMonadState (StateMonadState (Map × ℕ)) hiding (_⊗_)
30 |
31 | resolve : String → M ℕ
32 | resolve str = do
33 | (mp , gen) ← get
34 | case Map.assoc str mp of λ where
35 | (just n) → return n
36 | nothing → do
37 | put (Map.set str gen mp , suc gen)
38 | return gen
39 |
40 | cleanupType : Type String → M (Type ℕ)
41 | cleanupType (α str) = α <$> resolve str
42 | cleanupType (σ ⇒ τ) = _⇒_ <$> cleanupType σ ⊛ cleanupType τ
43 | cleanupType (σ ⊗ τ) = _⊗_ <$> cleanupType σ ⊛ cleanupType τ
44 |
45 | cleanupTerm : ∀ {i σ Γ} → Tm (surface String) i σ Γ → M (Scoped σ Γ)
46 | cleanupTerm (`var k) = return $ `var k
47 | cleanupTerm (r >[ t `∶ σ ]) = r >[_`∶_] <$> cleanupTerm t ⊛ cleanupType σ
48 | cleanupTerm (r >[ f `$ t ]) = r >[_`$_] <$> cleanupTerm f ⊛ cleanupTerm t
49 | cleanupTerm (r >`fst b) = r >`fst_ <$> cleanupTerm b
50 | cleanupTerm (r >`snd b) = r >`snd_ <$> cleanupTerm b
51 | cleanupTerm (r >`λ b) = r >`λ_ <$> cleanupTerm b
52 | cleanupTerm (r >[ a `, b ]) = r >[_`,_] <$> cleanupTerm a ⊛ cleanupTerm b
53 | cleanupTerm (r >`let e `in b) = r >`let_`in_ <$> cleanupTerm e ⊛ cleanupTerm b
54 | cleanupTerm (r >`- t) = r >`-_ <$> cleanupTerm t
55 |
56 | open RawMonad (Compiler.monad String)
57 | open Compiler
58 | open ScopeCheck
59 |
60 | scopecheck : ∀ {Σ m} (p : Definitions Σ) → Parsed m →
61 | Compiler String (Scoped m (modes p))
62 | scopecheck p r = do
63 | let scopeError = uncurry At_OutOfScope_
64 | t ← liftResult $ Sum.map₁ scopeError $ scopeCheck eqdecMode _ _ (names p) r
65 | liftState $ cleanupTerm t
66 |
--------------------------------------------------------------------------------
/stlc/src/System/Environment.agda:
--------------------------------------------------------------------------------
1 | module System.Environment where
2 |
3 | open import Data.List.Base using (List)
4 | open import Data.String.Base using (String)
5 |
6 | import IO.Primitive as Prim
7 | open import IO
8 |
9 | private
10 | postulate
11 | primGetArgs : Prim.IO (List String)
12 |
13 | {-# FOREIGN GHC import qualified System.Environment as Env #-}
14 | {-# FOREIGN GHC import qualified Data.Text as T #-}
15 | {-# COMPILE GHC primGetArgs = fmap (fmap T.pack) Env.getArgs #-}
16 |
17 | getArgs : IO (List String)
18 | getArgs = lift primGetArgs
19 |
--------------------------------------------------------------------------------
/stlc/src/Typecheck.agda:
--------------------------------------------------------------------------------
1 | module Typecheck where
2 |
3 | open import Data.Product as Prod
4 | open import Data.Nat as ℕ using (ℕ; _≟_)
5 | open import Data.List as List hiding (lookup ; fromMaybe)
6 | open import Data.List.All as All hiding (lookup)
7 | import Data.List.All.Properties as Allₚ
8 | open import Data.List.Relation.Unary.All.Extras as Allₑ
9 | open import Data.List.Any using (here; there)
10 | open import Data.List.Membership.Propositional
11 | open import Relation.Binary.PropositionalEquality as P using (_≡_; refl)
12 | open import Data.Maybe hiding (fromMaybe; All)
13 | open import Function
14 |
15 | open import Category.Monad
16 |
17 | open import var hiding (_<$>_)
18 | open import varlike using (base; vl^Var)
19 | open import environment hiding (_<$>_)
20 | open import Generic.Syntax
21 | open import Generic.Semantics
22 |
23 | open import Text.Parser.Position
24 |
25 | open import Language
26 | open Surface
27 | open Internal
28 | open import Types
29 |
30 | Typing : List Mode → Set
31 | Typing = All (const (Type ℕ))
32 |
33 | fromTyping : ∀ ms → Typing ms → List (Mode × Type ℕ)
34 | fromTyping ms = Allₑ.toList
35 |
36 | eq^fromTyping :
37 | ∀ Γ → fromTyping (List.map (const Infer) Γ) (Allₚ.map⁺ Allₑ.self)
38 | ≡ List.map (Infer ,_) Γ
39 | eq^fromTyping [] = refl
40 | eq^fromTyping (σ ∷ Γ) = P.cong (_ ∷_) (eq^fromTyping Γ)
41 |
42 | Elab : (Mode × Type ℕ) ─Scoped → Mode × Type ℕ → (ms : List Mode) → Typing ms → Set
43 | Elab T σ ms Γ = T σ (fromTyping ms Γ)
44 |
45 | data Var- : Mode ─Scoped where
46 | `var : ∀ {ms} → (infer : ∀ Γ → Σ[ σ ∈ Type ℕ ] Elab Var (Infer , σ) ms Γ) →
47 | Var- Infer ms
48 |
49 | var0 : ∀ {ms} → Var- Infer (Infer ∷ ms)
50 | var0 = `var (λ where (σ ∷ _) → σ , z)
51 |
52 | var : ∀ {m} (Σ : List (Type ℕ)) → let Γ = List.map (const Infer) Σ in
53 | Var m Γ → Var- m Γ
54 | var [] ()
55 | var (m ∷ Σ) z = var0
56 | var (m ∷ Σ) (s v) with var Σ v
57 | ... | `var infer = `var (λ where (σ ∷ Γ) → Prod.map₂ s $ infer Γ)
58 |
59 | toVar : ∀ {m : Mode} {ms} → m ∈ ms → Var m ms
60 | toVar (here refl) = z
61 | toVar (there v) = s (toVar v)
62 |
63 | fromVar : ∀ {m : Mode} {ms} → Var m ms → m ∈ ms
64 | fromVar z = here refl
65 | fromVar (s v) = there (fromVar v)
66 |
67 | coth^Typing : ∀ {ms ns} → Typing ns → Thinning ms ns → Typing ms
68 | coth^Typing Δ ρ = All.tabulate (λ x∈Γ → All.lookup Δ (fromVar (lookup ρ (toVar x∈Γ))))
69 |
70 | lookup-fromVar : ∀ {m ms} Δ (v : Var m ms) →
71 | Var (m , All.lookup Δ (fromVar v)) (fromTyping ms Δ)
72 | lookup-fromVar (_ ∷ _) z = z
73 | lookup-fromVar (_ ∷ _) (s v) = s (lookup-fromVar _ v)
74 |
75 | erase^coth : ∀ ms {m σ ns} Δ (ρ : Thinning ms ns) →
76 | Var (m , σ) (fromTyping ms (coth^Typing Δ ρ)) → Var (m , σ) (fromTyping ns Δ)
77 | erase^coth [] Δ ρ ()
78 | erase^coth (m ∷ ms) Δ ρ z = lookup-fromVar Δ (lookup ρ z)
79 | erase^coth (m ∷ ms) Δ ρ (s v) = erase^coth ms Δ (select extend ρ) v
80 |
81 | th^Var- : ∀ {m} → Thinnable (Var- m)
82 | th^Var- (`var infer) ρ = `var λ Δ →
83 | let (σ , v) = infer (coth^Typing Δ ρ) in
84 | σ , erase^coth _ Δ ρ v
85 |
86 | isArrow : (σ⇒τ : Type ℕ) → Maybe (Σ[ στ ∈ Type ℕ × Type ℕ ] σ⇒τ ≡ uncurry _⇒_ στ)
87 | isArrow (σ ⇒ τ) = just ( _ , refl)
88 | isArrow _ = nothing
89 |
90 | isProduct : (σ⊗τ : Type ℕ) → Maybe (Σ[ στ ∈ Type ℕ × Type ℕ ] σ⊗τ ≡ uncurry _⊗_ στ)
91 | isProduct (σ ⊗ τ) = just ( _ , refl)
92 | isProduct _ = nothing
93 |
94 | Type- : Mode → List Mode → Set
95 | Type- Infer Γ = ∀ γ → Result ℕ (∃ λ σ → Typed (Infer , σ) (fromTyping Γ γ))
96 | Type- Check Γ = ∀ γ σ → Result ℕ (Typed (Check , σ) (fromTyping Γ γ))
97 |
98 | open RawMonad (Result.monad ℕ) hiding (return)
99 | open Result
100 |
101 | Typecheck : Sem (surface ℕ) Var- Type-
102 | Sem.th^𝓥 Typecheck = th^Var-
103 | Sem.var Typecheck = λ where (`var infer) γ → pure $ map₂ `var (infer γ)
104 | Sem.alg Typecheck = λ where
105 | (r >[ t `∶' σ ]) γ → (-,_ ∘ (r >[_`∶ σ ])) <$> t γ σ
106 | (r >[ f `$' t ]) γ → do
107 | (σ⇒τ , f′) ← f γ
108 | ((σ , τ) , refl) ← fromMaybe (At r NotAnArrow σ⇒τ) (isArrow σ⇒τ)
109 | t′ ← t γ σ
110 | pure $ -, r >[ f′ `$ t′ ]
111 | (r >`fst' e) γ → do
112 | (σ⊗τ , e′) ← e γ
113 | ((σ , τ) , refl) ← fromMaybe (At r NotAProduct σ⊗τ) (isProduct σ⊗τ)
114 | pure $ -, r >`fst e′
115 | (r >`snd' e) γ → do
116 | (σ⊗τ , e′) ← e γ
117 | ((σ , τ) , refl) ← fromMaybe (At r NotAProduct σ⊗τ) (isProduct σ⊗τ)
118 | pure $ -, r >`snd e′
119 | (r >`λ' b) γ σ⇒τ → do
120 | ((σ , τ) , refl) ← fromMaybe (At r NotAnArrow σ⇒τ) (isArrow σ⇒τ)
121 | b′ ← b extend (ε ∙ var0) (σ ∷ γ) τ
122 | pure $ r >`λ b′
123 | (r >[ a `,' b ]) Γ σ⊗τ → do
124 | ((σ , τ) , refl) ← fromMaybe (At r NotAProduct σ⊗τ) (isProduct σ⊗τ)
125 | a′ ← a Γ σ
126 | b′ ← b Γ τ
127 | pure $ r >[ a′ `, b′ ]
128 | (r >`let' e `in b) γ τ → do
129 | (σ , e′) ← e γ
130 | b′ ← b extend (ε ∙ var0) (σ ∷ γ) τ
131 | pure $ r >`let e′ `in b′
132 | (r >`-' t) γ σ → do
133 | (τ , t′) ← t γ
134 | refl ← fromMaybe (At r Expected σ Got τ) (decToMaybe $ eqdecType ℕ._≟_ τ σ)
135 | pure $ r >`- t′
136 |
137 | type- : ∀ (m : Mode) (Σ : List (Type ℕ)) → let Γ = List.map (const Infer) Σ in
138 | Scoped m Γ → Type- m Γ
139 | type- Infer Σ t γ = Sem.sem Typecheck (pack (var Σ)) t γ
140 | type- Check Σ t γ σ = Sem.sem Typecheck (pack (var Σ)) t γ σ
141 |
--------------------------------------------------------------------------------
/stlc/src/Types.agda:
--------------------------------------------------------------------------------
1 | module Types where
2 |
3 | import Level as L
4 | open import Category.Monad
5 | open import Category.Monad.State
6 | open import Data.String as String using (String; _++_)
7 | import Data.String.Unsafe as String
8 | open import Data.Product as Prod using (_×_; _,_; proj₁)
9 | open import Data.List.Base using ([])
10 | open import Data.Nat as ℕ using (ℕ)
11 | open import Data.Maybe.Base using (Maybe; just; nothing; maybe′)
12 | import Data.Maybe.Categorical as MC
13 | open import Data.Sum.Base as Sum
14 | import Data.Sum.Categorical.Left as Sumₗ
15 | open import Function
16 |
17 | open import Text.Parser.Position as Position using (Position)
18 |
19 | open import Language hiding (show)
20 |
21 | --------------------------------------------------------------------------------
22 | -- Error type
23 |
24 | data Error (A : Set) : Set where
25 | At_ParseError : Position → Error A
26 | At_OutOfScope_ : Position → String → Error A
27 | At_Expected_Got_ : Position → Type A → Type A → Error A
28 | At_NotAnArrow_ : Position → Type A → Error A
29 | At_NotAProduct_ : Position → Type A → Error A
30 | At_ErrorWhenPrintingError : Position → Error A
31 |
32 | show : Error String → String
33 | show err = case err of λ where
34 | (At p ParseError) → at p "parse error."
35 | (At p OutOfScope x) → at p $ x ++ " is out of scope."
36 | (At p Expected σ Got τ) → at p $ "expected type " ++ Language.show σ
37 | ++ " but got type " ++ Language.show τ ++ " instead."
38 | (At p NotAnArrow σ) → at p $ "the type " ++ Language.show σ ++ " is not an arrow type."
39 | (At p NotAProduct σ) → at p $ "the type " ++ Language.show σ ++ " is not a product type."
40 | (At p ErrorWhenPrintingError) → at p $ "error when printing error."
41 |
42 | where at : Position → String → String
43 | at p str = "At " ++ Position.show p ++ ": " ++ str
44 |
45 | Result : Set → Set → Set
46 | Result E = Sumₗ.Sumₗ (Error E) L.zero
47 |
48 | module Result where
49 |
50 | monad : ∀ E → RawMonad (Result E)
51 | monad E = Sumₗ.monad (Error E) L.zero
52 |
53 | fail : ∀ {E A} → Error E → Result E A
54 | fail = inj₁
55 |
56 | fromMaybe : ∀ {E A} → Error E → Maybe A → Result E A
57 | fromMaybe = maybe′ inj₂ ∘′ fail
58 |
59 | -- Data.AVL is not quite usable with String at the moment IIRC
60 | -- So instead I'm using a quick and dirty representation
61 | import Data.Map as M
62 |
63 | private
64 | module RMap = M.Map ℕ._≟_ String
65 | module Map = M.Map String._≟_ ℕ
66 | open Map using (Map; RMap) public
67 |
68 | Compiler : Set → Set → Set
69 | Compiler E = State (Map × ℕ) ∘′ (Error E ⊎_)
70 |
71 | module Compiler where
72 |
73 | monad : ∀ E → RawMonad (Compiler E)
74 | monad E = Sumₗ.monadT (Error E) L.zero (StateMonad _)
75 |
76 | liftResult : ∀ {E A} → Error E ⊎ A → Compiler E A
77 | liftResult = _,_
78 |
79 | liftState : ∀ {E A} → State (Map × ℕ) A → Compiler E A
80 | liftState = let open RawMonad (StateMonad _) in inj₂ <$>_
81 |
82 | getMap : ∀ {E} → Compiler E Map
83 | getMap = liftState $ λ where s@(mp , n) → (mp , s)
84 |
85 | fail : ∀ {E A} → Error E → Compiler E A
86 | fail = liftResult ∘′ Result.fail
87 |
88 | fromMaybe : ∀ {E A} → Error E → Maybe A → Compiler E A
89 | fromMaybe e ma = liftResult $ Result.fromMaybe e ma
90 |
91 | run : ∀ {E A} → Compiler E A → Result E A
92 | run m = proj₁ (m ([] , 0))
93 |
94 |
95 | module PrettyPrint where
96 |
97 | open RawMonad (MC.monad {L.zero}) using (_<$>_; _⊛_)
98 |
99 | ppType : RMap → Type ℕ → Maybe (Type String)
100 | ppType rm (α k) = α <$> RMap.assoc k rm
101 | ppType rm (σ ⊗ τ) = _⊗_ <$> ppType rm σ ⊛ ppType rm τ
102 | ppType rm (σ ⇒ τ) = _⇒_ <$> ppType rm σ ⊛ ppType rm τ
103 |
104 | ppError : RMap → Error ℕ → Error String
105 | ppError rm err = case err of λ where
106 | (At p ParseError) → At p ParseError
107 | (At p OutOfScope x) → At p OutOfScope x
108 | (At p Expected σ Got τ) →
109 | case At p Expected_Got_ <$> ppType rm σ ⊛ ppType rm τ of λ where
110 | nothing → At p ErrorWhenPrintingError
111 | (just err) → err
112 | (At p NotAnArrow σ) →
113 | case At p NotAnArrow_ <$> ppType rm σ of λ where
114 | nothing → At p ErrorWhenPrintingError
115 | (just err) → err
116 | (At p NotAProduct σ) →
117 | case At p NotAProduct_ <$> ppType rm σ of λ where
118 | nothing → At p ErrorWhenPrintingError
119 | (just err) → err
120 | (At p ErrorWhenPrintingError) → At p ErrorWhenPrintingError
121 |
122 |
123 | ppCompiler : ∀ {A} → Compiler ℕ A → Compiler String A
124 | ppCompiler m = let open RawMonadState (StateMonadState _) in do
125 | v ← m
126 | mp ← proj₁ <$> get
127 | pure $ Sum.map₁ (PrettyPrint.ppError (Map.invert mp)) v
128 |
--------------------------------------------------------------------------------
/stlc/src/stlc.agda-lib:
--------------------------------------------------------------------------------
1 | name: stlc
2 | include: .
3 | depend: standard-library
4 | , agdarsec
5 | , generic-syntax
6 |
--------------------------------------------------------------------------------
/travis/install_agda.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | AGDA_VERSION=2.5.4.2
3 |
4 | if ! type "agda" > /dev/null || [ ! `agda -V | sed "s/[^2]*//"` = "$AGDA_VERSION" ]; then
5 | cabal update
6 | cabal install alex happy cpphs --force-reinstalls
7 | cabal install Agda-"$AGDA_VERSION" --force-reinstalls
8 | fi
9 |
10 | mkdir -p $HOME/.agda
11 | cp libraries-"$AGDA_VERSION" $HOME/.agda/
12 | cd $HOME/.agda/
13 | # install stdlib
14 | wget https://github.com/agda/agda-stdlib/archive/v0.17.tar.gz
15 | tar -xvzf v0.17.tar.gz
16 | # install agdarsec
17 | wget https://github.com/gallais/agdarsec/archive/v0.3.0.tar.gz
18 | tar -xvzf v0.3.0.tar.gz
19 | # install generic-syntax
20 | wget https://github.com/gallais/generic-syntax/archive/v0.2.tar.gz
21 | tar -xvzf v0.2.tar.gz
22 |
--------------------------------------------------------------------------------
/travis/libraries-2.5.4.2:
--------------------------------------------------------------------------------
1 | $HOME/.agda/agda-stdlib-0.17/standard-library.agda-lib
2 | $HOME/.agda/agdarsec-0.3.0/agdarsec.agda-lib
3 | $HOME/.agda/generic-syntax-0.2/src/generic-syntax.agda-lib
4 |
--------------------------------------------------------------------------------