Недавно я сделал тип для конечных множеств в Agda со следующей реализацией:
open import Relation.Nullary
open import Relation.Nullary.Negation
open import Data.Empty
open import Data.Unit
open import Relation.Binary.PropositionalEquality
open import Data.Nat
suc-inj : (n m : ℕ) → (suc n) ≡ (suc m) → n ≡ m
suc-inj n .n refl = refl
record Eq (A : Set) : Set₁ where
constructor mkEqInst
field
_decide≡_ : (a b : A) → Dec (a ≡ b)
open Eq {{...}}
mutual
data FinSet (A : Set) {{_ : Eq A }} : Set where
ε : FinSet A
_&_ : (a : A) → (X : FinSet A) → .{ p : ¬ (a ∈ X)} → FinSet A
_∈_ : {A : Set} → {{p : Eq A}} → (a : A) → FinSet A → Set
a ∈ ε = ⊥
a ∈ (b & B) with (a decide≡ b)
... | yes _ = ⊤
... | no _ = a ∈ B
_∉_ : {A : Set} → {{p : Eq A}} → (a : A) → FinSet A → Set
_∉_ a X = ¬ (a ∈ X)
decide∈ : {A : Set} → {{_ : Eq A}} → (a : A) → (X : FinSet A) → Dec (a ∈ X)
decide∈ a ε = no (λ z → z)
decide∈ a (b & X) with (a decide≡ b)
decide∈ a (b & X) | yes _ = yes tt
... | no _ = decide∈ a X
decide∉ : {A : Set} → {{_ : Eq A}} → (a : A) → (X : FinSet A) → Dec (a ∉ X)
decide∉ a X = ¬? (decide∈ a X)
instance
eqℕ : Eq ℕ
eqℕ = mkEqInst decide
where decide : (a b : ℕ) → Dec (a ≡ b)
decide zero zero = yes refl
decide zero (suc b) = no (λ ())
decide (suc a) zero = no (λ ())
decide (suc a) (suc b) with (decide a b)
... | yes p = yes (cong suc p)
... | no p = no (λ x → p ((suc-inj a b) x))
Однако, когда я тестирую этот тип со следующим:
test : FinSet ℕ
test = _&_ zero ε
По какой-то причине Agda не может вывести неявный аргумент типа ¬ ⊥
! Однако auto, конечно же, находит доказательство этого тривиального утверждения: λ x → x : ¬ ⊥
.
У меня такой вопрос: поскольку я пометил неявное доказательство как нерелевантное, почему Agda не может просто запустить auto
, чтобы найти доказательство ¬ ⊥
во время проверки типа? По-видимому, при заполнении других неявных аргументов может иметь значение, какое именно доказательство Agda finda, поэтому он не должен просто запускать auto
, но если доказательство было помечено как нерелевантное, как в моем случае, почему Agda не может найти доказательство?
Примечание: у меня есть лучшая реализация этого, где я реализую ∉
напрямую, и Agda может найти соответствующее доказательство, но я хочу понять в целом, почему Agda не может автоматически найти такого рода доказательства для неявных аргументов. Есть ли способ в текущей реализации Agda получить эти "автоматические имплициты", как я хочу здесь? Или есть какая-то теоретическая причина, по которой это было бы плохой идеей?