Logical equivalences
module foundation-core.logical-equivalences where
Imports
open import foundation-core.cartesian-product-types open import foundation-core.dependent-pair-types open import foundation-core.equivalences open import foundation-core.functions open import foundation-core.propositions open import foundation-core.universe-levels
Idea
Logical equivalences between two types A
and B
consist of a map A → B
and
a map B → A
. The type of logical equivalences between types is the
Curry-Howard interpretation of logical equivalences between propositions.
Definition
Logical equivalences between types
_↔_ : {l1 l2 : Level} → UU l1 → UU l2 → UU (l1 ⊔ l2) A ↔ B = (A → B) × (B → A) module _ {l1 l2 : Level} {A : UU l1} {B : UU l2} (H : A ↔ B) where forward-implication : A → B forward-implication = pr1 H backward-implication : B → A backward-implication = pr2 H
Logical equivalences between propositions
_⇔_ : {l1 l2 : Level} → Prop l1 → Prop l2 → UU (l1 ⊔ l2) P ⇔ Q = type-Prop P ↔ type-Prop Q is-prop-iff-Prop : {l1 l2 : Level} (P : Prop l1) (Q : Prop l2) → is-prop (P ⇔ Q) is-prop-iff-Prop P Q = is-prop-prod ( is-prop-function-type (is-prop-type-Prop Q)) ( is-prop-function-type (is-prop-type-Prop P)) iff-Prop : {l1 l2 : Level} → Prop l1 → Prop l2 → Prop (l1 ⊔ l2) pr1 (iff-Prop P Q) = P ⇔ Q pr2 (iff-Prop P Q) = is-prop-iff-Prop P Q
Composition of logical equivalences
_∘iff_ : {l1 l2 l3 : Level} {A : UU l1} {B : UU l2} {C : UU l3} → (B ↔ C) → (A ↔ B) → (A ↔ C) pr1 (pair g1 g2 ∘iff pair f1 f2) = g1 ∘ f1 pr2 (pair g1 g2 ∘iff pair f1 f2) = f2 ∘ g2
Inverting a logical equivalence
inv-iff : {l1 l2 : Level} {A : UU l1} {B : UU l2} → (A ↔ B) → (B ↔ A) pr1 (inv-iff (f , g)) = g pr2 (inv-iff (f , g)) = f
Logical equivalences between propositions induce equivalences
module _ {l1 l2 : Level} (P : Prop l1) (Q : Prop l2) where equiv-iff' : (P ⇔ Q) → (type-Prop P ≃ type-Prop Q) pr1 (equiv-iff' t) = pr1 t pr2 (equiv-iff' t) = is-equiv-is-prop (pr2 P) (pr2 Q) (pr2 t) equiv-iff : (type-Prop P → type-Prop Q) → (type-Prop Q → type-Prop P) → type-Prop P ≃ type-Prop Q equiv-iff f g = equiv-iff' (pair f g) iff-equiv : {l1 l2 : Level} {A : UU l1} {B : UU l2} → (A ≃ B) → (A ↔ B) pr1 (iff-equiv e) = map-equiv e pr2 (iff-equiv e) = map-inv-equiv e
Logical equivalences between dependent function types
module _ {l1 l2 l3 : Level} {I : UU l1} {A : I → UU l2} {B : I → UU l3} where iff-Π : ((i : I) → A i ↔ B i) → ((i : I) → A i) ↔ ((i : I) → B i) pr1 (iff-Π e) a i = forward-implication (e i) (a i) pr2 (iff-Π e) b i = backward-implication (e i) (b i)
Reasoning with logical equivalences
Logical equivalences can be constructed by equational reasoning in the following way:
logical-equivalence-reasoning
X ↔ Y by equiv-1
↔ Z by equiv-2
↔ V by equiv-3
infixl 1 logical-equivalence-reasoning_ infixl 0 step-logical-equivalence-reasoning logical-equivalence-reasoning_ : {l1 : Level} (X : UU l1) → X ↔ X logical-equivalence-reasoning X = pair id id step-logical-equivalence-reasoning : {l1 l2 l3 : Level} {X : UU l1} {Y : UU l2} → (X ↔ Y) → (Z : UU l3) → (Y ↔ Z) → (X ↔ Z) step-logical-equivalence-reasoning e Z f = f ∘iff e syntax step-logical-equivalence-reasoning e Z f = e ↔ Z by f