Agda nie może zakładać niczego na temat dowolnych funkcji, takich jak ++
. Załóżmy, że mamy zdefiniowane ++
następujący sposób:
_++_ : {A : Set} → List A → List A → List A
xs ++ ys = []
w tym przypadku sometype [] → ⊥
nie jest do udowodnienia, a przyjmując ()
absurdalny wzór byłby błąd.
W drugim przykładzie indeksmusi mieć postać n ∷ (l1 ++ l2)
, która jest wyrażeniem konstruktora, ponieważ _∷_
jest konstruktorem list. Agda może bezpiecznie wnioskować, że stworzona lista nie może być równa []
. Ogólnie rzecz biorąc, różne konstruktory mogą być postrzegane jako niemożliwe do ujednolicenia.
To, co Agda może zrobić z aplikacjami funkcyjnymi, zmniejsza je w miarę możliwości. W niektórych przypadkach redukcja daje wyrażenia konstruktorów, w innych przypadkach nie, i musimy napisać dodatkowe dowody.
Aby udowodnić, że sometype [] → ⊥
, powinniśmy najpierw wykonać pewne uogólnienie. Nie można dopasować wzorca na wartość sometype []
(ze względu na indeks ++
w indeksie typu), ale możemy dopasować na sometype xs
dla niektórych abstrakcyjnych xs
. Tak więc nasz lemat mówi:
someF' : ∀ xs → sometype xs → xs ≡ [] → ⊥
someF' .(n ∷ l2) (constr [] l2 n)()
someF' .(n' ∷ l1 ++ n ∷ l2) (constr (n' ∷ l1) l2 n)()
Innymi słowy, ∀ xs → sometype xs → xs ≢ []
. Możemy wyprowadzić pożądany dowód z tego:
someF : sometype [] → ⊥
someF p = someF' [] p refl
to kropka o "nieistotności"? Czy możesz wyjaśnić, co oznacza kropka? – davik
Znalazłem "przerywane wzory" w Internecie, ale wciąż nie do końca rozumiem. Dependently Typed Programming in Agda pdf mówi, że robisz to, kiedy można wydedukować wzorzec, ale czy kompilator faktycznie to sprawdza, to musi być jedyny przypadek? – davik
Sygnały punktowe, że zmienne wewnątrz (kropkowanego) wzorca są wprowadzone w innym wzorze. Każda zmienna wzoru musi być wprowadzona dokładnie raz, a jeśli chcemy użyć tej samej zmiennej w innym miejscu (ponieważ zależności typu wymuszają wartości w równych wzorach), możemy to zrobić wewnątrz wzorców kropkowanych. –