Zulip Chat Archive
Stream: lean4
Topic: ackermann
Ciprian Teodorov (Jan 11 2022 at 22:10):
Hi,
Is it possible to write the termination proof for ackermann in lean4. I think we should be able to use the lexicographic order, but I cannot find any documentation on how that might work.
def ackm : Nat × Nat → Nat
| (0, y) => y+1
| ((x+1), 0) => ackm (x, 1)
| ((x+1), (y+1)) => ackm (x, (ackm ((x+1), y)))
termination_by Prod.lex (Nat.lt_wfRel) (Nat.lt_wfRel)
decreasing_by exact (by {sorry})
cheers,
ciprian
Chris B (Jan 12 2022 at 01:11):
You can fulfill the base obligation like this:
def ackm : Nat × Nat → Nat
| (0, y) => y+1
| ((x+1), 0) => ackm (x, 1)
| ((x+1), (y+1)) => ackm (x, (ackm ((x+1), y)))
termination_by Prod.lex (Nat.lt_wfRel) (Nat.lt_wfRel)
decreasing_by
simp [Prod.lex, Prod.Lex]
exact Prod.Lex.left _ _ (Nat.lt.base _)
But it doesn't seem to like the presence of the outer call. If you change it to
def ackm : Nat × Nat → Nat
| (0, y) => y+1
| ((x+1), 0) => ackm (x, 1)
| ((x+1), (y+1)) =>
let inner := (ackm ((x+1), y))
ackm (x, inner)
Then it shows two goals, but it complains if you give either one saying it wants the other one. I'm not sure how you're supposed to discharge these.
David Renshaw (Jan 12 2022 at 03:29):
Here's another way to define it:
def iterate {α : Sort _} (op : α → α) : Nat → α → α
| 0, a => a
| Nat.succ k, a => iterate op k (op a)
def ackermann : Nat → Nat → Nat
| 0 => Nat.succ
| Nat.succ p => λ n => iterate (ackermann p) n (ackermann p 1)
David Renshaw (Jan 12 2022 at 03:29):
(from Bob Harper's _Practical Foundations for Programming Languages_ http://www.cs.cmu.edu/~rwh/pfpl/ )
David Renshaw (Jan 12 2022 at 03:30):
no extra termination proof needed with this formulation
Mario Carneiro (Jan 13 2022 at 02:08):
I believe this proof works, but I get unknown constant 'ackm'
on the definition and I'm not sure what to make of that.
def ackm : Nat × Nat → Nat
| (0, y) => y+1
| (x+1, 0) => ackm (x, 1)
| (x+1, y+1) => ackm (x, ackm (x+1, y))
termination_by Prod.lex Nat.lt_wfRel Nat.lt_wfRel
decreasing_by
first | apply Prod.Lex.right | apply Prod.Lex.left
apply Nat.lt.base
David Renshaw (Jan 13 2022 at 02:12):
Did y'all see this: https://github.com/leanprover/lean4/commit/068cc700d8540728558556bf6f86ff6988478d91 ?
Mario Carneiro (Jan 13 2022 at 02:13):
the syntax for termination_by
recently changed, this is for the old version
Leonardo de Moura (Jan 13 2022 at 18:22):
https://github.com/leanprover/lean4/blob/master/tests/lean/run/ack.lean
Last updated: Dec 20 2023 at 11:08 UTC