I need to break this long line:
postulate flipH/cw/cw/flipH : ∀ (t : Tile) -> flipH (cw (cw (flipH t))) ≡ cw (cw t)
Agda won't accept any of these:
postulate flipH/cw/cw/flipH
: ∀ (t : Tile) -> flipH (cw (cw (flipH t))) ≡ cw (cw t)
postulate flipH/cw/cw/flipH : ∀ (t : Tile) ->
flipH (cw (cw (flipH t))) ≡ cw (cw t)
but it does accept this which is not very ideal, since it does not give me much space to work with before it gets long again:
postulate flipH/cw/cw/flipH : ∀ (t : Tile) ->
flipH (cw (cw (flipH t))) ≡ cw (cw t)
Is there a way to break line similar to the way we do it in Haskell?
postulate is a block keyword, meaning that it's set up to parse multiple postulates under a single occurrence of postulate. For example:
postulate
A : Set
B : Set → Set
That means you'll have better luck when you put flipH/cw/cw/flipH on a new line. For example, you might want to write:
postulate
flipH/cw/cw/flipH : ∀ (t : Tile) ->
flipH (cw (cw (flipH t))) ≡ cw (cw t)
Related
Instance search requires that all found solutions are unique. According to the Agda wiki (https://agda.readthedocs.io/en/v2.6.0.1/language/instance-arguments.html, bottom of the page),
From the previous stage we get a list of potential solutions. If the list is empty we fail with an error saying that no instance for C vs could be found (no). If there is a single solution we use it to solve the goal (yes), and if there are multiple solutions we check if they are all equal. If they are, we solve the goal with one of them (yes), but if they are not, we postpone instance resolution (maybe), hoping that some of the maybes will turn into nos once we know more about the involved metavariables.
Here I have some code that uses rose trees of bools. There are two data structures Trues and Falses that witness that the contents of a rose tree is all true or all false, respectively. There is also a function Opp that swaps all trues to falses and vice-versa. Naturally, Trues x -> Falses (Opp x) and vice-versa, so I wrote a function OppTF to witness this. However, Agda now complains that there are two ways to prove Falses (B []), either directly with the constructor for Falses, or via the function OppTF. Of course, both of these produce the same result, and I prove this with the uniq function that proves that if p : Trues (B []) then p is unique. Nevertheless, Agda does not realise this.
How can I convince Agda that all solutions are equal? Unfortunately I cannot make the proof irrelevant with .{{ _ : Falses x }} as I need it later on. So I need to do one of the following:
Coax Agda into fully normalising both candidate solutions, which will reveal they are equal.
Use the uniq proof to convince Agda that all solutions are equal.
Make Agda stop caring about duplicate solutions, without making the argument irrelevant.
Is it possible to do any of these, and if so, how?
Code and error below:
module Example where
open import Data.List
open import Data.Bool
open import Relation.Binary.PropositionalEquality
data Rose : Set where
V : Bool → Rose
B : List Rose → Rose
Opp : Rose → Rose
Opp' : List Rose → List Rose
Opp (V x) = V (not x)
Opp (B xs) = B (Opp' xs)
Opp' [] = []
Opp' (x ∷ xs) = Opp x ∷ Opp' xs
data Trues : Rose → Set
data Trues' : List Rose → Set
data Trues where
instance VTrues : Trues (V true)
instance TTrues : ∀ {ts} ⦃ _ : Trues' ts ⦄ → Trues (B ts)
data Trues' where
instance VTrues' : Trues' []
instance TTrues' : ∀ {t ts} ⦃ _ : Trues t ⦄ ⦃ _ : Trues' ts ⦄ → Trues' (t ∷ ts)
data Falses : Rose → Set
data Falses' : List Rose → Set
data Falses where
instance VFalses : Falses (V false)
instance TFalses : ∀ {ts} ⦃ _ : Falses' ts ⦄ → Falses (B ts)
data Falses' where
instance VFalses' : Falses' []
instance TFalses' : ∀ {t ts} ⦃ _ : Falses t ⦄ ⦃ _ : Falses' ts ⦄ → Falses' (t ∷ ts)
instance
OppTF : ∀ {x} ⦃ _ : Trues x ⦄ → Falses (Opp x)
OppTF' : ∀ {xs} ⦃ _ : Trues' xs ⦄ → Falses' (Opp' xs)
OppTF {x} ⦃ VTrues ⦄ = VFalses
OppTF {x} ⦃ TTrues ⦃ xs ⦄ ⦄ = TFalses ⦃ OppTF' ⦃ xs ⦄ ⦄
OppTF' {[]} ⦃ VTrues' ⦄ = VFalses'
OppTF' {x ∷ xs} ⦃ TTrues' ⦃ p ⦄ ⦃ ps ⦄ ⦄ = TFalses' ⦃ OppTF ⦃ p ⦄ ⦄ ⦃ OppTF' ⦃ ps ⦄ ⦄
data Str : Rose → Set where
Tor : ∀ {x : Rose} → Str x
dummy : ∀ {x : Rose} ⦃ _ : Falses x ⦄ → Rose
dummy {x} = x
test : Rose
test = dummy {B []}
uniq : ∀ {p : Falses (B [])} → p ≡ TFalses ⦃ VFalses' ⦄
uniq {TFalses {_} ⦃ VFalses' ⦄} = refl
Error:
Failed to solve the following constraints:
Resolve instance argument _70 : Falses (B [])
Candidates
TFalses : {ts : List Rose} ⦃ _ : Falses' ts ⦄ → Falses (B ts)
OppTF : {x : Rose} ⦃ _ : Trues x ⦄ → Falses (Opp x)
(stuck)
This was solved over on the Zulip chat with the option
{-# OPTIONS --overlapping-instances #-}
In this particular case, allowing overlapping instances doesn't cause a slowdown, however in my actual use-case it did, so also adding
{-# OPTIONS --overlapping-instances --instance-search-depth 10 #-}
greatly sped it up (the default search depth is 500).
I'm a beginner with Agda and im stuck with a hole in my proof here:
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong; sym; subst; trans)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
data Tile : Set where
-- 90° rotation
postulate cw : Tile → Tile
-- -90° rotation
postulate ccw : Tile → Tile
postulate cw/cw/cw/cw : ∀ (t : Tile) → cw (cw (cw (cw t))) ≡ t
postulate ccw/cw : ∀ (t : Tile) → ccw (cw t) ≡ t
postulate cw/ccw : ∀ (t : Tile) → cw (ccw t) ≡ t
cw/cw/cw/ccw : ∀ (t : Tile) → ccw t ≡ cw (cw (cw t))
cw/cw/cw/ccw t =
begin
ccw t
≡⟨ cong ccw ( sym (cw/cw/cw/cw t)) ⟩
ccw ( cw ( cw ( cw ( cw t))))
≡⟨ {!!} ⟩
cw (cw (cw t))
∎
I simply need to show that given the ccw/cw postulation,
ccw (cw (cw (cw (cw t)))) ≡ cw (cw (cw t))
Found it: I needed to put this in the hole: (ccw/cw ( cw ( cw ( cw t))))
which produces this: ccw (cw ( cw ( cw ( cw t)))) ≡ ( cw ( cw ( cw t))),
essentially replacing t with ( cw ( cw ( cw t)))
Is the univalence axiom invertible (modulo paths)? Is it possible to prove, using Agda's Cubical library, to prove the following:
open import Cubical.Core.Glue
uaInj : ∀ {ℓ} {A B : Set ℓ} {f g : A ≃ B} →
ua f ≡ ua g → equivFun f ≡ equivFun g
I suspect the above should hold, because in example 3.19 of the HoTT book, there is a step in the proof where an equivalence between two equivalences is used to prove the equivalence between their functions:
[...] so f is an
equivalence. Hence, by univalence, f gives rise to a path p : A ≡ A.
If p were equal to refl A, then (again by univalence) f would equal the
identity function of A.
Sure, ua is an equivalence, so it's injective. In the HoTT book, the inverse of ua is idtoeqv, so by congruence idtoeqv (ua f) ≡ idtoeqv (ua g) and then by inverses f ≡ g. I'm not familiar with the contents of cubical Agda prelude but this should be provable since it follows directly from the statement of univalence.
To put András's answer into code, we can prove injectivity of equivalency functions in general:
equivInj : ∀ {ℓ₁ ℓ₂} {A : Set ℓ₁} {B : Set ℓ₂} (f : A ≃ B) →
∀ x x′ → equivFun f x ≡ equivFun f x′ → x ≡ x′
equivInj f x x′ p = cong fst $ begin
x , refl ≡⟨ sym (equivCtrPath f (equivFun f x) (x , refl)) ⟩
equivCtr f (equivFun f x) ≡⟨ equivCtrPath f (equivFun f x) (x′ , p) ⟩
x′ , p ∎
and then given
univalence : ∀ {ℓ} {A B : Set ℓ} → (A ≡ B) ≃ (A ≃ B)
we get
uaInj : ∀ {ℓ} {A B : Set ℓ} {f g : A ≃ B} → ua f ≡ ua g → equivFun f ≡ equivFun g
uaInj {f = f} {g = g} = cong equivFun ∘ equivInj (invEquiv univalence) f g
The only problem is, univalence is not readily available in the Cubical library. Hopefully that is getting sorted out shortly.
UPDATE: In reaction to the above bug ticket, proof of univalence is now available in the Cubical library.
Suppose I have, using the cubical-demo library, the following things in scope:
i : I
p0 : x ≡ y
p1 : x' ≡ y'
q0 : x ≡ x'
q1 : y ≡ y'
How do I then construct
q' : p0 i ≡ p1 i
?
One way is by contracting singleton pairs with J, there might be simpler proofs though.
open import Cubical.PathPrelude
q' : ∀ {A : Set} (i : I) (x : A)
x' (q0 : x ≡ x')
y (p0 : x ≡ y)
y' (p1 : x' ≡ y')
(q1 : y ≡ y') → p0 i ≡ p1 i
q' i x = pathJ _ (pathJ _ (pathJ _ (\ q1 → q1)))
Another one I've come up with is I think closer to the spirit of the original problem instead of going around:
slidingLid : ∀ (p₀ : a ≡ b) (p₁ : c ≡ d) (q : a ≡ c) → ∀ i → p₀ i ≡ p₁ i
slidingLid p₀ p₁ q i j = comp (λ _ → A)
(λ{ k (i = i0) → q j
; k (j = i0) → p₀ (i ∧ k)
; k (j = i1) → p₁ (i ∧ k)
})
(inc (q j))
This one has the very nice property that it degenerates to q at i = i0 definitionally:
slidingLid₀ : ∀ p₀ p₁ q → slidingLid p₀ p₁ q i0 ≡ q
slidingLid₀ p₀ p₁ q = refl
I've found another solution to this, which is more explicit that it is gluing together a prefix of p0 (flipped), q0, and a prefix of p1:
open import Cubical.PathPrelude
module _ {ℓ} {A : Set ℓ} where
midPath : ∀ {a b c d : A} (p₀ : a ≡ b) (p₁ : c ≡ d) → (a ≡ c) → ∀ i → p₀ i ≡ p₁ i
midPath {a = a} {c = c} p₀ p₁ q i = begin
p₀ i ≡⟨ transp (λ j → p₀ (i ∧ j) ≡ a) refl ⟩
a ≡⟨ q ⟩
c ≡⟨ transp (λ j → c ≡ p₁ (i ∧ j)) refl ⟩
p₁ i ∎
I am new to Agda, and I think I still have a problem to think in that paradigm. Here is my question..
I have a type monoid and a type Group implemented as follows:
record Monoid : Set₁ where
constructor monoid
field Carrier : Set
_⊙_ : Carrier → Carrier → Carrier
e : Carrier
leftId : ∀ {x : Carrier} → (e ⊙ x) ≡ x
rightId : ∀ {x : Carrier} → (x ⊙ e) ≡ x
assoc : ∀ {x y z : Carrier} → (x ⊙ (y ⊙ z)) ≡ ((x ⊙ y) ⊙ z)
record Group : Set₁ where
constructor group
field m : Monoid
inv : Carrier → Carrier
inverse1 : {x y : Carrier} → x ⊙ (inv x) ≡ e
inverse2 : {x y : Carrier} → (inv x) ⊙ x ≡ e
Now, I want to proof the following lemma :
lemma1 : (x y : Carrier) → (inv x) ⊙ (x ⊙ y) ≡ y
lemma1 x y = ?
If I do it on paper, I will apply associativity then left identity.. but I do not know how to tell agda to apply these rules.. I have the problem of translating my thoughts to the Agda paradigm..
Any help is highly appreciated..
When you do the proof on the paper, applying associativity and then left identity uses ony key property of the identity relation - transitivity. That is, when you have a proof of p : x ≡ y and q : y ≡ z you can combine them into a single proof of trans p q : x ≡ z. The trans function is already part of the standard library (Relation.Binary.PropositionalEquality module), but its implementation is fairly simple anyways:
trans : {A : Set} {i j k : A} → i ≡ j → j ≡ k → i ≡ k
trans refl eq = eq
I'm using a bit different presentation of monoids and groups, but you can easily adapt the proof to your scenario.
open import Function
open import Relation.Binary.PropositionalEquality
Op₁ : Set → Set
Op₁ A = A → A
Op₂ : Set → Set
Op₂ A = A → A → A
record IsMonoid {A : Set}
(_∙_ : Op₂ A) (ε : A) : Set where
field
right-id : ∀ x → x ∙ ε ≡ x
left-id : ∀ x → ε ∙ x ≡ x
assoc : ∀ x y z → x ∙ (y ∙ z) ≡ (x ∙ y) ∙ z
record IsGroup {A : Set}
(_∙_ : Op₂ A) (ε : A) (_⁻¹ : Op₁ A) : Set where
field
monoid : IsMonoid _∙_ ε
right-inv : ∀ x → x ∙ x ⁻¹ ≡ ε
left-inv : ∀ x → x ⁻¹ ∙ x ≡ ε
open IsMonoid monoid public
(To keep things simple, indented code is written as part of the IsGroup record). We'd like to prove that:
lemma : ∀ x y → x ⁻¹ ∙ (x ∙ y) ≡ y
lemma x y = ?
The first step is to use associativity, that is assoc (x ⁻¹) x y, this leaves us with a goal (x ⁻¹ ∙ x) ∙ y ≡ y - once we prove that, we can merge these two parts together using trans:
lemma x y =
trans (assoc (x ⁻¹) x y) ?
Now, we need to apply the right inverse property, but the types don't seem to fit. We have left-inv x : x ⁻¹ ∙ x ≡ ε and we need to somehow deal with the extra y. This is when another property of the identity comes into play.
Ordinary functions preserve identity; if we have a function f and a proof p : x ≡ y we can apply f to both x and y and the proof should be still valid, that is cong f p : f x ≡ f y. Again, implementation is already in the standard library, but here it is anyways:
cong : {A : Set} {B : Set}
(f : A → B) {x y} → x ≡ y → f x ≡ f y
cong f refl = refl
What function should we apply? Good candidate seems to be λ z → z ∙ y, which adds the missing y part. So, we have:
cong (λ z → z ∙ y) (left-inv x) : (x ⁻¹ ∙ x) ∙ y ≡ ε ∙ y
Again, we just need to prove that ε ∙ y ≡ y and we can then piece those together using trans. But this last property is easy, it's just left-id y. Putting it all together, we get:
lemma : ∀ x y → x ⁻¹ ∙ (x ∙ y) ≡ y
lemma x y =
trans (assoc (x ⁻¹) x y) $
trans (cong (λ z → z ∙ y) (left-inv x)) $
(left-id y)
Standard library also gives us some nice syntactic sugar for this:
open ≡-Reasoning
lemma′ : ∀ x y → x ⁻¹ ∙ (x ∙ y) ≡ y
lemma′ x y = begin
x ⁻¹ ∙ (x ∙ y) ≡⟨ assoc (x ⁻¹) x y ⟩
(x ⁻¹ ∙ x) ∙ y ≡⟨ cong (λ z → z ∙ y) (left-inv x) ⟩
ε ∙ y ≡⟨ left-id y ⟩
y ∎
Behind the scenes, ≡⟨ ⟩ uses precisely trans to merge those proofs. The types are optional (the proofs themselves carry enough information about them), but they are here for readability.
To get your original Group record, we can do something like:
record Group : Set₁ where
field
Carrier : Set
_∙_ : Op₂ Carrier
ε : Carrier
_⁻¹ : Op₁ Carrier
isGroup : IsGroup _∙_ ε _⁻¹
open IsGroup isGroup public