Agda


General

Imports needed

Mutually recursive types

Example from here:

mutual
  data ty-ctx : Set where
    ε    : ty-ctx
    _,-_ : (Δ : ty-ctx)  defn Δ  ty-ctx

  data defn : ty-ctx  Set where
    synonym :  {Δ}  ty Δ  defn Δ
    newtype :  {Δ}  ty Δ  defn Δ

  data ty : ty-ctx  Set where
    wk    :  {Δ τ}  ty Δ  ty (Δ ,- τ)
    defd  :  {Δ τ}  ty (Δ ,- τ)
    bit   :  {Δ}    ty Δ
    __  :  {Δ}    ty Δ  ty Δ  ty Δ

Record type

https://agda.readthedocs.io/en/latest/language/record-types.html

record RecName : Set where
  field
    a :
    b : 𝔹

'Open' a record to bring their field names into default scope.

open RecName

Example from docs:

record Pair (A B : Set) : Set where
  field
    fst : A
    snd : B

geta : Pair A B

Levels

Example from docs:

data _×_ {n m : Level} (A : Set n) (B : Set m) : Set (n ⊔ m) where
   _,_ : A  B  A × B

Example import:

Kinds

Cubical

DBT: Why the 'cubical' in cubical type theory?

Conventions

Agda Cubical
Set Type
Setω Typeω
lzero ℓ-zero
lsuc ℓ-suc
ℓ-max

From Cubical/Core/Primitives.agda.

Interval type (I)

Definition Notation
min ia ib ia ∧ ib
max ia ib ia ∨ ib
neg i ~i

Path type

Equality x ≡ y 'consists of a path p : I -> A such that p i0 == x and p i1 == y.

PathP is the primitive notion, not Path (_≡_)

postulate
  PathP :  {} (A : I -> Set) -> A i0 -> A i1 -> Set

Resources

Standard library

Installation

WARNING!: Each agda version will work with only a specific version of standard-library.

Standard library need to be installed separately.

-- ~/.agda/libraries
--
-- (old one. nix channel 24.05)
-- /nix/store/dhyjk470gy6l53zrcf72jg5n390h028z-standard-library-2.0/standard-library.agda-lib
--
-- (nix channel 24.11)
/nix/store/1wfcxqkrqsy17ads3j1c3x42cgz6b04m-standard-library-2.1.1/standard-library.agda-lib

Bool

open import Data.Bool
open import Data.Nat

b : Bool
b = Data.Nat._<ᵇ_ 1 2

Misc

'Extraction'

https://agda.readthedocs.io/en/latest/language/foreign-function-interface.html

A complete example (modified from the one at an older version of docs):

module HelloWorld where

{-# FOREIGN GHC import Data.Text.IO #-}

data Unit : Set where
  unit : Unit

{-# COMPILE GHC Unit = data () (()) #-}

postulate
  String : Set

{-# BUILTIN STRING String #-}

postulate
  IO : Set  Set

{-# BUILTIN IO IO #-}
{-# COMPILE GHC IO = type IO #-}

postulate
  putStr : String  IO Unit

{-# COMPILE GHC putStr = Data.Text.IO.putStr #-}

main : IO Unit
main = putStr "Hello, World!"

Compiled Haskell will be in a directory named MAlonzo/:

Pragmas

Special comments.

Example:

{-# BUILTIN NATURAL ℕ #-}

agda

associates numbers with elements of the type. So 2 would implicitly mean suc (suc zero).

See: https://plfa.github.io/Naturals/#a-pragma

Space matters: a : Set vs a: Set

The space matters. Looks like if we do a: Set, a: will be considered a name.

For example, this works:

data Type : Set where
  Nat : Type

But this doesn't:

data Type: Set where
  Nat : Type
{-
Missing type signature for data definition Type:
when scope checking the declaration
  data Type: Set where
    Nat : Type
 -}

Coq vs agda

https://wiki.portal.chalmers.se/agda/Main/AgdaVsCoq

False type:

Following comparison is probably a bit too approximative…

Coq Agda
False Empty type
unit Unit type
tt tt Value of unit type
Type Set
Axiom postulate

Coq-like notations

Other than mixfix operators, syntax declarations can help.

syntax wrong x = x + x

-- Eg.agda:16,22: Malformed syntax declaration: syntax must use holes exactly once
-- x<ERROR>

syntax wrong x = id
-- Eg.agda:16,18: Malformed syntax declaration: syntax must use holes exactly once
-- id<ERROR>
syntax #_ f = Atom f

-- Eg.agda:17,20: Syntax declarations are allowed only for simple names (without holes)
-- f<ERROR>

For example, a unary operator in agda-unimathˡ:

infix 25 ¬_

¬_ : {l : Level} → UU l → UU l
¬ A = A → empty

See:

Precedence

Lower precedence value => higher precedence (like in Coq)

Associativity of mixfix operators can be definied with one of the above three.

Erasure

https://agda.readthedocs.io/en/v2.6.3/language/runtime-irrelevance.html

Haskell-like type alias

Just make it like a normal definition.

open import Data.Nat using (ℕ)
open import Data.Vec

BMatrix2D : ℕ -> ℕ -> Set
BMatrix2D r c = Vec (Vec Bool c) r

'Type class instance'

Type classes are just records.

open import Data.List using (List; []; _++_)

record Monoid (A : Set) : Set where
  field
    mempty : A 
    _<>_ : A -> A -> A

-- Make mempty and _<>_ available
open Monoid {{...}} public

instance
  ListMonoid : {A : Set} -> Monoid (List A)
  ListMonoid =
    record {
      mempty = [];
      _<>_ = _++_
    }

Rewriting

See:

Emacs

https://agda.readthedocs.io/en/latest/tools/emacs-mode.html#keybindings

Todo

Unicode

Misc

Doubts

Resources