refactor(library/data): cleanup datatypes

Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
Leonardo de Moura 2014-09-04 22:31:52 -07:00
parent 6632a50015
commit 9412e604c8
14 changed files with 240 additions and 256 deletions

View file

@ -4,121 +4,112 @@
import logic.core.connectives logic.classes.decidable logic.classes.inhabited
open eq_ops decidable
open eq_ops eq decidable
inductive bool : Type :=
ff : bool,
tt : bool
ff : bool,
tt : bool
namespace bool
definition rec_on [protected] {C : bool → Type} (b : bool) (H₁ : C ff) (H₂ : C tt) : C b :=
rec H₁ H₂ b
theorem cases_on {p : bool → Prop} (b : bool) (H0 : p ff) (H1 : p tt) : p b :=
rec H0 H1 b
theorem cases_on [protected] {p : bool → Prop} (b : bool) (H₁ : p ff) (H₂ : p tt) : p b :=
rec H₁ H₂ b
theorem bool_inhabited [instance] : inhabited bool :=
inhabited.mk ff
definition cond {A : Type} (b : bool) (t e : A) :=
rec_on b e t
definition cond {A : Type} (b : bool) (t e : A) :=
rec e t b
theorem dichotomy (b : bool) : b = ff b = tt :=
cases_on b (or.inl rfl) (or.inr rfl)
theorem dichotomy (b : bool) : b = ff b = tt :=
cases_on b (or.inl (eq.refl ff)) (or.inr (eq.refl tt))
theorem cond_ff {A : Type} (t e : A) : cond ff t e = e :=
rfl
theorem cond_ff {A : Type} (t e : A) : cond ff t e = e :=
rfl
theorem cond_tt {A : Type} (t e : A) : cond tt t e = t :=
rfl
theorem cond_tt {A : Type} (t e : A) : cond tt t e = t :=
rfl
theorem ff_ne_tt : ¬ ff = tt :=
assume H : ff = tt, absurd
theorem ff_ne_tt : ¬ ff = tt :=
assume H : ff = tt, absurd
(calc true = cond tt true false : (cond_tt _ _)⁻¹
... = cond ff true false : {H⁻¹}
... = false : cond_ff _ _)
true_ne_false
theorem decidable_eq [instance] (a b : bool) : decidable (a = b) :=
rec
(rec (inl (eq.refl ff)) (inr ff_ne_tt) b)
(rec (inr (ne.symm ff_ne_tt)) (inl (eq.refl tt)) b)
a
definition bor (a b : bool) :=
rec_on a (rec_on b ff tt) tt
definition bor (a b : bool) :=
rec (rec ff tt b) tt a
theorem bor_tt_left (a : bool) : bor tt a = tt :=
rfl
theorem bor_tt_left (a : bool) : bor tt a = tt :=
rfl
infixl `||` := bor
infixl `||` := bor
theorem bor_tt_right (a : bool) : a || tt = tt :=
cases_on a rfl rfl
theorem bor_tt_right (a : bool) : a || tt = tt :=
cases_on a (eq.refl (ff || tt)) (eq.refl (tt || tt))
theorem bor_ff_left (a : bool) : ff || a = a :=
cases_on a rfl rfl
theorem bor_ff_left (a : bool) : ff || a = a :=
cases_on a (eq.refl (ff || ff)) (eq.refl (ff || tt))
theorem bor_ff_right (a : bool) : a || ff = a :=
cases_on a rfl rfl
theorem bor_ff_right (a : bool) : a || ff = a :=
cases_on a (eq.refl (ff || ff)) (eq.refl (tt || ff))
theorem bor_id (a : bool) : a || a = a :=
cases_on a rfl rfl
theorem bor_id (a : bool) : a || a = a :=
cases_on a (eq.refl (ff || ff)) (eq.refl (tt || tt))
theorem bor_comm (a b : bool) : a || b = b || a :=
cases_on a
(cases_on b rfl rfl)
(cases_on b rfl rfl)
theorem bor_comm (a b : bool) : a || b = b || a :=
cases_on a
(cases_on b (eq.refl (ff || ff)) (eq.refl (ff || tt)))
(cases_on b (eq.refl (tt || ff)) (eq.refl (tt || tt)))
theorem bor_assoc (a b c : bool) : (a || b) || c = a || (b || c) :=
cases_on a
theorem bor_assoc (a b c : bool) : (a || b) || c = a || (b || c) :=
cases_on a
(calc (ff || b) || c = b || c : {bor_ff_left b}
... = ff || (b || c) : bor_ff_left (b || c)⁻¹)
(calc (tt || b) || c = tt || c : {bor_tt_left b}
... = tt : bor_tt_left c
... = tt || (b || c) : bor_tt_left (b || c)⁻¹)
theorem bor_to_or {a b : bool} : a || b = tt → a = tt b = tt :=
rec
theorem bor_to_or {a b : bool} : a || b = tt → a = tt b = tt :=
rec_on a
(assume H : ff || b = tt,
have Hb : b = tt, from (bor_ff_left b) ▸ H,
or.inr Hb)
(assume H, or.inl (eq.refl tt))
a
(assume H, or.inl rfl)
definition band (a b : bool) :=
rec ff (rec ff tt b) a
definition band (a b : bool) :=
rec_on a ff (rec_on b ff tt)
infixl `&&` := band
infixl `&&` := band
theorem band_ff_left (a : bool) : ff && a = ff :=
rfl
theorem band_ff_left (a : bool) : ff && a = ff :=
rfl
theorem band_tt_left (a : bool) : tt && a = a :=
cases_on a (eq.refl (tt && ff)) (eq.refl (tt && tt))
theorem band_tt_left (a : bool) : tt && a = a :=
cases_on a rfl rfl
theorem band_ff_right (a : bool) : a && ff = ff :=
cases_on a (eq.refl (ff && ff)) (eq.refl (tt && ff))
theorem band_ff_right (a : bool) : a && ff = ff :=
cases_on a rfl rfl
theorem band_tt_right (a : bool) : a && tt = a :=
cases_on a (eq.refl (ff && tt)) (eq.refl (tt && tt))
theorem band_tt_right (a : bool) : a && tt = a :=
cases_on a rfl rfl
theorem band_id (a : bool) : a && a = a :=
cases_on a (eq.refl (ff && ff)) (eq.refl (tt && tt))
theorem band_id (a : bool) : a && a = a :=
cases_on a rfl rfl
theorem band_comm (a b : bool) : a && b = b && a :=
cases_on a
(cases_on b (eq.refl (ff && ff)) (eq.refl (ff && tt)))
(cases_on b (eq.refl (tt && ff)) (eq.refl (tt && tt)))
theorem band_comm (a b : bool) : a && b = b && a :=
cases_on a
(cases_on b rfl rfl)
(cases_on b rfl rfl)
theorem band_assoc (a b c : bool) : (a && b) && c = a && (b && c) :=
cases_on a
theorem band_assoc (a b c : bool) : (a && b) && c = a && (b && c) :=
cases_on a
(calc (ff && b) && c = ff && c : {band_ff_left b}
... = ff : band_ff_left c
... = ff && (b && c) : band_ff_left (b && c)⁻¹)
(calc (tt && b) && c = b && c : {band_tt_left b}
... = tt && (b && c) : band_tt_left (b && c)⁻¹)
theorem band_eq_tt_elim_left {a b : bool} (H : a && b = tt) : a = tt :=
or.elim (dichotomy a)
theorem band_eq_tt_elim_left {a b : bool} (H : a && b = tt) : a = tt :=
or.elim (dichotomy a)
(assume H0 : a = ff,
absurd
(calc ff = ff && b : (band_ff_left _)⁻¹
@ -127,20 +118,28 @@ or.elim (dichotomy a)
ff_ne_tt)
(assume H1 : a = tt, H1)
theorem band_eq_tt_elim_right {a b : bool} (H : a && b = tt) : b = tt :=
band_eq_tt_elim_left (eq.trans (band_comm b a) H)
theorem band_eq_tt_elim_right {a b : bool} (H : a && b = tt) : b = tt :=
band_eq_tt_elim_left (band_comm b a ⬝ H)
definition bnot (a : bool) := rec tt ff a
definition bnot (a : bool) :=
rec_on a tt ff
notation `!` x:max := bnot x
notation `!` x:max := bnot x
theorem bnot_bnot (a : bool) : !!a = a :=
cases_on a (eq.refl (!!ff)) (eq.refl (!!tt))
theorem bnot_bnot (a : bool) : !!a = a :=
cases_on a rfl rfl
theorem bnot_false : !ff = tt :=
rfl
theorem bnot_false : !ff = tt :=
rfl
theorem bnot_true : !tt = ff :=
rfl
theorem bnot_true : !tt = ff :=
rfl
theorem is_inhabited [protected] [instance] : inhabited bool :=
inhabited.mk ff
theorem has_decidable_eq [protected] [instance] (a b : bool) : decidable (a = b) :=
rec_on a
(rec_on b (inl rfl) (inr ff_ne_tt))
(rec_on b (inr (ne.symm ff_ne_tt)) (inl rfl))
end bool

View file

@ -9,4 +9,7 @@
inductive empty : Type
theorem empty_elim (A : Type) (H : empty) : A := empty.rec (λe, A) H
namespace empty
theorem elim [protected] (A : Type) (H : empty) : A :=
rec (λe, A) H
end empty

View file

@ -118,7 +118,7 @@ have special : ∀a, pr2 a ≤ pr1 a → proj (flip a) = flip (proj a), from
... = pr1 a - pr2 a : {flip_pr1 a}
... = pr1 (proj a) : (proj_ge_pr1 H)⁻¹
... = pr2 (flip (proj a)) : (flip_pr2 (proj a))⁻¹,
prod_eq H3 H4,
prod.equal H3 H4,
or.elim le_total
(assume H : pr2 a ≤ pr1 a, special a H)
(assume H : pr1 a ≤ pr2 a,
@ -162,7 +162,7 @@ have special : ∀a b, pr2 a ≤ pr1 a → rel a b → proj a = proj b, from
calc
pr2 (proj a) = 0 : proj_ge_pr2 H2
... = pr2 (proj b) : {(proj_ge_pr2 H4)⁻¹},
prod_eq H5 H6,
prod.equal H5 H6,
or.elim le_total
(assume H2 : pr2 a ≤ pr1 a, special a b H2 H)
(assume H2 : pr1 a ≤ pr2 a,

View file

@ -13,12 +13,14 @@ one : pos_num,
bit1 : pos_num → pos_num,
bit0 : pos_num → pos_num
namespace pos_num
theorem is_inhabited [instance] : inhabited pos_num :=
inhabited.mk one
end pos_num
inductive num : Type :=
zero : num,
pos : pos_num → num
theorem inhabited_pos_num [instance] : inhabited pos_num :=
inhabited.mk pos_num.one
theorem num_inhabited [instance] : inhabited num :=
inhabited.mk num.zero

View file

@ -6,47 +6,45 @@ import logic.core.eq logic.classes.inhabited logic.classes.decidable
open eq_ops decidable
inductive option (A : Type) : Type :=
none {} : option A,
some : A → option A
none {} : option A,
some : A → option A
namespace option
theorem induction_on [protected] {A : Type} {p : option A → Prop} (o : option A)
theorem induction_on [protected] {A : Type} {p : option A → Prop} (o : option A)
(H1 : p none) (H2 : ∀a, p (some a)) : p o :=
rec H1 H2 o
rec H1 H2 o
definition rec_on [protected] {A : Type} {C : option A → Type} (o : option A)
definition rec_on [protected] {A : Type} {C : option A → Type} (o : option A)
(H1 : C none) (H2 : ∀a, C (some a)) : C o :=
rec H1 H2 o
rec H1 H2 o
definition is_none {A : Type} (o : option A) : Prop :=
rec true (λ a, false) o
definition is_none {A : Type} (o : option A) : Prop :=
rec true (λ a, false) o
theorem is_none_none {A : Type} : is_none (@none A) :=
trivial
theorem is_none_none {A : Type} : is_none (@none A) :=
trivial
theorem not_is_none_some {A : Type} (a : A) : ¬ is_none (some a) :=
not_false_trivial
theorem not_is_none_some {A : Type} (a : A) : ¬ is_none (some a) :=
not_false_trivial
theorem none_ne_some {A : Type} (a : A) : none ≠ some a :=
assume H : none = some a, absurd
theorem none_ne_some {A : Type} (a : A) : none ≠ some a :=
assume H : none = some a, absurd
(H ▸ is_none_none)
(not_is_none_some a)
theorem some_inj {A : Type} {a₁ a₂ : A} (H : some a₁ = some a₂) : a₁ = a₂ :=
congr_arg (option.rec a₁ (λ a, a)) H
theorem equal [protected] {A : Type} {a₁ a₂ : A} (H : some a₁ = some a₂) : a₁ = a₂ :=
congr_arg (option.rec a₁ (λ a, a)) H
theorem option_inhabited [instance] (A : Type) : inhabited (option A) :=
inhabited.mk none
theorem is_inhabited [protected] [instance] (A : Type) : inhabited (option A) :=
inhabited.mk none
theorem decidable_eq [instance] {A : Type} {H : ∀a₁ a₂ : A, decidable (a₁ = a₂)}
theorem has_decidable_eq [protected] [instance] {A : Type} {H : ∀a₁ a₂ : A, decidable (a₁ = a₂)}
(o₁ o₂ : option A) : decidable (o₁ = o₂) :=
rec_on o₁
rec_on o₁
(rec_on o₂ (inl rfl) (take a₂, (inr (none_ne_some a₂))))
(take a₁ : A, rec_on o₂
(inr (ne.symm (none_ne_some a₁)))
(take a₂ : A, decidable.rec_on (H a₁ a₂)
(assume Heq : a₁ = a₂, inl (Heq ▸ rfl))
(assume Hne : a₁ ≠ a₂, inr (assume Hn : some a₁ = some a₂, absurd (some_inj Hn) Hne))))
(assume Hne : a₁ ≠ a₂, inr (assume Hn : some a₁ = some a₂, absurd (equal Hn) Hne))))
end option

View file

@ -1,30 +1,25 @@
-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
-- Released under Apache 2.0 license as described in the file LICENSE.
-- Author: Leonardo de Moura, Jeremy Avigad
import logic.classes.inhabited logic.core.eq logic.classes.decidable
-- data.prod
-- =========
-- The cartesian product.
import logic.classes.inhabited logic.core.eq logic.classes.decidable
open inhabited decidable
-- The cartesian product.
inductive prod (A B : Type) : Type :=
mk : A → B → prod A B
mk : A → B → prod A B
abbreviation pair := @prod.mk
infixr `×` := prod
-- notation for n-ary tuples
notation `(` h `,` t:(foldl `,` (e r, prod.mk r e) h) `)` := t
namespace prod
section
parameters {A B : Type}
abbreviation pr1 (p : prod A B) := rec (λ x y, x) p
@ -47,20 +42,18 @@ section
theorem pair_eq {a1 a2 : A} {b1 b2 : B} (H1 : a1 = a2) (H2 : b1 = b2) : (a1, b1) = (a2, b2) :=
H1 ▸ H2 ▸ rfl
theorem prod_eq {p1 p2 : prod A B} : ∀ (H1 : pr1 p1 = pr1 p2) (H2 : pr2 p1 = pr2 p2), p1 = p2 :=
theorem equal [protected] {p1 p2 : prod A B} : ∀ (H1 : pr1 p1 = pr1 p2) (H2 : pr2 p1 = pr2 p2), p1 = p2 :=
destruct p1 (take a1 b1, destruct p2 (take a2 b2 H1 H2, pair_eq H1 H2))
theorem prod_inhabited [instance] (H1 : inhabited A) (H2 : inhabited B) : inhabited (prod A B) :=
theorem is_inhabited [protected] [instance] (H1 : inhabited A) (H2 : inhabited B) : inhabited (prod A B) :=
inhabited.destruct H1 (λa, inhabited.destruct H2 (λb, inhabited.mk (pair a b)))
theorem prod_eq_decidable [instance] (u v : A × B) (H1 : decidable (pr1 u = pr1 v))
theorem has_decidable_eq [protected] [instance] (u v : A × B) (H1 : decidable (pr1 u = pr1 v))
(H2 : decidable (pr2 u = pr2 v)) : decidable (u = v) :=
have H3 : u = v ↔ (pr1 u = pr1 v) ∧ (pr2 u = pr2 v), from
iff.intro
(assume H, H ▸ and.intro rfl rfl)
(assume H, and.elim H (assume H4 H5, prod_eq H4 H5)),
(assume H, and.elim H (assume H4 H5, equal H4 H5)),
decidable_iff_equiv _ (iff.symm H3)
end
end prod

View file

@ -150,7 +150,7 @@ have Hy : pr2 (map_pair2 f v (pair e e)) = pr2 v, from
pr2 (map_pair2 f v (pair e e)) = f (pr2 v) (pr2 (pair e e)) : by simp
... = f (pr2 v) e : by simp
... = pr2 v : Hid (pr2 v)),
prod_eq Hx Hy
prod.equal Hx Hy
theorem map_pair2_id_left {A B : Type} {f : B → A → A} {e : B} (Hid : ∀a : A, f e a = a)
(v : A × A) : map_pair2 f (pair e e) v = v :=
@ -164,7 +164,7 @@ have Hy : pr2 (map_pair2 f (pair e e) v) = pr2 v, from
pr2 (map_pair2 f (pair e e) v) = f (pr2 (pair e e)) (pr2 v) : by simp
... = f e (pr2 v) : by simp
... = pr2 v : Hid (pr2 v),
prod_eq Hx Hy
prod.equal Hx Hy
opaque_hint (hiding flip map_pair map_pair2)

View file

@ -294,7 +294,7 @@ intro
... = f (f a) : {Ha⁻¹}
... = f a : representative_map_idempotent H1 H2 a
... = elt_of u : Ha,
show abs (elt_of u) = u, from subtype_eq H)
show abs (elt_of u) = u, from subtype.equal H)
(take u : image f,
show R (elt_of u) (elt_of u), from
obtain (a : A) (Ha : f a = elt_of u), from image_elt_of u,

View file

@ -42,13 +42,12 @@ section
... = dpair a1 b2' : {H2'}) H1)
b2 H1 H2
theorem sigma_eq {p1 p2 : Σx : A, B x} :
theorem equal [protected] {p1 p2 : Σx : A, B x} :
∀(H1 : dpr1 p1 = dpr1 p2) (H2 : eq.rec_on H1 (dpr2 p1) = (dpr2 p2)), p1 = p2 :=
sigma_destruct p1 (take a1 b1, sigma_destruct p2 (take a2 b2 H1 H2, dpair_eq H1 H2))
theorem sigma_inhabited [instance] (H1 : inhabited A) (H2 : inhabited (B (default A))) :
theorem is_inhabited [protected] [instance] (H1 : inhabited A) (H2 : inhabited (B (default A))) :
inhabited (sigma B) :=
inhabited.destruct H1 (λa, inhabited.destruct H2 (λb, inhabited.mk (dpair (default A) b)))
end
end sigma

View file

@ -7,14 +7,18 @@ import data.bool
open bool inhabited
inductive char : Type :=
mk : bool → bool → bool → bool → bool → bool → bool → bool → char
mk : bool → bool → bool → bool → bool → bool → bool → bool → char
namespace char
theorem is_inhabited [protected] [instance] : inhabited char :=
inhabited.mk (mk ff ff ff ff ff ff ff ff)
end char
inductive string : Type :=
empty : string,
str : char → string → string
empty : string,
str : char → string → string
theorem char_inhabited [instance] : inhabited char :=
inhabited.mk (char.mk ff ff ff ff ff ff ff ff)
theorem string_inhabited [instance] : inhabited string :=
inhabited.mk string.empty
namespace string
theorem is_inhabited [protected] [instance] : inhabited string :=
inhabited.mk empty
end string

View file

@ -7,12 +7,11 @@ import logic.classes.inhabited logic.core.eq logic.classes.decidable
open decidable
inductive subtype {A : Type} (P : A → Prop) : Type :=
tag : Πx : A, P x → subtype P
tag : Πx : A, P x → subtype P
notation `{` binders `,` r:(scoped P, subtype P) `}` := r
namespace subtype
section
parameter {A : Type}
parameter {P : A → Prop}
@ -36,18 +35,16 @@ section
theorem tag_eq {a1 a2 : A} {H1 : P a1} {H2 : P a2} (H3 : a1 = a2) : tag a1 H1 = tag a2 H2 :=
eq.subst H3 (take H2, tag_irrelevant H1 H2) H2
theorem subtype_eq {a1 a2 : {x, P x}} : ∀(H : elt_of a1 = elt_of a2), a1 = a2 :=
theorem equal [protected] {a1 a2 : {x, P x}} : ∀(H : elt_of a1 = elt_of a2), a1 = a2 :=
destruct a1 (take x1 H1, destruct a2 (take x2 H2 H, tag_eq H))
theorem subtype_inhabited [instance] {a : A} (H : P a) : inhabited {x, P x} :=
theorem is_inhabited [protected] [instance] {a : A} (H : P a) : inhabited {x, P x} :=
inhabited.mk (tag a H)
theorem eq_decidable [protected] [instance] (a1 a2 : {x, P x})
theorem has_decidable_eq [protected] [instance] (a1 a2 : {x, P x})
(H : decidable (elt_of a1 = elt_of a2)) : decidable (a1 = a2) :=
have H1 : (a1 = a2) ↔ (elt_of a1 = elt_of a2), from
iff.intro (assume H, eq.subst H rfl) (assume H, subtype_eq H),
iff.intro (assume H, eq.subst H rfl) (assume H, equal H),
decidable_iff_equiv _ (iff.symm H1)
end
end subtype

View file

@ -1,70 +1,64 @@
-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
-- Released under Apache 2.0 license as described in the file LICENSE.
-- Author: Leonardo de Moura, Jeremy Avigad
import logic.core.prop logic.classes.inhabited logic.classes.decidable
open inhabited decidable eq_ops
-- data.sum
-- ========
-- The sum type, aka disjoint union.
import logic.core.prop logic.classes.inhabited logic.classes.decidable
open inhabited decidable eq_ops
-- TODO: take this outside the namespace when the inductive package handles it better
inductive sum (A B : Type) : Type :=
inl : A → sum A B,
inr : B → sum A B
inl : A → sum A B,
inr : B → sum A B
namespace sum
infixr `⊎` := sum
infixr `⊎` := sum
namespace extra_notation
infixr `+`:25 := sum -- conflicts with notation for addition
end extra_notation
namespace sum_plus_notation
infixr `+`:25 := sum -- conflicts with notation for addition
end sum_plus_notation
abbreviation rec_on [protected] {A B : Type} {C : (A ⊎ B) → Type} (s : A ⊎ B)
abbreviation rec_on [protected] {A B : Type} {C : (A ⊎ B) → Type} (s : A ⊎ B)
(H1 : ∀a : A, C (inl B a)) (H2 : ∀b : B, C (inr A b)) : C s :=
rec H1 H2 s
rec H1 H2 s
abbreviation cases_on [protected] {A B : Type} {P : (A ⊎ B) → Prop} (s : A ⊎ B)
abbreviation cases_on [protected] {A B : Type} {P : (A ⊎ B) → Prop} (s : A ⊎ B)
(H1 : ∀a : A, P (inl B a)) (H2 : ∀b : B, P (inr A b)) : P s :=
rec H1 H2 s
rec H1 H2 s
-- Here is the trick for the theorems that follow:
-- Fixing a1, "f s" is a recursive description of "inl B a1 = s".
-- When s is (inl B a1), it reduces to a1 = a1.
-- When s is (inl B a2), it reduces to a1 = a2.
-- When s is (inr A b), it reduces to false.
-- Here is the trick for the theorems that follow:
-- Fixing a1, "f s" is a recursive description of "inl B a1 = s".
-- When s is (inl B a1), it reduces to a1 = a1.
-- When s is (inl B a2), it reduces to a1 = a2.
-- When s is (inr A b), it reduces to false.
theorem inl_inj {A B : Type} {a1 a2 : A} (H : inl B a1 = inl B a2) : a1 = a2 :=
let f := λs, rec_on s (λa, a1 = a) (λb, false) in
have H1 : f (inl B a1), from rfl,
have H2 : f (inl B a2), from H ▸ H1,
H2
theorem inl_inj {A B : Type} {a1 a2 : A} (H : inl B a1 = inl B a2) : a1 = a2 :=
let f := λs, rec_on s (λa, a1 = a) (λb, false) in
have H1 : f (inl B a1), from rfl,
have H2 : f (inl B a2), from H ▸ H1,
H2
theorem inl_neq_inr {A B : Type} {a : A} {b : B} (H : inl B a = inr A b) : false :=
let f := λs, rec_on s (λa', a = a') (λb, false) in
have H1 : f (inl B a), from rfl,
have H2 : f (inr A b), from H ▸ H1,
H2
theorem inl_neq_inr {A B : Type} {a : A} {b : B} (H : inl B a = inr A b) : false :=
let f := λs, rec_on s (λa', a = a') (λb, false) in
have H1 : f (inl B a), from rfl,
have H2 : f (inr A b), from H ▸ H1,
H2
theorem inr_inj {A B : Type} {b1 b2 : B} (H : inr A b1 = inr A b2) : b1 = b2 :=
let f := λs, rec_on s (λa, false) (λb, b1 = b) in
have H1 : f (inr A b1), from rfl,
have H2 : f (inr A b2), from H ▸ H1,
H2
theorem inr_inj {A B : Type} {b1 b2 : B} (H : inr A b1 = inr A b2) : b1 = b2 :=
let f := λs, rec_on s (λa, false) (λb, b1 = b) in
have H1 : f (inr A b1), from rfl,
have H2 : f (inr A b2), from H ▸ H1,
H2
theorem sum_inhabited_left [instance] {A B : Type} (H : inhabited A) : inhabited (A ⊎ B) :=
inhabited.mk (inl B (default A))
theorem is_inhabited_left [protected] [instance] {A B : Type} (H : inhabited A) : inhabited (A ⊎ B) :=
inhabited.mk (inl B (default A))
theorem sum_inhabited_right [instance] {A B : Type} (H : inhabited B) : inhabited (A ⊎ B) :=
inhabited.mk (inr A (default B))
theorem is_inhabited_right [protected] [instance] {A B : Type} (H : inhabited B) : inhabited (A ⊎ B) :=
inhabited.mk (inr A (default B))
theorem sum_eq_decidable [instance] {A B : Type} (s1 s2 : A ⊎ B)
theorem has_eq_decidable [protected] [instance] {A B : Type} (s1 s2 : A ⊎ B)
(H1 : ∀a1 a2 : A, decidable (inl B a1 = inl B a2))
(H2 : ∀b1 b2 : B, decidable (inr A b1 = inr A b2)) : decidable (s1 = s2) :=
rec_on s1
rec_on s1
(take a1, show decidable (inl B a1 = s2), from
rec_on s2
(take a2, show decidable (inl B a1 = inl B a2), from H1 a1 a2)
@ -79,5 +73,4 @@ rec_on s1
from iff.intro (assume H4, inl_neq_inr (H4⁻¹)) (assume H4, false_elim H4),
show decidable (inr A b1 = inl B a2), from decidable_iff_equiv _ (iff.symm H3))
(take b2, show decidable (inr A b1 = inr A b2), from H2 b1 b2))
end sum

View file

@ -2,26 +2,22 @@
-- Released under Apache 2.0 license as described in the file LICENSE.
-- Author: Leonardo de Moura
import logic.classes.decidable logic.classes.inhabited
open decidable
inductive unit : Type :=
star : unit
star : unit
namespace unit
notation `⋆`:max := star
notation `⋆`:max := star
theorem equal [protected] (a b : unit) : a = b :=
rec (rec rfl b) a
theorem at_most_one (a b : unit) : a = b :=
rec (rec rfl b) a
theorem eq_star (a : unit) : a = star :=
equal a star
theorem eq_star (a : unit) : a = star :=
at_most_one a star
theorem unit_inhabited [instance] : inhabited unit :=
inhabited.mk ⋆
theorem decidable_eq [instance] (a b : unit) : decidable (a = b) :=
inl (at_most_one a b)
theorem is_inhabited [protected] [instance] : inhabited unit :=
inhabited.mk ⋆
theorem has_decidable_eq [protected] [instance] (a b : unit) : decidable (a = b) :=
inl (equal a b)
end unit

View file

@ -1,7 +1,7 @@
empty.lean:6:25: error: type error in placeholder assigned to
char_inhabited
num_inhabited
placeholder has type
inhabited char
inhabited num
but is expected to have type
inhabited ?M_1
the assignment was attempted when trying to solve