Theory Last
theory Last
imports
HOLCF
LList
WorkerWrapper
begin
section‹Optimise ``last''.›
text‹Andy Gill's solution, mechanised. No fusion, works fine using their rule.›
subsection‹The @{term "last"} function.›
fixrec llast :: "'a llist → 'a"
where
"llast⋅(x :@ yys) = (case yys of lnil ⇒ x | y :@ ys ⇒ llast⋅yys)"
lemma llast_strict[simp]: "llast⋅⊥ = ⊥"
by fixrec_simp
fixrec llast_body :: "('a llist → 'a) → 'a llist → 'a"
where
"llast_body⋅f⋅(x :@ yys) = (case yys of lnil ⇒ x | y :@ ys ⇒ f⋅yys)"
lemma llast_llast_body: "llast = fix⋅llast_body"
by (rule cfun_eqI, subst llast_def, subst llast_body.unfold, simp)
definition wrap :: "('a → 'a llist → 'a) → ('a llist → 'a)" where
"wrap ≡ Λ f (x :@ xs). f⋅x⋅xs"
definition unwrap :: "('a llist → 'a) → ('a → 'a llist → 'a)" where
"unwrap ≡ Λ f x xs. f⋅(x :@ xs)"
lemma unwrap_strict[simp]: "unwrap⋅⊥ = ⊥"
unfolding unwrap_def by ((rule cfun_eqI)+, simp)
lemma wrap_unwrap_ID: "wrap oo unwrap oo llast_body = llast_body"
unfolding llast_body_def wrap_def unwrap_def
apply (rule cfun_eqI)+
apply (case_tac xa)
apply (simp_all add: fix_const)
done
definition llast_worker :: "('a → 'a llist → 'a) → 'a → 'a llist → 'a" where
"llast_worker ≡ Λ r x yys. case yys of lnil ⇒ x | y :@ ys ⇒ r⋅y⋅ys"
definition llast' :: "'a llist → 'a" where
"llast' ≡ wrap⋅(fix⋅llast_worker)"
lemma llast_worker_llast_body: "llast_worker = unwrap oo llast_body oo wrap"
unfolding llast_worker_def llast_body_def wrap_def unwrap_def
apply (rule cfun_eqI)+
apply (case_tac xb)
apply (simp_all add: fix_const)
done
lemma llast'_llast: "llast' = llast" (is "?lhs = ?rhs")
proof -
have "?rhs = fix⋅llast_body" by (simp only: llast_llast_body)
also have "… = wrap⋅(fix⋅(unwrap oo llast_body oo wrap))"
by (simp only: worker_wrapper_body[OF wrap_unwrap_ID])
also have "… = wrap⋅(fix⋅(llast_worker))"
by (simp only: llast_worker_llast_body)
also have "... = ?lhs" unfolding llast'_def by simp
finally show ?thesis by simp
qed
end