How can I use agda2-mode to generate patterns when I expect to see an absurd pattern? - emacs

For example, we're proving 2 + 2 != 5:
data _+_≡_ : ℕ → ℕ → ℕ → Set where
znn : ∀ {n} → zero + n ≡ n
sns : ∀ {m n k} → m + n ≡ k → suc m + n ≡ suc k
And I can manually prove it:
2+2≠5 : 2 + 2 ≡ 5 → ⊥
2+2≠5 (sns (sns ()))
But I want the pattern (sns (sns ())) to be generated (just like filling a hole). Are there any ways to achieve that?
I am using Emacs 25 with agda2-mode.

Ok, so let's say you start from this configuration:
2+2≠5 : 2 + 2 ≡ 5 → ⊥
2+2≠5 h = {!!}
In this case you can use emacs' keyboard macros because the sub-term generated by matching on h will also be named h. So using:
<f3> (start recording the macro)
C-c C-f (move to the hole)
C-c C-c h RET (match on h)
<f4> (record the macro)
you've recorded the action of "moving to the first goal an matching on h". You can now keep pressing <f4> until you reach an absurd case.

Related

How to prove two statements in propositional logic using LEAN?

Two proofs at the end of chapter 3 in the LEAN tutorial that I still struggle with (and hence prevent me from going further with reading the manual) are the following:
theorem T11 : ¬(p ↔ ¬p) := sorry
for which my attempt to prove the right implication stopped at this point:
theorem T11R : ¬(p → ¬p) :=
begin
assume hyp : p → ¬ p,
cases (em p) with hp hnp,
exact (hyp hp) hp,
exact sorry
end
as obviously I don't know yet how to make use of ¬p. Not sure how to show the left implication either. The other one is this:
theorem T2R : ((p ∨ q) → r) → (p → r) ∧ (q → r) :=
begin
intros porqr, sorry
end
which I'm supposedly using (as the right implication) to show the following:
theorem T2 : ((p ∨ q) → r) ↔ (p → r) ∧ (q → r) :=
begin
have goR : ((p ∨ q) → r) → (p → r) ∧ (q → r), from T2R p q r,
have goL : (p → r) ∧ (q → r) → ((p ∨ q) → r), from T2L p q r,
exact iff.intro (goR) (goL)
end
Here I got the left-side going:
theorem T2L : (p → r) ∧ (q → r) → ((p ∨ q) → r) :=
begin
intros prqr,
assume porq : p ∨ q,
exact or.elim porq prqr.left prqr.right
end
theorem T11R is not true, for example if p is false then p → ¬ p is true.
¬(p ↔ ¬p) is not equivalent to (¬ (p → ¬ p)) ∧ ¬ (¬ p → p); it's equivalent to ¬ ((p → ¬ p) ∧ (¬ p → p)), which is different.
For theorem T2R if you use the split tactic, it will give you two goals, one for each side of the and. You can use the left and right tactics to turn the goal p ∨ q into either p or q. The theorems or.inl and or.inr can be used to prove an or as well.
Here's a proof of T2R
theorem T2R : ((p ∨ q) → r) → (p → r) ∧ (q → r) :=
begin
intros porqr,
split,
{ assume hp : p,
apply porqr,
left,
exact hp },
{ assume hq : q,
apply porqr,
right,
exact hq },
end

What is the Parigot Mendler encoding?

The following encoding of Nats is used in some Cedille sources:
cNat : ★
cNat = ∀ X : ★ . X ➔ (∀ R : ★ . (R ➔ X) ➔ R ➔ X) ➔ X
cZ : cNat
cZ = Λ X . λ z . λ s . z
cS : ∀ A : ★ . (A ➔ cNat) ➔ A ➔ cNat
cS = Λ A . λ e . λ d . Λ X . λ z . λ s . s · A (λ a . e a · X z s) d
I wonder if this is a common encoding used in other languages (Agda, Idris, Coq). If so, how can I interpret it, how it works, and how can I construct members of this type?
I've tried applying cS as in:
c0 = cZ
c1 = (cS -CNat (λ p : CNat . p) C0)
c2 = (cS -CNat (λ p : CNat . p) C1)
c3 = (cS -CNat (λ p : CNat . p) C2)
Which checks, but looks rather weird to me. p could be replaced by any cNat inside lambdas, for example. This doesn't look isomorphic to cNat to me. I guess I don't get this structure.
Edit by JC (too long for a comment, isn't an answer at all). For those who want to experiment, here's an Agda rendering.
module Mendler where
open import Level renaming (suc to lsuc)
open import Data.Nat
cNat : (ℓ : Level) → Set (lsuc ℓ)
cNat ℓ = (X : Set ℓ) → X → ((R : Set ℓ) → (R → X) → R → X) → X
private
variable
ℓ : Level
cZ : cNat ℓ
cZ X z s = z
cS : (A : Set ℓ) → (A → cNat ℓ) → A → cNat ℓ
cS A e d X z s = s A (λ a → e a X z s) d
c0 : cNat 0ℓ
c0 = cZ
c1 : cNat 0ℓ
c1 = cS ℕ (λ _ → c0) 0

Do agda programs necessarily terminate?

It has been stated a few places that all agda programs terminate. However I can construct a function like this:
stall : ∀ n → ℕ
stall 0 = 0
stall x = stall x
The syntax highlighter doesn't seem to like it, but there are no compilation errors.
Computing the normal form of stall 0 results in 0. Computing the result of stall 1 causes Emacs to hang in what looks a lot like a non-terminating loop.
Is this a bug? Or can Agda sometimes run forever? Or is something more subtle going on?
In fact, there are compilation errors. The agda executable finds an error and passes that information to agda-mode in Emacs, which in turn does the syntax highlighting to let you know there was an error. We can take a look at what happens if we use agda directly. Here's the file I'm using:
module C1 where
open import Data.Nat
loop : ℕ → ℕ
loop 0 = 0
loop x = loop x
Now, we call agda -i../lib-0.7/src -i. C1.agda (don't mind the -i parameters, they just let the executable know where to look for the standard library) and we get the error:
Termination checking failed for the following functions:
loop
Problematic calls:
loop x
(at D:\Agda\tc\C1.agda:7,10-14)
This is indeed compilation error. Such errors prevent us from importing this module from other modules or compiling it. For example, if we add these lines to the file above:
open import IO
main = run (putStrLn "")
And compile the module using C-c C-x C-c, agda-mode complains:
You can only compile modules without unsolved metavariables
or termination checking problems.
Other kinds of compilation errors include type checking problems:
module C2 where
open import Data.Bool
open import Data.Nat
type-error : ℕ → Bool
type-error n = n
__________________________
D:\Agda\tc\C2.agda:7,16-17
ℕ !=< Bool of type Set
when checking that the expression n has type Bool
Failed positivity check:
module C3 where
data Positivity : Set where
bad : (Positivity → Positivity) → Positivity
__________________________
D:\Agda\tc\C3.agda:3,6-16
Positivity is not strictly positive, because it occurs to the left
of an arrow in the type of the constructor bad in the definition of
Positivity.
Or unsolved metavariables:
module C4 where
open import Data.Nat
meta : ∀ {a} → ℕ
meta = 0
__________________________
Unsolved metas at the following locations:
D:\Agda\tc\C4.agda:5,11-12
Now, you rightly noticed that some errors are "dead ends", while others let you carry on writing your program. That's because some errors are worse than others. For example, if you get unsolved metavariable, chances are that you'll be able to just fill in the missing information and everything will be okay.
As for hanging the compiler: checking or compiling a module shouldn't cause agda to loop. Let's try to force the type checker to loop. We'll add more stuff into the module C1:
data _≡_ {a} {A : Set a} (x : A) : A → Set a where
refl : x ≡ x
test : loop 1 ≡ 1
test = refl
Now, to check that refl is correct expression of that type, agda has to evaluate loop 1. However, since the termination check failed, agda will not unroll loop (and end up in an infinite loop).
However, C-c C-n really forces agda to try to evaluate the expression (you basically tell it "I know what I'm doing"), so naturally you get into an infinite loop.
Incidentally, you can make agda loop if you disable the termination check:
{-# NO_TERMINATION_CHECK #-}
loop : ℕ → ℕ
loop 0 = 0
loop x = loop x
data _≡_ {a} {A : Set a} (x : A) : A → Set a where
refl : x ≡ x
test : loop 1 ≡ 1
test = refl
Which ends up in:
stack overflow
As a rule of thumb: if you can make agda loop by checking (or compiling) a module without using any compiler pragmas, then this is indeed a bug and should be reported on the bug tracker. That being said, there are few ways to make non-terminating program if you are willing to use compiler pragmas. We've already seen {-# NO_TERMINATION_CHECK #-}, here are some other ways:
{-# OPTIONS --no-positivity-check #-}
module Boom where
data Bad (A : Set) : Set where
bad : (Bad A → A) → Bad A
unBad : {A : Set} → Bad A → Bad A → A
unBad (bad f) = f
fix : {A : Set} → (A → A) → A
fix f = (λ x → f (unBad x x)) (bad λ x → f (unBad x x))
loop : {A : Set} → A
loop = fix λ x → x
This one relies on a data type which is not strictly positive. Or we could force agda to accept Set : Set (that is, the type of Set is Set itself) and reconstruct Russell's paradox:
{-# OPTIONS --type-in-type #-}
module Boom where
open import Data.Empty
open import Data.Product
open import Relation.Binary.PropositionalEquality
data M : Set where
m : (I : Set) → (I → M) → M
_∈_ : M → M → Set
a ∈ m I f = Σ I λ i → a ≡ f i
_∉_ : M → M → Set
a ∉ b = (a ∈ b) → ⊥
-- Set of all sets that are not members of themselves.
R : M
R = m (Σ M λ a → a ∉ a) proj₁
-- If a set belongs to R, it does not contain itself.
lem₁ : ∀ {X} → X ∈ R → X ∉ X
lem₁ ((Y , Y∉Y) , refl) = Y∉Y
-- If a set does not contain itself, then it is in R.
lem₂ : ∀ {X} → X ∉ X → X ∈ R
lem₂ X∉X = (_ , X∉X) , refl
-- R does not contain itself.
lem₃ : R ∉ R
lem₃ R∈R = lem₁ R∈R R∈R
-- But R also contains itself - a paradox.
lem₄ : R ∈ R
lem₄ = lem₂ lem₃
loop : {A : Set} → A
loop = ⊥-elim (lem₃ lem₄)
(source). We could also write a variant of Girard's paradox, simplified by A.J.C. Hurkens:
{-# OPTIONS --type-in-type #-}
module Boom where
⊥ = ∀ p → p
¬_ = λ A → A → ⊥
℘_ = λ A → A → Set
℘℘_ = λ A → ℘ ℘ A
U = (X : Set) → (℘℘ X → X) → ℘℘ X
τ : ℘℘ U → U
τ t = λ (X : Set) (f : ℘℘ X → X) (p : ℘ X) → t λ (x : U) → p (f (x X f))
σ : U → ℘℘ U
σ s = s U λ (t : ℘℘ U) → τ t
τσ : U → U
τσ x = τ (σ x)
Δ = λ (y : U) → ¬ (∀ (p : ℘ U) → σ y p → p (τσ y))
Ω = τ λ (p : ℘ U) → ∀ (x : U) → σ x p → p x
loop : (A : Set) → A
loop = (λ (₀ : ∀ (p : ℘ U) → (∀ (x : U) → σ x p → p x) → p Ω) →
(₀ Δ λ (x : U) (₂ : σ x Δ) (₃ : ∀ (p : ℘ U) → σ x p → p (τσ x)) →
(₃ Δ ₂ λ (p : ℘ U) → (₃ λ (y : U) → p (τσ y)))) λ (p : ℘ U) →
₀ λ (y : U) → p (τσ y)) λ (p : ℘ U) (₁ : ∀ (x : U) → σ x p → p x) →
₁ Ω λ (x : U) → ₁ (τσ x)
This one is a real mess, though. But it has a nice property that it uses only dependent functions. Strangely, it doesn't even get past type checking and causes agda to loop. Splitting the whole loop term into two helps.
The syntax highlighting you are seeing is a compile error. The termination checker's effect is to highlight non-terminating functions in a kind of pink-orange color ("salmon"). You may notice that a module containing such an error cannot be imported from other modules. It can also not be compiled down to Haskell.
So yes, Agda programs always terminate and this is not a bug.

Proving a type empty in Agda

I am trying to prove 2*3!=5 in agda. To do this I will define a function with a signature 2 * 3 ≡ 5 → ⊥.
making use of my definition of multiplication
data _*_≡_ : ℕ → ℕ → ℕ → Set where
base : ∀ {n} → 0 * n ≡ 0
succ : ∀ {n m k j} → m * n ≡ j → j + n ≡ k → suc m * n ≡ k
I have proven
1*3≡3 : 1 * 3 ≡ 3
1*3≡3 = (succ base) znn
and
3+3≡5 : 3 + 3 ≡ 5 → ⊥
3+3≡5 (sns (sns (sns ())))
But when I try to prove:
m235 : 2 * 3 ≡ 5 → ⊥
m235 ( ( succ 1*3≡3 ) ( x ) ) = ( 3+3≡5 x )
the compiler spits out this error about x
.j != (suc 2) of type ℕ
when checking that the expression x has type 3 + 3 ≡ 5
Sorry if this is a stupid question. Thanks in advance.
First of all, you forgot to include the definition of _+_≡_. I assume it's as follows:
data _+_≡_ : ℕ → ℕ → ℕ → Set where
znn : ∀ {n} → 0 + n ≡ n
sns : ∀ {n m k} → n + m ≡ k → suc n + m ≡ suc k
Next, your problem is not with finding the correct syntax, but you have to figure out how you can conclude from a value of type 2 * 3 ≡ 5. With the pattern matching you have done, you can ask Agda what values are available in the context, by replacing the right-hand-side with a ?, calling C-c C-l to compile and using C-c C-, to ask for the context:
m235 : 2 * 3 ≡ 5 → ⊥
m235 ( ( succ 1*3≡3 ) ( x ) ) = ?
Agda will say:
Goal : ⊥
-----------------------------
x : .j + 3 ≡ 5
1*3≡3 : 1 * 3 ≡ .j
.j : ℕ
That is: you are looking to prove bottom (i.e. an inconsistency from the assumptions) and you have 3 values available in the context. You have a proof of type 1 * 3 ≡ .j, for an unknown number .j as well as a proof of type .j + 3 ≡ 5. You seem to assume that Agda can automatically notice that j must be 3, but this is too difficult for it: it will only conclude things here from unification, not perform actual reasoning itself. So the solution is to help Agda understand why .j must be 3. You can do this by further pattern matching on the proof of type 1 * 3 ≡ .j:
m235 : 2 * 3 ≡ 5 → ⊥
m235 ((succ (succ base znn)) sum) = ?
Now the context looks as follows:
Goal: ⊥
————————————————————————————————————————————————————————————
x : 3 + 3 ≡ 5
You can now finish by combining the proof x of type 3 + 3 ≡ 5 with your previous proof that such a proof cannot exist:
m235 : 2 * 3 ≡ 5 → ⊥
m235 (succ (succ base znn) x) = 3+3≡5 x
UPDATE: I missed it in my first reading, but there is a misunderstanding in the question that I missed and failed to explain. The error is in the following code:
m235 : 2 * 3 ≡ 5 → ⊥
m235 (succ 1*3≡3 x) = 3+3≡5 x
The misunderstanding here is that the variable name 1*3≡3 in the left-hand side of this clause does NOT refer to the previously defined value by the same name. Rather, it introduces a fresh new variable which is known by Agda to have the same type, but whose value is not known by it.
What you were expecting can be achieved by using the "pattern synonyms" feature that was introduced in Agda 2.3.2: see the release notes:
pattern 1*3≡3 = (succ base) znn
m235 : 2 * 3 ≡ 5 → ⊥
m235 (succ 1*3≡3 x) = 3+3≡5 x
Only pattern synonyms are expanded in patterns, other values aren't.

Eliminating subst to prove equality

I'm trying to representat mod-n counters as a cut of the interval [0, ..., n-1] into two parts:
data Counter : ℕ → Set where
cut : (i j : ℕ) → Counter (suc (i + j))
Using this, defining the two crucial operations is straightforward (some proofs omitted for brevity):
_+1 : ∀ {n} → Counter n → Counter n
cut i zero +1 = subst Counter {!!} (cut zero i)
cut i (suc j) +1 = subst Counter {!!} (cut (suc i) j)
_-1 : ∀ {n} → Counter n → Counter n
cut zero j -1 = subst Counter {!!} (cut j zero)
cut (suc i) j -1 = subst Counter {!!} (cut i (suc j))
The problem comes when trying to prove that +1 and -1 are inverses. I keep running into situations where I need an eliminator for these substs introduced, i.e. something like
subst-elim : {A : Set} → {B : A → Set} → {x x′ : A} → {x=x′ : x ≡ x′} → {y : B x} → subst B x=x′ y ≡ y
subst-elim {A} {B} {x} {.x} {refl} = refl
but this turns out to be (somewhat) begging the question: it isn't accepted by the type checker, because subst B x=x' y : B x' and y : B x...
you can state the type of your subst-elim if you use Relation.Binary.HeterogeneousEquality from the stdlib.
However i'd probably just pattern match on the eventual proof of x ≡ x′ in a with or rewrite clause, so you don't have to make an explicit eliminator and so no typing problem.