doc-src/TutorialI/Fun/fun0.thy
changeset 25261 3dc292be0b54
parent 25260 71b2a1fefb84
child 25263 b54744935036
equal deleted inserted replaced
25260:71b2a1fefb84 25261:3dc292be0b54
    86 @{const Suc} in the case of @{typ nat} and @{const "op #"} in the case
    86 @{const Suc} in the case of @{typ nat} and @{const "op #"} in the case
    87 of lists. A recursive function is accepted if \isacommand{fun} can
    87 of lists. A recursive function is accepted if \isacommand{fun} can
    88 show that the size of one fixed argument becomes smaller with each
    88 show that the size of one fixed argument becomes smaller with each
    89 recursive call.
    89 recursive call.
    90 
    90 
    91 More generally, @{text fun} allows any \emph{lexicographic
    91 More generally, \isacommand{fun} allows any \emph{lexicographic
    92 combination} of size measures in case there are multiple
    92 combination} of size measures in case there are multiple
    93 arguments. For example the following version of \rmindex{Ackermann's
    93 arguments. For example, the following version of \rmindex{Ackermann's
    94 function} is accepted: *}
    94 function} is accepted: *}
    95 
    95 
    96 fun ack2 :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
    96 fun ack2 :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
    97   "ack2 n 0 = Suc n" |
    97   "ack2 n 0 = Suc n" |
    98   "ack2 0 (Suc m) = ack2 (Suc 0) m" |
    98   "ack2 0 (Suc m) = ack2 (Suc 0) m" |
   112 terminate because of automatic splitting of @{text "if"}.
   112 terminate because of automatic splitting of @{text "if"}.
   113 \index{*if expressions!splitting of}
   113 \index{*if expressions!splitting of}
   114 Let us look at an example:
   114 Let us look at an example:
   115 *}
   115 *}
   116 
   116 
   117 fun gcd :: "nat \<times> nat \<Rightarrow> nat" where
   117 fun gcd :: "nat \<Rightarrow> nat \<Rightarrow> nat" where
   118   "gcd(m,n) = (if n=0 then m else gcd(n, m mod n))"
   118   "gcd m n = (if n=0 then m else gcd n (m mod n))"
   119 
   119 
   120 text{*\noindent
   120 text{*\noindent
   121 The second argument decreases with each recursive call.
   121 The second argument decreases with each recursive call.
   122 The termination condition
   122 The termination condition
   123 @{prop[display]"n ~= (0::nat) ==> m mod n < n"}
   123 @{prop[display]"n ~= (0::nat) ==> m mod n < n"}
   128 languages and our simplifier don't do that. Unfortunately the simplifier does
   128 languages and our simplifier don't do that. Unfortunately the simplifier does
   129 something else that leads to the same problem: it splits 
   129 something else that leads to the same problem: it splits 
   130 each @{text "if"}-expression unless its
   130 each @{text "if"}-expression unless its
   131 condition simplifies to @{term True} or @{term False}.  For
   131 condition simplifies to @{term True} or @{term False}.  For
   132 example, simplification reduces
   132 example, simplification reduces
   133 @{prop[display]"gcd(m,n) = k"}
   133 @{prop[display]"gcd m n = k"}
   134 in one step to
   134 in one step to
   135 @{prop[display]"(if n=0 then m else gcd(n, m mod n)) = k"}
   135 @{prop[display]"(if n=0 then m else gcd n (m mod n)) = k"}
   136 where the condition cannot be reduced further, and splitting leads to
   136 where the condition cannot be reduced further, and splitting leads to
   137 @{prop[display]"(n=0 --> m=k) & (n ~= 0 --> gcd(n, m mod n)=k)"}
   137 @{prop[display]"(n=0 --> m=k) & (n ~= 0 --> gcd n (m mod n)=k)"}
   138 Since the recursive call @{term"gcd(n, m mod n)"} is no longer protected by
   138 Since the recursive call @{term"gcd n (m mod n)"} is no longer protected by
   139 an @{text "if"}, it is unfolded again, which leads to an infinite chain of
   139 an @{text "if"}, it is unfolded again, which leads to an infinite chain of
   140 simplification steps. Fortunately, this problem can be avoided in many
   140 simplification steps. Fortunately, this problem can be avoided in many
   141 different ways.
   141 different ways.
   142 
   142 
   143 The most radical solution is to disable the offending theorem
   143 The most radical solution is to disable the offending theorem
   174 A final alternative is to replace the offending simplification rules by
   174 A final alternative is to replace the offending simplification rules by
   175 derived conditional ones. For @{term gcd} it means we have to prove
   175 derived conditional ones. For @{term gcd} it means we have to prove
   176 these lemmas:
   176 these lemmas:
   177 *}
   177 *}
   178 
   178 
   179 lemma [simp]: "gcd(m,0) = m"
   179 lemma [simp]: "gcd m 0 = m"
   180 apply(simp)
   180 apply(simp)
   181 done
   181 done
   182 
   182 
   183 lemma [simp]: "n \<noteq> 0 \<Longrightarrow> gcd(m,n) = gcd(n, m mod n)"
   183 lemma [simp]: "n \<noteq> 0 \<Longrightarrow> gcd m n = gcd n (m mod n)"
   184 apply(simp)
   184 apply(simp)
   185 done
   185 done
   186 
   186 
   187 text{*\noindent
   187 text{*\noindent
   188 Simplification terminates for these proofs because the condition of the @{text
   188 Simplification terminates for these proofs because the condition of the @{text