【问题标题】:`with f x` matches `false`, but cannot construct `f x == false``with f x` 匹配 `false`,但不能构造 `f x == false`
【发布时间】:2020-03-02 05:31:35
【问题描述】:

这里有一段代码:

-- transitivity
trans : {A : Set} {x y z : A} -> x == y -> y == z -> x == z
trans refl refl = refl

union-pair' : {A : Set} -> (m n : S {A}) -> (x : A) ->
                           (ismember (set-union (set-pair m n)) x) == (ismember (union m n) x)
union-pair' m n x with ismember m x | ismember n x | ismember (set-union (set-pair m n)) x
union-pair' : {A : Set} -> (m n : S {A}) -> (x : A) ->
                       (ismember (set-union (set-pair m n)) x) == (ismember (union m n) x)
union-pair' m n x with ismember m x | ismember n x | ismember (set-union (set-pair m n)) x
...                  | false | false | false = trans {x = ismember (set-union (set-pair m n)) x} {y = false}
                                                     refl -- line #102
                                                     (union-match m n x)
-- more code available on request, although I can't see why that would matter

产生错误:

code.agda:102,54-58
(ismember (set-union (set-pair m n)) x) != false of type Bool
when checking that the expression refl has type
ismember (set-union (set-pair m n)) x == false

我有一个with 声明,它准确地确定了ismember (set-union (set-pair m n)) xfalse 的事实。为什么不能确定是false


好的,我什至可以看到一些已知问题 https://agda.readthedocs.io/en/v2.5.2/language/with-abstraction.html#ill-typed-with-abstractions,但对于如何进行模式匹配仍然没有更明智的选择。

【问题讨论】:

    标签: agda


    【解决方案1】:

    看来你需要记住以下表达式

    ismember (set-union (set-pair m n)) x
    

    确实等于

    false
    

    这是一个非常常见的问题,它来自“with”构造的工作方式。默认情况下,您无权访问将模式匹配的元素与模式匹配结果连接起来的证明元素,即在您的示例中,类型为:

    ismember (set-union (set-pair m n)) x == false
    

    为了获得这种类型的元素,您需要使用在标准库中与命题相等性一起定义的“检查”习语。更具体地说,这意味着您必须在模式匹配中添加一个新元素,如下所示:

    ... | ismember (set-union (set-pair m n)) x | inspect (ismember (set-union (set-pair m n)) x
    

    这将导致您可以访问“假”和您需要的证明元素。有关检查习语的更多信息,请参阅:

    【讨论】:

    • 谢谢!这与我想出的类似,尽管我的方法要笨拙得多。最后我创建了一个可判定的(_==?_) 类型,它要么提供一个证明(ismember s x == true),要么证明(ismember s x == true) 是荒谬的,然后我们可以从那里开始。
    • 附带说明,在我看来,您可以更好地模拟您的问题,这样您就不必使用这些技术。例如,如果您将“ismember”设置为谓词而不是返回布尔值的函数,那么您的开发似乎会更加方便和优雅。如果您需要帮助,并且您认为我是对的,请随时提出另一个问题并将其链接到我这里。
    • 对,在我之前阅读您引用的页面期间,文档中令人困惑的一点是 withrewrite 的表面差异:One limitation of the rewrite construction is that you cannot do further pattern matching on the arguments after the rewrite, since everything happens in a single clause. You can however do with-abstractions after the rewrite. - 这对我来说暗示 @987654332 @ 不会丢失模式和产生它的表达式之间的联系。
    • 感谢您的提议。我想首先获得一个工作版本,无论它看起来多么困难或不规范 - 只是因为那时我遇到了有助于我更好地理解可用机制的怪癖。我会想用更好的风格重写它。
    • 另一个令人困惑的地方是 with-abstracting 用于某个中间目标和最终目标的表达式之间的区别 - 例如,特别令人沮丧的部分是 agda 不介意构建一个refl for ismember m x == true in ismember? : {A : Set} -> (m : S {A}) (x : A) -> (ismember m x) ==? true - 在这里,据我所知,不同之处在于with-abstraction 重写了所有可用的ismember m x - 包括返回类型中的。在示例中,ismember m x == true 类型的中间目标在重写时不可见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    相关资源
    最近更新 更多