refactor(library/logic): move logic/choice.lean to init/classical.lean

choice axiom is now in the classical namespace.
This commit is contained in:
Leonardo de Moura 2015-08-12 18:37:33 -07:00
parent cb9830beaf
commit d2eb99bf11
38 changed files with 70 additions and 74 deletions

View file

@ -125,13 +125,13 @@ Because we use _proposition as types_, we must support _empty types_. For exampl
the type =false= must be empty, since we don't have a proof for =false=. the type =false= must be empty, since we don't have a proof for =false=.
Most systems based on the _propositions as types_ paradigm are based on constructive logic. Most systems based on the _propositions as types_ paradigm are based on constructive logic.
In Lean, we support classical and constructive logic. We can load In Lean, we support classical and constructive logic. We can use
_classical choice axiom_ by using =import logic.choice= or =import classical=. When the classical _classical choice axiom_ by using =open classical=. When the classical
extensions are loaded, the _excluded middle_ is a theorem, extensions are loaded, the _excluded middle_ is a theorem,
and =em p= is a proof for =p ¬ p=. and =em p= is a proof for =p ¬ p=.
#+BEGIN_SRC lean #+BEGIN_SRC lean
import logic.choice open classical
constant p : Prop constant p : Prop
check em p check em p
#+END_SRC #+END_SRC

View file

@ -1,8 +0,0 @@
/-
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad
The standard library together with the classical axioms.
-/
import standard logic.choice

View file

@ -5,7 +5,7 @@ Author: Leonardo de Moura
Finite bags. Finite bags.
-/ -/
import data.nat data.list.perm data.subtype algebra.binary import data.nat data.list.perm algebra.binary
open nat quot list subtype binary function eq.ops open nat quot list subtype binary function eq.ops
open [declarations] perm open [declarations] perm

View file

@ -4,5 +4,5 @@ Released under Apache 2.0 license as described in the file LICENSE.
Author: Jeremy Avigad Author: Jeremy Avigad
-/ -/
import .empty .unit .bool .num .string .nat .int .rat .fintype import .empty .unit .bool .num .string .nat .int .rat .fintype
import .prod .sum .sigma .option .subtype .quotient .list .finset .set .stream import .prod .sum .sigma .option .quotient .list .finset .set .stream
import .fin import .fin

View file

@ -6,7 +6,7 @@ Author: Leonardo de Moura
Type class for encodable types. Type class for encodable types.
Note that every encodable type is countable. Note that every encodable type is countable.
-/ -/
import data.fintype data.list data.list.sort data.sum data.nat.div data.subtype data.countable data.equiv data.finset import data.fintype data.list data.list.sort data.sum data.nat.div data.countable data.equiv data.finset
open option list nat function open option list nat function
structure encodable [class] (A : Type) := structure encodable [class] (A : Type) :=

View file

@ -5,7 +5,7 @@ Author: Leonardo de Moura, Jeremy Avigad
Finite sets. Finite sets.
-/ -/
import data.fintype.basic data.nat data.list.perm data.subtype algebra.binary import data.fintype.basic data.nat data.list.perm algebra.binary
open nat quot list subtype binary function eq.ops open nat quot list subtype binary function eq.ops
open [declarations] perm open [declarations] perm

View file

@ -6,7 +6,7 @@ Author: Leonardo de Moura
The length of a list is encoded into its type. The length of a list is encoded into its type.
It is implemented as a subtype. It is implemented as a subtype.
-/ -/
import logic data.list data.subtype data.fin import logic data.list data.fin
open nat list subtype function open nat list subtype function
definition fixed_list [reducible] (A : Type) (n : nat) := {l : list A | length l = n} definition fixed_list [reducible] (A : Type) (n : nat) := {l : list A | length l = n}

View file

@ -14,7 +14,7 @@ without assuming classical axioms.
More importantly, they can be reduced inside of the Lean kernel. More importantly, they can be reduced inside of the Lean kernel.
-/ -/
import data.subtype data.nat.order data.nat.div import data.nat.order data.nat.div
namespace nat namespace nat
open subtype open subtype

View file

@ -10,7 +10,7 @@ This module provides the following two declarations:
choose {p : nat → Prop} [d : decidable_pred p] : (∃ x, p x) → nat choose {p : nat → Prop} [d : decidable_pred p] : (∃ x, p x) → nat
choose_spec {p : nat → Prop} [d : decidable_pred p] (ex : ∃ x, p x) : p (choose ex) choose_spec {p : nat → Prop} [d : decidable_pred p] (ex : ∃ x, p x) : p (choose ex)
-/ -/
import data.subtype data.nat.basic data.nat.order import data.nat.basic data.nat.order
open nat subtype decidable well_founded open nat subtype decidable well_founded
namespace nat namespace nat

View file

@ -5,7 +5,7 @@ Author: Floris van Doorn
An explicit treatment of quotients, without using Lean's built-in quotient types. An explicit treatment of quotients, without using Lean's built-in quotient types.
-/ -/
import logic data.subtype logic.cast algebra.relation data.prod import logic logic.cast algebra.relation data.prod
import logic.instances import logic.instances
import .util import .util

View file

@ -5,12 +5,11 @@ Author: Floris van Doorn
A classical treatment of quotients, using Hilbert choice. A classical treatment of quotients, using Hilbert choice.
-/ -/
import algebra.relation data.subtype logic.choice import algebra.relation
import .basic import .basic
namespace quotient namespace quotient
open relation nonempty subtype classical
open relation nonempty subtype
/- abstract quotient -/ /- abstract quotient -/

View file

@ -12,7 +12,6 @@ Here, we show that is complete.
-/ -/
import data.real.basic data.real.order data.real.division data.rat data.nat data.pnat import data.real.basic data.real.order data.real.division data.rat data.nat data.pnat
import logic.choice
open -[coercions] rat open -[coercions] rat
local notation 0 := rat.of_num 0 local notation 0 := rat.of_num 0
local notation 1 := rat.of_num 1 local notation 1 := rat.of_num 1

View file

@ -9,7 +9,7 @@ At this point, we no longer proceed constructively: this file makes heavy use of
and excluded middle. and excluded middle.
-/ -/
import data.real.basic data.real.order data.rat data.nat logic.choice import data.real.basic data.real.order data.rat data.nat
open -[coercions] rat open -[coercions] rat
open -[coercions] nat open -[coercions] nat
open eq.ops pnat classical open eq.ops pnat classical

View file

@ -6,7 +6,6 @@ Author: Jeremy Avigad, Andrew Zipperer
Using classical logic, defines an inverse function. Using classical logic, defines an inverse function.
-/ -/
import .function .map import .function .map
import logic.choice
open eq.ops classical open eq.ops classical
namespace set namespace set

View file

@ -6,7 +6,7 @@ Author: Jeremy Avigad
Filters, following Hölzl, Immler, and Huffman, "Type classes and filters for mathematical Filters, following Hölzl, Immler, and Huffman, "Type classes and filters for mathematical
analysis in Isabelle/HOL". analysis in Isabelle/HOL".
-/ -/
import data.set.function logic.identities logic.choice algebra.complete_lattice import data.set.function logic.identities algebra.complete_lattice
namespace set namespace set
open classical open classical

View file

@ -7,7 +7,7 @@ The notion of "finiteness" for sets. This approach is not computational: for exa
an element s : set A satsifies finite s doesn't mean that we can compute the cardinality. For an element s : set A satsifies finite s doesn't mean that we can compute the cardinality. For
a computational representation, use the finset type. a computational representation, use the finset type.
-/ -/
import data.set.function data.finset.to_set logic.choice import data.set.function data.finset.to_set
open nat classical open nat classical
variable {A : Type} variable {A : Type}

View file

@ -3,10 +3,11 @@ Copyright (c) 2015 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE. Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Jeremy Avigad Authors: Leonardo de Moura, Jeremy Avigad
-/ -/
import logic.quantifiers logic.eq prelude
import data.subtype data.sum import init.subtype init.funext
open subtype inhabited nonempty namespace classical
open subtype
/- the axiom -/ /- the axiom -/
@ -161,8 +162,7 @@ propext (iff.intro
end aux end aux
/- All propositions are decidable -/ /- All propositions are decidable -/
namespace classical open decidable
open decidable sum
noncomputable definition decidable_inhabited [instance] [priority 0] (a : Prop) : inhabited (decidable a) := noncomputable definition decidable_inhabited [instance] [priority 0] (a : Prop) : inhabited (decidable a) :=
inhabited_of_nonempty inhabited_of_nonempty
(or.elim (em a) (or.elim (em a)
@ -172,7 +172,7 @@ inhabited_of_nonempty
noncomputable definition prop_decidable [instance] [priority 0] (a : Prop) : decidable a := noncomputable definition prop_decidable [instance] [priority 0] (a : Prop) : decidable a :=
arbitrary (decidable a) arbitrary (decidable a)
noncomputable definition type_decidable (A : Type) : A + (A → false) := noncomputable definition type_decidable (A : Type) : sum A (A → false) :=
match prop_decidable (nonempty A) with match prop_decidable (nonempty A) with
| inl Hp := sum.inl (inhabited.value (inhabited_of_nonempty Hp)) | inl Hp := sum.inl (inhabited.value (inhabited_of_nonempty Hp))
| inr Hn := sum.inr (λ a, absurd (nonempty.intro a) Hn) | inr Hn := sum.inr (λ a, absurd (nonempty.intro a) Hn)

View file

@ -7,4 +7,4 @@ prelude
import init.datatypes init.reserved_notation init.tactic init.logic import init.datatypes init.reserved_notation init.tactic init.logic
import init.relation init.wf init.nat init.wf_k init.prod init.priority import init.relation init.wf init.nat init.wf_k init.prod init.priority
import init.bool init.num init.sigma init.measurable init.setoid init.quot import init.bool init.num init.sigma init.measurable init.setoid init.quot
import init.funext init.function import init.funext init.function init.subtype init.classical

View file

@ -21,6 +21,9 @@ prefix `¬` := not
definition absurd {a : Prop} {b : Type} (H1 : a) (H2 : ¬a) : b := definition absurd {a : Prop} {b : Type} (H1 : a) (H2 : ¬a) : b :=
false.rec b (H2 H1) false.rec b (H2 H1)
theorem mt {a b : Prop} (H1 : a → b) (H2 : ¬b) : ¬a :=
assume Ha : a, absurd (H1 Ha) H2
/- not -/ /- not -/
theorem not_false : ¬false := theorem not_false : ¬false :=
@ -31,6 +34,12 @@ definition non_contradictory (a : Prop) : Prop := ¬¬a
theorem non_contradictory_intro {a : Prop} (Ha : a) : ¬¬a := theorem non_contradictory_intro {a : Prop} (Ha : a) : ¬¬a :=
assume Hna : ¬a, absurd Ha Hna assume Hna : ¬a, absurd Ha Hna
/- false -/
theorem false.elim {c : Prop} (H : false) : c :=
false.rec c H
/- eq -/ /- eq -/
notation a = b := eq a b notation a = b := eq a b
@ -129,6 +138,20 @@ end ne
theorem false.of_ne {A : Type} {a : A} : a ≠ a → false := ne.irrefl theorem false.of_ne {A : Type} {a : A} : a ≠ a → false := ne.irrefl
section
open eq.ops
variables {p : Prop}
theorem ne_false_of_self : p → p ≠ false :=
assume (Hp : p) (Heq : p = false), Heq ▸ Hp
theorem ne_true_of_not : ¬p → p ≠ true :=
assume (Hnp : ¬p) (Heq : p = true), (Heq ▸ Hnp) trivial
theorem true_ne_false : ¬true = false :=
ne_false_of_self trivial
end
infixl `==`:50 := heq infixl `==`:50 := heq
namespace heq namespace heq
@ -471,6 +494,9 @@ nonempty.rec H2 H1
theorem nonempty_of_inhabited [instance] {A : Type} [H : inhabited A] : nonempty A := theorem nonempty_of_inhabited [instance] {A : Type} [H : inhabited A] : nonempty A :=
nonempty.intro !default nonempty.intro !default
theorem nonempty_of_exists {A : Type} {P : A → Prop} : (∃x, P x) → nonempty A :=
Exists.rec (λw H, nonempty.intro w)
/- subsingleton -/ /- subsingleton -/
inductive subsingleton [class] (A : Type) : Prop := inductive subsingleton [class] (A : Type) : Prop :=

View file

@ -3,6 +3,8 @@ Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE. Released under Apache 2.0 license as described in the file LICENSE.
Author: Leonardo de Moura, Jeremy Avigad Author: Leonardo de Moura, Jeremy Avigad
-/ -/
prelude
import init.datatypes init.logic
open decidable open decidable
set_option structure.proj_mk_thm true set_option structure.proj_mk_thm true

View file

@ -9,18 +9,10 @@ open eq.ops
variables {a b c d : Prop} variables {a b c d : Prop}
/- false -/
theorem false.elim {c : Prop} (H : false) : c :=
false.rec c H
/- implies -/ /- implies -/
definition imp (a b : Prop) : Prop := a → b definition imp (a b : Prop) : Prop := a → b
theorem mt (H1 : a → b) (H2 : ¬b) : ¬a :=
assume Ha : a, absurd (H1 Ha) H2
theorem imp.id (H : a) : a := H theorem imp.id (H : a) : a := H
theorem imp.intro (H : a) (H₂ : b) : a := H theorem imp.intro (H : a) (H₂ : b) : a := H

View file

@ -102,16 +102,3 @@ section
theorem eq_imp_trans (H₁ : a = b) (H₂ : b → c) : a → c := theorem eq_imp_trans (H₁ : a = b) (H₂ : b → c) : a → c :=
assume Ha, H₂ (H₁ ▸ Ha) assume Ha, H₂ (H₁ ▸ Ha)
end end
section
variables {p : Prop}
theorem ne_false_of_self : p → p ≠ false :=
assume (Hp : p) (Heq : p = false), Heq ▸ Hp
theorem ne_true_of_not : ¬p → p ≠ true :=
assume (Hnp : ¬p) (Heq : p = true), (Heq ▸ Hnp) trivial
end
theorem true_ne_false : ¬true = false :=
ne_false_of_self trivial

View file

@ -9,7 +9,6 @@ The proof uses the classical axioms: choice and excluded middle.
The excluded middle is being used "behind the scenes" to allow us to write the if-then-else expression The excluded middle is being used "behind the scenes" to allow us to write the if-then-else expression
with (∃ a : A, f a = b). with (∃ a : A, f a = b).
-/ -/
import logic.choice
open function classical open function classical
noncomputable definition mk_left_inv {A B : Type} [h : nonempty A] (f : A → B) : B → A := noncomputable definition mk_left_inv {A B : Type} [h : nonempty A] (f : A → B) : B → A :=

View file

@ -52,9 +52,6 @@ iff.intro
(or.rec (exists_imp_exists (λx, or.inl)) (or.rec (exists_imp_exists (λx, or.inl))
(exists_imp_exists (λx, or.inr))) (exists_imp_exists (λx, or.inr)))
theorem nonempty_of_exists {A : Type} {P : A → Prop} : (∃x, P x) → nonempty A :=
Exists.rec (λw H, intro w)
section section
open decidable eq.ops open decidable eq.ops

View file

@ -1,4 +1,4 @@
import classical open classical open classical
eval if true then 1 else 0 eval if true then 1 else 0
attribute prop_decidable [priority 0] attribute prop_decidable [priority 0]
eval if true then 1 else 0 eval if true then 1 else 0

View file

@ -1,5 +1,5 @@
import logic logic.choice import logic
open inhabited nonempty open inhabited nonempty classical
noncomputable definition v1 : Prop := epsilon (λ x, true) noncomputable definition v1 : Prop := epsilon (λ x, true)
inductive Empty : Type inductive Empty : Type

View file

@ -5,7 +5,7 @@ Author: Leonardo de Moura
Finite bags. Finite bags.
-/ -/
import data.nat data.list.perm data.subtype algebra.binary import data.nat data.list.perm algebra.binary
open nat quot list subtype binary function eq.ops open nat quot list subtype binary function eq.ops
open [declarations] perm open [declarations] perm

View file

@ -1,5 +1,5 @@
import logic.choice data.nat.basic import data.nat.basic
open nonempty inhabited nat open nonempty inhabited nat classical
theorem int_inhabited [instance] : inhabited nat := inhabited.mk zero theorem int_inhabited [instance] : inhabited nat := inhabited.mk zero

View file

@ -3,6 +3,7 @@
-- BEGINFINDP STALE -- BEGINFINDP STALE
false|Prop false|Prop
false.rec|Π (C : Type), false → C false.rec|Π (C : Type), false → C
false.elim|false → ?c
false.of_ne|?a ≠ ?a → false false.of_ne|?a ≠ ?a → false
false.rec_on|Π (C : Type), false → C false.rec_on|Π (C : Type), false → C
false.cases_on|Π (C : Type), false → C false.cases_on|Π (C : Type), false → C
@ -12,6 +13,8 @@ nat.lt_self_iff_false|∀ (n : nat), nat.lt n n ↔ false
not_of_is_false|is_false ?c → ¬?c not_of_is_false|is_false ?c → ¬?c
not_of_iff_false|(?a ↔ false) → ¬?a not_of_iff_false|(?a ↔ false) → ¬?a
is_false|Π (c : Prop) [H : decidable c], Prop is_false|Π (c : Prop) [H : decidable c], Prop
classical.eq_true_or_eq_false|∀ (a : Prop), a = true a = false
classical.eq_false_or_eq_true|∀ (a : Prop), a = false a = true
nat.lt_zero_iff_false|∀ (a : nat), nat.lt a nat.zero ↔ false nat.lt_zero_iff_false|∀ (a : nat), nat.lt a nat.zero ↔ false
not_of_eq_false|?p = false → ¬?p not_of_eq_false|?p = false → ¬?p
nat.succ_le_self_iff_false|∀ (n : nat), nat.le (nat.succ n) n ↔ false nat.succ_le_self_iff_false|∀ (n : nat), nat.le (nat.succ n) n ↔ false
@ -19,6 +22,7 @@ decidable.rec_on_false|Π (H3 : ¬?p), ?H2 H3 → decidable.rec_on ?H ?H1 ?H2
not_false|¬false not_false|¬false
decidable_false|decidable false decidable_false|decidable false
of_not_is_false|¬is_false ?c → ?c of_not_is_false|¬is_false ?c → ?c
classical.cases_true_false|∀ (P : Prop → Prop), P true → P false → (∀ (a : Prop), P a)
iff_false_intro|¬?a → (?a ↔ false) iff_false_intro|¬?a → (?a ↔ false)
ne_false_of_self|?p → ?p ≠ false ne_false_of_self|?p → ?p ≠ false
nat.succ_le_zero_iff_false|∀ (n : nat), nat.le (nat.succ n) nat.zero ↔ false nat.succ_le_zero_iff_false|∀ (n : nat), nat.le (nat.succ n) nat.zero ↔ false

View file

@ -5,7 +5,7 @@
( → Prop) → ( → Prop) →
-- ACK -- ACK
-- IDENTIFIER|6|6 -- IDENTIFIER|6|6
epsilon classical.epsilon
-- ACK -- ACK
-- SYMBOL|6|14 -- SYMBOL|6|14
( (

View file

@ -1,2 +1,3 @@
quot.sound : ∀ {A : Type} [s : setoid A] {a b : A}, setoid.r a b → quot.mk a = quot.mk b quot.sound : ∀ {A : Type} [s : setoid A] {a b : A}, setoid.r a b → quot.mk a = quot.mk b
classical.strong_indefinite_description : Π {A : Type} (P : A → Prop), nonempty A → {x : A | Exists P → P x}
propext : ∀ {a b : Prop}, (a ↔ b) → a = b propext : ∀ {a b : Prop}, (a ↔ b) → a = b

View file

@ -1,3 +1 @@
import logic.choice
print axioms print axioms

View file

@ -1,3 +1,3 @@
quot.sound : ∀ {A : Type} [s : setoid A] {a b : A}, setoid.r a b → quot.mk a = quot.mk b quot.sound : ∀ {A : Type} [s : setoid A] {a b : A}, setoid.r a b → quot.mk a = quot.mk b
classical.strong_indefinite_description : Π {A : Type} (P : A → Prop), nonempty A → {x : A | Exists P → P x}
propext : ∀ {a b : Prop}, (a ↔ b) → a = b propext : ∀ {a b : Prop}, (a ↔ b) → a = b
strong_indefinite_description : Π {A : Type} (P : A → Prop), nonempty A → {x : A | Exists P → P x}

View file

@ -1,6 +1,7 @@
no axioms no axioms
------ ------
quot.sound : ∀ {A : Type} [s : setoid A] {a b : A}, setoid.r a b → quot.mk a = quot.mk b quot.sound : ∀ {A : Type} [s : setoid A] {a b : A}, setoid.r a b → quot.mk a = quot.mk b
classical.strong_indefinite_description : Π {A : Type} (P : A → Prop), nonempty A → {x : A | Exists P → P x}
propext : ∀ {a b : Prop}, (a ↔ b) → a = b propext : ∀ {a b : Prop}, (a ↔ b) → a = b
------ ------
theorem foo3 : 0 = 0 := theorem foo3 : 0 = 0 :=

View file

@ -1,4 +1,4 @@
import classical import data.nat
open nat open nat
print pp.max_depth print pp.max_depth
@ -9,7 +9,7 @@ print nat
print nat.zero print nat.zero
print nat.add print nat.add
print nat.rec print nat.rec
print em print classical.em
print quot.lift print quot.lift
print nat.of_num print nat.of_num
print nat.add.assoc print nat.add.assoc

View file

@ -1,4 +1,4 @@
import data.subtype data.nat import data.nat
open nat open nat
notation `{` binders:55 `|` r:(scoped P, subtype P) `}` := r notation `{` binders:55 `|` r:(scoped P, subtype P) `}` := r

View file

@ -1,3 +1,3 @@
import data.subtype data.nat import data.nat
open nat open nat
check { x : nat | x > 0} check { x : nat | x > 0}

View file

@ -1,4 +1,4 @@
import data.subtype -- import data.subtype
open nat open nat
check {x : nat| x > 0 } check {x : nat| x > 0 }