Alfa is a WYSIWYG proof editor. It allows you to, interactively and incrementally, define theories (axioms and inference rules), formulate theorems and construct proofs of the theorems. All steps in the proof construction are immediately checked by the system and no erroneous proofs can be constructed. The logical framework used is Agda, implemented by Catarina Coquand, based on work by Thierry Coquand. It is a version of Per Martin-Löf's Type Theory.
Alternatively, you can view Alfa as a syntax-directed editor for a small purely functional programming language with a type system that provides dependent types. In fact, the functional language is very similar to the language Cayenne by Lennart Augustsson.
This document describes how to use the WYSIWYG editor, but it does not explain Type Theory.
Before you start playing with Alfa, please note that Alfa is currently under development and that you are using a test version only. Beware that Alfa
Fore more details, see Limitations of the current version.
Alfa is started with the command
alfa
[ rtflags ] [ -
flags ]
where
-H
heapsizeM
, which
sets the heap size to heapsize megabytes. The default
is 30 (25 in older versions), which is enough for editing small
documents. A 30MB heap is too big if you run Alfa on a
computer with 32MB of RAM or less.
-
preceding these flags.
Alfa can be stopped by selecting the Quit command from the File menu.
When Alfa is started it opens two windows:
Closing the main editing window is the same as quitting Alfa. Closing the menu window causes it to disappear, but you can get it back with a command in the Utils menu.
The size of the info display at the bottom of the main editing window is adjusted automatically to fit the currently displayed message, but you can also resize it manually by dragging the separating line.
The commands shown in the various menus can be executed by selecting them using the mouse, but most of them also have keyboard shortcuts that can be used instead.
[ ]
.
They are one or more keys long and should be entered
without pressing a modifier key like
Meta or Control.
Alfa allows you to edit a document, which is a sequence of declarations. A declaration is a group of (possibly) mutually recursive definitions. A definition associates a name with a type and a value of that type (x = a : A). (The syntax and meaning of expressions follow Agda's definitions and is not covered in this document.) The names introduced in a declaration are in scope in that declaration and following declarations.
The two most common editing operations are probably adding declarations and filling in place holders (instantiating meta variables). The former is explained below. The latter can be done in many ways, as noted on the quick reference page Top 10 ways to fill in a place holder.
You can add a new declaration to the end of the document by selecting the command New Declaration from the Edit menu in the editing window. You will then have to enter the names to be defined in the declaration in a pop-up window. The names should be separated by commas. You can also include the names of formal parameters in the list.
You can also add declarations in arbitrary places in the document by clicking in the empty space just above or below an existing declaration and then selecting the command Insert New Declaration in the menu window and proceeding as above. (Note: this way of adding declaration is less efficient since is not directly supported in the proof engine and requires the entire module to be rechecked.)
Provided the names defined in a declaration are not in use, the declaration can be deleted by selecting it and executing the Delete operation (which is shown in menu window). You can actually delete a declaration, even if the names are in use. Affected declaration will then be marked with an error bar.
Most editing is done by selecting a part of the document, usually a place holder, declaration or expression, and performing an editing operation on it. Applicable editing operations are displayed in the menu window. They can be executed by clicking on them or by typing the key combination shown in square brackets. (Note: the keyboard shortcuts are generated dynamically, so the same alternative may be assigned different keys in different contexts.) Further editing operations are provided in the Edit menu.
Note: some of the commands in the Edit menu may not be applicable, but there is no visual feedback for this in the current version.
By clicking at some point in the editing window you select the smallest syntactic unit containing that point. You can also use the following keys:
Cut-and-Paste editing works in much the same way as in other programs.
The currently selected part of the document can be copied to the (invisible) clipboard by executing the Copy command in the Edit menu. It can then be pasted in other places in the document. It can also be pasted in other X Windows programs, e.g., emacs, usually by pressing the middle mouse button (in emacs you can also use C-y). When a place holder is selected and the clipboard contains an expression of a suitable type, the place holder can be replaced with the expression by executing the Paste command in the Edit menu. A syntax error may occur if the clipboard contains some text (from a text editor) that does not form a syntactically correct expression.
You can paste a declaration when the empty space immediately above or below a declaration is selected and the clipboard contains a declaration.
You can also paste on top of existing expressions and declarations. If a type error occurs, you get an error bar.
You add new constructors to an existing data
type by
selecting the data expression and picking the command Add
constructor from the menu window. After this, you probably
also need to add branches for the new constructors in some case
expressions. This is done in the same way, i.e., select the
case
expression and pick the command Add
branch from the menu window.
The type checker may not accept case expression that aren't exhaustive, so adding a constructor to a data type may give rise to an error, causing declarations containing affected case expressions to be marked with an error bar. It is still possible to add a branch for the new constructor.
It is also possible to delete branches from
case
expressions and constructors from data
types. To do this, select the branch or constructor and pick the
Delete command from the menu window (or the
Edit menu). Deleting a constructor that is still in
use somewhere will cause affected declarations to be
marked as erroneous.
In some situations, e.g., when using the Give
command
and when constructing case expressions, you have to enter expressions
as text. The syntax to use in these cases is the same syntax Alfa uses
for storing documents in files.
(See the documentaton of Agda for details.)
This means for example that constructors should be suffixed with
@_
and that you can not leave out hidden arguments. You
can use place holders (?
or {| |}
) for
subexpressions you don't want to fill in.
Alfa currently provides the following ways for the user to influence the layout:
Terms in the monomorphic type theory often contain a lot of redundant type information. This type information is often inferred by the proof engine and does not have to be filled in by the user. The argument hiding mechanism is provided as a way of hiding some redundant information and thereby making the terms smaller and more readable.
You can set the number of hidden arguments for an identifer as described below. In expressions where an identifier with n hidden arguments is applied to some arguments, the first n arguments will be invisible. (In earlier versions of Alfa, they were represented by a °, allowing you to see that there was something hidden.)
Note that argument hiding is a lexical property of an identifier and is not connected to the scope of a certain binding.
The View menu contains commands for switching on and off the argument hiding mechanism.
As an example of the effect of argument hiding, consider the definition of the list function map:
Without argument hiding | With 2 hidden arguments |
---|---|
The layout options for an identifier can be edited by clicking on a binding occurence of the identifier and choosing the command Change layout options shown in the menu window. This pops up a window where you can change the various options.
The layout options show in this window, from top to bottom are:
Nonfix | Infix | Postfix |
---|---|---|
op | op | op |
op x | (x op) | x op |
op x y | x op y | (x op) y |
op x y z | (x op y) z | (x op) y z |
Forall (\(x::A)->B x)
, could appear as
.
The domain of quantification can be shown, as in this example,
or be hidden.
f a b c
to be displayed as
b | |
f | c |
a |
f a b (\ i -> c)
to be displayed as
b | |
f | c |
i=a |
_
characters in
the name of the function (or the Display As string, if
given). For example, the application
if_then_else_ x y z
would be displayed as
if x then y else z
It is also possible to use digits to refer to arguments at specific positions. For example, by changing the Display As string for the above function to
2 if 1, 3 otherwise
the same application would be displayed as
y if x, z otherwise
The View menu contains commands for switching on and off compact notation. In the current version, compact notation means that function types and lambda expressions are abbreviated:
Full notation | Compact notation |
---|---|
(a:A) -> (b:B) -> C | (a:A,b:B) -> C |
(a:A) -> (b:A) -> C | (a,b:A) -> C |
\ x -> \ y -> e | \ x y -> e |
It also causes nested case expressions to be displayed in a more compact way. Definitions where the right hand side is a case expression is displayed in an equational style. Nested case expressions are displayed as nested patterns.
Normal | Compact |
---|---|
Bug warning: some editing operations don't work properly when compact notation is in use, so you might want to turn it off temporarily. For example, if you change (a,b:A)->C to (a,b:B)->C you will see (a,b:B)->C, but you will get (a:B,b:A)->C.
The command Evaluate Expressions
in the
Utils
menu pops up a window where you can enter
expressions to be evaluated. The expressions have to entered as text
(as explained above). When a place holder is selected,
the expressions will be evaluated in the context of that place
holder. Otherwise they will be evaluated in the top level context
(i.e., all identifiers defined on the top level are in scope).
Note: there is a termination test, so if you try to evaluate an expression that doesn't terminate, or one that requires too many computation steps, you will get an error message.
The arrow buttons in this window allow you to step back and forth in the evaluation (the < and > buttons) or go directly to the original form and the normal form of the expression (the << and >> buttons).
Since Alfa is a syntax directed editor, it is not possible to construct syntactically incorrect documents. However, text representing expressions or other syntactic entities can of course contain errors and can enter the system in the following ways:
Everything entered into Alfa is immediately type checked, so it is usually impossible to create type incorrect documents. However, there are some cases when editing operations that lead to type errors are allowed:
When a declaration is in the unchecked state, only limited editing operations are available inside it. In particular, you can not see the type of place holders, and things you fill in aren't type checked. After making some changes, you can use the command Check Again to have the type checker re-check the declaration and, if the error has been corrected, return it to the normal, type checked state.