|
| 1 | +module Haskell.Law.Eq.Instances where |
| 2 | + |
| 3 | +open import Agda.Builtin.Char.Properties renaming (primCharToNatInjective to c2n-injective) |
| 4 | +open import Agda.Builtin.Word.Properties renaming (primWord64ToNatInjective to w2n-injective) |
| 5 | + |
| 6 | +open import Haskell.Prim |
| 7 | +open import Haskell.Prim.Eq |
| 8 | + |
| 9 | +open import Haskell.Prim.Either using ( Either; Left; Right ) |
| 10 | +open import Haskell.Prim.Int using ( Int; int64 ) |
| 11 | +open import Haskell.Prim.Maybe |
| 12 | +open import Haskell.Prim.Ord using ( Ordering; LT; GT; EQ ) |
| 13 | +open import Haskell.Prim.Tuple |
| 14 | +open import Haskell.Prim.Word using ( Word ) |
| 15 | + |
| 16 | +open import Haskell.Extra.Dec using ( mapReflects ) |
| 17 | + |
| 18 | +open import Haskell.Law.Eq.Def |
| 19 | +open import Haskell.Law.Equality |
| 20 | + |
| 21 | +open import Haskell.Law.Either |
| 22 | +open import Haskell.Law.Int |
| 23 | +open import Haskell.Law.Integer |
| 24 | +open import Haskell.Law.List using ( ∷-injective-left; ∷-injective-right ) |
| 25 | +open import Haskell.Law.Maybe |
| 26 | +open import Haskell.Law.Nat |
| 27 | + |
| 28 | +instance |
| 29 | + iLawfulEqNat : IsLawfulEq Nat |
| 30 | + iLawfulEqNat .isEquality zero zero = refl |
| 31 | + iLawfulEqNat .isEquality zero (suc _) = λ () |
| 32 | + iLawfulEqNat .isEquality (suc _) zero = λ () |
| 33 | + iLawfulEqNat .isEquality (suc x) (suc y) = mapReflects |
| 34 | + (cong suc) |
| 35 | + suc-injective |
| 36 | + (isEquality x y) |
| 37 | + |
| 38 | + iLawfulEqWord : IsLawfulEq Word |
| 39 | + iLawfulEqWord .isEquality x y |
| 40 | + with (w2n x) in h₁ | (w2n y) in h₂ |
| 41 | + ... | a | b = mapReflects |
| 42 | + (λ h → w2n-injective x y $ sym $ trans (trans h₂ $ sym h) (sym h₁)) |
| 43 | + (λ h → trans (sym $ trans (cong w2n (sym h)) h₁) h₂) |
| 44 | + (isEquality a b) |
| 45 | + |
| 46 | + iLawfulEqBool : IsLawfulEq Bool |
| 47 | + iLawfulEqBool .isEquality False False = refl |
| 48 | + iLawfulEqBool .isEquality False True = λ() |
| 49 | + iLawfulEqBool .isEquality True False = λ() |
| 50 | + iLawfulEqBool .isEquality True True = refl |
| 51 | + |
| 52 | + iLawfulEqChar : IsLawfulEq Char |
| 53 | + iLawfulEqChar .isEquality x y |
| 54 | + with (c2n x) in h₁ | (c2n y) in h₂ |
| 55 | + ... | a | b = mapReflects { a ≡ b } { x ≡ y } { eqNat a b } |
| 56 | + (λ h → c2n-injective x y $ sym $ trans (trans h₂ $ sym h) (sym h₁)) |
| 57 | + (λ h → trans (sym $ trans (cong c2n (sym h)) h₁) h₂) |
| 58 | + (isEquality a b) |
| 59 | + |
| 60 | + iLawfulEqEither : ⦃ iEqA : Eq a ⦄ → ⦃ iEqB : Eq b ⦄ |
| 61 | + → ⦃ IsLawfulEq a ⦄ → ⦃ IsLawfulEq b ⦄ |
| 62 | + → IsLawfulEq (Either a b) |
| 63 | + iLawfulEqEither .isEquality (Left _) (Right _) = λ () |
| 64 | + iLawfulEqEither .isEquality (Right _) (Left _) = λ () |
| 65 | + iLawfulEqEither .isEquality a@(Left x) b@(Left y) = mapReflects |
| 66 | + (cong Left) (Left-injective a b) (isEquality x y) |
| 67 | + iLawfulEqEither .isEquality a@(Right x) b@(Right y) = mapReflects |
| 68 | + (cong Right) (Right-injective a b) (isEquality x y) |
| 69 | + |
| 70 | + iLawfulEqInt : IsLawfulEq Int |
| 71 | + iLawfulEqInt .isEquality (int64 x) (int64 y) = mapReflects |
| 72 | + (cong int64) int64-injective (isEquality x y) |
| 73 | + |
| 74 | + iLawfulEqInteger : IsLawfulEq Integer |
| 75 | + iLawfulEqInteger .isEquality (pos n) (pos m) = mapReflects |
| 76 | + (cong pos) pos-injective (isEquality n m) |
| 77 | + iLawfulEqInteger .isEquality (pos _) (negsuc _) = λ () |
| 78 | + iLawfulEqInteger .isEquality (negsuc _) (pos _) = λ () |
| 79 | + iLawfulEqInteger .isEquality (negsuc n) (negsuc m) = mapReflects |
| 80 | + (cong negsuc) neg-injective (isEquality n m) |
| 81 | + |
| 82 | + iLawfulEqList : ⦃ iEqA : Eq a ⦄ → ⦃ IsLawfulEq a ⦄ → IsLawfulEq (List a) |
| 83 | + iLawfulEqList .isEquality [] [] = refl |
| 84 | + iLawfulEqList .isEquality [] (_ ∷ _) = λ () |
| 85 | + iLawfulEqList .isEquality (_ ∷ _) [] = λ () |
| 86 | + iLawfulEqList .isEquality (x ∷ xs) (y ∷ ys) |
| 87 | + with (x == y) in h₁ |
| 88 | + ... | True = mapReflects |
| 89 | + (λ h → cong₂ (_∷_) (equality x y h₁) h) |
| 90 | + ∷-injective-right |
| 91 | + (isEquality xs ys) |
| 92 | + ... | False = λ h → (nequality x y h₁) (∷-injective-left h) |
| 93 | + |
| 94 | + iLawfulEqMaybe : ⦃ iEqA : Eq a ⦄ → ⦃ IsLawfulEq a ⦄ → IsLawfulEq (Maybe a) |
| 95 | + iLawfulEqMaybe .isEquality Nothing Nothing = refl |
| 96 | + iLawfulEqMaybe .isEquality Nothing (Just _) = λ() |
| 97 | + iLawfulEqMaybe .isEquality (Just _) Nothing = λ() |
| 98 | + iLawfulEqMaybe .isEquality (Just x) (Just y) = mapReflects |
| 99 | + (cong Just) injective (isEquality x y) |
| 100 | + |
| 101 | + iLawfulEqOrdering : IsLawfulEq Ordering |
| 102 | + iLawfulEqOrdering .isEquality LT LT = refl |
| 103 | + iLawfulEqOrdering .isEquality LT EQ = λ() |
| 104 | + iLawfulEqOrdering .isEquality LT GT = λ() |
| 105 | + iLawfulEqOrdering .isEquality EQ LT = λ() |
| 106 | + iLawfulEqOrdering .isEquality EQ EQ = refl |
| 107 | + iLawfulEqOrdering .isEquality EQ GT = λ() |
| 108 | + iLawfulEqOrdering .isEquality GT LT = λ() |
| 109 | + iLawfulEqOrdering .isEquality GT EQ = λ() |
| 110 | + iLawfulEqOrdering .isEquality GT GT = refl |
| 111 | + |
| 112 | + iLawfulEqTuple₂ : ⦃ iEqA : Eq a ⦄ ⦃ iEqB : Eq b ⦄ |
| 113 | + → ⦃ IsLawfulEq a ⦄ → ⦃ IsLawfulEq b ⦄ |
| 114 | + → IsLawfulEq (a × b) |
| 115 | + iLawfulEqTuple₂ .isEquality (x₁ , x₂) (y₁ , y₂) with (x₁ == y₁) in h₁ |
| 116 | + ... | True = mapReflects |
| 117 | + (λ h → cong₂ _,_ (equality x₁ y₁ h₁) h) |
| 118 | + (cong snd) |
| 119 | + (isEquality x₂ y₂) |
| 120 | + ... | False = λ h → exFalso (equality' x₁ y₁ (cong fst h)) h₁ |
| 121 | + |
| 122 | + iLawfulEqTuple₃ : ⦃ iEqA : Eq a ⦄ ⦃ iEqB : Eq b ⦄ ⦃ iEqC : Eq c ⦄ |
| 123 | + → ⦃ IsLawfulEq a ⦄ → ⦃ IsLawfulEq b ⦄ → ⦃ IsLawfulEq c ⦄ |
| 124 | + → IsLawfulEq (a × b × c) |
| 125 | + iLawfulEqTuple₃ .isEquality (x₁ , x₂ , x₃) (y₁ , y₂ , y₃) with (x₁ == y₁) in h₁ |
| 126 | + ... | True = mapReflects |
| 127 | + (λ h → cong₂ (λ a (b , c) → a , b , c) (equality x₁ y₁ h₁) h) |
| 128 | + (cong λ h → snd₃ h , thd₃ h) |
| 129 | + (isEquality (x₂ , x₃) (y₂ , y₃)) |
| 130 | + ... | False = λ h → exFalso (equality' x₁ y₁ (cong fst₃ h)) h₁ |
| 131 | + |
| 132 | + iLawfulEqUnit : IsLawfulEq ⊤ |
| 133 | + iLawfulEqUnit .isEquality tt tt = refl |
0 commit comments