Search code examples
fstar

FStar function strange behavior


It seems incorrect that the following simple function is accepted as a terminating one:

val fnc : (nw: nat) -> (ni: nat) -> (ni_max: nat) -> bool
let rec fnc nw ni ni_max =
  match ni with 
  | ni_max -> false
  | _      -> fnc nw (nw + ni) ni_max

Surprisingly, the function does terminate upon evaluating it, for instance, by fnc 0 0 1 and returns false. What am I missing out?


Solution

  • The ni_max in the first branch of the pattern is a fresh binder and has no relation to the parameter ni_max of the function. Your code is equivalent to:

    let rec fnc nw ni ni_max =
      match ni with 
      | _ -> false
      | _      -> fnc nw (nw + ni) ni_max
    

    which is a function that always returns false.

    You probably intended to write

    let rec fnc nw ni ni_max =
      if ni = ni_max then false
      else fnc nw (nw + ni) ni_max
    

    and now the termination checker should complain.