agda2hs-1.4: lib/base/Haskell/Law/Eq/Def.agda
module Haskell.Law.Eq.Def where
open import Haskell.Prim
open import Haskell.Prim.Bool
open import Haskell.Prim.Double
open import Haskell.Prim.Eq
open import Haskell.Extra.Dec
open import Haskell.Extra.Refinement
open import Haskell.Law.Bool
open import Haskell.Law.Equality
record IsLawfulEq (e : Type) ⦃ iEq : Eq e ⦄ : Type₁ where
field
isEquality : ∀ (x y : e) → Reflects (x ≡ y) (x == y)
equality : ∀ (x y : e) → (x == y) ≡ True → x ≡ y
equality x y h = extractTrue ⦃ h ⦄ (isEquality x y)
nequality : ∀ (x y : e) → (x == y) ≡ False → (x ≡ y → ⊥)
nequality x y h = extractFalse ⦃ h ⦄ (isEquality x y)
-- contrapositive of nequality
equality' : ∀ (x y : e) → x ≡ y → (x == y) ≡ True
equality' x y h with x == y in eq
... | False = magic (nequality x y eq h)
... | True = refl
-- contrapositive of equality
nequality' : ∀ (x y : e) → (x ≡ y → ⊥) → (x == y) ≡ False
nequality' x y h with x == y in eq
... | True = magic (h (equality x y eq))
... | False = refl
open IsLawfulEq ⦃ ... ⦄ public
-- Types with a lawful Eq instance have decidable equality
_≟_ : {{_ : Eq a}} {{_ : IsLawfulEq a}} → (x y : a) → Dec (x ≡ y)
x ≟ y = (x == y) ⟨ isEquality x y ⟩
{-# COMPILE AGDA2HS _≟_ inline #-}
-- Reflexivity: x == x = True
eqReflexivity : ⦃ iEq : Eq e ⦄ → ⦃ IsLawfulEq e ⦄
→ ∀ (x : e) → (x == x) ≡ True
eqReflexivity x = equality' x x refl
-- Symmetry: x == y = y == x
eqSymmetry : ⦃ iEq : Eq e ⦄ → ⦃ IsLawfulEq e ⦄
→ ∀ (x y : e) → (x == y) ≡ (y == x)
eqSymmetry x y with x == y in eq
... | True = sym (equality' y x (sym (equality x y eq)))
... | False = sym (nequality' y x (λ qe → (nequality x y eq) (sym qe)))
-- Transitivity: if x == y && y == z = True, then x == z = True
eqTransitivity : ⦃ iEq : Eq e ⦄ → ⦃ IsLawfulEq e ⦄
→ ∀ (x y z : e) → ((x == y) && (y == z)) ≡ True → (x == z) ≡ True
eqTransitivity x y z h
= equality' x z (trans
(equality x y (&&-leftTrue (x == y) (y == z) h))
(equality y z (&&-rightTrue (x == y) (y == z) h)))
-- Extensionality: if x == y = True and f is a function whose return type is an instance of Eq, then f x == f y = True
eqExtensionality : ⦃ iEq : Eq e ⦄ → ⦃ IsLawfulEq e ⦄
→ ⦃ iEq : Eq a ⦄ → ⦃ iLawfulEq : IsLawfulEq a ⦄
→ ∀ ( x y : e ) ( f : e → a ) → (x == y) ≡ True → (f x == f y) ≡ True
eqExtensionality x y f h = equality' (f x) (f y) (cong f (equality x y h))
-- Negation: x /= y = not (x == y)
eqNegation : ⦃ iEq : Eq e ⦄ → ⦃ IsLawfulEq e ⦄
→ ∀ { x y : e } → (x /= y) ≡ not (x == y)
eqNegation = refl