2016-09-04 8 views
1

В главе 9 Type Driven Development with Idris, мы введены в Elem предиката с конструкторами Here и There для доказательства того, что элемент является членом вектора. напримердоказав Не (Эль х Xs) когда х и хз статически известны

oneInVector : Elem 1 [1, 2, 3] 
oneInVector = Here 

twoInVector : Elem 2 [1, 2, 3] 
twoInVector = There Here 

мне интересно, как показать, что элемент в векторе не. Это, возможно, следует быть, предоставляя решение этого типа:

notThere : Elem 4 [1, 2, 3] -> Void 
notThere = ?rhs 

Выражение/Proof поиск не приходит с ответом в этом случае дает:

notThere : Elem 4 [1,2,3] -> Void 
notThere = \__pi_arg => ?rhs1 

Scanning through the library for Data.Vect, эти определения выглядят полезными (но я не уверен, как соединить точки):

||| Nothing can be in an empty Vect 
noEmptyElem : {x : a} -> Elem x [] -> Void 
noEmptyElem Here impossible 

Uninhabited (Elem x []) where 
    uninhabited = noEmptyElem 

ответ

5

Elem соотношение Dec idable (если тип элемента имеет DecEq idable uality себя), используя isElem:

isElem : DecEq a => (x : a) -> (xs : Vect n a) -> Dec (Elem x xs) 

Идея заключается в том, чтобы использовать isElem 4 [1, 2, 3], чтобы Идрис вычислить доказательство Not (Elem 4 [1, 2, 3]).Нам нужно создать некоторую технику, аналогичный Agda-х Relation.Nullary.Decidable.toWitnessFalse так, что мы можем извлечь доказательства из (отрицательных) Dec результатов:

fromFalse : (d : Dec p) -> {auto isFalse : decAsBool d = False} -> Not p 
fromFalse (Yes _) {isFalse = Refl} impossible 
fromFalse (No contra) = contra 

, а затем мы можем использовать это в notThere определении:

notThere : Not (Elem 4 [1, 2, 3]) 
notThere = fromFalse (isElem 4 [1, 2, 3]) 
0

Вместо того, задающую свою RHS для notThere, то лучше использовать Идрис редактор Suppor т:

Начиная с:

notThere : Elem 4 [1, 2, 3] -> Void 

Добавить определение на notThere:

notThere : Elem 4 [1, 2, 3] -> Void 
notThere x = ?notThere_rhs 

раскол Дело о x:

notThere : Elem 4 [1, 2, 3] -> Void 
notThere (There later) = ?notThere_rhs 

раскол Дело о later:

notThere : Elem 4 [1, 2, 3] -> Void 
notThere (There (There later)) = ?notThere_rhs 

Корпус разделен на later:

notThere : Elem 4 [1, 2, 3] -> Void 
notThere (There (There There later))) = ?notThere_rhs 

Корпус разделен на later:

notThere : Elem 4 [1,2,3] -> Void 
notThere (There (There (There Here))) impossible 
notThere (There (There (There (There _)))) impossible 

Это определение общей и поэтому мы сделали:

*Elem> :total notThere 
Main.notThere is Total 

Я бы все еще заинтересованы, если есть более приятное решение, которое использует noEmptyElem и/или uninhabited от Data.Vect.