Zulip Chat Archive
Stream: general
Topic: Combining induction with cases in Lean
Kristina Sojakova (Mar 13 2025 at 11:47):
Dear all,
I am a new user to Lean and want to prove a lemma of the following form:
lemma Stmt.repeatUntil_correct_left_to_right {S B s t} :
(repeatUntil S B, s) ⟹ t →
(S; whileDo (fun s => ¬ (B s)) S, s) ⟹ t :=
showing that the repeatUntil construct can be encoded in terms of whileDo without changing its big-step semantics. Is there a form of induction that allows me to combine "cases" with induction? I want to perform induction on the first argument "(repeatUntil S B, s) ⟹ t", but this does not work outright since the indices are not variables. On the other hand, the cases tactic does not give me an inductive hypothesis. If I try to use dependent pattern matching, Lean fails to infer termination.
I could of course employ the standard trick and generalize the goal to something like "x ⟹ t \to (repeatUntil S B, s) = x \to (S; whileDo (fun s => ¬ (B s)) S, s) ⟹ t" but surely there must be something better.
Thanks in advance,
Kristina
Aaron Liu (Mar 13 2025 at 11:54):
Can you post a #mwe?
Kristina Sojakova (Mar 13 2025 at 13:02):
I would like something along the following example to work:
def State : Type := String → Nat
inductive Prog : Type where
| seq : Prog → Prog → Prog
| whileDo : (State → Bool) → Prog → Prog
| repeatUntil : Prog → (State → Bool) → Prog
infixr:90 "; " => Prog.seq
inductive BigStep : Prog × State → State → Prop where
| seq (S T s t u) (hS : BigStep (S, s) t)
(hT : BigStep (T, t) u) :
BigStep (S; T, s) u
| while_true (B S s t u) (hcond : B s)
(hbody : BigStep (S, s) t)
(hrest : BigStep (Prog.whileDo B S, t) u) :
BigStep (Prog.whileDo B S, s) u
| while_false (B S s) (hcond : ¬ B s) :
BigStep (Prog.whileDo B S, s) s
| repeatUntil_true (S B s t) (hcond : B t)
(hbody : BigStep (S, s) t) :
BigStep (Prog.repeatUntil S B, s) t
| repeatUntil_false (B S s t u) (hcond : ¬ B t)
(hbody : BigStep (S, s) t)
(hrepeat : BigStep (Prog.repeatUntil S B, t) u) :
BigStep (Prog.repeatUntil S B, s) u
infix:110 " ⟹ " => BigStep
theorem Prog.repeatUntil_correct_left_to_right {S B s t} :
(Prog.repeatUntil S B, s) ⟹ t →
(S; whileDo (fun s => ¬ (B s)) S, s) ⟹ t :=
by intro h
cases h with
| repeatUntil_true B S s t hcond hbody =>
apply BigStep.seq (t := t)
{ exact hbody }
{ apply BigStep.while_false
sorry }
| repeatUntil_false S B s r t hcond hbody hrepeat =>
apply Prog.repeatUntil_correct_left_to_right at hrepeat
apply BigStep.seq (t := r)
{ exact hbody }
{ cases hrepeat with
| seq _ _ _ q _ hS hwhile =>
apply BigStep.while_true (t := q)
{ sorry }
{ sorry }
{ sorry } }
Aaron Liu (Mar 13 2025 at 13:02):
Can you use #backticks?
Kristina Sojakova (Mar 13 2025 at 13:08):
Done, sorry.
Aaron Liu (Mar 13 2025 at 13:14):
Can you post your code without  ?
Kristina Sojakova (Mar 13 2025 at 13:23):
Sorry I don't know how to do that ... I just pasted the code from VSCode
Ruben Van de Velde (Mar 13 2025 at 13:29):
Maybe with ctrl+shift+v
Damiano Testa (Mar 13 2025 at 13:29):
For me it opens fine in the online playground.
Kristina Sojakova (Mar 13 2025 at 13:31):
I'm also able to open it.
Kristina Sojakova (Mar 13 2025 at 13:40):
I installed a Non-breaking space visualizer extension but I cannot see any of those highlighted.
Aaron Liu (Mar 13 2025 at 14:46):
Unfortunately, BigStep.brecOn
fails to generate, so this is a bit tricky.
Kristina Sojakova (Mar 13 2025 at 14:50):
Aaron Liu said:
Unfortunately,
BigStep.brecOn
fails to generate, so this is a bit tricky.
Thanks for looking into this. Seems like this case should come up a lot though so I'm surprised it doesn't work.
Last updated: May 02 2025 at 03:31 UTC