Skip to content

chore: Decidable as subtype of Bool using the new compiler #8309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 32 additions & 34 deletions src/Init/Core.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ theorem Exists.elim {α : Sort u} {p : α → Prop} {b : Prop}

/-- Similar to `decide`, but uses an explicit instance -/
@[inline] def toBoolUsing {p : Prop} (d : Decidable p) : Bool :=
decide (h := d)
@decide p d

theorem toBoolUsing_eq_true {p : Prop} (d : Decidable p) (h : p) : toBoolUsing d = true :=
decide_eq_true (inst := d) h
Expand Down Expand Up @@ -1119,34 +1119,34 @@ end Decidable
section
variable {p q : Prop}
/-- Transfer a decidability proof across an equivalence of propositions. -/
@[inline] def decidable_of_decidable_of_iff [Decidable p] (h : p ↔ q) : Decidable q :=
if hp : p then
isTrue (Iff.mp h hp)
else
isFalse fun hq => absurd (Iff.mpr h hq) hp
@[inline] def decidable_of_decidable_of_iff [dp : Decidable p] (h : p ↔ q) : Decidable q where
decide := decide p
of_decide :=
match dp with
| isTrue hp => Iff.mp h hp
| isFalse hp => fun hq => absurd (Iff.mpr h hq) hp

/-- Transfer a decidability proof across an equality of propositions. -/
@[inline] def decidable_of_decidable_of_eq [Decidable p] (h : p = q) : Decidable q :=
decidable_of_decidable_of_iff (p := p) (h ▸ Iff.rfl)
end

@[macro_inline] instance {p q} [Decidable p] [Decidable q] : Decidable (p → q) :=
if hp : p then
if hq : q then isTrue (fun _ => hq)
else isFalse (fun h => absurd (h hp) hq)
else isTrue (fun h => absurd h hp)

instance {p q} [Decidable p] [Decidable q] : Decidable (p ↔ q) :=
if hp : p then
if hq : q then
isTrue ⟨fun _ => hq, fun _ => hp⟩
else
isFalse fun h => hq (h.1 hp)
else
if hq : q then
isFalse fun h => hp (h.2 hq)
else
isTrue ⟨fun h => absurd h hp, fun h => absurd h hq⟩
@[macro_inline] instance {p q} [dp : Decidable p] [dq : Decidable q] : Decidable (p → q) where
decide := !p || q
of_decide :=
match dp, dq with
| isTrue _, isTrue hq => fun _ => hq
| isTrue hp, isFalse hq => fun h => absurd (h hp) hq
| isFalse hp, _ => fun h => absurd h hp

instance {p q} [dp : Decidable p] [dq : Decidable q] : Decidable (p ↔ q) where
decide := (decide p).beq (decide q)
of_decide :=
match dp, dq with
| isTrue hp, isTrue hq => ⟨fun _ => hq, fun _ => hp⟩
| isTrue hp, isFalse hq => fun h => hq (h.1 hp)
| isFalse hp, isTrue hq => fun h => hp (h.2 hq)
| isFalse hp, isFalse hq => ⟨fun h => absurd h hp, fun h => absurd h hq⟩

/-! # if-then-else expression theorems -/

Expand Down Expand Up @@ -1194,18 +1194,16 @@ instance {c : Prop} {t : c → Prop} {e : ¬c → Prop} [dC : Decidable c] [dT :
| isFalse hc => dE hc

/-- Auxiliary definition for generating compact `noConfusion` for enumeration types -/
abbrev noConfusionTypeEnum {α : Sort u} {β : Sort v} [inst : DecidableEq β] (f : α → β) (P : Sort w) (x y : α) : Sort w :=
(inst (f x) (f y)).casesOn
(fun _ => P)
(fun _ => P → P)
abbrev noConfusionTypeEnum {α : Sort u} (f : α → Nat) (P : Sort w) (x y : α) : Sort w :=
((f x).beq (f y)).casesOn P (P → P)

/-- Auxiliary definition for generating compact `noConfusion` for enumeration types -/
abbrev noConfusionEnum {α : Sort u} {β : Sort v} [inst : DecidableEq β] (f : α → β) {P : Sort w} {x y : α} (h : x = y) : noConfusionTypeEnum f P x y :=
Decidable.casesOn
(motive := fun (inst : Decidable (f x = f y)) => Decidable.casesOn (motive := fun _ => Sort w) inst (fun _ => P) (fun _ => P → P))
(inst (f x) (f y))
(fun h' => False.elim (h' (congrArg f h)))
(fun _ => fun x => x)
abbrev noConfusionEnum {α : Sort u} (f : α → Nat) {P : Sort w} {x y : α} (h : x = y) : noConfusionTypeEnum f P x y :=
((f x).beq (f y)).casesOn
(motive := fun b => (f x).beq (f y) = b → b.casesOn P (P → P))
(fun h' => False.elim (Nat.ne_of_beq_eq_false h' (congrArg f h)))
(fun _ a => a)
rfl

/-! # Inhabited -/

Expand Down Expand Up @@ -1270,7 +1268,7 @@ theorem recSubsingleton
{h₂ : ¬p → Sort u}
[h₃ : ∀ (h : p), Subsingleton (h₁ h)]
[h₄ : ∀ (h : ¬p), Subsingleton (h₂ h)]
: Subsingleton (h.casesOn h₂ h₁) :=
: Subsingleton (h.falseTrueCases h₂ h₁) :=
match h with
| isTrue h => h₃ h
| isFalse h => h₄ h
Expand Down
9 changes: 0 additions & 9 deletions src/Init/Data/List/Basic.lean
Original file line number Diff line number Diff line change
Expand Up @@ -120,15 +120,6 @@ theorem of_concat_eq_concat {as bs : List α} {a b : α} (h : as.concat a = bs.c

/-! ## Equality -/

/--
Checks whether two lists have the same length and their elements are pairwise `BEq`. Normally used
via the `==` operator.
-/
protected def beq [BEq α] : List α → List α → Bool
| [], [] => true
| a::as, b::bs => a == b && List.beq as bs
| _, _ => false

@[simp] theorem beq_nil_nil [BEq α] : List.beq ([] : List α) ([] : List α) = true := rfl
@[simp] theorem beq_cons_nil [BEq α] {a : α} {as : List α} : List.beq (a::as) [] = false := rfl
@[simp] theorem beq_nil_cons [BEq α] {a : α} {as : List α} : List.beq [] (a::as) = false := rfl
Expand Down
2 changes: 2 additions & 0 deletions src/Init/Data/Vector/Extract.lean
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ prelude
import Init.Data.Vector.Lemmas
import Init.Data.Array.Extract

set_option maxHeartbeats 20000000

/-!
# Lemmas about `Vector.extract`
-/
Expand Down
Loading
Loading