Zulip Chat Archive

Stream: lean4

Topic: assert! in recursive functions


Joachim Breitner (Oct 17 2024 at 20:34):

TIL that assert!, when used in a recursive function, can help lean find a termination argument, e.g. in

def allSplits (s : Nat) (P : Nat  Nat  Bool) : Bool :=
  (List.range (s+1)).all fun s' => P s' (s-s')

def allPartitions (s: Nat) (P : List Nat  Bool) :=
  match s with
  | 0 =>
    P []
  | s+1 =>
    allSplits s fun s1 s2 =>
      assert! s1 + s2 = s
      allPartitions s1 fun xs =>
        allPartitions s2 fun ys =>
          P (xs ++ ys)

This makes sense when one thinks about it (and may actually be genuinely useful and still allow verification later), but I did not expect it.

Joachim Breitner (Oct 17 2024 at 22:01):

This can sometimes probably even work as a more convenient alternative to adding subtypes to the result just for termination checking (for non-empty result types, else you can't assert! easily), that defers discharging these conditions until after the function is defined.

François G. Dorais (Oct 18 2024 at 03:30):

How about a realize_assertions tactic to make the behavior explicit and extendible?

Joachim Breitner (Oct 18 2024 at 06:49):

Sorry, I don't quite follow, can you elaborate?

Mario Carneiro (Oct 18 2024 at 20:27):

it would be great if there was a assert! h : cond form


Last updated: May 02 2025 at 03:31 UTC