Zulip Chat Archive
Stream: new members
Topic: Pulling Subtype.val inside a for-Loop
Johannes Tantow (Nov 09 2024 at 21:37):
Hi!
Suppose I have two functions f1 and f2 as definied below. They behave the same on the value but the properties of the resulting subtype may be different. I don't care about these and only want to prove that there values are equal, which seems intuitively true, but I am struggling to prove that. I can destruct the goal further with congr, but this wants me to show (fun a => p a) = fun a => q a
, which doesn't seem true to me. Ideally, I want to pull Subtype.val inside the for loop and then it simplifies, but I am unsure how to do that.
def f1 {α ρ: Type u}[ForIn Id ρ α] (l: ρ)(f: α → α → α) (p: α → Prop) (start: α) (pstart: p start) (f_prev: ∀ (a b:α), p a → p (f a b)): {a: α // p a} := Id.run do
let mut s := ⟨start, pstart⟩
for a in l do
s := ⟨f s.1 a, f_prev s.1 a s.2⟩
return s
def f2 {α ρ: Type u}[ForIn Id ρ α] (l: ρ)(f: α → α → α) (q: α → Prop) (start: α) (qstart: q start) (f_prev: ∀ (a b:α), q a → q (f a b)): {a: α // q a} := Id.run do
let mut s := ⟨start, qstart⟩
for a in l do
s := ⟨f s.1 a, f_prev s.1 a s.2⟩
return s
theorem f1_eq_f2_val {α ρ: Type u}[ForIn Id ρ α] (l: ρ)(f: α → α → α) (p: α → Prop) (start: α) (pstart: p start) (f_prev_p: ∀ (a b:α), p a → p (f a b)) (q: α → Prop) (qstart: q start) (f_prev_q: ∀ (a b:α), q a → q (f a b)): (f1 l f p start pstart f_prev_p).1 = (f2 l f q start qstart f_prev_q).1 := by
unfold f1
unfold f2
simp[Id.run]
admit
Why am I trying to do this? Std.DHashMap.Internal.Raw₀.insertMany
has a similar structure and I am trying to prove that the value of it on lists is equal to some function I defined on lists using the constructors of list, so that I can continue with this simpler function to prove results about it. In the induction on lists, I reach such a goal.
Andrew Yang (Nov 10 2024 at 00:38):
f1_eq_f2_val
is false because you have no idea how ForIn
is implemented
universe u
def f1 {α ρ : Type u} [ForIn Id ρ α] (l : ρ) (f : α → α → α)
(p : α → Prop) (start : α) (pstart : p start)
(f_prev : ∀ a b, p a → p (f a b)) : {a // p a} := Id.run do
let mut s := ⟨start, pstart⟩
for a in l do
s := ⟨f s.1 a, f_prev s.1 a s.2⟩
return s
def f2 {α ρ : Type u} [ForIn Id ρ α] (l : ρ) (f : α → α → α)
(q : α → Prop) (start : α) (qstart : q start)
(f_prev: ∀ a b, q a → q (f a b)) : {a // q a} := Id.run do
let mut s := ⟨start, qstart⟩
for a in l do
s := ⟨f s.1 a, f_prev s.1 a s.2⟩
return s
theorem f1_eq_f2_val {α ρ : Type u} [ForIn Id ρ α] (l : ρ) (f: α → α → α)
(p : α → Prop) (start : α) (pstart: p start) (f_prev_p : ∀ (a b:α), p a → p (f a b))
(q : α → Prop) (qstart : q start) (f_prev_q: ∀ (a b : α), q a → q (f a b)) :
(f1 l f p start pstart f_prev_p).1 = (f2 l f q start qstart f_prev_q).1 := by
admit
-- unfold f1
-- unfold f2
-- simp[Id.run]
-- admit
example : False := by
classical
have := @f1_eq_f2_val Nat Nat ⟨fun {β} _ _ d _ ↦
if e : { n : Nat // True } = β then e.rec ⟨1, trivial⟩ else d⟩ 37 (fun _ _ ↦ 0) (fun _ ↦ True) 0
trivial (fun _ _ _ ↦ trivial) (· = 0) rfl (fun _ _ _ ↦ rfl)
have H : { a : Nat // True } ≠ { a // a = 0 } := by
intro h
have : Subsingleton { a // a = 0 } := ⟨fun a b ↦ Subtype.ext (a.2.trans b.2.symm)⟩
have : Subsingleton { a // True } := h ▸ this
cases this.1 ⟨0, trivial⟩ ⟨1, trivial⟩
simp [f1, f2, Id.run, H] at this
Johannes Tantow (Nov 10 2024 at 08:31):
Interesting, thank you. I guess I abstracted a bit too far. For my purpose it would suffice to have that ρ
is a List, where your counterexample should no longer work. I try to show the following and at the end I get a similar goal I cannot prove. I hope this time its really true
import Std.Data.DHashMap.Internal.Defs
variable {α : Type u} {β : α → Type v}
namespace Std.DHashMap.Internal.Raw₀
/-- Internal implementation detail of the hash map -/
def insertMany_val [BEq α] [Hashable α]
(m : Raw₀ α β) (l : List ((a : α) × β a)) : Raw₀ α β := Id.run do
let mut r := m
for ⟨a,b⟩ in l do
r:= r.insert a b
return r
theorem insertMany_val_eq [BEq α] [Hashable α]
(m : Raw₀ α β) (l : List ((a : α) × β a)) : (insertMany m l).val = insertMany_val m l := by
simp[insertMany, insertMany_val, Id.run]
induction l generalizing m with
| nil => simp
| cons hd tl ih=>
simp
specialize ih (m.insert hd.1 hd.2)
sorry
Last updated: May 02 2025 at 03:31 UTC