This PR adds a (failing) test case for an obstacle I've been running into setting up `grind` for `HashMap`.
40 lines
1.6 KiB
Text
40 lines
1.6 KiB
Text
import Std.Data.HashMap
|
||
|
||
reset_grind_attrs%
|
||
set_option grind.warning false
|
||
|
||
open Std
|
||
open scoped HashMap
|
||
|
||
attribute [grind]
|
||
HashMap.getElem?_eq_some_getElem HashMap.getElem?_filter
|
||
HashMap.getElem?_insert HashMap.getElem_insert HashMap.mem_insert
|
||
HashMap.Equiv.of_forall_getElem?_eq
|
||
HashMap.getKey_eq
|
||
Option.pfilter_eq_filter
|
||
|
||
example (m : HashMap Nat Nat) :
|
||
(m.insert 1 2).filter (fun k v => k > 1000) ~m m.filter fun k v => k > 1000 := by
|
||
grind -- fails, but I'd like it to work!
|
||
|
||
-- One of the equivalence classes here is:
|
||
-- {(HashMap.filter (fun k v => decide (1001 ≤ k)) m)[w]?,
|
||
-- m[w]?.pfilter fun x h' => decide (1001 ≤ m.getKey w ⋯)}
|
||
-- What I would like to happen is `getKey_eq` fires,
|
||
-- replacing `m.getKey w ⋯` with `w`, and then `Option.pfilter_eq_filter` to fire
|
||
-- (now that the proof argument `h'` is not used.)
|
||
-- I'm not sure why this is not working, perhaps the proof abstraction `⋯`
|
||
-- is getting in the way?
|
||
|
||
-- Here's a similar example that *does* work, but where abstraction hasn't occurred.
|
||
example [BEq α] [LawfulBEq α] [Hashable α] [LawfulHashable α]
|
||
{m : HashMap α β} {f : α → β → γ} {k : α} :
|
||
(m.map f)[k]? = m[k]?.map (f k) := by
|
||
-- Fails, because we've left out the critical lemma `Option.pmap_eq_map`
|
||
fail_if_success grind [HashMap.getElem?_map, HashMap.getKey_eq]
|
||
-- We see a similar equivalence class
|
||
-- {(HashMap.map f m)[k]?, Option.pmap (fun v h' => f (m.getKey k h') v) m[k]? ⋯}
|
||
-- although this time `⋯` has not been abstracted.
|
||
|
||
-- Now it works:
|
||
grind [HashMap.getElem?_map, HashMap.getKey_eq, Option.pmap_eq_map]
|