Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".
Project: Xena
Views: 18536License: APACHE
/- Copyright (c) 2017 Johannes Hölzl. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Johannes Hölzl Relator for functions, pairs, sums, and lists. -/ namespace relator universe variables u₁ u₂ v₁ v₂ reserve infixr ` ⇒ `:40 /- TODO(johoelzl): * should we introduce relators of datatypes as recursive function or as inductive predicate? For now we stick to the recursor approach. * relation lift for datatypes, Π, Σ, set, and subtype types * proof composition and identity laws * implement method to derive relators from datatype -/ section variables {α : Sort u₁} {β : Sort u₂} {γ : Sort v₁} {δ : Sort v₂} variables (R : α → β → Prop) (S : γ → δ → Prop) def lift_fun (f : α → γ) (g : β → δ) : Prop := ∀⦃a b⦄, R a b → S (f a) (g b) infixr ⇒ := lift_fun end section variables {α : Type u₁} {β : out_param $ Type u₂} (R : out_param $ α → β → Prop) @[class] def right_total := ∀b, ∃a, R a b @[class] def left_total := ∀a, ∃b, R a b @[class] def bi_total := left_total R ∧ right_total R end section variables {α : Type u₁} {β : Type u₂} (R : α → β → Prop) @[class] def left_unique := ∀{a b c}, R a b → R c b → a = c @[class] def right_unique := ∀{a b c}, R a b → R a c → b = c lemma rel_forall_of_right_total [t : right_total R] : ((R ⇒ implies) ⇒ implies) (λp, ∀i, p i) (λq, ∀i, q i) := assume p q Hrel H b, exists.elim (t b) (assume a Rab, Hrel Rab (H _)) lemma rel_exists_of_left_total [t : left_total R] : ((R ⇒ implies) ⇒ implies) (λp, ∃i, p i) (λq, ∃i, q i) := assume p q Hrel ⟨a, pa⟩, let ⟨b, Rab⟩ := t a in ⟨b, Hrel Rab pa⟩ lemma rel_forall_of_total [t : bi_total R] : ((R ⇒ iff) ⇒ iff) (λp, ∀i, p i) (λq, ∀i, q i) := assume p q Hrel, ⟨assume H b, exists.elim (t.right b) (assume a Rab, (Hrel Rab).mp (H _)), assume H a, exists.elim (t.left a) (assume b Rab, (Hrel Rab).mpr (H _))⟩ lemma rel_exists_of_total [t : bi_total R] : ((R ⇒ iff) ⇒ iff) (λp, ∃i, p i) (λq, ∃i, q i) := assume p q Hrel, ⟨assume ⟨a, pa⟩, let ⟨b, Rab⟩ := t.left a in ⟨b, (Hrel Rab).1 pa⟩, assume ⟨b, qb⟩, let ⟨a, Rab⟩ := t.right b in ⟨a, (Hrel Rab).2 qb⟩⟩ lemma left_unique_of_rel_eq {eq' : β → β → Prop} (he : (R ⇒ (R ⇒ iff)) eq eq') : left_unique R | a b c (ab : R a b) (cb : R c b) := have eq' b b, from iff.mp (he ab ab) rfl, iff.mpr (he ab cb) this end lemma rel_imp : (iff ⇒ (iff ⇒ iff)) implies implies := assume p q h r s l, imp_congr h l lemma rel_not : (iff ⇒ iff) not not := assume p q h, not_congr h @[priority 100] -- see Note [lower instance priority] -- (this is an instance is always applies, since the relation is an out-param) instance bi_total_eq {α : Type u₁} : relator.bi_total (@eq α) := ⟨assume a, ⟨a, rfl⟩, assume a, ⟨a, rfl⟩⟩ variables {α : Type*} {β : Type*} {γ : Type*} {δ : Type*} variables {r : α → β → Prop} {p : β → γ → Prop} {q : γ → δ → Prop} def bi_unique (r : α → β → Prop) : Prop := left_unique r ∧ right_unique r lemma left_unique_flip (h : left_unique r) : right_unique (flip r) | a b c h₁ h₂ := h h₁ h₂ lemma rel_and : ((↔) ⇒ (↔) ⇒ (↔)) (∧) (∧) := assume a b h₁ c d h₂, and_congr h₁ h₂ lemma rel_or : ((↔) ⇒ (↔) ⇒ (↔)) (∨) (∨) := assume a b h₁ c d h₂, or_congr h₁ h₂ lemma rel_iff : ((↔) ⇒ (↔) ⇒ (↔)) (↔) (↔) := assume a b h₁ c d h₂, iff_congr h₁ h₂ lemma rel_eq {r : α → β → Prop} (hr : bi_unique r) : (r ⇒ r ⇒ (↔)) (=) (=) := assume a b h₁ c d h₂, iff.intro begin intro h, subst h, exact hr.right h₁ h₂ end begin intro h, subst h, exact hr.left h₁ h₂ end end relator