module Data.Dec.Base where
Decidable typesπ
The type Dec
, of
decisions for a type A
, is a renaming of
the coproduct A + Β¬ A
. A value of Dec A
witnesses not that A
is decidable, but that it has been
decided; A witness of decidability, then, is a proof assigning
decisions to values of a certain type.
data Dec {β} (A : Type β) : Type β where
: (a : A) β Dec A
yes : (Β¬a : Β¬ A) β Dec A
no
Dec-elim: β {β β'} {A : Type β} (P : Dec A β Type β')
β (β y β P (yes y))
β (β y β P (no y))
β β x β P x
(yes x) = f x
Dec-elim P f g (no x) = g x
Dec-elim P f g
Dec-rec: β {β β'} {A : Type β} {X : Type β'}
β (A β X)
β (Β¬ A β X)
β Dec A β X
= Dec-elim _ Dec-rec
A type is discrete if it has decidable equality.
: β {β} β Type β β Type β
Discrete = {x y : A} β Dec (x β‘ y) Discrete A
If we can construct a pair of maps and , then we can deduce decidability of from decidability of .
Dec-map: (A β B) β (B β A)
β Dec A β Dec B
to from (yes a) = yes (to a)
Dec-map to from (no Β¬a) = no (Β¬a β from)
Dec-map
: A β B β Dec A β Dec B
Dec-β = Dec-map (Equiv.to e) (Equiv.from e) Dec-β e
This lets us show the following useful lemma: if injects into a discrete type, then is also discrete.
Discrete-inj: (f : A β B)
β (β {x y} β f x β‘ f y β x β‘ y)
β Discrete B β Discrete A
{x} {y} =
Discrete-inj f inj eq? (ap f) (eq? {f x} {f y}) Dec-map inj
Programming with decisionsπ
Despite the failure of Dec A
to be a proposition for general
A
, in the 1Lab, we like to work with decisions through
instance search. This is facilitated by the following functions, which
perform instance search:
-- Searches for a type given explicitly.
: β {β} (A : Type β) β¦ d : Dec A β¦ β Dec A
holds? = d
holds? A β¦ d β¦
-- Searches for equality of inhabitants of a discrete type.
_β‘?_ : β¦ d : Discrete A β¦ (x y : A) β Dec (x β‘ y)
= holds? (x β‘ y)
x β‘? y
infix 3 _β‘?_
And the following operators, which combine instance search with case analysis:
_of_ : β {β β'} (A : Type β) β¦ d : Dec A β¦ {B : Type β'} β (Dec A β B) β B
caseα΅= f (holds? A)
caseα΅ A of f
_return_of_ : β {β β'} (A : Type β) β¦ d : Dec A β¦ (B : Dec A β Type β') β (β x β B x) β B d
caseα΅= f (holds? A)
caseα΅ A return P of f
{-# INLINE caseα΅_of_ #-}
{-# INLINE caseα΅_return_of_ #-}
We then have the following basic instances for combining decisions, expressing that the class of decidable types is closed under products and negation, and contains the empty type.
instance
: β¦ _ : Dec P β¦ β¦ _ : Dec Q β¦ β Dec (P Γ Q)
Dec-Γ {Q = _} β¦ yes p β¦ β¦ yes q β¦ = yes (p , q)
Dec-Γ {Q = _} β¦ yes p β¦ β¦ no Β¬q β¦ = no Ξ» z β Β¬q (snd z)
Dec-Γ {Q = _} β¦ no Β¬p β¦ β¦ _ β¦ = no Ξ» z β Β¬p (fst z)
Dec-Γ
: Dec β€
Dec-β€ = yes tt
Dec-β€
: Dec β₯
Dec-β₯ = no id
Dec-β₯
: β¦ _ : Dec A β¦ β Dec (A β β₯)
Dec-Β¬ {A = _} β¦ yes a β¦ = no Ξ» Β¬a β Β¬a a
Dec-Β¬ {A = _} β¦ no Β¬a β¦ = yes Β¬a Dec-Β¬