I am trying to proof inverse property over integer (which is represented as setoid i.e (a , b) represents a - b.)
I have defined the negation part as - (a , b) = (b , a):
-_ : ℤ -> ℤ
- (x , y) = (y , x)
is0 : ℤ → Set
is0 (a , b) = a ≡ b
leftInverse : (x : ℤ) → - x + x ≡ zero
leftInverse (x , x₁) = {!!}
The goal of this is : (x₁ ℕ.+ x) , (x ℕ.+ x₁) ≡ 0 , 0
I can not use cong₂ here. I am thinking of using if else statement but I dont know that it will be proof. How should i proceed??
Related
I was asked to finish one of the recommended question from plfa:
Exercise ⇔≃× (recommended)
Show that A ⇔ B as defined earlier is isomorphic to (A → B) × (B → A).
I know I need to prove some property of equivalence first, and here is my proof:
record _⇔_ (A B : Set) : Set where
field
to : A → B
from : B → A
⇔-refl : ∀ {A : Set} → A ⇔ A
⇔-refl =
record
{ to = λ{x → x}
; from = λ{y → y}
}
⇔-sym : ∀ {A B : Set}
→ A ⇔ B
→ B ⇔ A
⇔-sym A⇔B =
record
{ to = _⇔_.from A⇔B
; from = _⇔_.to A⇔B
}
⇔-trans : ∀ {A B C : Set}
→ A ⇔ B
→ B ⇔ C
→ A ⇔ C
⇔-trans A⇔B B⇔C =
record
{ to = (_⇔_.to B⇔C) ∘ (_⇔_.to A⇔B )
; from = (_⇔_.from A⇔B) ∘ (_⇔_.from B⇔C )
}
And now, from my understanding, I need to prove
⇔≃× : ∀ {A B : Set} → A ⇔ B ≃ (A → B) × (B → A)
So to prove this, we need to prove four sections: "to" "from" "from∘to" "to∘from"
⇔≃× : ∀ {A B : Set} → (A ⇔ B) ≃ ((A → B) × (B → A))
⇔≃× =
record
{ to = λ{ x ⇔ y → ⟨ ( x → y ) , ( y → x ) ⟩ }
; from = ?
; from∘to = ?
; to∘from = ?
}
But when I finish the "to" section, I want to see if it can pass. So I compile and I got this error message:
Cannot eliminate type (A → B) × (B → A) with variable pattern ⇔(did you supply too many arguments?)when checking the clause left hand side.extendedlambda2 x ⇔ y
Can anyone give some explanation on this type of error message?
Thanks in advance
λ{ x ⇔ y → binds three arguments: x, ⇔, and y but the function you're supposed to define only takes one.
I'm experimenting with Homotopy Type Theory in Agda. I use HITs to define the integers:
{-# OPTIONS --cubical --safe #-}
open import Cubical.Foundations.Prelude
open import Data.Nat using (ℕ; _+_)
data ℤ : Set where
-- | An integer i is a pair of natural numbers (m, n)
-- where i = m - n
int : ℕ → ℕ → ℤ
-- | (a, b) = (c, d)
-- a - b = c - d
-- a + d = b + c
int-eq : ∀ {a b c d : ℕ} → (a + d ≡ b + c) → int a b ≡ int c d
Now, I want to define addition on the integers:
add-ints : ℤ → ℤ → ℤ
add-ints (int a b) (int c d) = int (a + c) (b + d)
However, the compiler gives an error because I need to pattern match the equality constructors as well:
Incomplete pattern matching for add-ints. Missing cases:
add-ints (int-eq x i) (int x₁ x₂)
add-ints x (int-eq x₁ i)
when checking the definition of add-ints
So, I end up with this:
add-ints : ℤ → ℤ → ℤ
add-ints (int a b) (int c d) = int (a + c) (b + d)
add-ints (int-eq x i) (int c d) = { }0
add-ints (int a b) (int-eq x i) = { }1
add-ints (int-eq x i) (int-eq y j) = { }2
Agda's typed holes don't help:
?0 : ℤ
?1 : ℤ
?2 : ℤ
———— Errors ————————————————————————————————————————————————
Failed to solve the following constraints:
?0 (x = x) (i = i) (c = a) (d = b)
= ?2 (x = x) (i = i) (y = x₁) (j = i0)
: ℤ
?0 (x = x) (i = i) (c = c) (d = d)
= ?2 (x = x) (i = i) (y = x₁) (j = i1)
: ℤ
?1 (a = a₁) (b = b₁) (x = x₁) (i = i)
= ?2 (x = x) (i = i0) (y = x₁) (j = i)
: ℤ
?1 (a = c₁) (b = d₁) (x = x₁) (i = i)
= ?2 (x = x) (i = i1) (y = x₁) (j = i)
: ℤ
int (a + x) (b + x₁) = ?0 (x = x₂) (i = i0) (c = x) (d = x₁) : ℤ
int (c + x) (d + x₁) = ?0 (x = x₂) (i = i1) (c = x) (d = x₁) : ℤ
int (x + a) (x₁ + b) = ?1 (a = x) (b = x₁) (x = x₂) (i = i0) : ℤ
int (x + c) (x₁ + d) = ?1 (a = x) (b = x₁) (x = x₂) (i = i1) : ℤ
The Agda documentation gives examples of HIT usage, where it pattern matches on the equality constructors when operating on the torus and propositional truncation. However, as someone without a background in topology, I don't completely follow what's going on.
What is the purpose of the i and j from the [0, 1] interval, and why do they appear in my equality constructor patterns? How do I use i and j? How do I handle the higher inductive cases?
You can think of path constructors as taking an interval variable, and satisfying additional equations about the endpoints of that interval,
data ℤ : Set where
int : ℕ → ℕ → ℤ
int-eq : ∀ {a b c d : ℕ} → (a + d ≡ b + c) → I → ℤ
-- such that int-eq {a} {b} {c} {d} _ i0 = int a b
-- and int-eq {a} {b} {c} {d} _ i1 = int c d
In your equations for add-ints of int-eq you also have to produce a ℤ, and it has to match the first clause (for the int constructor) at both endpoints. These are the constraints that Agda reports, saying that the different clauses have to agree.
You can start with ?0 first. For which only the last two contraints matter. It helps here to fill in the implicit variables,
add-ints (int-eq {a0} {b0} {a1} {b1} x i) (int c d) = { }0
To match the first clause, you need to come up with a value of type ℤ that is equal to int (a0 + c) (b0 + d) when i = i0 and equal to int (a1 + c) (b1 + d) when i = i1. You can use an int-eq constructor for this,
?0 = int-eq {a0 + c} {b0 + d} {a1 + c} {b1 + d} ?4 i
The equality ?4 has to be worked out.
I have define the datatype of real number as..
record ℝ : Set where
field
L : Stream pair
R : Stream pair
inhabited : ∀ (x : pair) → ( (x mem L) or (x mem R))
disjoint : ∀ (x : pair) → ( (not (x mem L)) or (not (x mem R)))
located : ∀ (x y : pair) → (x ≤pair y) → ((x mem L) or (y mem R))
Now I want to define an element of type R . I tried as..
mkReal : Stream pair -> Stream pair -> R
mkReal x y = record { L = x; R = y}.
But this is not working please help.
Your record ℝ has five fields, L, R, inhabited, disjoint, and located. To define an instance of ℝ, you have to supply values for all five fields:
mkReal x y = record { L = x; R = y; inhabited = ?; disjoint = ?; located = ? }
You will likely have to pass the values of inhabited, disjoint, and located as arguments to mkReal as well.
By the way, there is a way to automatically define a constructor for your record:
record ℝ : Set where
constructor mkReal
field
L : Stream pair
R : Stream pair
inhabited : ∀ (x : pair) → ((x mem L) or (x mem R))
disjoint : ∀ (x : pair) → ((not (x mem L)) or (not (x mem R)))
located : ∀ (x y : pair) → (x ≤pair y) → ((x mem L) or (y mem R))
As a bonus, you can now use mkReal when pattern matching:
foo : ℝ → ?
foo (mkReal L R inhabited disjoint located) = ?
After hours of trying different versions of it, I give up. I just want to typecheck a proof of the transitivity of equality as stated in the HoTT-Book. I'm new to Agda so it might be just a small flaw or perhaps a bigger one... dont know. I consulted different libs for HoTT in Agda, but the ones I found had (in my eyes) rather complex solutions.
trans : ∀ {ℓ} (A : Type ℓ) (x y : A)
→ (x == y) → (z : A) → (y == z) → (x == z)
trans A x y = pathInd (λ p → (z : A) → (y == z) → (x == z))
(λ x → pathInd (λ x → (z : A) → (x == z) → (x == z))) (λ x → refl x))
Its based on the following implementation of path induction.
pathInd : ∀ {m n} {A : Type m} (P : {x y : A} → (x == y) → Type n) →
(∀ x → P (refl x)) → ∀ {x y} (p : (x == y)) → P p
pathInd P r (refl x) = r _
Thanks for any help.
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