header {* Mixed Recursion-Corecursion *}
theory Mixed
imports Stream_Examples GCD
begin
function primes⇩r⇩e⇩c :: "(nat * nat) => (stream + nat * nat) ΣΣ0 F ΣΣ0" where
"primes⇩r⇩e⇩c (m, n) =
(if (m = 0 ∧ n > 1) ∨ coprime m n then GUARD0 (n, CONT0 (m * n, Suc n))
else (primes⇩r⇩e⇩c (m, Suc n)))"
by pat_completeness auto
termination
apply (relation "measure (λ(m, n).
if n = 0 then 1 else if coprime m n then 0 else m - n mod m)")
apply (auto simp: mod_Suc intro: Suc_lessI)
apply (metis One_nat_def coprime_Suc_nat gcd_nat.commute gcd_red_nat)
apply (metis diff_less_mono2 lessI mod_less_divisor)
done
definition primes :: "nat => nat => stream" where
"primes = curry (corecUU0 primes⇩r⇩e⇩c)"
lemma primes_code:
"primes m n =
(if (m = 0 ∧ n > 1) ∨ coprime m n then SCons n (primes (m * n) (Suc n))
else primes m (Suc n))"
unfolding primes_def curry_def
by (subst corecUU0, subst primes⇩r⇩e⇩c.simps)
(simp del: primes⇩r⇩e⇩c.simps add: map_pre_J_def BNF_Comp.id_bnf_comp_def eval0_leaf0' corecUU0)
lemma primes: "primes 1 2 = SCons 2 (primes 2 3)"
by (subst primes_code) auto
fun catalan⇩r⇩e⇩c :: "nat => (stream + nat) ΣΣ1 F ΣΣ1" where
"catalan⇩r⇩e⇩c n =
(if n > 0 then PLS1 (catalan⇩r⇩e⇩c (n - 1), GUARD1 (0, CONT1 (n+1))) else GUARD1 (1, CONT1 1))"
definition catalan :: "nat => stream" where
"catalan = corecUU1 catalan⇩r⇩e⇩c"
lemma catalan_code:
"catalan n =
(if n > 0 then pls (catalan (n - 1)) (SCons 0 (catalan (n + 1)))
else SCons 1 (catalan 1))"
unfolding catalan_def
by (subst corecUU1, subst catalan⇩r⇩e⇩c.simps)
(simp del: catalan⇩r⇩e⇩c.simps add: map_pre_J_def BNF_Comp.id_bnf_comp_def
eval1_\<oo>\<pp>1 eval1_leaf1' algΛ1_Inr o_eq_dest[OF Abs_Σ1_natural] corecUU1 pls_uniform)
end