<commit_before>-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
-- Released under Apache 2.0 license as described in the file LICENSE.
-- Authors: <NAME>, <NAME>
open inhabited nonempty

theorem exists_not_forall {A : Type} {p : A → Prop} (H : ∃x, p x) : ¬∀x, ¬p x :=
assume H1 : ∀x, ¬p x,
  obtain (w : A) (Hw : p w), from H,
  absurd Hw (H1 w)

theorem forall_not_exists {A : Type} {p : A → Prop} (H2 : ∀x, p x) : ¬∃x, ¬p x :=
assume H1 : ∃x, ¬p x,
  obtain (w : A) (Hw : ¬p w), from H1,
  absurd (H2 w) Hw

theorem forall_congr {A : Type} {φ ψ : A → Prop} (H : ∀x, φ x ↔ ψ x) : (∀x, φ x) ↔ (∀x, ψ x) :=
iff.intro
  (assume Hl, take x, iff.elim_left (H x) (Hl x))
  (assume Hr, take x, iff.elim_right (H x) (Hr x))

theorem exists_congr {A : Type} {φ ψ : A → Prop} (H : ∀x, φ x ↔ ψ x) : (∃x, φ x) ↔ (∃x, ψ x) :=
iff.intro
  (assume Hex, obtain w Pw, from Hex,
    exists_intro w (iff.elim_left (H w) Pw))
  (assume Hex, obtain w Qw, from Hex,
    exists_intro w (iff.elim_right (H w) Qw))

theorem forall_true_iff_true (A : Type) : (∀x : A, true) ↔ true :=
iff.intro (assume H, trivial) (assume H, take x, trivial)

theorem forall_p_iff_p (A : Type) [H : inhabited A] (p : Prop) : (∀x : A, p) ↔ p :=
iff.intro (assume Hl, inhabited.destruct H (take x, Hl x)) (assume Hr, take x, Hr)

theorem exists_p_iff_p (A : Type) [H : inhabited A] (p : Prop) : (∃x : A, p) ↔ p :=
iff.intro
  (assume Hl, obtain a Hp, from Hl, Hp)
  (assume Hr, inhabited.destruct H (take a, exists_intro a Hr))

theorem forall_and_distribute {A : Type} (φ ψ : A → Prop) : (∀x, φ x ∧ ψ x) ↔ (∀x, φ x) ∧ (∀x, ψ x) :=
iff.intro
  (assume H, and.intro (take x, and.elim_left (H x)) (take x, and.elim_right (H x)))
  (assume H, take x, and.intro (and.elim_left H x) (and.elim_right H x))

theorem exists_or_distribute {A : Type} (φ ψ : A → Prop) : (∃x, φ x ∨ ψ x) ↔ (∃x, φ x) ∨ (∃x, ψ x) :=
iff.intro
  (assume H, obtain (w : A) (Hw : φ w ∨ ψ w), from H,
    or.elim Hw
      (assume Hw1 : φ w, or.inl (exists_intro w Hw1))
      (assume Hw2 : ψ w, or.inr (exists_intro w Hw2)))
  (assume H, or.elim H
    (assume H1, obtain (w : A) (Hw : φ w), from H1,
      exists_intro w (or.inl Hw))
    (assume H2, obtain (w : A) (Hw : ψ w), from H2,
      exists_intro w (or.inr Hw)))

theorem exists_imp_nonempty {A : Type} {P : A → Prop} (H : ∃x, P x) : nonempty A :=
obtain w Hw, from H, nonempty.intro w
<commit_msg>feat(library/logic/quantifiers): add decidable_forall_eq and decidable_exists_eq theorems<commit_after>-- Copyright (c) 2014 Microsoft Corporation. All rights reserved.
-- Released under Apache 2.0 license as described in the file LICENSE.
-- Authors: <NAME>, <NAME>
open inhabited nonempty

theorem exists_not_forall {A : Type} {p : A → Prop} (H : ∃x, p x) : ¬∀x, ¬p x :=
assume H1 : ∀x, ¬p x,
  obtain (w : A) (Hw : p w), from H,
  absurd Hw (H1 w)

theorem forall_not_exists {A : Type} {p : A → Prop} (H2 : ∀x, p x) : ¬∃x, ¬p x :=
assume H1 : ∃x, ¬p x,
  obtain (w : A) (Hw : ¬p w), from H1,
  absurd (H2 w) Hw

theorem forall_congr {A : Type} {φ ψ : A → Prop} (H : ∀x, φ x ↔ ψ x) : (∀x, φ x) ↔ (∀x, ψ x) :=
iff.intro
  (assume Hl, take x, iff.elim_left (H x) (Hl x))
  (assume Hr, take x, iff.elim_right (H x) (Hr x))

theorem exists_congr {A : Type} {φ ψ : A → Prop} (H : ∀x, φ x ↔ ψ x) : (∃x, φ x) ↔ (∃x, ψ x) :=
iff.intro
  (assume Hex, obtain w Pw, from Hex,
    exists_intro w (iff.elim_left (H w) Pw))
  (assume Hex, obtain w Qw, from Hex,
    exists_intro w (iff.elim_right (H w) Qw))

theorem forall_true_iff_true (A : Type) : (∀x : A, true) ↔ true :=
iff.intro (assume H, trivial) (assume H, take x, trivial)

theorem forall_p_iff_p (A : Type) [H : inhabited A] (p : Prop) : (∀x : A, p) ↔ p :=
iff.intro (assume Hl, inhabited.destruct H (take x, Hl x)) (assume Hr, take x, Hr)

theorem exists_p_iff_p (A : Type) [H : inhabited A] (p : Prop) : (∃x : A, p) ↔ p :=
iff.intro
  (assume Hl, obtain a Hp, from Hl, Hp)
  (assume Hr, inhabited.destruct H (take a, exists_intro a Hr))

theorem forall_and_distribute {A : Type} (φ ψ : A → Prop) : (∀x, φ x ∧ ψ x) ↔ (∀x, φ x) ∧ (∀x, ψ x) :=
iff.intro
  (assume H, and.intro (take x, and.elim_left (H x)) (take x, and.elim_right (H x)))
  (assume H, take x, and.intro (and.elim_left H x) (and.elim_right H x))

theorem exists_or_distribute {A : Type} (φ ψ : A → Prop) : (∃x, φ x ∨ ψ x) ↔ (∃x, φ x) ∨ (∃x, ψ x) :=
iff.intro
  (assume H, obtain (w : A) (Hw : φ w ∨ ψ w), from H,
    or.elim Hw
      (assume Hw1 : φ w, or.inl (exists_intro w Hw1))
      (assume Hw2 : ψ w, or.inr (exists_intro w Hw2)))
  (assume H, or.elim H
    (assume H1, obtain (w : A) (Hw : φ w), from H1,
      exists_intro w (or.inl Hw))
    (assume H2, obtain (w : A) (Hw : ψ w), from H2,
      exists_intro w (or.inr Hw)))

theorem exists_imp_nonempty {A : Type} {P : A → Prop} (H : ∃x, P x) : nonempty A :=
obtain w Hw, from H, nonempty.intro w

section
  open decidable eq.ops

  variables {A : Type} (P : A → Prop) (a : A) [H : decidable (P a)]
  include H

  definition decidable_forall_eq [instance] : decidable (∀ x, x = a → P x) :=
  decidable.rec_on H
     (λ pa,  inl (λ x heq, eq.rec_on (eq.rec_on heq rfl) pa))
     (λ npa, inr (λ h, absurd (h a rfl) npa))

  definition decidable_exists_eq [instance] : decidable (∃ x, x = a ∧ P x) :=
  decidable.rec_on H
     (λ pa, inl (exists_intro a (and.intro rfl pa)))
     (λ npa, inr (λ h,
       obtain (w : A) (Hw : w = a ∧ P w), from h,
       absurd (and.rec_on Hw (λ h₁ h₂, h₁ ▸ h₂)) npa))
end

{'fraction_non_alphanumeric': 0.1695596564955235, 'fraction_numerical': 0.0073086058834277365, 'mean_word_length': 2.966666666666667, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6790513', 'n_tokens_mistral': 2698, 'n_tokens_neox': 2527, 'n_words': 938}