Definition of choice in Lean - lean

In Lean, the axiom choice is implemented as follows:
axiom choice {α : Sort u} : nonempty α → α
Given only the assertion h that α is nonempty, choice h magically produces an element of α.
Now if I read literature (Jech) on set theory and the axiom of choice:
Axiom of Choice (AC). Every family of nonempty sets has a choice function.
If S is a family of sets and ∅ not in S, then a choice function for S is a function f on S such that f(X) ∈ X for every X ∈ S.
To me, these things don't seem to be equivalent. Can someone elaborate on this?

The axiom choice in Lean is indeed not the same as the axiom of choice in set theory. The axiom choice in Lean doesn't really have a corresponding statement in set theory. It says that there is a function that takes a proof that some type α is nonempty, and produces an inhabitant of α. In set theory, we cannot define functions that take proofs as arguments since proofs are not objects in set theory; they are in the layer of logic on top of that.
That said, the two choice axioms are not completely unrelated. From Lean's axiom choice, you can prove the more familiar axiom of choice from set theory, which you can find here:
theorem axiomOfChoice {α : Sort u} {β : α → Sort v} {r : ∀ x, β x → Prop}
(h : ∀ x, ∃ y, r x y) : ∃ (f : ∀ x, β x), ∀ x, r x (f x) :=
⟨_, fun x => choose_spec (h x)⟩
In other parts of the library, other equivalent statements to the axiom of choice are proven, like the one stating that every surjective function has a right inverse.
Maybe the statement closest to the version of the axiom of choice you quoted is the following:
theorem axiomOfChoice' {α : Sort u} {β : α → Sort v} (h : ∀ x, Nonempty (β x)) :
Nonempty (∀ x, β x) :=
⟨fun x => Classical.choice (h x)⟩
In words, this says that given a family of nonempty types (sets), the type of choice functions is nonempty. As you can see the proof is immediate from Lean's choice.

Related

Does * in (<*>) have a special meaning?

Trying to expand my understanding about symbols in Haskell :
($) : Function Application operator (Allow you to apply arguments over a function)
(&) : flipped version of Function Application Operator? (&) = flip ($)
(<>) : associative operator (You'll find it in Semigroups and Monoids)
(<$>) : function application ($) lifted over a Functor structure
(<&>) : flipped functor map
Can we make a link between (*) and (<*>)?
I don't understand the meaning of * actually...
This is deliberate. <*> has characteristics of a tensor product. This is best seen in the list monad:
Prelude> (,) <$> ['a'..'e'] <*> [0..4]
[('a',0),('a',1),('a',2),('a',3),('a',4)
,('b',0),('b',1),('b',2),('b',3),('b',4)
,('c',0),('c',1),('c',2),('c',3),('c',4)
,('d',0),('d',1),('d',2),('d',3),('d',4)
,('e',0),('e',1),('e',2),('e',3),('e',4)]
More generally, applicative functors (aka monoidal functors) map from the product of two objects (i.e. product type, aka tuple or via currying two function arguments) behind the functor to the functor-result of a product before the functor. So it's a pretty product-ey operation indeed.
φA,B: F A ∙ F B → F(A⊗B)
...in Haskell,
φ :: (f a, f b) -> f (a,b)
φ = uncurry (liftA2 (,))
-- recall `liftA2 f x y = f <$> x <*> y`
or even
{-# LANGUAGE TypeOperators #-}
type x ⊗ y = (x,y)
φ :: f a ⊗ f b -> f (a⊗b)
To see the historical side, look into McBride and Paterson 2008 (doi:10.1017/S0956796807006326), the paper that first introduced the Applicative typeclass. They note
The Applicative class features the asymmetrical operation ⊛, but there is an equivalent symmetrical definition.class Functor f -> Monoidal f where
unit :: f ()
(★) :: f a -> f b -> f (a,b)
These operations are clearly definable for any Applicative functor...
So, the <*> is an ASCII rendition of McBride and Paterson's ⊛ operator, which in turn is an “applicativised” form of ★ which the category theorists call, in uncurried form, φ.

Name for a type constructor that is both a category and a monad?

Is there any standard name for a type constructor F :: * -> * -> * -> * with operations
return :: x -> F a a x
bind :: F a b x -> (x -> F b c y) -> F a c y
that is a contravariant functor in the first argument and a covariant functor in the second and third? In particular, does this correspond to any kind construction in category theory?
The operations give rise to a
join :: F a b (F b c x) -> F a c x
operation that makes this seem like some kind of "category in the category of endofunctors", but I'm not sure how that could be formalised.
EDIT: As chi points out, this is related to the indexed monad: given an indexed monad
F' : (* -> *) -> (* -> *)
we can use the Atkey construction
data (:=) :: * -> * -> * -> *
V :: x -> (x := a) a
and then define
F a b x = F' (x := b) a
to get the kind of monad we want. I've done the construction in Agda to check. I'd still like to know whether this more limited structure is known, though.
As pointed out in the comments, this is the notion of a Parametrised Monad introduced by Robert Atkey in his Parametrised Notions of Computation paper. This corresponds to the notion of a category enriched over a category of endofunctors in category theory.
For a category C to be enriched over a category V with monoidal structure (I, x) means that for every objects X, Y of C, the Hom-object Hom(X, Y) is an object of V, and there exist morphisms that give the identity and composition, I -> Hom(X, X) and Hom(Y, Z) x Hom(X, Y) -> Hom(X, Z). Certain idenity and associativity conditions must hold, corresponding to the usual requirements of identity and associativity for a category.
A monad M on C can be seen as a one-object category enriched over endofunctors on C. Since there is only one object X, there is also one Hom-object Hom(X, X), which is M. The return operation gives rise to an identity morphism, a natural transformation I -> M, and the join operation gives rise to a composition morphism, a natural transformation M x M -> M. The identity and associativity conditions then correspond exactly to those of a monad.
A parametrised monad M on C with parameters taken from some set S can be seen as a category with elements of S as objects, enriched over the endofunctors of C. The Hom-object Hom(X, Y) is M X Y and the return and join operations described in the question again give rise to the families of morphisms required.

Generic programming via effects

In the Idris Effects library effects are represented as
||| This type is parameterised by:
||| + The return type of the computation.
||| + The input resource.
||| + The computation to run on the resource given the return value.
Effect : Type
Effect = (x : Type) -> Type -> (x -> Type) -> Type
If we allow resources to be values and swap the first two arguments, we get (the rest of the code is in Agda)
Effect : Set -> Set
Effect R = R -> (A : Set) -> (A -> R) -> Set
Having some basic type-context-membership machinery
data Type : Set where
nat : Type
_⇒_ : Type -> Type -> Type
data Con : Set where
ε : Con
_▻_ : Con -> Type -> Con
data _∈_ σ : Con -> Set where
vz : ∀ {Γ} -> σ ∈ Γ ▻ σ
vs_ : ∀ {Γ τ} -> σ ∈ Γ -> σ ∈ Γ ▻ τ
we can encode lambda terms constructors as follows:
app-arg : Bool -> Type -> Type -> Type
app-arg b σ τ = if b then σ ⇒ τ else σ
data TermE : Effect (Con × Type) where
Var : ∀ {Γ σ } -> σ ∈ Γ -> TermE (Γ , σ ) ⊥ λ()
Lam : ∀ {Γ σ τ} -> TermE (Γ , σ ⇒ τ ) ⊤ (λ _ -> Γ ▻ σ , τ )
App : ∀ {Γ σ τ} -> TermE (Γ , τ ) Bool (λ b -> Γ , app-arg b σ τ)
In TermE i r i′ i is an output index (e.g. lambda abstractions (Lam) construct function types (σ ⇒ τ) (for ease of description I'll ignore that indices also contain contexts besides types)), r represents a number of inductive positions (Var doesn't (⊥) receive any TermE, Lam receives one (⊤), App receives two (Bool) — a function and its argument) and i′ computes an index at each inductive position (e.g. the index at the first inductive position of App is σ ⇒ τ and the index at the second is σ, i.e. we can apply a function to a value only if the type of the first argument of the function equals the type of the value).
To construct a real lambda term we must tie the knot using something like a W data type. Here is the definition:
data Wer {R} (Ψ : Effect R) : Effect R where
call : ∀ {r A r′ B r′′} -> Ψ r A r′ -> (∀ x -> Wer Ψ (r′ x) B r′′) -> Wer Ψ r B r′′
It's the indexed variant of the Oleg Kiselyov's Freer monad (effects stuff again), but without return. Using this we can recover the usual constructors:
_<∨>_ : ∀ {B : Bool -> Set} -> B true -> B false -> ∀ b -> B b
(x <∨> y) true = x
(x <∨> y) false = y
_⊢_ : Con -> Type -> Set
Γ ⊢ σ = Wer TermE (Γ , σ) ⊥ λ()
var : ∀ {Γ σ} -> σ ∈ Γ -> Γ ⊢ σ
var v = call (Var v) λ()
ƛ_ : ∀ {Γ σ τ} -> Γ ▻ σ ⊢ τ -> Γ ⊢ σ ⇒ τ
ƛ b = call Lam (const b)
_·_ : ∀ {Γ σ τ} -> Γ ⊢ σ ⇒ τ -> Γ ⊢ σ -> Γ ⊢ τ
f · x = call App (f <∨> x)
The whole encoding is very similar to the corresponding encoding in terms of indexed containers: Effect corresponds to IContainer and Wer corresponds to ITree (the type of Petersson-Synek Trees). However the above encoding looks simpler to me, because you don't need to think about things you have to put into shapes to be able to recover indices at inductive positions. Instead, you have everything in one place and the encoding process is really straightforward.
So what am I doing here? Is there some real relation to the indexed containers approach (besides the fact that this encoding has the same extensionality problems)? Can we do something useful this way? One natural thought is to built an effectful lambda calculus as we can freely mix lambda terms with effects, since a lambda term is itself just an effect, but it's an external effect and we either need other effects to be external as well (which means that we can't say something like tell (var vz), because var vz is not a value — it's a computation) or we need to somehow internalize this effect and the whole effects machinery (which means I don't know what).
The code used.
Interesting work! I don't know much about effects and i have only a basic understanding of indexed containers, but i am doing stuff with generic programming so here's my take on it.
The type of TermE : Con × Type → (A : Set) → (A → Con × Type) → Set reminds me of the type of descriptions used to formalize indexed induction recursion in [1]. The second chapter of that paper tells us that there is an equivalence between Set/I = (A : Set) × (A → I) and I → Set. This means that the type of TermE is equivalent to Con × Type → (Con × Type → Set) → Set or (Con × Type → Set) → Con × Type → Set. The latter is an indexed functor, which is used in the polynomial functor ('sum-of-products') style of generic programming, for instance in [2] and [3]. If you have not seen it before, it looks something like this:
data Desc (I : Set) : Set1 where
`Σ : (S : Set) → (S → Desc I) → Desc I
`var : I → Desc I → Desc I
`ι : I → Desc I
⟦_⟧ : ∀{I} → Desc I → (I → Set) → I → Set
⟦ `Σ S x ⟧ X o = Σ S (λ s → ⟦ x s ⟧ X o)
⟦ `var i xs ⟧ X o = X i × ⟦ xs ⟧ X o
⟦ `ι o′ ⟧ X o = o ≡ o′
data μ {I : Set} (D : Desc I) : I → Set where
⟨_⟩ : {o : I} → ⟦ D ⟧ (μ D) o → μ D o
natDesc : Desc ⊤
natDesc = `Σ Bool (λ { false → `ι tt ; true → `var tt (`ι tt) })
nat-example : μ natDesc tt
nat-example = ⟨ true , ⟨ true , ⟨ false , refl ⟩ , refl ⟩ , refl ⟩
finDesc : Desc Nat
finDesc = `Σ Bool (λ { false → `Σ Nat (λ n → `ι (suc n))
; true → `Σ Nat (λ n → `var n (`ι (suc n)))
})
fin-example : μ finDesc 5
fin-example = ⟨ true , 4 , ⟨ true , 3 , ⟨ false , 2 , refl ⟩ , refl ⟩ , refl ⟩
So the fixpoint μ corresponds directly to your Wer datatype, and the interpreted descriptions (using ⟦_⟧) correspond to your TermE. I'm guessing that some of the literature on this topic will be relevant for you. I don't remember whether indexed containers and indexed functors are really equivalent but they are definitely related. I do not entirely understand your remark about tell (var vz), but could that be related to the internalization of fixpoints in these kinds of descriptions? In that case maybe [3] can help you with that.
[1]: Peter Hancock, Conor McBride, Neil Ghani, Lorenzo Malatesta, Thorsten Altenkirch - Small Induction Recursion (2013)
[2]: James Chapman, Pierre-Evariste Dagand, Conor McBride, Peter Morris - The gentle art of levitation (2010)
[3]: Andres Löh, José Pedro Magalhães - Generic programming with indexed functors

Proving decidability of subset in Agda

Suppose I have this definition of Subset in Agda
Subset : ∀ {α} → Set α → {ℓ : Level} → Set (α ⊔ suc ℓ)
Subset A {ℓ} = A → Set ℓ
and I have a set
data Q : Set where
a : Q
b : Q
Is it possible to prove that all subset of q is decidable and why?
Qs? : (qs : Subset Q {zero}) → Decidable qs
Decidable is defined here:
-- Membership
infix 10 _∈_
_∈_ : ∀ {α ℓ}{A : Set α} → A → Subset A → Set ℓ
a ∈ p = p a
-- Decidable
Decidable : ∀ {α ℓ}{A : Set α} → Subset A {ℓ} → Set (α ⊔ ℓ)
Decidable as = ∀ a → Dec (a ∈ as)
Not for that definition of Subset, since decidability would require to check whether "p a" is inhabited or not, i.e. excluded middle.
Decidable subsets would exactly be maps into Bool:
Subset : ∀ {α} (A : Set α) -> Set
Subset A = A → Bool
_∈_ : ∀ {α}{A : Set α} → A → Subset A → Set
a ∈ p = T (p a)
But if you want more flexibility on the shape of the membership proofs you could use your definition of Subset and carry around a proof that it is Decidable.

How to encode the axiom of choice in Haskell/Functional programming?

> {-# LANGUAGE RankNTypes #-}
I was wondering if there was a way to represent the axiom of choice in haskell and/or some other functional programming language.
As we know, false is represented by the type with no values (Void in haskell).
> import Data.Void
We can represent negation like so
> type Not a = a -> Void
We can express the law of excluded middle for a type a like so
> type LEM a = Either a (Not a)
This means we can make classical logic into a Reader monad
> type Classical a = (forall r. LEM r) -> a
We can, for example, do double negation elimination in it
> doubleneg :: Classical (Not (Not a) -> a)
> doubleneg = \lem nna -> either id (absurd . nna) lem
We can also have a monad where the law of excluded middle fails
> type AntiClassical a = Not (forall r. LEM r) -> a
Now the question is, how can we make a type that represents the axiom of choice? The axiom of choice talks about sets of sets. This implies we would need types of types or something. Is there something equivalent to the axiom of choice that could be encoded? (If you can encode the negation, just combine it with the law of excluded middle). Maybe trickery would allow us to have types of types.
Note: Ideally, it should be a version of the axiom of choice that works with Diaconescu's theorem.
This is just a hint.
The axiom of choice can be expressed as:
If for every x : A there's a y : B such that the property P x y holds, then there's a choice function f : A -> B such that, for all x : A we have P x (f x).
More precisely
choice : {A B : Set} (P : A -> B -> Set) ->
((x : A) -> Σ B (λ y -> P x y)) ->
Σ (A -> B) (λ f -> (x : A) -> P x (f x))
choice P h = ?
given
data Σ (A : Set) (P : A -> Set) : Set where
_,_ : (x : A) -> P x -> Σ A P
Above, choice is indeed provable. Indeed, h assigns to each x a (dependent) pair whose first component y is an element of A and the second component is a proof that the first indeed satisfies P x y. Instead, the f in the thesis must assign to x only y, without any proof.
As you see, obtaining the choice function f from h is just a matter of discarding the proof component in the pair.
There's no need to extend Agda with LEM or any other axiom to prove this. The above proof is entirely constructive.
If we were using Coq, note that Coq forbids to eliminate a proof (such as h : ... -> Prop) to construct a non-proof (f), so translating this into Coq directly fails. (This is to allow program extraction.) However, if we avoid the Prop sort of Coq and use Type directly, then the above can be translated.
You may want to use the following projections for this exercise:
pr1 : ∀ {A : Set} {P} -> Σ A P -> A
pr1 (x , _) = x
pr2 : ∀ {A : Set} {P} -> (p : Σ A P) -> P (pr1 p)
pr2 (_ , y) = y

Resources