()
(kinda like False
in
Coq)
tt
: not exactly unit type as in Coq??. It's like the
I
constructor (of True
type) in Coq.public
in open import Universes public
allows other module importing this module to access what's imported here
Export Require Import
in Coqλ x -> body
3 * 4
is fine, but 3*4
isn't.A -> B -> C
is
A -> (B -> C)
:
in type annotations
zero: ℕ
and zero :ℕ
give parse error,
zero : ℕ
doesn't.Set
in Agda is like Type
in Coq
Type = Set
.;{}()@"
_|_
can't be used because it is used for
with
--without-K
and --safe
seems like
not-so-good-to-use flags.
--safe
option 'to avoid possible misuses of certain
features which could lead to logical inconsistencies' ʳ--cubical
: implements a computational interpretation of
HoTT.
postulate
: like Axiom
in Coq
\ x -> x
open import Data.List using ([]; [_]; _++_; List; sum)
open import Data.Nat using (ℕ; _+_)
open import Data.Bool
mutual
keywordExample from here:
mutual
data ty-ctx : Set where
: ty-ctx
ε _,-_ : (Δ : ty-ctx) → defn Δ → ty-ctx
data defn : ty-ctx → Set where
: ∀ {Δ} → ty Δ → defn Δ
synonym : ∀ {Δ} → ty Δ → defn Δ
newtype
data ty : ty-ctx → Set where
: ∀ {Δ τ} → ty Δ → ty (Δ ,- τ)
wk : ∀ {Δ τ} → ty (Δ ,- τ)
defd : ∀ {Δ} → ty Δ
bit _⇒_ : ∀ {Δ} → ty Δ → ty Δ → ty Δ
https://agda.readthedocs.io/en/latest/language/record-types.html
.fieldname
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
: A
fst : B
snd
: Pair A B geta
Level
lzero: Level
: lowest levellsuc: Level -> Level
: Next level_⊔_: Level -> Level -> Level
: Least upper bound
of 2 levelsSet
: Like Type
in Coq
Set
: Set0Set₁
: Set ∈ Set₁ ??Set₂
: Set₁ ∈ Set₂ ??0ℓ
: Level zero
Example from docs:
data _×_ {n m : Level} (A : Set n) (B : Set m) : Set (n ⊔ m) where
_,_ : A → B → A × B
Example import:
open import Level using (0ℓ) renaming (suc to lsuc)
Kinds
Setω
: Like type of types(n : Level) → Set n
is a type, but it doesn't
have a type without Setω
.{-# OPTIONS --cubical #-}
--without-k
disables Streicher's axiom (aka Axiom K),
"which we don't want for univalent mathematics"
export LC_ALL=C.UTF-8
(locale found
with locale -a
) beforehand.
DBT: Why the 'cubical' in cubical type theory?
Agda | Cubical |
---|---|
Set | Type |
Setω | Typeω |
lzero | ℓ-zero |
lsuc | ℓ-suc |
⊔ | ℓ-max |
From Cubical/Core/Primitives.agda
.
I
)I : IUniv
, where IUniv
is a special sort
(used to be Setω
in earlier versions of cubical ??)
I
valuesi : I
is indicative of i ∈ [0.0, 1.0]
i0
) and 1.0 (i1
) are the end
points of the intervalneg i
: symmetry
1.0 - x
for a given x
.Definition | Notation |
---|---|
min ia ib |
ia ∧ ib |
max ia ib |
ia ∨ ib |
neg i |
~i |
A
is represented with a function of
type I -> A
Path A a b
: Type of paths between a
and
b
A : Type
, a b : A
Equality x ≡ y
'consists of a path
p : I -> A
such that p i0 == x
and
p i1 == y
.
==
is definitional equalityPathP
is the primitive notion, not Path
(_≡_
)
postulate
.postulate
: ∀ {ℓ} (A : I -> Set ℓ) -> A i0 -> A i1 -> Set ℓ PathP
WARNING!: Each agda version will work with only a specific version of standard-library.
Standard library need to be installed separately.
—
~/.agda/defaults
: list of agda
libraries loaded by default
~/.agda/libraries
~/.agda/libraries
: list of paths
complete paths to agda-lib files of packages (including the agda-lib
file name with extension)AGDA_DIR
in unix: ~/.agda
-- ~/.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
_<ᵇ_
: a boolean function_<_
: in 'prop-world'open import Data.Bool
open import Data.Nat
: Bool
b = Data.Nat._<ᵇ_ 1 2 b
https://agda.readthedocs.io/en/latest/language/foreign-function-interface.html
agda --compile input.agda
agda --js input.agda
—
{-# COMPILE GHC <Name> as <HaskellName> #-}
{-# COMPILE GHC <Name> = type <HaskellType> #-}
{-# COMPILE GHC <Name> = data <HaskellData> (<HsCon1> | .. | <HsConN>) #-}
{-# COMPILE GHC Unit = data () (()) #-}
{-# COMPILE GHC <Name> = <HaskellCode> #-}
{-# COMPILE GHC putStr = type Data.Text.IO.putStr #-}
{-# COMPILE GHC agdaName as agdaNameInHaskell #-}
JS
instead of
GHC
.{-# FOREIGN GHC import Text.Parsec #-}
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
: Set
String
{-# BUILTIN STRING String #-}
postulate
: Set → Set
IO
{-# BUILTIN IO IO #-}
{-# COMPILE GHC IO = type IO #-}
postulate
: String → IO Unit
putStr
{-# COMPILE GHC putStr = Data.Text.IO.putStr #-}
: IO Unit
main = putStr "Hello, World!" main
—
Compiled Haskell will be in a directory named
MAlonzo/
:
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
—
{-# BUILTIN NATURAL ℕ #-}
zero
)Int
(log₂ space)
instead of unary nat.{-# OPTIONS --exact-split #-}
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
: Type Nat
But this doesn't:
data Type: Set where
: Type
Nat {-
Missing type signature for data definition Type:
when scope checking the declaration
data Type: Set where
Nat : Type
-}
https://wiki.portal.chalmers.se/agda/Main/AgdaVsCoq
False type:
data 𝟘 : Type where
Inductive False : Prop :=.
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 |
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:
Lower precedence value => higher precedence (like in Coq)
infixl
: left associativityinfixr
: right associativityinfix
: no associativity (parenthesis always
needed)Associativity of mixfix operators can be definied with one of the above three.
https://agda.readthedocs.io/en/v2.6.3/language/runtime-irrelevance.html
Needs --erasure
option
Syntax: @0
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 classes are just records.
open import Data.List using (List; []; _++_)
record Monoid (A : Set) : Set where
field
: A
mempty _<>_ : A -> A -> A
-- Make mempty and _<>_ available
open Monoid {{...}} public
instance
: {A : Set} -> Monoid (List A)
ListMonoid =
ListMonoid record {
= [];
mempty _<>_ = _++_
}
private instance
: limit the scope of instance to
current module{-# OPTIONS --rewriting #-}
REWRITE
pragma.
{-# REWRITE +zero +suc #-}
See:
C-c C-w: Show definition of a name
C-c C-c: Case split
C-c C-,: Show current goal info
C-c C-Space: Finish hole after filling it
C-c C-l: Type check buffer
?
and do C-c C-l
to insert a
holeC-c C-r: Refine
Right click on a typechecked part to go to its definiton
Find type of an expression: C-c C-d
Evaluate (find normal form) of an expression: C-c C-n
—
{!!}
can be used to place a hole manuallyC-c C-SPC
—
C-c C-f
C-c C-b
C-c C-n
C-c C-d
https://agda.readthedocs.io/en/latest/tools/emacs-mode.html#keybindings
—
M-x quail-show-key