author | wenzelm |
Mon, 01 Jul 2024 13:09:03 +0200 | |
changeset 80465 | 7fe5aa0ca3c4 |
parent 77569 | a8fa53c086a4 |
permissions | -rw-r--r-- |
72029 | 1 |
(* Title: HOL/Examples/Ackermann.thy |
2 |
Author: Larry Paulson |
|
3 |
*) |
|
4 |
||
71930 | 5 |
section \<open>A Tail-Recursive, Stack-Based Ackermann's Function\<close> |
6 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
7 |
theory Ackermann |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
8 |
imports "HOL-Library.Multiset_Order" "HOL-Library.Product_Lexorder" |
71930 | 9 |
begin |
10 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
11 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
12 |
This theory investigates a stack-based implementation of Ackermann's |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
13 |
function. Let's recall the traditional definition, as modified by Péter |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
14 |
Rózsa and Raphael Robinson. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
15 |
\<close> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
16 |
fun ack :: "[nat, nat] \<Rightarrow> nat" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
17 |
where |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
18 |
"ack 0 n = Suc n" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
19 |
| "ack (Suc m) 0 = ack m 1" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
20 |
| "ack (Suc m) (Suc n) = ack m (ack (Suc m) n)" |
71930 | 21 |
|
22 |
||
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
23 |
subsection \<open>Example of proving termination by reasoning about the domain\<close> |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
24 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
25 |
text \<open>The stack-based version uses lists.\<close> |
71930 | 26 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
27 |
function (domintros) ackloop :: "nat list \<Rightarrow> nat" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
28 |
where |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
29 |
"ackloop (n # 0 # l) = ackloop (Suc n # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
30 |
| "ackloop (0 # Suc m # l) = ackloop (1 # m # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
31 |
| "ackloop (Suc n # Suc m # l) = ackloop (n # Suc m # m # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
32 |
| "ackloop [m] = m" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
33 |
| "ackloop [] = 0" |
71930 | 34 |
by pat_completeness auto |
35 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
36 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
37 |
The key task is to prove termination. In the first recursive call, the head of |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
38 |
the list gets bigger while the list gets shorter, suggesting that the length |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
39 |
of the list should be the primary termination criterion. But in the third |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
40 |
recursive call, the list gets longer. The idea of trying a multiset-based |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
41 |
termination argument is frustrated by the second recursive call when \<open>m = 0\<close>: |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
42 |
the list elements are simply permuted. |
71930 | 43 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
44 |
Fortunately, the function definition package allows us to define a function |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
45 |
and only later identify its domain of termination. Instead, it makes all the |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
46 |
recursion equations conditional on satisfying the function's domain predicate. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
47 |
Here we shall eventually be able to show that the predicate is always |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
48 |
satisfied. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
49 |
\<close> |
71930 | 50 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
51 |
text \<open>@{thm [display] ackloop.domintros[no_vars]}\<close> |
71930 | 52 |
declare ackloop.domintros [simp] |
53 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
54 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
55 |
Termination is trivial if the length of the list is less then two. The |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
56 |
following lemma is the key to proving termination for longer lists. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
57 |
\<close> |
73531
c89922715bf5
Cosmetic: no !! in the lemma statement
paulson <lp15@cam.ac.uk>
parents:
72029
diff
changeset
|
58 |
lemma "ackloop_dom (ack m n # l) \<Longrightarrow> ackloop_dom (n # m # l)" |
c89922715bf5
Cosmetic: no !! in the lemma statement
paulson <lp15@cam.ac.uk>
parents:
72029
diff
changeset
|
59 |
proof (induction m arbitrary: n l) |
71930 | 60 |
case 0 |
61 |
then show ?case |
|
62 |
by auto |
|
63 |
next |
|
64 |
case (Suc m) |
|
73531
c89922715bf5
Cosmetic: no !! in the lemma statement
paulson <lp15@cam.ac.uk>
parents:
72029
diff
changeset
|
65 |
show ?case |
c89922715bf5
Cosmetic: no !! in the lemma statement
paulson <lp15@cam.ac.uk>
parents:
72029
diff
changeset
|
66 |
using Suc.prems |
c89922715bf5
Cosmetic: no !! in the lemma statement
paulson <lp15@cam.ac.uk>
parents:
72029
diff
changeset
|
67 |
by (induction n arbitrary: l) (simp_all add: Suc) |
71930 | 68 |
qed |
69 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
70 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
71 |
The proof above (which actually is unused) can be expressed concisely as |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
72 |
follows. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
73 |
\<close> |
71930 | 74 |
lemma ackloop_dom_longer: |
75 |
"ackloop_dom (ack m n # l) \<Longrightarrow> ackloop_dom (n # m # l)" |
|
76 |
by (induction m n arbitrary: l rule: ack.induct) auto |
|
77 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
78 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
79 |
This function codifies what @{term ackloop} is designed to do. Proving the |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
80 |
two functions equivalent also shows that @{term ackloop} can be used to |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
81 |
compute Ackermann's function. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
82 |
\<close> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
83 |
fun acklist :: "nat list \<Rightarrow> nat" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
84 |
where |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
85 |
"acklist (n#m#l) = acklist (ack m n # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
86 |
| "acklist [m] = m" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
87 |
| "acklist [] = 0" |
71930 | 88 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
89 |
text \<open>The induction rule for @{term acklist} is @{thm [display] acklist.induct[no_vars]}.\<close> |
71930 | 90 |
|
91 |
lemma ackloop_dom: "ackloop_dom l" |
|
92 |
by (induction l rule: acklist.induct) (auto simp: ackloop_dom_longer) |
|
93 |
||
94 |
termination ackloop |
|
95 |
by (simp add: ackloop_dom) |
|
96 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
97 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
98 |
This result is trivial even by inspection of the function definitions (which |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
99 |
faithfully follow the definition of Ackermann's function). All that we |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
100 |
needed was termination. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
101 |
\<close> |
71930 | 102 |
lemma ackloop_acklist: "ackloop l = acklist l" |
103 |
by (induction l rule: ackloop.induct) auto |
|
104 |
||
105 |
theorem ack: "ack m n = ackloop [n,m]" |
|
106 |
by (simp add: ackloop_acklist) |
|
107 |
||
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
108 |
|
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
109 |
subsection \<open>Example of proving termination using a multiset ordering\<close> |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
110 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
111 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
112 |
This termination proof uses the argument from |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
113 |
Nachum Dershowitz and Zohar Manna. Proving termination with multiset orderings. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
114 |
Communications of the ACM 22 (8) 1979, 465--476. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
115 |
\<close> |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
116 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
117 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
118 |
Setting up the termination proof. Note that Dershowitz had @{term z} as a |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
119 |
global variable. The top two stack elements are treated differently from the |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
120 |
rest. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
121 |
\<close> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
122 |
fun ack_mset :: "nat list \<Rightarrow> (nat\<times>nat) multiset" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
123 |
where |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
124 |
"ack_mset [] = {#}" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
125 |
| "ack_mset [x] = {#}" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
126 |
| "ack_mset (z#y#l) = mset ((y,z) # map (\<lambda>x. (Suc x, 0)) l)" |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
127 |
|
76304 | 128 |
lemma case1: "ack_mset (Suc n # l) < add_mset (0,n) {# (Suc x, 0). x \<in># mset l #}" |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
129 |
proof (cases l) |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
130 |
case (Cons m list) |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
131 |
have "{#(m, Suc n)#} < {#(Suc m, 0)#}" |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
132 |
by auto |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
133 |
also have "\<dots> \<le> {#(Suc m, 0), (0,n)#}" |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
134 |
by auto |
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
135 |
finally show ?thesis |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
136 |
by (simp add: Cons) |
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
137 |
next |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
138 |
case Nil |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
139 |
then show ?thesis by auto |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
140 |
qed |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
141 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
142 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
143 |
The stack-based version again. We need a fresh copy because we've already |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
144 |
proved the termination of @{term ackloop}. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
145 |
\<close> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
146 |
function Ackloop :: "nat list \<Rightarrow> nat" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
147 |
where |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
148 |
"Ackloop (n # 0 # l) = Ackloop (Suc n # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
149 |
| "Ackloop (0 # Suc m # l) = Ackloop (1 # m # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
150 |
| "Ackloop (Suc n # Suc m # l) = Ackloop (n # Suc m # m # l)" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
151 |
| "Ackloop [m] = m" |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
152 |
| "Ackloop [] = 0" |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
153 |
by pat_completeness auto |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
154 |
|
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
155 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
156 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
157 |
In each recursive call, the function @{term ack_mset} decreases according to |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
158 |
the multiset ordering. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
159 |
\<close> |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
160 |
termination |
76304 | 161 |
by (relation "inv_image {(x,y). x<y} ack_mset") (auto simp: wf case1) |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
162 |
|
80465
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
163 |
text \<open> |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
164 |
Another shortcut compared with before: equivalence follows directly from |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
165 |
this lemma. |
7fe5aa0ca3c4
tuned document layout, for more prominent presentation;
wenzelm
parents:
77569
diff
changeset
|
166 |
\<close> |
76302
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
167 |
lemma Ackloop_ack: "Ackloop (n # m # l) = Ackloop (ack m n # l)" |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
168 |
by (induction m n arbitrary: l rule: ack.induct) auto |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
169 |
|
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
170 |
theorem "ack m n = Ackloop [n,m]" |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
171 |
by (simp add: Ackloop_ack) |
8d2bf9ce5302
Added the multiset termination proof
paulson <lp15@cam.ac.uk>
parents:
75013
diff
changeset
|
172 |
|
71930 | 173 |
end |