0

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?

Attila Karoly
  • 951
  • 5
  • 13

1 Answers1

2

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.

Nik Swamy
  • 281
  • 1
  • 2