open import Data.Product using (_×_; ∃; ∃-syntax)
open import Data.List
Any-∃ : ∀ {A : Set} {P : A → Set} {xs : List A} → ∃[ x ∈ xs ] P x
Could not parse the application ∃[ x ∈ xs ] P x
Operators used in the grammar:
∃[_] (prefix notation, level 20) [∃-syntax (C:\Users\Marko\AppData\Roaming\cabal\x86_64-windows-ghc-8.6.5\Agda-2.6.0\lib\agda-stdlib\src\Data\Product.agda:78,1-9)]
when scope checking ∃[ x ∈ xs ] P x
For some reason it seems like it is not importing the precedence properly from the standard library module. Defining it as...
Any-∃ : ∀ {A : Set} {P : A → Set} {xs : List A} → ∃[ x ] P x
...will make it pass parsing, but I am not sure this is doing the right thing for one of the problems I am trying to solve.
What should I do here?
∃ is precisely for the cases where you can leave out the domain of the function
because it's evident. Otherwise you are supposed to use Σ. And indeed Σ-syntax
does give you the ability to write Σ[ x ∈ A ] B.
Related
In Agda, it seems it is not possible to show ∀ {A : Set} (f : ⊥ → A) → f ≡ λ ().
However, the seemingly similar term ∀ {A : Set} (f : ⊤ → A) → f ≡ λ _ → f tt can be proven by refl. It can be later used to prove a form of extensionality for ⊤:
ext⊤ : ∀ {A : Set} (f g : ⊤ → A) (H : ∀ x → f x ≡ g x) → f ≡ g
According to this question and answer, the explanation might be in considering different models of type theory. Is it possible to have any intuition on why one is accepted and not the other? Shouldn't f ≡ λ () be some form of eta law?
The ⊤ type has the eta rule which says that any terms with that type are definitionally equal. Hence, f ≡ (λ x → f x) ≡ (λ x → f tt).
⊥ does not have an eta rule in Agda. If f : ⊥ → A, then we only know that f ≡ λ x → f x. λ () is essentially syntactic sugar for ⊥-elim, and f is not definitionally equal to ⊥-elim.
I draw your attention that the first statement is attempting to prove the uniqueness of ⊥ → A. Usually it is true up to isomorphism.
The full correspondence would have been between ∀ {A : Set} (f : ⊤ → A) → f ≡ λ _ → f tt and ∀ {A : Set} (f : ⊥ → A) → f ≡ λ _ → f () - the expression for ⊤ constructs the value tt, so you should be constructing a value for ⊥.
Agda has no means of constructing a value of ⊥, so () is not a valid constructor, it is only a placeholder for what you want.
Although it isn't really pattern-matching, it probably is not harmful to see the use of () as pattern-matching for the empty type - it is allowed to occur only in the pattern-matching positions.
This is intended to show the similarity is superficial, so should amend your intuition about the expressions.
Shouldn't f ≡ λ () be some form of eta law?
It is not clear what you would gain from that. Many things can be proven only up to isomorphism. So, for example, proving the uniqueness of ⊥ → A could correspond to proving the uniqueness of A → ⊤ (not eta-equality of f and λ _ → f tt). Both of these is doable.
I know that there is an AVL tree in the standard library, but that feels too complex for my purposes. A vanilla function meets most my requirements, except for being able to iterate over the keys.
It is not like I strictly do not know how to make some proposition that for every element in a list there is no duplicate - I did so in Coq once, but I am trying to get a handle on how to bake it into the structure directly and am running into difficulties.
open import Relation.Nullary
open import Relation.Binary.PropositionalEquality
data UniqueList {a} (A : Set a) : Set a
data NotIn {a} {A : Set a} : A → UniqueList A → Set a
data UniqueList A where
[] : UniqueList A
_∷_ : ∀ (x : A) (xs : UniqueList A) → NotIn x xs → UniqueList A
data NotIn {a} {A} where
done : ∀ (x : A) → NotIn x []
dive : ∀ (x y : A) (ys : UniqueList A) (prf : NotIn y ys) → NotIn x ys → ¬ x ≡ y → NotIn x ((y ∷ ys) prf)
I thought I might try something like this, but it feels awkward. Any advice for how to deal with this?
Suppose I have a record type for some algebraic structure; e.g. for monoids:
{-# OPTIONS --cubical #-}
module _ where
open import Cubical.Core.Everything
open import Cubical.Foundations.Everything hiding (assoc)
record Monoid {ℓ} (A : Type ℓ) : Type ℓ where
field
set : isSet A
_⋄_ : A → A → A
e : A
eˡ : ∀ x → e ⋄ x ≡ x
eʳ : ∀ x → x ⋄ e ≡ x
assoc : ∀ x y z → (x ⋄ y) ⋄ z ≡ x ⋄ (y ⋄ z)
Then I can manually create a type for monoid homomorphisms:
record Hom {ℓ ℓ′} {A : Type ℓ} {B : Type ℓ′} (M : Monoid A) (N : Monoid B) : Type (ℓ-max ℓ ℓ′) where
open Monoid M renaming (_⋄_ to _⊕_)
open Monoid N renaming (_⋄_ to _⊗_; e to ε)
field
map : A → B
map-unit : map e ≡ ε
map-op : ∀ x y → map (x ⊕ y) ≡ map x ⊗ map y
But is there a way to define Hom without spelling out the homomorphism laws? So as some kind of mapping from the witness M : Monoid A to N : Monoid B, but that doesn't make much sense to me because it'd be a "mapping" where we already know that it should map M to N...
There currently isn't. But that's what the follow up to the recent paper A feature to unbundle data at will is about. In the repo for that work, you'll find the sources for 'package former'; the accompanying documentation uses Monoid as one of its examples, and section 2.17 is all about homomorphism generation.
The aim of this prototype is to figure out what features are needed (and feasible), to guide the development of both the meta-theory and an 'inside Agda' implementation.
#### Exercise `Any-∃`
Show that `Any P xs` is isomorphic to `∃[ x ∈ xs ] P x`.
Leaving aside the fact that ∃[ x ∈ xs ] P x is not even valid syntax - only Σ[ x ∈ xs ] P x could be valid, none of the type signatures I've tried typecheck for that particular problem.
Any-∃ : ∀ {A : Set} {P : A → Set} {xs : List A} → Any P xs ≃ Σ[ x ∈ xs ] P x
List A !=< Set _a_1582 of type Set
when checking that the expression xs has type Set _a_1582
The most obvious thing here fails. I sort of understand what the question is trying to ask me here, but I am not sure what the structure ∃[ x ∈ xs ] P x is supposed to be.
This is the penultimate exercise in the Lists chapter of the PLFA book.
The book has been corrected now:
Exercise Any-∃ (practice)
Show that Any P xs is isomorphic to ∃[ x ] (x ∈ xs × P x).
When dealing with equalities on types in Agda, it is often necessary to coerce the inhabitants the types using a hand-made coercion like
coerce : ∀ {ℓ} {A B : Set ℓ} → A ≡ B → A → B
coerce refl x = x
It was discussed here that explicit coercion of terms could sometimes be avoided using rewriting. I was wondering if this technique worked as well when defining types. So I wrote a little example where f,g : A → Set are two (extentionally) equal dependent types and a property p : A → Set where p x state that every element y : f x is equal to every element z : g x, that is y ≡ z. The last equality is ill-typed, as one can expect since y : f x and z : g x do not share the same type a priori, however I was hoping that rewriting could allow it. Something like:
open import Relation.Binary.PropositionalEquality
postulate A : Set
postulate B : Set
postulate f : A → Set
postulate g : A → Set
postulate f≡g : ∀ {x} → (f x) ≡ (g x)
p : {x : A} → Set
p {x} rewrite f≡g {x} = (y : f x ) (z : g x) → y ≡ z
But the error is still there, even though the rewrite advice is accepted. So, is there a way to make Agda accept this definition without using an explicit coercion, like
p {x} = (y : f x ) (z : g x) → (coerce f≡g y) ≡ z
?
Thank you
Here's a variation of your code that does what you want:
open import Relation.Binary.PropositionalEquality
postulate
A : Set
f : A → Set
g : A → Set
f≡g : ∀ x → f x ≡ g x
p : (x : A) → Set
p x = ∀ y z → R y z
where
R : f x → g x → Set
R fx gx rewrite f≡g x = fx ≡ gx
Why does this work when your version doesn't? rewrite affects two things: (a) the types of variables introduced in patterns left of the rewrite; (b) the goal type. If you look at your rewrite, when it takes effect, there is no f x to be found, so it does nothing. My rewrite, on the other hand, changes the type of fx : f x to g x because fx is introduced before the rewrite.
However, I would be surprised if this helped you much. In my experience, heterogeneous equality (i.e. equality between things of different types) remains annoying, regardless of what tricks you throw at it. For example, consider this variation of your idea, where we define a type R by rewriting:
R : ∀ {x} → f x → g x → Set
R {x} fx gx rewrite f≡g x = fx ≡ gx
R is a heterogenous relation which 'looks' reflexive. However, the closest we can come to stating reflexivity is
coerce : {A B : Set} → A ≡ B → A → B
coerce refl x = x
R-refl : ∀ {x} {fx : f x} → R fx (coerce (f≡g x) fx)
R-refl {x} rewrite f≡g x = refl
Without the coerce, fx would have the wrong type, and so we're back to the problem that we have these coercions polluting our types. This is not necessarily a deal breaker, but it complicates things. So, my advice is to avoid heterogeneous relations if possible.