------------------------------------------------------------------------------
-- Dependently typed functional languages - 2011-01

-- Leibniz's equality
------------------------------------------------------------------------------

-- Common options
{-# OPTIONS --double-check   #-}
{-# OPTIONS --exact-split    #-}
{-# OPTIONS --guardedness    #-}
{-# OPTIONS --no-sized-types #-}
{-# OPTIONS --warning=all    #-}
{-# OPTIONS --warning=error  #-}

-- Other options
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --safe                     #-}
{-# OPTIONS --without-K                #-}

module Lecture.LeibnizEquality where

open import Extra.Relation.Binary.PropositionalEquality

------------------------------------------------------------------------------
-- Introduction

-- Leibniz's law:
-- 'Two objects of the same type are equal if and only if they cannot
-- be distinguished by any property.' [Zhaohui 1994, §5.1.3]

-- Indiscernible: Incapable of being discerned. Not recognizable as distinct
-- (Merrian Webster).

-- Two parts of Leibniz's law: [Forrest 2010]
-- A. The identity of indiscernibles: ∀P(P x ↔ P y) → x ≐ y.

-- B. The indiscernibility of identicals: x ≐ y → ∀P(P x ↔ P y)

-- Luo, Zhaohui (1994). Computation and Reasoning. A Type Theory for
-- Computer Science. Oxford University Press.

-- Forrest, Peter (2010). The Identity of Indiscernibles.
-- http://plato.stanford.edu/entries/identity-indiscernible/.

------------------------------------------------------------------------------
-- Leibniz's equality [Zhaohui 1994]

-- (From Agda/examples/lib/Logic/Leibniz.agda)

infix 4 _≐_

_≐_  : {A : Set}  A  A  Set1
x  y = (P : _  Set)  P x  P y

-- Properties
≐-refl : {A : Set}{x : A}  x  x
≐-refl P Px = Px

≐-sym : {A : Set}(x y : A)  x  y  y  x
≐-sym x y x≐y P Py = x≐y  z  P z  P x)  Px  Px) Py

≐-trans : {A : Set}{x y z : A}  x  y  y  z  x  z
≐-trans x≐y y≐z P Px = y≐z P (x≐y P Px)

≐-subst : {A : Set}(P : A  Set){x y : A}  x  y  P x  P y
≐-subst P x≐y = x≐y P

------------------------------------------------------------------------------
-- Leibniz's equality and the identity type

≐→≡ : {A : Set}{x y : A}  x  y  x  y
≐→≡ {x = x} x≐y = x≐y  z  x  z) refl

≡→≐ : {A : Set}{x y : A}  x  y  x  y
≡→≐ refl P Px = Px