`with f x` matches `false`, but cannot construct `f x == false`

偶尔善良 提交于 2020-08-17 12:06:08

问题


A piece of code here:

-- 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

produces an error:

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

I have a with-statement, which establishes exactly the fact that ismember (set-union (set-pair m n)) x is false. Why can it not establish that it is false?


Ok, I can even see some known issues https://agda.readthedocs.io/en/v2.5.2/language/with-abstraction.html#ill-typed-with-abstractions but still none the wiser as to how to pattern match then.


回答1:


It looks like you need to remember the fact that the following expression

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

is indeed equal to

false

This is a very common problem that comes from the way the 'with' construct works. By default, you don't have access to the proof element that connects the element on which you pattern match with the result of the pattern matching, that is, in your example, an element of type:

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

In order to get an element of this type, you need to use the 'inspect' idiom that is defined alongside the propositional equality in the standard library. More concretely, this means you'll have to add a new element to your pattern matching as follows:

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

This will result in you having access both to 'false' and the proof element you require. For more information about the inspect idiom, see :

  • The wiki page on the with-abtraction : https://agda.readthedocs.io/en/v2.6.0.1/language/with-abstraction.html
  • The file PropositionalEquality.agda in the standard library, which provides the idiom as well as a quick description of how to use it
  • The file README/Inspect.agda in the standard library as well which provides a complete example on how and when to use the inspect idiom


来源:https://stackoverflow.com/questions/58718174/with-f-x-matches-false-but-cannot-construct-f-x-false

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!