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.brecOnfails 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