Agda 图案结果不可见

Agda 图案结果不可见,agda,Agda,我试图了解如何分支到“安全键入”代码。例如,下文旨在仅在安全路径上调用tail——即,如果输入列表为非空。当然,有一种简单的方法可以只对列表进行模式匹配,但其思想是协调函数(null)的结果及其在右侧的使用: data Void : Set where data _==_ {A : Set} (x : A) : A -> Set where refl : x == x data Bool : Set where True : Bool False : Bool data

我试图了解如何分支到“安全键入”代码。例如,下文旨在仅在安全路径上调用
tail
——即,如果输入列表为非空。当然,有一种简单的方法可以只对列表进行模式匹配,但其思想是协调函数(
null
)的结果及其在右侧的使用:

data Void : Set where

data _==_ {A : Set} (x : A) : A -> Set where
  refl : x == x

data Bool : Set where
  True : Bool
  False : Bool

data List (A : Set) : Set where
  nil  : List A
  _::_ : A -> List A -> List A

null : forall {A} -> List A -> Bool
null nil         = True
null (x :: xs)   = False

non-null : forall {A} -> List A -> Set
non-null nil = Void
non-null (x :: xs) = (x :: xs) == (x :: xs)

tail : forall {A} -> (xs : List A) -> {p : non-null xs} -> List A
tail (_ :: xs) = xs
tail nil      {p = ()}

prove-non-null : forall {A} -> (xs : List A) -> (null xs == False) -> non-null xs
prove-non-null nil         ()
prove-non-null (x :: xs)   refl = refl

compileme : forall {A} -> List A -> List A
compileme xs with null xs
...             | True    = xs
...             | False   = tail xs {prove-non-null xs refl}
在最后一行,agda抱怨说,无法证明
refl
的类型为
null xs==False
。为什么它看不到with子句刚刚见证了
null xs
False


正确的方法是什么?如何从看似不相关的结果(如
Bool
类型)中“提取”相关性并不依赖于列表
xs
,但在上下文中它是?

这是关于
inspect
的习惯用法。检查并确认。标准库中的
inspect
部分来自线程(也有一些)

如果删除
的定义,则可以将
compileme
定义为

open import Relation.Binary.PropositionalEquality renaming (_≡_ to _==_)

...

compileme : forall {A} -> List A -> List A
compileme xs with null xs | inspect null xs
...             | True    | [ _ ] = xs
...             | False   | [ p ] = tail xs {prove-non-null xs p}
顺便说一句,
(x::xs)==(x::xs)
应该是什么意思?只是

open import Data.Unit
...
non-null (x :: xs) = ⊤

顺便说一句,您可以定义类型安全
tail
,就像我在回答中定义的类型安全
pred
一样。

这是关于
inspect
的习惯用法。检查并确认。标准库中的
inspect
部分来自线程(也有一些)

如果删除
的定义,则可以将
compileme
定义为

open import Relation.Binary.PropositionalEquality renaming (_≡_ to _==_)

...

compileme : forall {A} -> List A -> List A
compileme xs with null xs | inspect null xs
...             | True    | [ _ ] = xs
...             | False   | [ p ] = tail xs {prove-non-null xs p}
顺便说一句,
(x::xs)==(x::xs)
应该是什么意思?只是

open import Data.Unit
...
non-null (x :: xs) = ⊤

BTW2,你可以定义类型安全
tail
,就像我在回答中定义的类型安全
pred
一样。

好吧,起初
非空
的意思是以某种方式表示一个类型
(x::xs)==ys
,如果
ys
是非空的,但是我减少了要求,这让它看起来很愚蠢,起初,如果
ys
为非null,那么
non-null
的意思是以某种方式表示类型
(x::xs)==ys
,但后来我减少了要求,这使它看起来很愚蠢。