How to define a functor fixpoint? - functor

In Haskell i can define an endofunctor fixpoint so:
data Fix f = Fix (f (Fix f))
But in Agda can't:
data Fix (F : Id (Set → Set)) : Set where
fix : (unId F) (Fix F) → Fix F
as it says "Fix is not strictly positive, because it occurs in an argument to a bound variable in the type of the constructor fix in the definition of Fix."
I tried using Coinduction.∞ from the stdlib, in vain:
data Fix (F : Set → Set) : Set where
fix : ∞ (F (Fix F)) → Fix F
or
data Fix (F : Set → Set) : Set where
fix : F (∞ (Fix F)) → Fix F
neither works.
I found this doc which defines polynomial functors Functor and a function [_] : Functor → Set → Set which works:
data Functor : Set₁ where
Id : Functor
Const : Set → Functor
_⊕_ : Functor → Functor → Functor
_⊗_ : Functor → Functor → Functor
[_] : Functor → Set → Set
[ Id ] B = B
[ Const C ] _ = C
[ F ⊕ G ] B = [ F ] B ⊎ [ G ] B
[ F ⊗ G ] B = [ F ] B × [ G ] B
data Fix (F : Functor) : Set where
fix : [ F ] (Fix F) → Fix F
but i'm not sure why that would and this wouldn't, as both have Fix as an argument to the bound variable F.
Can one define a general endofunctor fixpoint in Agda, and if so, how?
EDIT: This was marked as a possible duplicate of 14699334, but the only answer there links to an (the?) Agda tutorial which includes fixpoints of a specific polynomial functor type; i want to know whether one can define this more generally. In particular, i want to define fixpoints of types which may be structurally equal but are nominally inequal.

Related

What are the rules for custom syntax declarations in Agda?

The Agda docs don't really have much to say on syntax declarations, and a cursory glance at the source code is less than illuminating, so I've been trying to piece it together myself using examples from the standard library like Σ[_]_ and ∃[_]_. I can reproduce an (admittedly rather contrived) example like theirs fairly easily
twice : {A : Set} → (A → A) → A → A
twice f x = f (f x)
syntax twice (λ x → body) = twice[ x ] body
But when I try to define custom syntax that binds two variables, I get an error
swap : {A B C : Set} → (A → B → C) → B → A → C
swap f y x = f x y
syntax swap (λ x y → body) = swap[ x , y ] body
Specifically,
Parse error
y<ERROR>
→ body) = swap[ x , y ] body
...
So I assume there are some rules as to what's allowed on the left-hand side of a syntax declaration. What are these rules, and what of them prohibits my two-variable lambda form above?
Currently Agda does not allow syntax declarations with multi-argument lambda abstractions. This is a known limitation, see the issue tracker for the corresponding enhancement request.

Translating Coq Definitions to agda?

I'm wondering if there is a systematic way to interpret Coq Definitions as agda programs. I'm working through translating part of programming foundations and am not able to get the tUpdate function to work below. Why is this failing. The coq code is commented.
--Definition total_map (A : Type) := string -> A.
totalMap : Set → Set
totalMap A = String → A
-- Definition t_empty {A : Type} (v : A) : total_map A :=
-- (fun _ => v).
tEmpty : {A : Set} (v : A) → totalMap A
tEmpty = λ v x → v
-- Definition t_update {A : Type} (m : total_map A)
-- (x : string) (v : A) :=
-- fun x' => if eqb_string x x' then v else m x'.
tUpdate : {A : Set} (m : totalMap A) (x : String) (v : A) → Set
tUpdate m x v = λ x' → (if (x == x') then v else m x')
The lambda term produces the below error
(x' : String) → A !=< Set of type Set
when checking that the expression
λ x' → if x == x' then v else m x' has type Set
Is this a correct general schema for doing this translation, e.g., is this translation sound and complete?
Edit:
I realized update was supposed to return a map, but i'm confused as it coq can seemingly infer this while agda can't? I'd still welcome a more general answer to the latter question.
tUpdate : {A : Set} (m : totalMap A) (x : String) (v : A) → totalMap A
tUpdate m x v = λ x' → (if (x == x') then v else m x')
Coq and Agda are both based on very roughly the same dependent type theory, so in theory it would be possible to take the proof term generated by a Coq script and translate it into an Agda program. However, there are many small (and not so small) differences, e.g. Coq's impredicative Prop, cumulativity, differences in the termination checkers, ect, that would make such a translation difficult or impossible.
However, what you're asking for here isn't really an automatic translator but rather a set of rules for translating Coq to Agda by hand. Since many basic features can be mapped one-to-one, this process is much more straightforward. However, any use of tactics in the Coq code you'll either have to translate to an explicit proof term in Agda or write your own Agda reflection macros (since there is no full tactic library for Agda yet).
To answer the specific problem you encountered here: Agda did not try to infer the return type of the tUpdate function because you already specified it to be Set yourself. If you want Agda to infer it for you, you can simply replace the return type with an underscore _ (which works fine in this case):
tUpdate : {A : Set} (m : totalMap A) (x : String) (v : A) → _
tUpdate m x v = λ x' → (if (x == x') then v else m x')

Is this formalization of the empty set correct in Agda?

I'm following The Haskell Road to Logic, Maths and Programming in Agda.
The book states:
The empty set is trivially a relation and is the smallest relation between two sets A and B
in Agda:
data ∅ : Set where
record ⊤ : Set where
record Σ (A : Set) (B : A → Set) : Set₁ where
constructor _,_
field
π₁ : A
π₂ : B π₁
_×_ : Set → Set → Set₁
A × B = Σ A (λ _ → B)
infixr 5 _×_ _,_
Relation : Set → Set₁
Relation P = P × P → Set
With that, I can define relations on specific sets:
lteℕ : Relation ℕ
lteℕ(x , y) = x ≤ℕ y where
_≤ℕ_ : ℕ → ℕ → Set
O ≤ℕ O = ⊤
O ≤ℕ S y = ⊤
S x ≤ℕ O = ∅
S x ≤ℕ S y = x ≤ℕ y
infixr 5 _≤ℕ_
But now I have a problem, because the signature for the empty set relation:
cannot be the empty set, since I already defined it as the unhabited type previously
results in the error Set₁ != Set when checking that the expression Set has type Set even when defined with a distinct symbol as Ø : Relation Set due to the necessity to avoid Russell's paradox in the language.
Is there a way around that that is still logically consistent? Thanks!
The answer depends on what you call a set. If by set you mean a representation of the mathematical sets, such as a list, then the empty set is just represented by the empty list.
If by set you mean the Agda Set which means a type, then the answer is a bit more complicated: there is not an empty type, but there are as many as you can think of. More precisely, there are as many empty types as data types for which you don't provide any constructor. The question is then more "which of these types do I chose to model the empty set ?" rather than "how do I model the empty set ?".
Here is an example of an agda module which emphasizes this aspect: First, I have a few imports and the header of my module:
open import Agda.Primitive
open import Data.Nat hiding (_⊔_)
module EmptySets where
Then I start by an empty type, the more simple you can think of:
data Empty : Set where
From this data type, it is possible to write an eliminator:
Empty-elim : ∀ {a} {A : Set a} → Empty → A
Empty-elim ()
This basically says that anything holds if Empty holds.
But, I could have also chosen to represent the empty set as the empty relation by defining a family of types, all empty, which are all relations. First, relations needs to be defined (I took the definition from the standard library):
REL : ∀ {a b} → Set a → Set b → (ℓ : Level) → Set (a ⊔ b ⊔ lsuc ℓ)
REL A B ℓ = A → B → Set ℓ
Then the family of empty relations can be defined :
data EmptyRelation {a b ℓ} {A : Set a} {B : Set b} : REL A B ℓ where
Since all these types are empty, they all provide an eliminator as well:
EmptyRelation-elim : ∀ {a b x ℓ} {A : Set a} {B : Set b} {X : Set x} {u : A} {v : B} → EmptyRelation {ℓ = ℓ} u v → X
EmptyRelation-elim ()
And, as a consequence, it is possible to instantiate this generic type to get a specific empty type, for instance, the empty relation over natural numbers, which never holds:
EmptyNaturalRelation : REL ℕ ℕ lzero
EmptyNaturalRelation = EmptyRelation
This is what is explained in the book: since a relation is a set of pairs, then the empty type is the smallest of this relation: the one where there are no pairs in it.
But you could also use predicates instead of relations, saying that the empty set is the smallest predicate over a given type: the one that never holds, in which case this is represented as the following:
Pred : ∀ {a} → Set a → (ℓ : Level) → Set (a ⊔ lsuc ℓ)
Pred A ℓ = A → Set ℓ
data EmptyPredicate {a ℓ} {A : Set a} : Pred A ℓ where
And you could be even crazier and decide to model the empty set as the following:
data EmptySomething {a} {A B C D E Z : Set a} : A → B → C → D → E → Z → Set where
All in all, there are no empty set in agda, but there are a potential infinity of empty types.
As for the code you presented in your question, there are several inaccuracies:
The relations are usually defined on two arguments instead of pairs of argument, which you can then curry on if needed to make them take a pair as parameter.
Why would you make lteℕ depend on _≤ℕ_ and not define it directly ?
You should define lteℕ as a data type rather than a function which returns either bottom or top, which will allow you to case-split on such a term in the future. Usually, this is defined this way (in the standard library):
data _≤_ : Rel ℕ 0ℓ where
z≤n : ∀ {n} → zero ≤ n
s≤s : ∀ {m n} (m≤n : m ≤ n) → suc m ≤ suc n

Law of excluded middle in Agda

I've heard the claim that Agda's Martin-Lof Type Theory with Excluded Middle is consistent. How would I go about adding it as a postulate? Also, after Adding LEM, is it then classical first-order logic? By this I mean, do I also have the not (for all) = there exist (not) equivalence? I don't know type theory, so please add additional explanation if you quote any results in type theory.
In MLTT, exists corresponds to a dependent pair which is defined in Data.Product in the standard library. It packages together the existence witness and the proof that it has the right property.
It is not necessary to postulate anything to prove that the negation of an existential statement implies the universal statement of the negated property:
∄⇒∀ : {A : Set} {B : A → Set} →
¬ (∃ λ a → B a) →
∀ a → ¬ (B a)
∄⇒∀ ¬∃ a b = ¬∃ (a , b)
To prove the converse however you do need the law of excluded middle to have a witness appear out of thin air. It is really easy to extend Agda with new postulates, you can simply write (Dec is defined in Relation.Nullary):
postulate LEM : (A : Set) → Dec A
It's always a good thing to remember how to prove double-negation elimination starting from LEM and we will need later on anyway so there it is (case_of_ is defined in Function and explained in README.Case):
¬¬A⇒A : {A : Set} → ¬ (¬ A) → A
¬¬A⇒A {A} ¬¬p =
case LEM A of λ
{ (yes p) → p
; (no ¬p) → ⊥-elim $ ¬¬p ¬p
}
And you can then prove that the negation of a universal statement implies an
existential one like so:
¬∀⇒∃ : {A : Set} {B : A → Set} →
¬ (∀ a → B a) →
∃ λ a → ¬ (B a)
¬∀⇒∃ {A} {B} ¬∀ =
case LEM (∃ λ a → ¬ B a) of λ
{ (yes p) → p
; (no ¬p) → ⊥-elim $ ¬∀ (¬¬A⇒A ∘ ∄⇒∀ ¬p)
}
A gist with all the right imports

Realising level polymorphic subsets within records

Using the notion of subsets as predicates,
ℙ : ∀ {b a} → Set a → Set (a ⊔ suc b)
ℙ {b} {a} X = X → Set b
I'd like to consider structures endowed with a predicate on subsets,
record SetWithAPredicate {a c} : Set {!!} where
field
S : Set a
P : ∀ {b} → ℙ {b} S → Set c
This is an ill-formed construction due to the level quantification used in ℙ. Everything works fine when I use S, P as parameters to a module, but I'd like them to be records so that I can form constructions on them and give instances of them.
I've tried a few other things, such as moving the level b of ℙ inside the definition via an existential but then that led to metavaraible trouble. I also tried changing the type of P,
P : ℙ {a} S → Set c
but then I can no longer ask for, say, the empty set to have the property:
P-⊥ : P(λ _ → ⊥)
This is not well typed since Set != Set a ---I must admit, I tried to use Level.lift here, but failed to do so.
More generally, this will also not allow me to express closure properties, such as P is closed under arbitrary unions ---this is what I'm really interested in.
I understand that I can just avoid level polymorphism,
ℙ' : ∀ {a} → Set a → Set (suc zero ⊔ a)
ℙ' {a} X = X → Set
but then simple items such as the largest subset,
ℙ'-⊤ : ∀ {i} {A : Set i} → ℙ' A
ℙ'-⊤ {i} {A} = λ e → Σ a ∶ A • a ≡ e
-- Σ_∶_•_ is just syntax for Σ A (λ a → ...)
will not even typecheck!
Perhaps I did not realise the notion of subset as predicate appropriately ---any advice would be appreciated. Thank-you!
You need to lift b out from P like this
record SetWithAPredicate {a c} b : Set {!!} where
field
S : Set a
P : ℙ {b} S → Set c
Yes, this is ugly and annoying, but that's how it's done in Agda (an example from standard library: _>>=_ is not properly universe polymorphic). Lift can help sometimes, but it quickly gets out of hand.
Perhaps I did not realise the notion of subset as predicate
appropriately ---any advice would be appreciated.
Your definition is correct, but there is another one, see 4.8.3 in Conor McBride's lecture notes.

Resources