How do you represent terms of the CoC in Agda? - agda

Representing, for example, the STLC in Agda can be done as:
data Type : Set where
* : Type
_⇒_ : (S T : Type) → Type
data Context : Set where
ε : Context
_,_ : (Γ : Context) (S : Type) → Context
data _∋_ : Context → Type → Set where
here : ∀ {Γ S} → (Γ , S) ∋ S
there : ∀ {Γ S T} (i : Γ ∋ S) → (Γ , T) ∋ S
data Term : Context → Type → Set where
var : ∀ {Γ S} (v : Γ ∋ S) → Term Γ S
lam : ∀ {Γ S T} (t : Term (Γ , S) T) → Term Γ (S ⇒ T)
app : ∀ {Γ S T} (f : Term Γ (S ⇒ T)) (x : Term Γ S) → Term Γ T
(From here.) Trying to adapt this to the Calculus of Constructions, though, is problematic, because Type and Term are a single type. This means not only Context/Term must be mutually recursive, but also that Term must be indexed on itself. Here is an initial attempt:
data Γ : Set
data Term : Γ → Term → Set
data Γ where
ε : Γ
_,_ : (ty : Term) (ctx : Γ) → Γ
infixr 5 _,_
data Term where
-- ...
Agda, though, complains that Term isn't in scope on its initial declaration. Is it possible to represent it that way, or do we really need to have different types for Term and Type? I'd highly like to see a minimal/reference implementation of CoC in Agda.

This is known to be a very hard problem. As far as I'm aware there is no "minimal" way to encode CoC in Agda. You have to either prove a lot of stuff or use shallow encoding or use heavy (but perfectly sensible) techniques like quotient induction or define untyped terms first and then reify them into typed ones. Here is some related literature:
Functional Program Correctness Through Types, Nils Anders Danielsson -- the last chapter of this thesis is a formalization of a dependently typed language. This is a ton-of-lemmas-style formalization and also contains some untyped terms.
Type checking and normalisation, James Chapman -- the fifth chapter of this thesis is a formalization of a dependently typed language. It is also a ton-of-lemmas-style formalization, except many lemmas are just constructors of the corresponding data types. For example, you have explicit substitutions as constructors rather than as computing functions (the previous thesis didn't have those for types, only for terms, while this thesis have explicit substitutions even for types).
Outrageous but Meaningful Coincidences. Dependent type-safe syntax and evaluation, Conor McBride -- this paper presents a deep encoding of a dependent type theory that reifies a shallow encoding of the theory. This means that instead of defining substitution and proving properties about it the author just uses the Agda's evaluation model, but also gives a full syntax for the target language.
Typed Syntactic Meta-programming, Dominique Devriese, Frank Piessens -- untyped terms reified into typed ones. IIRC there were a lot of postulates in the code when I looked into it, as this is a framework for meta-programming rather than a formalization.
Type theory eating itself?, Chuangjie Xu & Martin Escardo -- a single file formalization. As always, several data types defined mutually. Explicit substitutions with explicit transports that "mimic" the behavior of the substitution operations.
EatEval.agda -- we get this by combining the ideas from the previous two formalizations. In this file instead of defining multiple explicit transports we have just a single transport which allows to change the type of a term to a denotationally equal one. I.e. instead of explicitly specifying the behavior of substitution via constructors, we have a single constructor that says "if evaluating two types in Agda gives the same results, then you can convert a term of one type to the another one via a constructor".
Type Theory in Type Theory using Quotient Inductive Type, Thorsten Altenkirch, Ambrus Kaposi -- this is the most promising approach I'd say. It "legalizes" computation at the type level via the quotient types device. But we do not yet have quotient types in Agda, they are essentially postulated in the paper. People work a lot on quotient types (there is an entire thesis: Quotient inductive-inductive definitions -- Dijkstra, Gabe), though, so we'll probably have them at some point.
Decidability of Conversion for Type Theory in Type Theory, Andreas Abel, Joakim Öhman, Andrea Vezzosi -- untyped terms reified as typed ones. Lots of properties. Also has a lot of metatheoretical proofs and a particularly interesting device that allows to prove soundness and completeness using the same logical relation. The formalization is huge and well-commented.
A setoid model of extensional Martin-Löf type theory in Agda (zip file with the development), Erik Palmgren -- abstract:
Abstract. We present details of an Agda formalization of a setoid
model of Martin-Löf type theory with Pi, Sigma, extensional identity
types, natural numbers and an infinite hiearchy of universe à la
Russell. A crucial ingredient is the use of Aczel's type V of
iterative sets as an extensional universe of setoids, which allows for
a well-behaved interpretation of type equality.
Coq in Coq, Bruno Barras and Benjamin Werner -- a formalization of CC in Coq (the code). Untyped terms reified as types ones + lots of lemmas + metatheoretical proofs.
Thanks to András Kovács and James Chapman for suggestions.

Related

What is `where .force`?

I've been playing around with the idea of writing programs that run on Streams and properties with them, but I feel that I am stuck even with the simplest of things. When I look at the definition of repeat in Codata/Streams in the standard library, I find a construction that I haven't seen anywhere in Agda: λ where .force →.
Here, an excerpt of a Stream defined with this weird feature:
repeat : ∀ {i} → A → Stream A i
repeat a = a ∷ λ where .force → repeat a
Why does where appear in the middle of the lambda function definition?, and what is the purpose of .force if it is never used?
I might be asking something that is in the documentation, but I can't figure out how to search for it.
Also, is there a place where I can find documentation to use "Codata" and proofs with it? Thanks!
Why does where appear in the middle of the lambda function definition?,
Quoting the docs:
Anonymous pattern matching functions can be defined using one of the
two following syntaxes:
\ { p11 .. p1n -> e1 ; … ; pm1 .. pmn -> em }
\ where p11 .. p1n -> e1 … pm1 .. pmn -> em
So λ where is an anonymous pattern matching function. force is the field of Thunk and .force is a copattern in postfix notation (originally I said nonsense here, but thanks to #Cactus it's now fixed, see his answer).
Also, is there a place where I can find documentation to use "Codata" and proofs with it? Thanks!
Check out these papers
Normalization by Evaluation in the Delay Monad
A Case Study for Coinduction via Copatterns and Sized Types
Equational Reasoning about Formal Languages in Coalgebraic Style
Guarded Recursion in Agda via Sized Types
As one can see in the definition of Thunk, force is the field of the Thunk record type:
record Thunk {ℓ} (F : Size → Set ℓ) (i : Size) : Set ℓ where
coinductive
field force : {j : Size< i} → F j
So in the pattern-matching lambda, .force is not a dot pattern (why would it be? there is nothing prescribing the value of the parameter), but instead is simply syntax for the record field selector force. So the above code is equivalent to making a record with a single field called force with the given value, using copatterns:
repeat a = a :: as
where
force as = repeat a
or, which is actually where the .force syntax comes from, using postfix projection syntax:
repeat a = a :: as
where
as .force = repeat a

What is positivity checking? [duplicate]

This question already has an answer here:
"Strictly positive" in Agda
(1 answer)
Closed 4 years ago.
Apparently, there is some feature in Agda called positivity checking which can apparently keep the system sound even if type-in-type is enabled.
I am curious to know what this is about, but the Agda Manual fails to answer the question, and only explains how to turn it off.
At a lunch table I overheard that this is about polarity in type theory, but that is about all I know. I am failing to find anything online which explains this concept and why it is useful in maintaining soundness. Any intelligible explanation would be appreciated.
First, I have to clear up a misconception: positivity checking does not guarantee soundness when type-in-type is enabled. Data types must thus satisfy both the positivity check and universe check to preserve soundness.
Now, to explain positivity checking, let's first look at a counterexample when we wouldn't have positivity checking:
-- the empty type
data ⊥ : Set where
-- a non-positive type
data Bad : Set where
bad : (Bad → ⊥) → Bad
Suppose this datatype was allowed, then you could easily prove ⊥:
bad-is-false : Bad → ⊥
bad-is-false (bad f) = f (bad f)
bad-is-true : Bad
bad-is-true = bad bad-is-false
boom : ⊥
boom = bad-is-false bad-is-true
Under the Curry-Howard correspondence, the definition of Bad says: Bad is true if and only if Bad is false. So it is not surprising that it leads to inconsistencies.
Positivity checking rules out datatypes such as Bad. In general, the (strict) positivity criterion says that each constructor c of a datatype D should have a type of the form
c : (x1 : A1)(x2 : A2) ... (xn : An) → D xs
where the type Ai of each argument is either non-recursive (i.e. it doesn't refer to D) or of the form (y1 : B1)(y2 : B2) ... (ym : Bm) → D ys where each Bj doesn't refer to D.
Bad doesn't satisfy this criterion because the argument of the constructor bad has type Bad → ⊥, which is neither of the two allowed forms.
The name 'positivity checking' comes (as many things in type theory do) from category theory, specifically the notion of a positive endofunctor. Each definition of a datatype that satisfies the positivity criterion is such a positive endofunctor on the category of types. This means we can construct the initial algebra of that endofunctor, which can be used to model the datatype when constructing a model of type theory (which is used to prove soundness).

How to define real number in agda?

I want to implement Dedekind's cut in Agda. I tried to represent real number first. But I am not able to define it in Agda. How to define it??
Real numbers can be constructed in a few different ways:
Following Erret Bishop's construction of real numbers in Constructive Analysis, real numbers can be formalized in Agda as a sequence of rational numbers along with a proof of convergence of this sequence:
-- Constructible Real numbers as described by Bishop
-- A real number is defined to be a sequence along
-- with a proof that the sequence is regular
record ℝ : Set where
constructor Real
field
f : ℕ -> ℚ
reg : {n m : ℕ} -> ∣ f n - f m ∣ ≤ (suc n)⁻¹ + (suc m)⁻¹
Checkout this repository for the formalized construction of an equivalence relation using this definition.
Another way to define real numbers is with Dedekind cuts, which as #vitrus mentioned, is discussed in chapter 11 in the Homotopy Type Theory book

Is it possible to get hold of free theorems as propositional equalities?

"Free theorems" in the sense of Wadler's paper "Theorems for Free!" are equations about certain values are derived based only on their type. So that, for example,
f : {A : Set} → List A → List A
automatically satisfies
f . map g = map g . f
Can I get my hands on an Agda term, then, of the following type:
(f : {A : Set} → List A → List A) {B C : Set} (g : B → C) (xs : List B)
→ f (map g xs) ≡ map g (f xs)
or if so/if not, can I do something more/less general?
I'm aware of the existence of the Lightweight Free Theorems library but I don't think it does what I want (or if it does, I don't understand it well enough to do it).
(An example use case is that I have a functor F : Set → Set and would like to prove that a polymorphic function F A × F B → F (A × B) is automatically a natural transformation.)
No, the type theory on which Agda is build is not strong enough to prove this. This would require a feature called "internalized parametricity", see the work by Guilhem:
Jean-Philippe Bernardy and Guilhem Moulin: A Computational Interpretation of Parametricity (2012)
Guilhem Moulin: Pure Type Systems with an Internalized Parametricity Theorem (2013)
This would allow you for example to prove that all inhabitants of "(A : Set) → A → A" are equal to the (polymorphic) identity function. As far as I know, this has not been implemented in any language yet.
Chantal Keller and Marc Lasson developped a tactic for Coq generating the parametricity relation corresponding to a (closed) type and proving that this type's inhabitants satisfy the generated relation. You can find more details about this work on Keller's website.
Now in Agda's case, it is in theory possible to do the same sort of work by implementing the tactic in pure Agda using a technique called reflection.

How to prove that equal function types have equal domains?

I want to prove
∀ {ℓ} {A B C D : Set ℓ} → (A → B) ≡ (C → D) → A ≡ C
(and similar for the codomain).
If I had a function domain that returns the domain of a function type, I could write the proof as
cong domain
but I don't think it's possible to write such a function.
Is there any way to do this?
I posed a very similar question on the Agda mailing list a few months ago, see: http://permalink.gmane.org/gmane.comp.lang.agda/5624. The short answer is that you cannot prove this in Agda.
The technical reason is that the unification algorithm used internally by Agda for pattern matching doesn't include a case for problems of the form (A → B) ≡ (C → D), so this definition does not typecheck:
cong-domain : ∀ {ℓ} {A B C D : Set ℓ} → (A → B) ≡ (C → D) → A ≡ C
cong-domain refl = refl
It is also impossible to define the function domain directly. Think about it: what should be the domain of a type that is not a function type, e.g. Bool?
The deeper reason why you cannot prove this is that it would be incompatible with the univalence axiom from Homotopy Type Theory. In an answer given by Guillaume Brunerie on my mail, he gives the following example: Consider the two types Bool -> Bool and Unit -> (Bool + Bool). Both have 4 elements, so we can use the univalence axiom to give a proof of type Bool -> Bool ≡ Unit -> (Bool + Bool) (in fact there are 24 different proofs). But clearly we do not want Bool ≡ Unit! So in the presence of univalence, we cannot assume that equal function types have equal domains.
In the end, I 'solved' this problem by passing an extra argument of type A ≡ C everywhere it was needed. I know it's not ideal, but maybe you can do the same.
I should also note that Agda does include an option for injective type constructors, which you can enable by putting {-# OPTIONS --injective-type-constructors #-} at the top of your .agda file. This allows you for example to prove A ≡ B from List A ≡ List B, but unfortunately this only works for type constructors such as List, and not for function types.
You could of course always make a feature request at https://code.google.com/p/agda/issues/list to add a option --injective-function-types to Agda. This option would be incompatible with univalence, but so is --injective-type-constructors, yet for many applications this is not a real problem. I feel that the main Agda developers are usually very open to such requests, and very fast to add them to the development version of Agda.

Resources