最近我在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由于某种原因无法推断类型为¬ ⊥
的隐式参数!然而,汽车当然会找到这个琐碎命题的证明:λ x → x : ¬ ⊥
。
我的问题是:由于我已将隐式证明标记为不相关,为什么Agda只能运行auto
以在类型中找到¬ ⊥
的证据检查?据推测,每当填写其他隐含的参数时,确切地说Agda会找到什么证据可能很重要,所以它不应该只运行auto
,但如果证明已被标记为不相关,就像我的情况那样,为什么可以&# 39; t Agda找到证据?
注意:我有更好的实现,我直接实现∉
,Agda可以找到相关的证据,但我想了解为什么Agda不能自动找到这些类型的隐式参数的证明。在目前的Agda实现中是否有任何方法可以获得这些" auto implicits"我喜欢这里吗?或者有一些理论上的理由说明为什么这会是一个坏主意?
答案 0 :(得分:2)
没有根本原因可以通过证据搜索解决无关的论点,但是担心的是在很多情况下它会很慢和/或找不到解决方案。
更多用户指导的事情是允许用户指定应使用特定策略推断某个参数,但这也没有实现。在你的情况下,你会提供一个试图用(\ x - > x)来解决目标的策略。
答案 1 :(得分:1)
如果您更直接地定义- (void)userPressedSubmitButtonOnLastCell
{
[self updateData];
[self.tableView reloadData];
[self performSelector:@selector(scrollTableView) withObject:nil afterDelay:0.5];
}
- (void)scrollTableView
{
[self.tableView setContentOffset:CGPointMake(0,199) animated:NO];
}
,则隐式参数将获取类型∉
而不是⊤
。 Agda可以通过eta-expansion自动填充¬ ⊥
类型的参数,因此您的代码可以正常工作:
⊤