I've noticed that isabelle raises an exception given this function
function test :: "nat ⇒ nat" where
"test n = (if n = 0 then 0 else
let x = (λn. test n) in
test (x (n - 1)))"
I'm not sure whether it's worth reporting since the condition generated is going to be impossible to prove anyway see this which succeeds but can't be proved.
function test :: "nat ⇒ nat" where
"test n = (if n = 0 then 0 else
let x = (λn. test n) in
(x (n - 1)))"
The package also raises exceptions when you give bad fundef_cong rules but that's also kinda to be expected
This is surely worth reporting, especially because it can be broken to relatively simple functions, e.g.
fun f :: "nat ⇒ nat" where
"f 0 = 0" |
"f _ = (let x = f in f 0)"
Isn't f still unprovable due to how the let cong rule works
Not sure what you mean by that
Surely one can always remove the let e.g. via Let_const rule?
In any case, throwing a raw exception is not good
function test :: "nat ⇒ nat" where
"test n = (if n = 0 then 0 else
let x = test in
(x (0)))"
apply pat_completeness
by auto
termination test
apply(relation "measure id ")
apply auto (*the goal here is unprovable *)
lemma let_cong [fundef_cong]: "M = N ⟹ (⋀x. x = N ⟹ f x = g x) ⟹ Let M f = Let N g"
The issue here is that M = N is not restricted
And you can't restrict a cong rule this way
Maybe @Alexander Krauss knows how to make the fun package support this?
Fabian Huch said:
Surely one can always remove the let e.g. via
Let_construle?
If you inline by removing the let it's provable i think
But you can't inline unconditionally without having to fix back the induction rule
You can use an alternative congruence rule for let:
lemma let_cong_alt [fundef_cong]: "f x = g y ⟹ Let x f = Let y g" by auto
function test :: "nat ⇒ nat" where
"test n = (if n = 0 then 0 else
let x = test in x 0)"
by auto
termination by (relation "measure id ") auto
Do you know how to phrase the MAP cong rule for this?
function test :: "nat ⇒ nat" where
"test n = (if n = 0 then 0 else
hd (map (λf. f (n - 1)) [test]))"
lemma map_cong_single [fundef_cong]: "f x = g y ⟹ map f [x] = map g [y]"
by auto
irvin said:
And you can't restrict a cong rule this way
You can just ignore the variable, e.g. with "f = g ⟹ Let x (λ_. f) = Let y (λ_. g)". With that, the function package works of course, but raising a THM 0 instead of reporting that it could not find termination is not great IMO.
Last updated: Feb 06 2026 at 20:37 UTC