不相关的含义:为什么agda不推测这个证明?

时间:2017-04-02 02:16:20

标签: agda

最近我在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"我喜欢这里吗?或者有一些理论上的理由说明为什么这会是一个坏主意?

2 个答案:

答案 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自动填充¬ ⊥类型的参数,因此您的代码可以正常工作: