I have made an emacs file trial_agda.agda with the following code:
module trial_agda where
data π : Set where
zero : π
suc : π β π
data _even : π β Set where
ZERO : zero even
STEP : β x β x even β suc (suc x) even
_+_ : π β π β π
(zero + n) = n
(suc n) + nβ² = suc (n + nβ²)
In http://learnyouanagda.liamoc.net/pages/proofs.html, the author writes:
Now weβll prove in Agda that four is even. Type the following into an emacs buffer, and type C-c C-l:
-- \_1 to type β
proofβ : suc (suc (suc (suc zero))) even
proofβ = ?
I typed C-c C-n and then copied and pasted the above code. I received the error Error: First load the file.
What has gone wrong?
It is required to add the code to the same emacs file, underneath the code defining the module and the types, etc.
This was not specified in the book.
Related
I am currently working on one of the recommended question from the chapter Negation in plfa
Here is the question description:
Using negation, show that strict inequality is irreflexive, that is, n < n holds for no n.
From my understanding, I think in strict inequality, it will take two natural numbers as the argument and output a set right? :
data _<_ : β β β β Set where
z<s : β {n : β}
------------
β zero < suc n
s<s : β {m n : β}
β m < n
-------------
β suc m < suc n
And here is my definition of irreflexive:
<-irreflexive : β {n : β} β n < n β β₯
<-irreflexive n<n = ?
I know that I need to achieve a "β₯" in the RHS. And since "n<n" is a set, I try to use Β¬, but the complier says "n<n" :(n < n) !=< Set. So, what is the type of "n<n" in this case? And am I approaching right in this question? Could anybody give me a hint on that? Thanks in advance !!!
You're on the right track! The trick is now to use the argument n<n for which there can be no real element to produce something of type β₯. We do this by pattern matching on n<n. Agda can already see that the constructor z<s can't possibly apply (this is morally equivalent of producing something of type β₯) so all that's left to do is to handle the s<s case:
<-irreflexive : β {n : β} β n < n β β₯
<-irreflexive (s<s n<n) = ?
However, we can now use recursion to produce the required element of type β₯
<-irreflexive : β {n : β} β n < n β β₯
<-irreflexive (s<s n<n) = <-irreflexive n<n
Tada, done!
I made an emacs file Prelude.agda containing the information on this page: http://www2.tcs.ifi.lmu.de/~abel/ssft18/lec1/Prelude.agda. After loading with C-c C-l I receive the error:
/Users/M/Prelude.agda:19,11-11 /Users/M/Prelude.agda:19,11::19,11: Parse error (n : Γ’ββ’) Γ’β β Γ’ββ’ -- To use ...
The error points to the following line:
data Γ’ββ’ : Set where
zero : Γ’ββ’
suc : (n : Γ’ββ’) Γ’β β Γ’ββ’
What is the parse error?
There is an encoding problem on the web page whose content you copy pasted in your emacs file, which is why it does not typecheck.
For example, the entity Γ’β β should be displayed β which is why Agda does not accept this specific definition because it thinks it should be some kind of operator defined earlier.
However, since the encoding problem is all over the file, replacing this specific instance of the problem would not solve it for the whole file.
Another example is Γ’ββ’ that should appear as β.
I corrected the file for you:
-- 8th Summer School on Formal Techniques
-- Menlo College, Atherton, California, US
--
-- 21-25 May 2018
--
-- Lecture 1: Introduction to Agda
--
-- File 1: The Curry-Howard Isomorphism
{-# OPTIONS --allow-unsolved-metas #-}
module Prelude where
-- Natural numbers as our first example of
-- an inductive data type.
data β : Set where
zero : β
suc : (n : β) β β
-- To use decimal notation for numerals, like
-- 2 instead of (suc (suc zero)), connect it
-- to the built-in natural numbers.
{-# BUILTIN NATURAL β #-}
-- Lists are a parameterized inductive data type.
data List (A : Set) : Set where
[] : List A
_β·_ : (x : A) (xs : List A) β List A -- \ : :
infixr 6 _β·_
-- C-c C-l load
-- Disjoint sum type.
data _β_ (S T : Set) : Set where -- \uplus
inl : S β S β T
inr : T β S β T
infixr 4 _β_
-- The empty sum is the type with 0 alternatives,
-- which is the empty type.
-- By the Curry-Howard-Isomorphism,
-- which views a proposition as the set/type of its proofs,
-- it is also the absurd proposition.
data False : Set where
β₯-elim : False β {A : Set} β A
β₯-elim () {A}
-- C-c C-SPC give
-- C-c C-, show hypotheses and goal
-- C-c C-. show hypotheses and infers type
-- Tuple types
-- The generic record type with two fields
-- where the type of the second depends on the value of the first
-- is called Sigma-type (or dependent sum), in analogy to
--
-- β β A = β A(n) = A(0) + A(1) + ...
-- n β β
record β (A : Set) (B : A β Set) : Set where -- \GS \Sigma
constructor _,_
field fst : A
snd : B fst
open β
-- module β {A : Set} {B : A β Set} (p : β A B) where
-- fst : A
-- fst = case p of (a , b) -> a
-- snd : B fst
-- snd = case p of (a , b) -> b
infixr 5 _,_
-- The non-dependent version is the ordinary Cartesian product.
_Γ_ : (S T : Set) β Set
S Γ T = β S Ξ» _ β T
infixr 5 _Γ_
-- The record type with no fields has exactly one inhabitant
-- namely the empty tuple record{}
-- By Curry-Howard, it corresponds to Truth, as
-- no evidence is needed to construct this proposition.
record True : Set where
test : True
test = _
-- C-c C-= show constraints
-- C-c C-r refine
-- C-c C-s solve
-- C-c C-SPC give
-- C-c C-a auto
-- Example: distributivity A Γ (B β C) β (A Γ B) β (A Γ C)
dist : β {A B C : Set} β A Γ (B β C) β (A Γ B) β (A Γ C)
dist (a , inl b) = inl (a , b)
dist (a , inr c) = inr (a , c)
dist' : β {A B : Set} β A Γ (B β A) β (A Γ B) β (A Γ A)
dist' (a , inl b) = inl (a , b)
dist' (a , inr c) = inr (c , c)
-- Relations
-- Type-theoretically, the type of relations over (AΓA) is
--
-- A Γ A β Prop
--
-- which is
--
-- A Γ A β Set
--
-- by the Curry-Howard-Isomorphism
-- and
--
-- A β A β Set
--
-- by currying.
Rel : (A : Set) β Setβ
Rel A = A β A β Set
-- Less-or-equal on natural numbers
_β€_ : Rel β
zero β€ y = True
suc x β€ zero = False
suc x β€ suc y = x β€ y
-- C-c C-l load
-- C-c C-c case split
-- C-c C-, show goal and assumptions
-- C-c C-. show goal and assumptions and current term
-- C-c C-SPC give
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.
Since Agda is intuitionistic one has to postulate the law of excluded middle. But as far as I know, intuitionistic logic accepts ex falso quodlibet or the principle of explosion (the theorem that everything follows from absurdity). How can one prove this postulate:
data β₯ : Set where
postulate exp : β {n} {x : Set n} β β₯ β x
One can prove the principle of explosion as follows
data β₯ : Set where
exp : β {n} {x : Set n} β β₯ β x
exp ()
If one does not know how to prove this, one may start with a hole:
data β₯ : Set where
exp : β {n} {x : Set n} β β₯ β x
exp absurd = {! !}
Then, in emacs agda2-mode one can press C-c C-l to typecheck, so that hole will be replaced and emacs will show the target. In this case target is of type .x. Then one can click on that hole and press C-c C-c and type absurd to split this function by variable absurd. Emacs will produce the final result as given above.
All negations, i.e. conclusions of the form A -> Bottom in agda that I've seen came from absurd pattern matchings. Are there any other cases where it's possible to get negation in agda? Are there any other cases in dependent type theory where it's possible?
Type theories usually don't have a notion of pattern matching (and by extension absurd patterns) and yet they can prove negation of the sort you are describing.
First of all, we'll have to look at data types. Without pattern matching, you characterise them by introduction and elimination rules. Introduction rules are basically constructors, they tell you how to construct a value of that type. On the other hand, elimination rules tell you how to use a value of that type. There are also associated computation rules (Ξ²-reduction and sometimes Ξ·-reduction), but we needn't deal with those now.
Elimination rules look a bit like folds (at least for positive types). For example, here's how an elimination rule for natural numbers would look like in Agda:
β-elim : β {p} (P : β β Set p)
(s : β {n} β P n β P (suc n))
(z : P 0) β
β n β P n
β-elim P s z zero = z
β-elim P s z (suc n) = s (β-elim P s z n)
While Agda does have introduction rules (constructors), it doesn't have elimination rules. Instead, it has pattern matching and as you can see above, we can recover the elimination rule with it. However, we can also do the converse: we can simulate pattern matching using elimination rules. Truth be told, it's usually much more inconvenient, but it can be done - the elimination rule mentioned above basically does pattern matching on the outermost constructor and if we need to go deeper, we can just apply the elimination rule again.
So, we can sort of simulate pattern matching. What about absurd patterns? As an example, we'll take fourth Peano axiom:
peano : β n β suc n β‘ zero β β₯
However, there's a trick involved (and in fact, it's quite crucial; in Martin-LΓΆf's type theory without universes you cannot do it without the trick, see this paper). We need to construct a function that will return two different types based on its arguments:
Nope : (m n : β) β Set
Nope (suc _) zero = β₯
Nope _ _ = β€
If m β‘ n, we should be able to prove that Nope m n holds (is inhabitated). And indeed, this is quite easy:
nope : β m n β m β‘ n β Nope m n
nope zero ._ refl = _
nope (suc m) ._ refl = _
You can now sort of see where this is heading. If we apply nope to the "bad" proof that suc n β‘ zero, Nope (suc n) zero will reduce to β₯ and we'll get the desired function:
peano : β n β suc n β‘ zero β β₯
peano _ p = nope _ _ p
Now, you might notice that I cheated a bit. I used pattern matching even though I said earlier that these type theories don't come with pattern matching. I'll remedy that for the next example, but I suggest you try to prove peano without pattern matching on the numbers (use β-elim given above); if you really want a hardcore version, do it without pattern matching on equality as well and use this eliminator instead:
J : β {a p} {A : Set a} (P : β (x : A) y β x β‘ y β Set p)
(f : β x β P x x refl) β β x y β (p : x β‘ y) β P x y p
J P f x .x refl = f x
Another popular absurd pattern is on something of type Fin 0 (and from this example, you'll get the idea how other such absurd matches could be simulated). So, first of all, we'll need eliminator for Fin.
Fin-elim : β {p} (P : β n β Fin n β Set p)
(s : β {n} {fn : Fin n} β P n fn β P (suc n) (fsuc fn))
(z : β {n} β P (suc n) fzero) β
β {n} (fn : Fin n) β P n fn
Fin-elim P s z fzero = z
Fin-elim P s z (fsuc x) = s (Fin-elim P s z x)
Yes, the type is really ugly. Anyways, we're going to use the same trick, but this time, we only need to depend on one number:
Nope : β β Set
Nope = β-elim (Ξ» _ β Set) (Ξ» _ β β€) β₯
Note that is equivalent to:
Nope zero = β₯
Nope (suc _) = β€
Now, notice that both cases for the eliminator above (that is, s and z case) return something of type P (suc n) _. If we choose P = Ξ» n _ β Nope n, we'll have to return something of type β€ for both cases - but that's easy! And indeed, it was easy:
bad : Fin 0 β β₯
bad = Fin-elim (Ξ» n _ β Nope n) (Ξ» _ β _) _
The last thing you might be wondering about is how do we get value of any type from β₯ (known as ex falso quodlibet in logic). In Agda, we obviously have:
β₯-elim : β {w} {Whatever : Set w} β β₯ β Whatever
β₯-elim ()
But it turns out that this is precisely the eliminator for β₯, so it is given when defining this type in type theory.
Are you asking for something like
open import Relation.Nullary
β-transposition : {P Q : Set} β (P β Q) β Β¬ Q β Β¬ P
β-transposition pβq Β¬q p = Β¬q (pβq p)
?