Pointwise Equality ≗ vs Propositional Equality ≡ in Agda - agda

When trying to prove a property over functions using list, I had to prove that the property is preserved by map over a list. Gladly, I found this useful congruence proof in Agda's standard library (here):
map-cong : ∀ {f g : A → B} → f ≗ g → map f ≗ map g
map-cong f≗g [] = refl
map-cong f≗g (x ∷ xs) = cong₂ _∷_ (f≗g x) (map-cong f≗g xs)
I am trying to do my proof with respect to propositional equality ≡ but map-cong proves pointwise equality ≗. I have several questions here:
I noticed that map-cong was previously implemented via ≡ but was generalized (I found this issue). This suggests that ≗ is a generalization of ≡. Is there a way to conclude propositional equality from pointwise equality? Something like a function f ≗ g → f ≡ g?
When looking at the implementation, point-wise equality seems to be defined as propositional equality for functions via the extensionality axiom: Two functions are equal if they yield the same results for all inputs. This is emphasized by the above definition of map-cong which indeed matches not only on the proof f≗g but also on possible input arguments. Is my understanding correct? Is there any documentation or explanation on the implementation of ≗? I found the implementation in the standard library to be undocumented and rather intricate, split across several files and using multiple levels of abstraction.
(Is there any way to conventiently browse the standard library except for browsing the source code (e.g., via grep or clicking in Github)?)

No there isn't.
That's correct. The definition of ≗ is a bit involved because it reuses existing notion but you can ask Agda to normalise it (C-c C-n in emacs) and see that it's just:
λ {A} {B} f g → (x : A) → f x ≡ g x
I typically use http://agda.github.io/agda-stdlib/

Related

Why does cubical agda choose the particular two component homogeneous path composition operator it does?

In the implementation of the prelude for cubical agda, there is a definition of 3 component path composition
_∙∙_∙∙_ : w ≡ x → x ≡ y → y ≡ z → w ≡ z
This definition feels reasonably natural and clean to me. But then to get the 2 component path composition operator there are 3 choices: One for fixing each of the arguments as refl.
The standard ∙ is done by fixing the first argument, and another implementation (∙') is given for fixing the third argument. There is then a proof that they are the same. But the version fixing the 2nd argument is not discussed.
It seems to me that the 2nd argument version (call it ∘) has a nice property that
sym (p1 ∘ p2) is equal to sym p2 ∘ sym p1 definitionally. This seems like it can reduce the book keeping in some proofs.
Are there reasons why this version is not the standard version? Are there other computational properties that are better with the standard version?

How are the equational reasoning operators used in practice?

The Agda Standard Library exports some operators that allow you to write proofs in a manner similar to what you would do on paper, or how it is taught in the Haskell community. While you can write "conventional" Agda proofs in a somewhat systematic manner by refining a Goal using with abstractions, rewrites or helper lemmas as needed, it isn't really clear to me how a proof using the equality reasoning primitives "comes to be".
That is, while you can find examples about what these proofs look like when they are finished and type-check here and there, these already worked examples don't show you how they are developed in a systematic step-by-step (maybe hole-driven) manner.
How is it done in practice? Do people "refactor" an already existing proof? Do you try to "burn the candle from both sides" by starting with the left-hand and right-hand sides of the initial Goal and a hole in the middle?
Furthermore, the Agda documentation states that if the equality reasoning primitives are in scope, "then Auto will do equality reasoning using these constructs". What does that mean?
I would appreciate it if someone could point me in the right direction, or even post an example of how they develop these kinds of proofs step-by-step, what questions they ask themselves as they go through it, where they put the holes and so on. Thanks!
I think it would be more helpful for you to look at the definitions for equational reasoning for Identity here Equational Reasoning. The main point is that it is just a nicer way to apply transitivity chains and allowing the user to see the actual expression in code, rather than the proof evidence which is not that easy to read.
The way I go about building a proof using equational reasoning for any setoid is this. With the example of natural numbers
open import Relation.Binary.PropositionalEquality
open ≡-Reasoning
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
_+_ : ℕ → ℕ → ℕ
m + zero = m
m + succ n = succ (m + n)
Let's take commutativity as an example.
This is how I start with the goals.
comm+ : ∀ m n → m + n ≡ n + m
comm+ m zero = {!!}
comm+ m (succ n) =
begin
succ (m + n)
≡⟨ {!!} ⟩
succ n + m
∎
Now I see the original expression and goal and my goal proof is between the brackets.
I work only on the expression leaving the proof objects untouched and add
what I think should work.
comm+ : ∀ m n → m + n ≡ n + m
comm+ m zero = {!!}
comm+ m (succ n) =
begin
succ (m + n)
≡⟨ {!!} ⟩
succ (n + m)
≡⟨ {!!}⟩
succ n + m
∎
Once I think I have a proof, I work on the proof objects that justify my steps.
Regarding the auto-tactic, you should not bother with that in my opinion. It's not being worked on for a while.

Parametricity-exploiting proofs in Agda

Reading this answer prompted me to try to construct, and then prove, the canonical form of polymorphic container functions. The construction was straightforward, but the proof stumps me. Below is a simplified-minimized version of how I tried to write the proof.
The simplified version is proving that sufficiently polymorphic functions, due to parametricity, can't change their behaviour only based on the choice of parameter. Let's say we have functions of two arguments, one of a fixed type and one parametric:
PolyFun : Set → Set _
PolyFun A = ∀ {X : Set} → A → X → A
the property I'd like to prove:
open import Relation.Binary.PropositionalEquality
parametricity : ∀ {A X Y} → (f : PolyFun A) → ∀ a x y → f {X} a x ≡ f {Y} a y
parametricity f a x y = {!!}
Are statements like that provable from inside Agda?
Nope, there's no parametricity principle accessible in Agda (yet! [1]).
However you can use these combinators to build the type of the corresponding free theorem and postulate it:
http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Libraries.LightweightFreeTheorems
[1] http://www.cse.chalmers.se/~mouling/share/PresheafModelParametericTT.pdf

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