Zulip Chat Archive
Stream: lean4
Topic: Termination via well founded relation on subtype?
James Gallicchio (Feb 12 2022 at 23:35):
Two newbie questions about how to get this definition to compile:
def mwe [Stream ρ τ] (res : α) : {l : ρ // isFinite l} → α
| ⟨l,h⟩ =>
match next? l with
| none => res
| some (_,xs) =>
have h_next : hasNext l xs := sorry
mwe res ⟨xs, by sorry⟩
termination_by _ l => l
I know there's a lot going on here, but I've essentially defined a subtype for streams which are finite, and now am trying to recurse through the stream.
1) I have an instance of WellFoundedRelation {l // isFinite l}
but I'm not really sure how to use it to prove termination here
2) I'm not sure how to maintain information from the match; in particular, I need that next? l = some (_,xs)
to prove the first sorry. I've tried the generalizing := true
flag that I saw elsewhere, but that did not seem to do anything here
Chris B (Feb 13 2022 at 02:17):
The syntax for 2 is match h:next? l with
, with no whitespace after the h:
.
Chris B (Feb 13 2022 at 02:18):
I'll see about adding it to the docs, it looks like that's still not in there.
Chris B (Feb 13 2022 at 02:20):
For 1, you can try adding
termination_by _ l => l
decreasing_by
trace_state
and observing the proof goal.
James Gallicchio (Feb 13 2022 at 02:38):
Chris B said:
The syntax for 2 is
match h:next? l with
, with no whitespace after theh:
.
Ahh, I was trying h : with whitespace, that is a bit unfortunate whitespace sensitivity
Chris B (Feb 13 2022 at 02:40):
You're not alone. I'll mention the whitespace thing in the documentation.
James Gallicchio (Feb 13 2022 at 03:34):
As for the termination, it comes up as a type error?
type mismatch
l
has type
{ l // isFinite l } : Type (max 0 u_1)
but is expected to have type
?β : Sort ?u.12065
Chris B (Feb 13 2022 at 03:42):
Is the whole thing posted anywhere?
James Gallicchio (Feb 13 2022 at 03:43):
hm, lemme try to cut this file down
James Gallicchio (Feb 13 2022 at 03:49):
https://gist.github.com/JamesGallicchio/9e5d08bce7ce4f9f563d1a9edc765d5b this should compile on most recent nightly (it does need a bug fix from a few days ago)
Chris B (Feb 13 2022 at 15:56):
There seems to be some issue with type parameter visibility in termination blocks; this makes this issue more clear:
set_option pp.all true in
def mwe [Stream ρ τ] (acc : α) : {l : ρ // isFinite l} → α
| ⟨l,h⟩ =>
match h:next? l with
| none => acc
| some (x,xs) =>
have h_next : hasNext l xs := by exists x; simp [hasNext, h]
mwe acc ⟨xs, by sorry⟩
termination_by'
invImage (fun ⟨ρ, τ, α, _, _, subty⟩ => subty) (hasNextWF)
/-
subty : @Subtype.{u_1 + 1} ρ fun (l : ρ) => @Stream.isFinite.{u_1, u_2} ρ τ x✝¹ l
type mismatch
subty
has type
@Subtype.{u_1 + 1} ρ fun (l : ρ) => @Stream.isFinite.{u_1, u_2} ρ τ x✝ l : Type (max 0 u_1)
but is expected to have type
@Subtype.{?u.8671 + 1} ?m.8672 fun (s : ?m.8672) =>
@Stream.isFinite.{?u.8671, ?u.8670} ?m.8672 ?m.8673 ?m.8674 s : Type ?u.8671
-/
And I can't give hasNextWF
the type arguments explicitly.
James Gallicchio (Feb 13 2022 at 16:02):
Oh boy. I do see what you mean, since it feels like those should unify fine
Leonardo de Moura (Feb 14 2022 at 19:10):
Created an issue on GitHub for this. We will try to fix it this week. https://github.com/leanprover/lean4/issues/1017
Leonardo de Moura (Feb 18 2022 at 18:43):
This issue has been fixed.
Last updated: Dec 20 2023 at 11:08 UTC