0

Given a list, a "property" (a function to Bools), and a proof any f xs ≡ true, I want to get a value of Any (λ x → T (f x)) ns, i.e. I want a to convert a proof from any to a proof of Any.

So far, I have been able to sketch the proof, but I am stuck at a seemingly simple statement (please see the second to last line below):

open import Data.Bool
open import Data.Bool.Properties
open import Data.List
open import Data.List.Relation.Unary.Any using (Any; here; there)
open import Data.Unit
open import Relation.Binary.PropositionalEquality 

≡→T : ∀ {b : Bool} → b ≡ true → T b
≡→T refl = tt

any-val : ∀ {a} {A : Set a} (f) (ns : List A)
        → any f ns ≡ true
        → Any (λ x → T (f x)) ns
any-val f [] ()
any-val f (n ∷ ns) any-f-⟨n∷ns⟩≡true with f n
...                            | true  = here (≡→T ?)
...                            | false = there (any-val f ns any-f-⟨n∷ns⟩≡true)

Apparently, I need to prove that f n ≡ true, which should be trivial to prove because we are in the true branch of the with statement f ≡ true.

What is supposed to go in there? What am I understanding incorrectly?

helq
  • 1,451
  • 1
  • 9
  • 12

1 Answers1

2

The key is to use the inspect idiom, which I already described thoroughly in another answer here:

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

This gives the following code, which I cleaned up, including imports:

open import Data.Bool
open import Data.List
open import Data.List.Relation.Unary.Any using (Any; here; there)
open import Data.Unit
open import Relation.Binary.PropositionalEquality 
open import Function

≡→T : ∀ {b : Bool} → b ≡ true → T b
≡→T refl = tt

any-val : ∀ {a} {A : Set a}
  f (ns : List A) → any f ns ≡ true → Any (T ∘ f) ns
any-val f (x ∷ l) p with f x | inspect f x
... | false | _ = there (any-val f l p)
... | true | [ fx≡true ] = here (≡→T fx≡true)

On a side note, be sure that you have Agda updated to the last version so that you don't have to handle the empty case any-val f [] (), as in your code.

MrO
  • 1,291
  • 7
  • 14
  • Just figured it out too (I was reading the documentation. Damn, I should look a the documentation before posting, but there are so many things to look at in the documentation!). Anyway. Thanks a lot! I had no idea there was no need to handle the empty case. I just added because I felt obliged to do it – helq Jun 09 '20 at 20:03
  • No worries, it can be sometimes hard to find the required information, especially in the Agda std lib. About the empty case, it's quite a new behavior, which is more of a syntactic sugar, but still very convenient. Glad I could help. – MrO Jun 09 '20 at 20:06