The main way of defining data types in Agda is via inductive data types which are similar to algebraic data types in non-dependently typed programming languages. Here is a definition of Peano numbers in Agda: data ℕ : Set where zero : ℕ suc : ℕ → ℕ
Basically, it means that there are two ways to construct a value of type ℕ, representing a natural number. To begin, zero is a natural number, and if n is a natural number, then suc n, standing for the successor of n, is a natural number too. Here is a definition of the "less than or equal" relation between two natural numbers: data _≤_ : ℕ → ℕ → Set where z≤n : → zero ≤ n s≤s : → n ≤ m → suc n ≤ suc m
The first constructor, z≤n, corresponds to the axiom that zero is less than or equal to any natural number. The second constructor, s≤s, corresponds to an inference rule, allowing to turn a proof of n ≤ m into a proof of suc n ≤ suc m. So the value s≤s is a proof that one, is less than or equal to two. The parameters provided in curly brackets may be omitted if they can be inferred.
In core type theory, induction and recursion principles are used to prove theorems about inductive types. In Agda, dependently typed pattern matching is used instead. For example, natural number addition can be defined like this: add zero n = n add n = suc
This way of writing recursive functions/inductive proofs is more natural than applying raw induction principles. In Agda, dependently typed pattern matching is a primitive of the language; the core language lacks the induction/recursion principles that pattern matching translates to.
Metavariables
One of the distinctive features of Agda, when compared with other similar systems such as Coq, is heavy reliance on metavariables for program construction. For example, one can write functions like this in Agda: add : ℕ → ℕ → ℕ add x y = ?
? here is a metavariable. When interacting with the system in emacs mode, it will show the user expected type and allow them to refine the metavariable, i.e., to replace it with more detailed code. This feature allows incremental program construction in a way similar to tactics-based proof assistants such as Coq.
Proof automation
Programming in pure type theory involves a lot of tedious and repetitive proofs. Although Agda has no separate tactics language, it is possible to program useful tactics within Agda itself. Typically, this works by writing an Agda function that optionally returns a proof of some property of interest. A tactic is then constructed by running this function at type-checking time, for example using the following auxiliary definitions: data Maybe : Set where Just : A → Maybe A Nothing : Maybe A data isJust : Maybe A → Set where auto : ∀ → isJust Tactic : ∀ → isJust x → A Tactic Nothing Tactic auto = x
Given a function check-even : → Maybe that inputs a number and optionally returns a proof of its evenness, a tactic can then be constructed as follows: check-even-tactic : → isJust → Even n check-even-tactic = Tactic lemma0 : Even zero lemma0 = check-even-tactic auto lemma2 : Even lemma2 = check-even-tactic auto
The actual proof of each lemma will be automatically constructed at type-checking time. If the tactic fails, type-checking will fail. Additionally, to write more complex tactics, Agda has support for automation via reflection. The reflection mechanism allows one to quote program fragments into – or unquote them from – the abstract syntax tree. The way reflection is used is similar to the way Template Haskell works. Another mechanism for proof automation is proof search action in emacs mode. It enumerates possible proof terms, and if one of the terms fits the specification, it will be put in the meta variable where the action is invoked. This action accepts hints, e.g., which theorems and from which modules can be used, whether the action can use pattern matching, etc.
Termination checking
Agda is a total language, i.e., each program in it must terminate and all possible patterns must be matched. Without this feature, the logic behind the language becomes inconsistent, and it becomes possible to prove arbitrary statements. For termination checking, Agda uses the approach of the Foetus termination checker.
Standard library
Agda has an extensive de facto standard library, which includes many useful definitions and theorems about basic data structures, such as natural numbers, lists, and vectors. The library is in beta, and is under active development.
One of the more notable features of Agda is a heavy reliance on Unicode in program source code. The standard emacs mode uses shortcuts for input, such as \Sigma for Σ.
Backends
There are two compiler backends, MAlonzo for Haskell and one for JavaScript.