2016-02-12 3 views
5

Так что я пытаюсь понять, почему этот код дает желтую подсветку вокруг()Как Agda определяет тип невозможно

data sometype : List ℕ → Set where 
    constr : (l1 l2 : List ℕ)(n : ℕ) → sometype (l1 ++ (n ∷ l2)) 

somef : sometype [] → ⊥ 
somef() 

Но это не

data sometype : List ℕ → Set where 
    constr : (l1 l2 : List ℕ)(n : ℕ) → sometype (n ∷ (l1 ++ l2)) 

somef : sometype [] → ⊥ 
somef() 

И, кажется, таким образом, что sometype [] пуст, но Agda не может определить первый из них? Зачем? Что это за код? Могу ли я определить somef, чтобы сделать работу над первым определением?

ответ

6

Agda ничего не может принять за произвольные функции, такие как ++. Предположим, что мы определили ++ следующим образом:

_++_ : {A : Set} → List A → List A → List A 
xs ++ ys = [] 

В этом случае sometype [] → ⊥ не доказуемо, и принимая () абсурдную картину было бы ошибкой.

В вашем втором примере индекс sometype должен иметь форму n ∷ (l1 ++ l2), которая является выражением конструктора, поскольку _∷_ является конструктором списка. Agda может смело заключить, что список _∷_ не может быть равен []. В целом, различные конструкторы можно рассматривать как невозможные для унификации.

Что может сделать Agda с приложениями функций, это как можно меньше. В некоторых случаях сокращение дает выражения конструктора, в других случаях это не так, и нам нужно написать дополнительные доказательства.

Чтобы доказать sometype [] → ⊥, мы должны сначала сделать обобщение. Мы не можем сопоставлять соответствие по значению sometype [] (из-за ++ в индексе типа), но мы можем сопоставить sometype xs для некоторых абстрагированных xs. Итак, наша лемма говорит следующее:

someF' : ∀ xs → sometype xs → xs ≡ [] → ⊥ 
someF' .(n ∷ l2)   (constr [] l2 n)() 
someF' .(n' ∷ l1 ++ n ∷ l2) (constr (n' ∷ l1) l2 n)() 

Другими словами, ∀ xs → sometype xs → xs ≢ []. Мы можем получить требуемое доказательство из этого:

someF : sometype [] → ⊥ 
someF p = someF' [] p refl 
+0

- точка о «нерелевантности»? Можете ли вы дать объяснение, что означает точка? – davik

+0

Я нашел «пунктирные узоры» в Интернете, но я до сих пор не совсем понимаю. Зависимое программирование в Agda pdf говорит, что вы делаете это, когда шаблон можно вывести, но действительно ли компилятор проверяет это, это единственный случай? – davik

+3

Точка сигнализирует, что переменные внутри (пунктирного) шаблона вводятся в какой-либо другой схеме. Каждая переменная шаблона должна вводиться ровно один раз, и если мы хотим использовать одну и ту же переменную в другом месте (потому что зависимости типов заставляют значения быть одинаковыми в шаблонах), мы можем сделать это внутри усеченных шаблонов. –