module Utils.Decidable where
open import Data.Bool using (false;true) open import Function using (const;_∘_) open import Relation.Binary using (DecidableEquality) open import Relation.Binary.PropositionalEquality using (_≡_;refl;sym;cong;cong₂;subst) open import Relation.Nullary using (Dec;yes;no;¬_) open import Data.Product using (Σ;_×_;proj₁;proj₂) renaming (_,_ to _,,_)
Some functions to help define DecidableEquality
predicates, inspired by effectfully’s Generic Library.
dmap : ∀ {α β} {A : Set α} {B : Set β} → (A → B) → (¬ A → ¬ B) → Dec A → Dec B dmap f g (no ¬p) = no (g ¬p) dmap f g (yes p) = yes (f p) dcong : ∀ {α β} {A : Set α} {B : Set β} {x y} → (f : A → B) → (f x ≡ f y → x ≡ y) → Dec (x ≡ y) → Dec (f x ≡ f y) dcong f inj = dmap (cong f) (_∘ inj) dcong₂ : ∀ {α β γ} {A : Set α} {B : Set β} {C : Set γ} {x₁ x₂ y₁ y₂} → (f : A → B → C) → (f x₁ y₁ ≡ f x₂ y₂ → x₁ ≡ x₂ × y₁ ≡ y₂) → Dec (x₁ ≡ x₂) → Dec (y₁ ≡ y₂) → Dec (f x₁ y₁ ≡ f x₂ y₂) dcong₂ f inj (yes refl) (yes refl) = yes refl dcong₂ f inj (yes _) (no ¬q) = no (λ x → ¬q (proj₂ (inj x))) dcong₂ f inj (no ¬p) _ = no (λ x → ¬p (proj₁ (inj x))) dhcong : ∀ {α β γ} {A : Set α} {B : A → Set β} {C : Set γ} {x₁ x₂ y₁ y₂} → (f : ∀ x → B x → C) → (f x₁ y₁ ≡ f x₂ y₂ → Σ (x₁ ≡ x₂) (λ p → subst B p y₁ ≡ y₂)) → Dec (x₁ ≡ x₂) → (∀ y₂ → Dec (y₁ ≡ y₂)) → Dec (f x₁ y₁ ≡ f x₂ y₂) dhcong f inj (yes refl) q = dcong (f _) ((λ { (refl ,, yy) → yy }) ∘ inj) (q _) dhcong f inj (no c) q = no λ {p → c (proj₁ (inj p))} dhcong₂ : ∀ {α β γ} {A : Set α} {B B' : A → Set β} {C : Set γ} {x₁ x₂ y₁ y₂ z₁ z₂} → (f : ∀ x → B x → B' x → C) → (f x₁ y₁ z₁ ≡ f x₂ y₂ z₂ → Σ (x₁ ≡ x₂) (λ p → subst B p y₁ ≡ y₂ × subst B' p z₁ ≡ z₂ )) → Dec (x₁ ≡ x₂) → (∀ y₂ → Dec (y₁ ≡ y₂)) → (∀ z₂ → Dec (z₁ ≡ z₂)) → Dec (f x₁ y₁ z₁ ≡ f x₂ y₂ z₂) dhcong₂ f inj (yes refl) qy qz = dcong₂ (f _) ((λ { (refl ,, yy) → yy }) ∘ inj) (qy _) (qz _) dhcong₂ f inj (no c) _ _ = no λ {p → c (proj₁ (inj p))}