Theory While_Combinator_Exts
section ‹Code Generation›
subsection ‹While Combinator Extensions›
theory While_Combinator_Exts imports
"HOL-Library.While_Combinator"
begin
lemma while_option_None_invD:
assumes "while_option b c s = None" and "wf r"
and "I s" and "⋀s. ⟦ I s; b s ⟧ ⟹ I (c s)"
and "⋀s. ⟦ I s; b s ⟧ ⟹ (c s, s ) ∈ r"
shows "False"
using assms
by -(drule wf_rel_while_option_Some [of r I b c], auto)
lemma while_option_NoneD:
assumes "while_option b c s = None"
and "wf r" and "⋀s. b s ⟹ (c s, s) ∈ r"
shows "False"
using assms
by (blast intro: while_option_None_invD)
lemma while_option_sim:
assumes start: "R (Some s1) (Some s2)"
and cond: "⋀s1 s2. ⟦ R (Some s1) (Some s2); I s1 ⟧ ⟹ b1 s1 = b2 s2"
and step : "⋀s1 s2. ⟦ R (Some s1) (Some s2); I s1; b1 s1 ⟧ ⟹ R (Some (c1 s1)) (Some (c2 s2))"
and diverge: "R None None"
and inv_start: "I s1"
and inv_step: "⋀s1. ⟦ I s1; b1 s1 ⟧ ⟹ I (c1 s1)"
shows "R (while_option b1 c1 s1) (while_option b2 c2 s2)"
proof -
{ fix k
assume "∀k' < k. b1 ((c1 ^^ k') s1)"
with start cond step inv_start inv_step
have "b1 ((c1 ^^ k) s1) = b2 ((c2 ^^ k) s2)" and "I ((c1 ^^ k) s1)"
and "R (Some ((c1 ^^ k) s1)) (Some ((c2 ^^ k) s2))"
by (induction k) auto
}
moreover
{ fix k
assume "¬ b1 ((c1 ^^ k) s1)"
hence "∀k' < LEAST k. ¬ b1 ((c1 ^^ k) s1). b1 ((c1 ^^ k') s1)"
by (metis (lifting) not_less_Least)
}
moreover
{ fix k
assume "¬ b2 ((c2 ^^ k) s2)"
hence "∀k' < LEAST k. ¬ b2 ((c2 ^^ k) s2). b2 ((c2 ^^ k') s2)"
by (metis (lifting) not_less_Least)
}
moreover
{
assume "∃k. ¬ b1 ((c1 ^^ k) s1)"
and "∃k. ¬ b2 ((c2 ^^ k) s2)"
hence not_cond_Least: "¬ b1 ((c1 ^^ (LEAST k. ¬ b1 ((c1 ^^ k) s1))) s1)"
"¬ b2 ((c2 ^^ (LEAST k. ¬ b2 ((c2 ^^ k) s2))) s2)"
by -(drule LeastI_ex, assumption)+
{ fix k
assume "∀k' < k. b1 ((c1 ^^ k') s1)"
with calculation(1) dual_order.strict_trans
have "∀k' < k. b2 ((c2 ^^ k') s2)"
by blast
}
hence "(LEAST k'. ¬ b1 ((c1 ^^ k') s1)) = (LEAST k'. ¬ b2 ((c2 ^^ k') s2))"
by (metis (no_types, lifting) not_cond_Least calculation(1,4,5) less_linear)
with calculation(3,4)
have "R (Some ((c1 ^^ (LEAST k. ¬ b1 ((c1 ^^ k) s1))) s1))
(Some ((c2 ^^ (LEAST k. ¬ b2 ((c2 ^^ k) s2))) s2))"
by auto
}
ultimately show ?thesis using diverge
unfolding while_option_def
apply (split if_split)
apply (rule conjI)
apply (split if_split)
apply metis
apply (split if_split)
by (metis (lifting) LeastI_ex)
qed
end