我在Agda中编写证据时遇到了麻烦。所以我简化了它。
ffff : bool -> bool
ffff x with x , x
ffff x | t , t = t
ffff x | f , f = t
ffff x | t , ()
ffff x | f , ()
编译错误:
bool × bool should be empty, but the following constructor patterns
are valid:
_,_ _ _
我知道这是一种愚蠢的情况。但它切入了我经常想要在agda中做的事情的核心。我如何重组这个证据,以便最后两个案例是荒谬的?
答案 0 :(得分:4)
您的代码不起作用的原因是当您使用荒谬模式()时,它应该认为没有具有正确类型的模式的有效实例化。在这种情况下,情况并非如此:类型是荒谬模式只是bool
并且有明显有效的实例化f
和t
。问题是你知道除了模式的类型之外没有原因的模式的有效情况,而Agda只查看模式的类型。
因此,您应该尝试做的是更改代码,使其遵循某些模式的类型,即没有有效的案例。在这种情况下通常有用的一种模式是“检查类固醇”模式。从本质上讲,您要记住在with块中模式匹配的是值(x , x)
。您可以使用“检查类固醇”模式执行此操作,如下所示,尽管这可能不是您在实际非简化代码中所需的精确值:
open import Data.Bool
open import Relation.Binary.PropositionalEquality
open import Data.Product
ffff : Bool -> Bool
ffff x with (x , x) | inspect (λ x → (x , x)) x
ffff x | true , true | _ = true
ffff x | false , false | _ = true
ffff x | true , false | [ () ]
ffff x | false , true | [ () ]
无论如何,我建议你谷歌对“检查类固醇”模式(或较旧的“检查”模式)的一个很好的解释,研究它,也许研究上面的例子并尝试将它应用到你的实际代码..