86 findnth ("find'_nth") and |
86 findnth ("find'_nth") and |
87 recf.id ("id\<^raw:\makebox[0mm]{\,\,\,\,>\<^isup>_\<^raw:}>\<^isub>_") and |
87 recf.id ("id\<^raw:\makebox[0mm]{\,\,\,\,>\<^isup>_\<^raw:}>\<^isub>_") and |
88 Pr ("Pr\<^isup>_") and |
88 Pr ("Pr\<^isup>_") and |
89 Cn ("Cn\<^isup>_") and |
89 Cn ("Cn\<^isup>_") and |
90 Mn ("Mn\<^isup>_") and |
90 Mn ("Mn\<^isup>_") and |
91 rec_calc_rel ("eval") and |
91 rec_exec ("eval") and |
92 tm_of_rec ("translate") and |
92 tm_of_rec ("translate") and |
93 listsum ("\<Sigma>") |
93 listsum ("\<Sigma>") |
94 |
94 |
95 |
95 |
96 lemma inv_begin_print: |
96 lemma inv_begin_print: |
101 "s = 4 \<Longrightarrow> inv_begin n (s, tp) = inv_begin4 n tp" and |
101 "s = 4 \<Longrightarrow> inv_begin n (s, tp) = inv_begin4 n tp" and |
102 "s \<notin> {0,1,2,3,4} \<Longrightarrow> inv_begin n (s, l, r) = False" |
102 "s \<notin> {0,1,2,3,4} \<Longrightarrow> inv_begin n (s, l, r) = False" |
103 apply(case_tac [!] tp) |
103 apply(case_tac [!] tp) |
104 by (auto) |
104 by (auto) |
105 |
105 |
|
106 |
106 lemma inv1: |
107 lemma inv1: |
107 shows "0 < n \<Longrightarrow> inv_begin0 n \<mapsto> inv_loop1 n" |
108 shows "0 < (n::nat) \<Longrightarrow> Turing_Hoare.assert_imp (inv_begin0 n) (inv_loop1 n)" |
108 unfolding assert_imp_def |
109 unfolding Turing_Hoare.assert_imp_def |
109 unfolding inv_loop1.simps inv_begin0.simps |
110 unfolding inv_loop1.simps inv_begin0.simps |
110 apply(auto) |
111 apply(auto) |
111 apply(rule_tac x="1" in exI) |
112 apply(rule_tac x="1" in exI) |
112 apply(auto simp add: replicate.simps) |
113 apply(auto simp add: replicate.simps) |
113 done |
114 done |
870 \end{equation} |
871 \end{equation} |
871 |
872 |
872 \noindent |
873 \noindent |
873 whose three components are given in Figure~\ref{copy}. For our |
874 whose three components are given in Figure~\ref{copy}. For our |
874 correctness proofs, we introduce the notion of total correctness |
875 correctness proofs, we introduce the notion of total correctness |
875 defined in terms of \emph{Hoare-triples}, written @{term "{P} p |
876 defined in terms of \emph{Hoare-triples}, written @{term "{P} (p::tprog0) |
876 {Q}"}. They implement the idea that a program @{term |
877 {Q}"}. They implement the idea that a program @{term |
877 p} started in state @{term "1::nat"} with a tape satisfying @{term |
878 p} started in state @{term "1::nat"} with a tape satisfying @{term |
878 P} will after some @{text n} steps halt (have transitioned into the |
879 P} will after some @{text n} steps halt (have transitioned into the |
879 halting state) with a tape satisfying @{term Q}. This idea is very |
880 halting state) with a tape satisfying @{term Q}. This idea is very |
880 similar to the notion of \emph{realisability} in \cite{AspertiRicciotti12}. We |
881 similar to the notion of \emph{realisability} in \cite{AspertiRicciotti12}. We |
881 also have \emph{Hoare-pairs} of the form @{term "{P} p \<up>"} |
882 also have \emph{Hoare-pairs} of the form @{term "{P} (p::tprog0) \<up>"} |
882 implementing the case that a program @{term p} started with a tape |
883 implementing the case that a program @{term p} started with a tape |
883 satisfying @{term P} will loop (never transition into the halting |
884 satisfying @{term P} will loop (never transition into the halting |
884 state). Both notion are formally defined as |
885 state). Both notion are formally defined as |
885 |
886 |
886 \begin{center} |
887 \begin{center} |
1120 |
1121 |
1121 \noindent |
1122 \noindent |
1122 where we assume @{text "0 < n"} (similar reasoning is needed for |
1123 where we assume @{text "0 < n"} (similar reasoning is needed for |
1123 the Hoare-triples for @{term tcopy_loop} and @{term tcopy_end}). Since the invariant of |
1124 the Hoare-triples for @{term tcopy_loop} and @{term tcopy_end}). Since the invariant of |
1124 the halting state of @{term tcopy_begin} implies the invariant of |
1125 the halting state of @{term tcopy_begin} implies the invariant of |
1125 the starting state of @{term tcopy_loop}, that is @{term "inv_begin0 |
1126 the starting state of @{term tcopy_loop}, that is @{term "Turing_Hoare.assert_imp (inv_begin0 n) |
1126 n \<mapsto> inv_loop1 n"} holds, and also @{term "inv_loop0 n = inv_end1 |
1127 (inv_loop1 n)"} holds, and also @{term "inv_loop0 n = inv_end1 |
1127 n"}, we can derive the following Hoare-triple for the correctness |
1128 n"}, we can derive the following Hoare-triple for the correctness |
1128 of @{term tcopy}: |
1129 of @{term tcopy}: |
1129 |
1130 |
1130 \begin{center} |
1131 \begin{center} |
1131 @{thm tcopy_correct} |
1132 @{thm tcopy_correct} |
1404 @{term r} & @{text "::="} & @{term z} & (zero-function)\\ |
1405 @{term r} & @{text "::="} & @{term z} & (zero-function)\\ |
1405 & @{text "|"} & @{term s} & (successor-function)\\ |
1406 & @{text "|"} & @{term s} & (successor-function)\\ |
1406 & @{text "|"} & @{term "id n m"} & (projection)\\ |
1407 & @{text "|"} & @{term "id n m"} & (projection)\\ |
1407 \end{tabular} & |
1408 \end{tabular} & |
1408 \begin{tabular}{cl@ {\hspace{4mm}}l} |
1409 \begin{tabular}{cl@ {\hspace{4mm}}l} |
1409 @{text "|"} & @{term "Cn n r rs"} & (composition)\\ |
1410 @{text "|"} & @{term "Cn n f fs"} & (composition)\\ |
1410 @{text "|"} & @{term "Pr n r\<^isub>1 r\<^isub>2"} & (primitive recursion)\\ |
1411 @{text "|"} & @{term "Pr n f\<^isub>1 f\<^isub>2"} & (primitive recursion)\\ |
1411 @{text "|"} & @{term "Mn n r"} & (minimisation)\\ |
1412 @{text "|"} & @{term "Mn n f"} & (minimisation)\\ |
1412 \end{tabular} |
1413 \end{tabular} |
1413 \end{tabular} |
1414 \end{tabular} |
1414 \end{center} |
1415 \end{center} |
1415 |
1416 |
1416 \noindent |
1417 \noindent |
1417 where @{text n} indicates the function expects @{term n} arguments |
1418 where @{text n} indicates the function expects @{term n} arguments |
1418 (in \cite{Boolos87} both @{text z} and @{term s} expect one |
1419 (in \cite{Boolos87} both @{text z} and @{term s} expect one |
1419 argument), and @{text rs} stands for a list of recursive |
1420 argument), and @{text fs} stands for a list of recursive |
1420 functions. Since we know in each case the arity, say @{term l}, we |
1421 functions. Since we know in each case the arity, say @{term l}, we |
1421 can define an inductive evaluation relation that relates a recursive |
1422 can define an evaluation function, called @{term rec_exec}, that takes a recursive |
1422 function @{text r} and a list @{term ns} of natural numbers of |
1423 function @{text f} and a list @{term ns} of natural numbers of |
1423 length @{text l}, to what the result of the recursive function is, |
1424 length @{text l} as arguments. Since this evaluation function uses |
1424 say @{text n}. We omit the definition of @{term "rec_calc_rel r ns |
1425 the minimisation operator |
1425 n"}. Because of space reasons, we also omit the definition of |
1426 from HOL, this function might not terminate always. As a result we also |
|
1427 need to inductively characterise when @{term rec_exec} terminates. |
|
1428 We omit the definitions for |
|
1429 @{term "rec_exec f ns"} and @{term "terminate f ns"}. Because of |
|
1430 space reasons, we also omit the definition of |
1426 translating recursive functions into abacus programs. We can prove, |
1431 translating recursive functions into abacus programs. We can prove, |
1427 however, the following theorem about the translation: If @{thm (prem |
1432 however, the following theorem about the translation: If @{thm (prem |
1428 1) recursive_compile_to_tm_correct3[where recf="r" and args="ns" and |
1433 1) recursive_compile_to_tm_correct3[where recf="f" and args="ns"]} |
1429 r="n"]} holds for the recursive function @{text r}, then the |
1434 holds for the recursive function @{text f} and arguments @{term ns}, then the |
1430 following Hoare-triple holds |
1435 following Hoare-triple holds |
1431 |
1436 |
1432 \begin{center} |
1437 \begin{center} |
1433 @{thm (concl) recursive_compile_to_tm_correct3[where recf="r" and args="ns" and r="n"]} |
1438 @{thm (concl) recursive_compile_to_tm_correct3[where recf="f" and args="ns"]} |
1434 \end{center} |
1439 \end{center} |
1435 |
1440 |
1436 \noindent |
1441 \noindent |
1437 for the translated Turing machine @{term "translate r"}. This |
1442 for the Turing machine generated by @{term "translate f"}. This |
1438 means that if the recursive function @{text r} with arguments @{text ns} evaluates |
1443 means the translated Turing machine if started |
1439 to @{text n}, then the translated Turing machine if started |
|
1440 with the standard tape @{term "([Bk, Bk], <ns::nat list>)"} will terminate |
1444 with the standard tape @{term "([Bk, Bk], <ns::nat list>)"} will terminate |
1441 with the standard tape @{term "(Bk \<up> k, <n::nat> @ Bk \<up> l)"} for some @{text k} and @{text l}. |
1445 with the standard tape @{term "(Bk \<up> k, <(rec_exec f ns)::nat> @ Bk \<up> l)"} for some @{text k} and @{text l}. |
1442 |
1446 |
1443 Having recursive functions under our belt, we can construct a universal |
1447 Having recursive functions under our belt, we can construct a universal |
1444 function, written @{text UF}. This universal function acts like an interpreter for Turing machines. |
1448 function, written @{text UF}. This universal function acts like an interpreter for Turing machines. |
1445 It takes two arguments: one is the code of the Turing machine to be interpreted and the |
1449 It takes two arguments: one is the code of the Turing machine to be interpreted and the |
1446 other is the ``packed version'' of the arguments of the Turing machine. |
1450 other is the ``packed version'' of the arguments of the Turing machine. |
1558 |
1562 |
1559 \noindent |
1563 \noindent |
1560 If started with standard tape @{term "([], [Oc])"}, it halts with the |
1564 If started with standard tape @{term "([], [Oc])"}, it halts with the |
1561 non-standard tape @{term "([Oc], [])"} according to the definition in Chapter 3---so no |
1565 non-standard tape @{term "([Oc], [])"} according to the definition in Chapter 3---so no |
1562 result is calculated; but with the standard tape @{term "([], [Oc])"} according to the |
1566 result is calculated; but with the standard tape @{term "([], [Oc])"} according to the |
1563 definition in Chapter 8. We solve this inconsitency in our formalisation by |
1567 definition in Chapter 8. |
|
1568 We solve this inconsistency in our formalisation by |
1564 setting up our definitions so that the @{text counter_example} Turing machine does not |
1569 setting up our definitions so that the @{text counter_example} Turing machine does not |
1565 produce any result by looping forever fetching @{term Nop}s in state @{text 0}. |
1570 produce any result by looping forever fetching @{term Nop}s in state @{text 0}. |
1566 This solution is different from the definition in Chapter 3, but also |
1571 This solution implements essentially the definition in Chapter 3; it |
1567 different from the one in Chapter 8, where the instruction from state @{text 1} is |
1572 differs from the definition in Chapter 8, where perplexingly the instruction |
1568 fetched. |
1573 from state @{text 1} is fetched. |
1569 *} |
1574 *} |
1570 |
1575 |
1571 (* |
1576 (* |
1572 section {* XYZ *} |
1577 section {* XYZ *} |
1573 |
1578 |
1674 as we estimated when reading the paper by Norrish \cite{Norrish11}. The work |
1679 as we estimated when reading the paper by Norrish \cite{Norrish11}. The work |
1675 involved with constructing a universal Turing machine via recursive |
1680 involved with constructing a universal Turing machine via recursive |
1676 functions and abacus machines, we agree, is not a project |
1681 functions and abacus machines, we agree, is not a project |
1677 one wants to undertake too many times (our formalisation of abacus |
1682 one wants to undertake too many times (our formalisation of abacus |
1678 machines and their correct translation is approximately 4600 loc; |
1683 machines and their correct translation is approximately 4600 loc; |
1679 recursive functions 5000 loc and the universal Turing machine 10000 loc). |
1684 recursive functions 2800 loc and the universal Turing machine 10000 loc). |
1680 |
1685 |
1681 Our work is also very much inspired by the formalisation of Turing |
1686 Our work is also very much inspired by the formalisation of Turing |
1682 machines of Asperti and Ricciotti \cite{AspertiRicciotti12} in the |
1687 machines of Asperti and Ricciotti \cite{AspertiRicciotti12} in the |
1683 Matita theorem prover. It turns out that their notion of |
1688 Matita theorem prover. It turns out that their notion of |
1684 realisability and our Hoare-triples are very similar, however we |
1689 realisability and our Hoare-triples are very similar, however we |