mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-19 17:21:59 +03:00
95 lines
2.5 KiB
Idris
95 lines
2.5 KiB
Idris
|
||| Indexing Vectors.
|
||
|
|||
|
||
|
||| `Elem` proofs give existential quantification that a given element
|
||
|
||| *is* in the list, but not where in the list it is! Here we give a
|
||
|
||| predicate that presents proof that a given index of a vector,
|
||
|
||| given by a `Fin` instance, will return a certain element.
|
||
|
|||
|
||
|
||| Two decidable decision procedures are presented:
|
||
|
|||
|
||
|
||| 1. Check that a given index points to the provided element in the
|
||
|
||| presented vector.
|
||
|
|||
|
||
|
||| 2. Find the element at the given index in the presented vector.
|
||
|
module Data.Vect.AtIndex
|
||
|
|
||
|
import Data.Vect
|
||
|
import Decidable.Equality
|
||
|
|
||
|
%default total
|
||
|
|
||
|
public export
|
||
|
data AtIndex : (idx : Fin n)
|
||
|
-> (xs : Vect n type)
|
||
|
-> (x : type)
|
||
|
-> Type
|
||
|
where
|
||
|
Here : AtIndex FZ (x::xs) x
|
||
|
|
||
|
There : (later : AtIndex rest xs x)
|
||
|
-> AtIndex (FS rest) (y::xs) x
|
||
|
|
||
|
namespace Check
|
||
|
public export
|
||
|
elemDiffers : (y = x -> Void)
|
||
|
-> AtIndex FZ (y :: xs) x
|
||
|
-> Void
|
||
|
elemDiffers f Here
|
||
|
= f Refl
|
||
|
|
||
|
public export
|
||
|
elemNotInRest : (AtIndex z xs x -> Void)
|
||
|
-> AtIndex (FS z) (y :: xs) x
|
||
|
-> Void
|
||
|
elemNotInRest f (There later)
|
||
|
= f later
|
||
|
|
||
|
||| Is the element at the given index?
|
||
|
|||
|
||
|
public export
|
||
|
index : DecEq type
|
||
|
=> (idx : Fin n)
|
||
|
-> (x : type)
|
||
|
-> (xs : Vect n type)
|
||
|
-> Dec (AtIndex idx xs x)
|
||
|
|
||
|
index FZ _ [] impossible
|
||
|
index (FS y) _ [] impossible
|
||
|
|
||
|
index FZ x (y :: xs) with (decEq y x)
|
||
|
index FZ x (x :: xs) | (Yes Refl)
|
||
|
= Yes Here
|
||
|
index FZ x (y :: xs) | (No contra)
|
||
|
= No (elemDiffers contra)
|
||
|
|
||
|
index (FS z) x (y :: xs) with (Check.index z x xs)
|
||
|
index (FS z) x (y :: xs) | (Yes prf)
|
||
|
= Yes (There prf)
|
||
|
index (FS z) x (y :: xs) | (No contra)
|
||
|
= No (elemNotInRest contra)
|
||
|
|
||
|
namespace Find
|
||
|
public export
|
||
|
elemNotInRest : (DPair type (AtIndex x xs) -> Void)
|
||
|
-> DPair type (AtIndex (FS x) (y :: xs)) -> Void
|
||
|
|
||
|
elemNotInRest f (MkDPair i (There later))
|
||
|
= f (MkDPair i later)
|
||
|
|
||
|
||| What is the element at the given index?
|
||
|
|||
|
||
|
public export
|
||
|
index : DecEq type
|
||
|
=> (idx : Fin n)
|
||
|
-> (xs : Vect n type)
|
||
|
-> Dec (DPair type (AtIndex idx xs))
|
||
|
index FZ (x :: xs)
|
||
|
= Yes (MkDPair x Here)
|
||
|
|
||
|
index (FS x) (y :: xs) with (Find.index x xs)
|
||
|
index (FS x) (y :: xs) | (Yes (MkDPair i idx))
|
||
|
= Yes (MkDPair i (There idx))
|
||
|
index (FS x) (y :: xs) | (No contra) = No (elemNotInRest contra)
|
||
|
|
||
|
-- [ EOF ]
|