|
| 1 | +/- |
| 2 | +Copyright (c) 2017 Johannes Hölzl. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Johannes Hölzl |
| 5 | +-/ |
| 6 | + |
| 7 | +import Mathlib.Logic.Basic |
| 8 | + |
| 9 | +/-! |
| 10 | +# Relator for functions, pairs, sums, and lists. |
| 11 | +-/ |
| 12 | + |
| 13 | +namespace Relator |
| 14 | +universe u₁ u₂ v₁ v₂ |
| 15 | + |
| 16 | +/- TODO(johoelzl): |
| 17 | + * should we introduce relators of datatypes as recursive function or as inductive |
| 18 | +predicate? For now we stick to the recursor approach. |
| 19 | + * relation lift for datatypes, Π, Σ, set, and subtype types |
| 20 | + * proof composition and identity laws |
| 21 | + * implement method to derive relators from datatype |
| 22 | +-/ |
| 23 | + |
| 24 | +section |
| 25 | + |
| 26 | +variable {α : Sort u₁} {β : Sort u₂} {γ : Sort v₁} {δ : Sort v₂} |
| 27 | +variable (R : α → β → Prop) (S : γ → δ → Prop) |
| 28 | + |
| 29 | +/-- The binary relations `R : α → β → Prop` and `S : γ → δ → Prop` induce a binary |
| 30 | + relation on functions `LiftFun : (f : α → γ) (g : β → δ) : Prop'. -/ |
| 31 | +def LiftFun (f : α → γ) (g : β → δ) : Prop := |
| 32 | +∀⦃a b⦄, R a b → S (f a) (g b) |
| 33 | + |
| 34 | +/-- `(R ⇒ S) f g` means `LiftFun R S f g`. -/ |
| 35 | +infixr:40 " ⇒ " => LiftFun |
| 36 | + |
| 37 | +end |
| 38 | + |
| 39 | +section |
| 40 | + |
| 41 | +variable {α : Type u₁} {β : Type u₂} (R : α → β → Prop) |
| 42 | + |
| 43 | +/-- A relation is "right total" if every element appears on the right. -/ |
| 44 | +def RightTotal : Prop := ∀ b, ∃ a, R a b |
| 45 | + |
| 46 | +/-- A relation is "left total" if every element appears on the left. -/ |
| 47 | +def LeftTotal : Prop := ∀ a, ∃ b, R a b |
| 48 | + |
| 49 | +/-- A relation is "bi-total" if it is both right total and left total. -/ |
| 50 | +def BiTotal : Prop := LeftTotal R ∧ RightTotal R |
| 51 | + |
| 52 | +/-- A relation is "left unique" if every element on the right is paired with at |
| 53 | + most one element on the left. -/ |
| 54 | +def LeftUnique : Prop := ∀ ⦃a b c⦄, R a c → R b c → a = b |
| 55 | + |
| 56 | +/-- A relation is "right unique" if every element on the left is paired with at |
| 57 | + most one element on the right. -/ |
| 58 | +def RightUnique : Prop := ∀ ⦃a b c⦄, R a b → R a c → b = c |
| 59 | + |
| 60 | +/-- A relation is "bi-unique" if it is both left unique and right unique. -/ |
| 61 | +def BiUnique : Prop := LeftUnique R ∧ RightUnique R |
| 62 | + |
| 63 | +variable {R} |
| 64 | + |
| 65 | +lemma RightTotal.rel_forall (h : RightTotal R) : |
| 66 | + ((R ⇒ (· → ·)) ⇒ (· → ·)) (λ p => ∀i, p i) (λ q => ∀i, q i) := |
| 67 | +λ _ _ Hrel H b => Exists.elim (h b) (λ _ Rab => Hrel Rab (H _)) |
| 68 | + |
| 69 | +lemma LeftTotal.rel_exists (h : LeftTotal R) : |
| 70 | + ((R ⇒ (· → ·)) ⇒ (· → ·)) (λ p => ∃i, p i) (λ q => ∃i, q i) := |
| 71 | +λ _ _ Hrel ⟨a, pa⟩ => (h a).imp $ λ _ Rab => Hrel Rab pa |
| 72 | + |
| 73 | +lemma BiTotal.rel_forall (h : BiTotal R) : |
| 74 | + ((R ⇒ Iff) ⇒ Iff) (λ p => ∀i, p i) (λ q => ∀i, q i) := |
| 75 | +λ _ _ Hrel => |
| 76 | + ⟨λ H b => Exists.elim (h.right b) (λ _ Rab => (Hrel Rab).mp (H _)), |
| 77 | + λ H a => Exists.elim (h.left a) (λ _ Rab => (Hrel Rab).mpr (H _))⟩ |
| 78 | + |
| 79 | +lemma BiTotal.rel_exists (h : BiTotal R) : |
| 80 | + ((R ⇒ Iff) ⇒ Iff) (λ p => ∃i, p i) (λ q => ∃i, q i) := |
| 81 | +λ _ _ Hrel => |
| 82 | + ⟨λ ⟨a, pa⟩ => (h.left a).imp $ λ _ Rab => (Hrel Rab).1 pa, |
| 83 | + λ ⟨b, qb⟩ => (h.right b).imp $ λ _ Rab => (Hrel Rab).2 qb⟩ |
| 84 | + |
| 85 | +lemma left_unique_of_rel_eq {eq' : β → β → Prop} (he : (R ⇒ (R ⇒ Iff)) Eq eq') : |
| 86 | + LeftUnique R := |
| 87 | +λ a b c (ac : R a c) (bc : R b c) => (he ac bc).mpr ((he bc bc).mp rfl) |
| 88 | + |
| 89 | +end |
| 90 | + |
| 91 | +lemma rel_imp : (Iff ⇒ (Iff ⇒ Iff)) (· → ·) (· → ·) := |
| 92 | +λ _ _ h _ _ l => imp_congr h l |
| 93 | + |
| 94 | +lemma rel_not : (Iff ⇒ Iff) Not Not := |
| 95 | +λ _ _ h => not_congr h |
| 96 | + |
| 97 | +lemma bi_total_eq {α : Type u₁} : Relator.BiTotal (@Eq α) := |
| 98 | +{ left := λ a => ⟨a, rfl⟩, right := λ a => ⟨a, rfl⟩ } |
| 99 | + |
| 100 | +variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _} |
| 101 | +variable {r : α → β → Prop} {p : β → γ → Prop} {q : γ → δ → Prop} |
| 102 | + |
| 103 | +lemma LeftUnique.flip (h : LeftUnique r) : RightUnique (flip r) := |
| 104 | +λ _ _ _ h₁ h₂ => h h₁ h₂ |
| 105 | + |
| 106 | +lemma rel_and : ((·↔·) ⇒ (·↔·) ⇒ (·↔·)) (·∧·) (·∧·) := |
| 107 | +λ _ _ h₁ _ _ h₂ => and_congr h₁ h₂ |
| 108 | + |
| 109 | +lemma rel_or : ((·↔·) ⇒ (·↔·) ⇒ (·↔·)) (·∨·) (·∨·) := |
| 110 | +λ _ _ h₁ _ _ h₂ => or_congr h₁ h₂ |
| 111 | + |
| 112 | +lemma rel_iff : ((·↔·) ⇒ (·↔·) ⇒ (·↔·)) (·↔·) (·↔·) := |
| 113 | +λ _ _ h₁ _ _ h₂ => iff_congr h₁ h₂ |
| 114 | + |
| 115 | +lemma rel_eq {r : α → β → Prop} (hr : BiUnique r) : (r ⇒ r ⇒ (·↔·)) (·=·) (·=·) := |
| 116 | +λ _ _ h₁ _ _ h₂ => ⟨λ h => hr.right h₁ $ h.symm ▸ h₂, λ h => hr.left h₁ $ h.symm ▸ h₂⟩ |
| 117 | + |
| 118 | +end Relator |
0 commit comments