Agda如何确定一种类型是不可能的

dav*_*vik 5 agda dependent-type

所以我试图理解为什么这段代码在()周围给出黄色突出显示

data sometype : List ? ? Set where
  constr : (l1 l2 : List ?)(n : ?) ? sometype (l1 ++ (n ? l2))

somef : sometype [] ? ?
somef ()
Run Code Online (Sandbox Code Playgroud)

但事实并非如此

data sometype : List ? ? Set where
  constr : (l1 l2 : List ?)(n : ?) ? sometype (n ? (l1 ++ l2))

somef : sometype [] ? ?
somef ()
Run Code Online (Sandbox Code Playgroud)

两者似乎都是sometype []是空的,但是Agda无法想出第一个?为什么?这背后的代码是什么?我能否以某种方式定义somef以使第一个定义有效?

And*_*ács 6

Agda不能假设任何关于任意函数的事情++.假设我们定义++了以下方式:

_++_ : {A : Set} ? List A ? List A ? List A
xs ++ ys = []
Run Code Online (Sandbox Code Playgroud)

在这种情况下,sometype [] ? ?不可证明,接受()荒谬的模式将是一个错误.

在第二个示例中,索引sometype必须是表单n ? (l1 ++ l2),它是构造函数表达式,因为它_?_是一个列表构造函数.Agda可以安全地推断出_?_构造列表永远不会等于[].一般而言,不同的构造者可被视为不可能统一.

Agda可以对功能应用程序做些什么,尽可能减少它们.在某些情况下,reduce会产生构造函数表达式,在其他情况下则不会,我们需要编写其他证明.

为了证明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) ()
Run Code Online (Sandbox Code Playgroud)

换句话说,? xs ? sometype xs ? xs ? [].我们可以从中得出所需的证据:

someF : sometype [] ? ?
someF p = someF' [] p refl
Run Code Online (Sandbox Code Playgroud)

  • 点表示(虚线)图案内的变量以某种其他模式引入.每个模式变量必须只引入一次,如果我们想在其他地方使用相同的相同变量(因为类型依赖关系强制值在模式中相等),我们可以在虚线模式中进行. (3认同)
  • 顺便说一句,如果你在一个洞中使用待扩展的绑定点击`Cc`,则在Emacs Agda界面中会自动扩展点状图案.这是其他[Emacs键](http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Docs.EmacsModeKeyCombinations). (2认同)
  • Agda确实知道_ ++ _的定义,并将其子句用作重写规则.确实如此,因为没有重写规则匹配(l1 ++(n∷l2))Agda只知道它等于它自己. (2认同)