-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot prove property of function that uses with-in instead of stdlib's inspect
#5833
Comments
The first function does now typecheck, as follows: ∈-mapMaybe⁻ {y = y} {xs = x ∷ xs} y∈
with f x in fx≡
... | nothing = map₂ (map₁ there) (∈-mapMaybe⁻ y∈)
... | just y′ with y∈
... | here refl = x , here refl , fx≡
... | there y∈′ = map₂ (map₁ there) (∈-mapMaybe⁻ y∈′) Ah... gotcha. [UPDATED: solved below] |
For which one can prove the following lemma: [UPDATED to streamline the use of ∈-mapMaybe⁻-nothing-∈-mapMaybe⁺ : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
f x ≡ nothing → y ∈ mapMaybe f xs
∈-mapMaybe⁻-nothing-∈-mapMaybe⁺ {y = y} {x = x} {xs = xs} y∈ fx≡nothing
with _ ← mapMaybe f (x ∷ xs) in eq rewrite fx≡nothing | eq = y∈ but for which I don't seem able to prove the lemma that you want. [UPDATED: see below] |
A question I cannot yet answer is whether implementing ∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
(eq : f x ≡ nothing) →
Is-there {xs = x ∷ xs} (∈-mapMaybe⁻ {y = y} (y∈ | f x | eq) .proj₂ .proj₁) i.e. to correlate the equation The other thing to say is that the lemma I should have liked to prove may require |
Here are some more example on the same theme if you want to play around a bit more: https://omelkonian.github.io/formal-prelude/Prelude.Lists.MapMaybe.html |
Actually, I think the following solves it: ∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
(fx≡nothing : f x ≡ nothing) →
Is-there ((∈-mapMaybe⁻ y∈) .proj₂ .proj₁)
∈-mapMaybe⁻-nothing y∈ fx≡nothing with ∈-mapMaybe⁻ y∈
... | x , here refl , fx≡just[y] with () ← ≡.trans (≡.sym fx≡nothing) fx≡just[y]
... | z , there y∈′ , fz≡just[y] = _ The wart in this is of course the RHS treatment of |
Rewriting this with an auxiliary function helps clarify things a little, but I kept hitting the error message Cannot `with` on variable fz≡just[y] bound in a module telescope
(or patterns of a parent clause)
when inferring the type of fx≡just[y] Accordingly, with a bit more abstraction (can the machine do this?), and noting that ∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
(fx≡nothing : f x ≡ nothing) →
Is-there ((∈-mapMaybe⁻ y∈) .proj₂ .proj₁)
∈-mapMaybe⁻-nothing {y = y} {x = x} {xs = xs} y∈ fx≡nothing
with z , p , fz≡just[y] ← ∈-mapMaybe⁻ y∈ = aux p fz≡just[y]
where
aux : (p : Any (_≡_ z) (x ∷ xs)) → (f z ≡ just y) → Is-there p
aux (here refl) fx≡just[y] rewrite fx≡nothing with () ← fx≡just[y]
aux (there p) _ = _ |
None of this, of course, vitiates @omelkonian 's original (meta-)point (made eloquently at AIMXXXVI last month) about "don't use But I don't think that this example shows that the use of But perhaps other fiendish (counter)examples exist out there? |
@jamesmckinna Nice workaround, although I don't like that it's following an entirely different recursion pattern than the original in So I guess a bug remains with respect to how faithfully ∈-mapMaybe⁻ : y ∈ mapMaybe f xs
→ ∃ λ x → (x ∈ xs) × (f x ≡ just y)
∈-mapMaybe⁻ {y = y} {xs = x ∷ xs} y∈
with f x | inspect f x
... | nothing | _ = map₂ (map₁ there) (∈-mapMaybe⁻ y∈)
... | just y′ | ≡.[ fx≡ ]
with y∈
... | here refl = x , here refl , fx≡
... | there y∈′ = map₂ (map₁ there) (∈-mapMaybe⁻ y∈′)
∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs))
→ f x ≡ nothing
→ Is-there (∈-mapMaybe⁻ y∈ .proj₂ .proj₁)
∈-mapMaybe⁻-nothing {x = x} {xs = xs} y∈ fx≡
with f x | inspect f x
... | nothing | _ = tt ...but this is not: ∈-mapMaybe⁻ : y ∈ mapMaybe f xs
→ ∃ λ x → (x ∈ xs) × (f x ≡ just y)
∈-mapMaybe⁻ {y = y} {xs = x ∷ xs} y∈
with f x in fx≡
... | nothing = map₂ (map₁ there) (∈-mapMaybe⁻ y∈)
... | just y′
with y∈
... | here refl = x , here refl , fx≡
... | there y∈′ = map₂ (map₁ there) (∈-mapMaybe⁻ y∈′)
∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs))
→ f x ≡ nothing
→ Is-there (∈-mapMaybe⁻ y∈ .proj₂ .proj₁)
∈-mapMaybe⁻-nothing {x = x} {xs = xs} y∈ fx≡
with f x in _
... | nothing | _ = tt |
Hmmm. Just to be clear:
Regarding the former, there does seem to be a clear like-for-like replacement of the use of the Regarding the latter, I think I do see a (the?) problem: In that respect, it's actually a bit weird that the original pragmatics (of each idiom) was to give a name (pattern variable binding) to the equation, when in the case of So the issue seems to be that the lazier @gallais, do you think the idiom could be extended to incorporate such behaviour? eg by positing the auxiliary function generated by |
Exactly, I find it odd that |
I agree they are different proofs! But I think my analysis above of the real problem lies in the strictness of |
A weird anomaly (is it a 'bug'? not sure, but it's weird): inspect : {A : Set a} {B : A → Set b} →
(f : (x : A) → B x) (x : A) →
Reveal f · x is f x
inspect f a = let eq = refl {x = f a} in [ eq ] is fine... whereas strict-inspect : {A : Set a} {B : A → Set b} →
(f : (x : A) → B x) (x : A) →
Reveal f · x is f x
strict-inspect f a = let eq@refl = refl {x = f a} in [ eq ] is not, because the attempt to match/constrain Related: pattern explicit-refl f a = refl {x = .(f a)} fails because dotted patterns aren't allowed in pattern synonyms, while pattern inspect-refl f a = refl fails because the variables So it seems that the old library definition of |
Hmmm... I've been playing a bit more, and you still won't like it, I'm sure, but here goes as the 'simplest' version I can offer: -- warm-up exercise, exhibiting reduction behaviour in `y∈`
∈-mapMaybe⁻-nothing-∈-mapMaybe⁺ : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
f x ≡ nothing → y ∈ mapMaybe f xs
∈-mapMaybe⁻-nothing-∈-mapMaybe⁺ y∈ fx≡nothing
rewrite fx≡nothing = y∈
-- tidier version of 'impossible' lemma
∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
(fx≡nothing : f x ≡ nothing) →
Is-there ((∈-mapMaybe⁻ y∈) .proj₂ .proj₁)
∈-mapMaybe⁻-nothing y∈ fx≡nothing
with ∈-mapMaybe⁻ y∈
... | x , here refl , fx≡just[y] with nothing ← f x | () ← fx≡just[y]
... | z , there y∈′ , fz≡just[y] = _ This seems to be the best I can do, and corresponds, as you say, not to your original 'computational' proof, which uses the equation The first, failing case, is when The second is the customary success case that 'just works', and so we're done. So... still puzzling... I'm certainly still puzzled!!! UPDATED: the mistake, perhaps, is to introduce ∈-mapMaybe⁻-nothing : (y∈ : y ∈ mapMaybe f (x ∷ xs)) →
(fx≡nothing : f x ≡ nothing) →
Is-there ((∈-mapMaybe⁻ y∈) .proj₂ .proj₁)
∈-mapMaybe⁻-nothing y∈ with z , z∈ , fz≡just[y] ← ∈-mapMaybe⁻ y∈ | z∈
... | here refl rewrite fz≡just[y] = λ ()
... | there _ = λ _ → _ ... FWIW |
Aaargh: #6841 the saga continues... |
The following lemma about membership and
mapMaybe
has to be defined using the non-internalized inspect,in order to prove the
∈-mapMaybe⁻-nothing
property:Seems like a bug in the implementation of
with...in...
, @gallais?The text was updated successfully, but these errors were encountered: