section ‹CFG›
theory WCFG imports Com "../Basic/BasicDefs" begin
subsection‹CFG nodes›
datatype w_node = Node nat (‹'('_ _ '_')›)
| Entry (‹'('_Entry'_')›)
| Exit (‹'('_Exit'_')›)
fun label_incr :: "w_node → nat → w_node" (‹_ ⊕ _› 60)
where "(_ l _) ⊕ i = (_ l + i _)"
| "(_Entry_) ⊕ i = (_Entry_)"
| "(_Exit_) ⊕ i = (_Exit_)"
lemma Exit_label_incr [dest]: "(_Exit_) = n ⊕ i ==> n = (_Exit_)"
by(cases n,auto)
lemma label_incr_Exit [dest]: "n ⊕ i = (_Exit_) ==> n = (_Exit_)"
by(cases n,auto)
lemma Entry_label_incr [dest]: "(_Entry_) = n ⊕ i ==> n = (_Entry_)"
by(cases n,auto)
lemma label_incr_Entry [dest]: "n ⊕ i = (_Entry_) ==> n = (_Entry_)"
by(cases n,auto)
lemma label_incr_inj:
"n ⊕ c = n' ⊕ c ==> n = n'"
by(cases n)(cases n',auto)+
lemma label_incr_simp:"n ⊕ i = m ⊕ (i + j) ==> n = m ⊕ j"
by(cases n,auto,cases m,auto)
lemma label_incr_simp_rev:"m ⊕ (j + i) = n ⊕ i ==> m ⊕ j = n"
by(cases n,auto,cases m,auto)
lemma label_incr_start_Node_smaller:
"(_ l _) = n ⊕ i ==> n = (_(l - i)_)"
by(cases n,auto)
lemma label_incr_ge:"(_ l _) = n ⊕ i ==> l ≥ i"
by(cases n) auto
lemma label_incr_0 [dest]:
"[(_0_) = n ⊕ i; i > 0] ==> False"
by(cases n) auto
lemma label_incr_0_rev [dest]:
"[n ⊕ i = (_0_); i > 0] ==> False"
by(cases n) auto
subsection‹CFG edges›
type_synonym w_edge = "(w_node × state edge_kind × w_node)"
inductive While_CFG :: "cmd → w_node → state edge_kind → w_node → bool"
(‹_ ⊨ _ -_→ _›)
where
WCFG_Entry_Exit:
"prog ⊨ (_Entry_) -(λs. False)\<surd>→ (_Exit_)"
| WCFG_Entry:
"prog ⊨ (_Entry_) -(λs. True)\<surd>→ (_0_)"
| WCFG_Skip:
"Skip ⊨ (_0_) -⇑id→ (_Exit_)"
| WCFG_LAss:
"V:=e ⊨ (_0_) -⇑(λs. s(V:=(interpret e s)))→ (_1_)"
| WCFG_LAssSkip:
"V:=e ⊨ (_1_) -⇑id→ (_Exit_)"
| WCFG_SeqFirst:
"[c1 ⊨ n -et→ n'; n' ≠ (_Exit_)] ==> c1;;c2 ⊨ n -et→ n'"
| WCFG_SeqConnect:
"[c1 ⊨ n -et→ (_Exit_); n ≠ (_Entry_)] ==> c1;;c2 ⊨ n -et→ (_0_) ⊕ #:c1"
| WCFG_SeqSecond:
"[c2 ⊨ n -et→ n'; n ≠ (_Entry_)] ==> c1;;c2 ⊨ n ⊕ #:c1 -et→ n' ⊕ #:c1"
| WCFG_CondTrue:
"if (b) c1 else c2 ⊨ (_0_) -(λs. interpret b s = Some true)\<surd>→ (_0_) ⊕ 1"
| WCFG_CondFalse:
"if (b) c1 else c2 ⊨ (_0_) -(λs. interpret b s = Some false)\<surd>→ (_0_) ⊕ (#:c1 + 1)"
| WCFG_CondThen:
"[c1 ⊨ n -et→ n'; n ≠ (_Entry_)] ==> if (b) c1 else c2 ⊨ n ⊕ 1 -et→ n' ⊕ 1"
| WCFG_CondElse:
"[c2 ⊨ n -et→ n'; n ≠ (_Entry_)]
==> if (b) c1 else c2 ⊨ n ⊕ (#:c1 + 1) -et→ n' ⊕ (#:c1 + 1)"
| WCFG_WhileTrue:
"while (b) c' ⊨ (_0_) -(λs. interpret b s = Some true)\<surd>→ (_0_) ⊕ 2"
| WCFG_WhileFalse:
"while (b) c' ⊨ (_0_) -(λs. interpret b s = Some false)\<surd>→ (_1_)"
| WCFG_WhileFalseSkip:
"while (b) c' ⊨ (_1_) -⇑id→ (_Exit_)"
| WCFG_WhileBody:
"[c' ⊨ n -et→ n'; n ≠ (_Entry_); n' ≠ (_Exit_)]
==> while (b) c' ⊨ n ⊕ 2 -et→ n' ⊕ 2"
| WCFG_WhileBodyExit:
"[c' ⊨ n -et→ (_Exit_); n ≠ (_Entry_)] ==> while (b) c' ⊨ n ⊕ 2 -et→ (_0_)"
lemmas WCFG_intros = While_CFG.intros[split_format (complete)]
lemmas WCFG_elims = While_CFG.cases[split_format (complete)]
lemmas WCFG_induct = While_CFG.induct[split_format (complete)]
subsection ‹Some lemmas about the CFG›
lemma WCFG_Exit_no_sourcenode [dest]:
"prog ⊨ (_Exit_) -et→ n' ==> False"
by(induct prog n≡"(_Exit_)" et n' rule:WCFG_induct,auto)
lemma WCFG_Entry_no_targetnode [dest]:
"prog ⊨ n -et→ (_Entry_) ==> False"
by(induct prog n et n'≡"(_Entry_)" rule:WCFG_induct,auto)
lemma WCFG_sourcelabel_less_num_nodes:
"prog ⊨ (_ l _) -et→ n' ==> l < #:prog"
proof(induct prog "(_ l _)" et n' arbitrary:l rule:WCFG_induct)
case (WCFG_SeqFirst c1 et n' c2)
from ‹l < #:c1› show ?case by simp
next
case (WCFG_SeqConnect c1 et c2)
from ‹l < #:c1› show ?case by simp
next
case (WCFG_SeqSecond c2 n et n' c1)
note IH = ‹∧l. n = (_ l _) ==> l < #:c2›
from ‹n ⊕ #:c1 = (_ l _)› obtain l' where "n = (_ l' _)" by(cases n) auto
from IH[OF this] have "l' < #:c2" .
with ‹n ⊕ #:c1 = (_ l _)› ‹n = (_ l' _)› show ?case by simp
next
case (WCFG_CondThen c1 n et n' b c2)
note IH = ‹∧l. n = (_ l _) ==> l < #:c1›
from ‹n ⊕ 1 = (_ l _)› obtain l' where "n = (_ l' _)" by(cases n) auto
from IH[OF this] have "l' < #:c1" .
with ‹n ⊕ 1 = (_ l _)› ‹n = (_ l' _)› show ?case by simp
next
case (WCFG_CondElse c2 n et n' b c1)
note IH = ‹∧l. n = (_ l _) ==> l < #:c2›
from ‹n ⊕ (#:c1 + 1) = (_ l _)› obtain l' where "n = (_ l' _)" by(cases n) auto
from IH[OF this] have "l' < #:c2" .
with ‹n ⊕ (#:c1 + 1) = (_ l _)› ‹n = (_ l' _)› show ?case by simp
next
case (WCFG_WhileBody c' n et n' b)
note IH = ‹∧l. n = (_ l _) ==> l < #:c'›
from ‹n ⊕ 2 = (_ l _)› obtain l' where "n = (_ l' _)" by(cases n) auto
from IH[OF this] have "l' < #:c'" .
with ‹n ⊕ 2 = (_ l _)› ‹n = (_ l' _)› show ?case by simp
next
case (WCFG_WhileBodyExit c' n et b)
note IH = ‹∧l. n = (_ l _) ==> l < #:c'›
from ‹n ⊕ 2 = (_ l _)› obtain l' where "n = (_ l' _)" by(cases n) auto
from IH[OF this] have "l' < #:c'" .
with ‹n ⊕ 2 = (_ l _)› ‹n = (_ l' _)› show ?case by simp
qed (auto simp:num_inner_nodes_gr_0)
lemma WCFG_targetlabel_less_num_nodes:
"prog ⊨ n -et→ (_ l _) ==> l < #:prog"
proof(induct prog n et "(_ l _)" arbitrary:l rule:WCFG_induct)
case (WCFG_SeqFirst c1 n et c2)
from ‹l < #:c1› show ?case by simp
next
case (WCFG_SeqSecond c2 n et n' c1)
note IH = ‹∧l. n' = (_ l _) ==> l < #:c2›
from ‹n' ⊕ #:c1 = (_ l _)› obtain l' where "n' = (_ l' _)" by(cases n') auto
from IH[OF this] have "l' < #:c2" .
with ‹n' ⊕ #:c1 = (_ l _)› ‹n' = (_ l' _)› show ?case by simp
next
case (WCFG_CondThen c1 n et n' b c2)
note IH = ‹∧l. n' = (_ l _) ==> l < #:c1›
from ‹n' ⊕ 1 = (_ l _)› obtain l' where "n' = (_ l' _)" by(cases n') auto
from IH[OF this] have "l' < #:c1" .
with ‹n' ⊕ 1 = (_ l _)› ‹n' = (_ l' _)› show ?case by simp
next
case (WCFG_CondElse c2 n et n' b c1)
note IH = ‹∧l. n' = (_ l _) ==> l < #:c2›
from ‹n' ⊕ (#:c1 + 1) = (_ l _)› obtain l' where "n' = (_ l' _)" by(cases n') auto
from IH[OF this] have "l' < #:c2" .
with ‹n' ⊕ (#:c1 + 1) = (_ l _)› ‹n' = (_ l' _)› show ?case by simp
next
case (WCFG_WhileBody c' n et n' b)
note IH = ‹∧l. n' = (_ l _) ==> l < #:c'›
from ‹n' ⊕ 2 = (_ l _)› obtain l' where "n' = (_ l' _)" by(cases n') auto
from IH[OF this] have "l' < #:c'" .
with ‹n' ⊕ 2 = (_ l _)› ‹n' = (_ l' _)› show ?case by simp
qed (auto simp:num_inner_nodes_gr_0)
lemma WCFG_EntryD:
"prog ⊨ (_Entry_) -et→ n'
==> (n' = (_Exit_) ∧ et = (λs. False)\<surd>) ∨ (n' = (_0_) ∧ et = (λs. True)\<surd>)"
by(induct prog n≡"(_Entry_)" et n' rule:WCFG_induct,auto)
(*<*)declare One_nat_def [simp del] add_2_eq_Suc' [simp del](*>*)
lemma WCFG_edge_det:
"[prog ⊨ n -et→ n'; prog ⊨ n -et'→ n'] ==> et = et'"
proof(induct rule:WCFG_induct)
case WCFG_Entry_Exit thus ?case by(fastforce dest:WCFG_EntryD)
next
case WCFG_Entry thus ?case by(fastforce dest:WCFG_EntryD)
next
case WCFG_Skip thus ?case by(fastforce elim:WCFG_elims)
next
case WCFG_LAss thus ?case by(fastforce elim:WCFG_elims)
next
case WCFG_LAssSkip thus ?case by(fastforce elim:WCFG_elims)
next
case (WCFG_SeqFirst c1 n et n' c2)
note IH = ‹c1 ⊨ n -et'→ n' ==> et = et'›
from ‹c1 ⊨ n -et→ n'› ‹n' ≠ (_Exit_)› obtain l where "n' = (_ l _)"
by (cases n') auto
with ‹c1 ⊨ n -et→ n'› have "l < #:c1"
by(fastforce intro:WCFG_targetlabel_less_num_nodes)
with ‹c1;;c2 ⊨ n -et'→ n'› ‹n' = (_ l _)› have "c1 ⊨ n -et'→ n'"
by(fastforce elim:WCFG_elims intro:WCFG_intros dest:label_incr_ge)
from IH[OF this] show ?case .
next
case (WCFG_SeqConnect c1 n et c2)
note IH = ‹c1 ⊨ n -et'→ (_Exit_) ==> et = et'›
from ‹c1 ⊨ n -et→ (_Exit_)› ‹n ≠ (_Entry_)› obtain l where "n = (_ l _)"
by (cases n) auto
with ‹c1 ⊨ n -et→ (_Exit_)› have "l < #:c1"
by(fastforce intro:WCFG_sourcelabel_less_num_nodes)
with ‹c1;;c2 ⊨ n -et'→ (_ 0 _) ⊕ #:c1› ‹n = (_ l _)› have "c1 ⊨ n -et'→ (_Exit_)"
by(fastforce elim:WCFG_elims dest:WCFG_targetlabel_less_num_nodes label_incr_ge)
from IH[OF this] show ?case .
next
case (WCFG_SeqSecond c2 n et n' c1)
note IH = ‹c2 ⊨ n -et'→ n' ==> et = et'›
from ‹c2 ⊨ n -et→ n'› ‹n ≠ (_Entry_)› obtain l where "n = (_ l _)"
by (cases n) auto
with ‹c2 ⊨ n -et→ n'› have "l < #:c2"
by(fastforce intro:WCFG_sourcelabel_less_num_nodes)
with ‹c1;;c2 ⊨ n ⊕ #:c1 -et'→ n' ⊕ #:c1› ‹n = (_ l _)› have "c2 ⊨ n -et'→ n'"
by -(erule WCFG_elims,(fastforce dest:WCFG_sourcelabel_less_num_nodes label_incr_ge
dest!:label_incr_inj)+)
from IH[OF this] show ?case .
next
case WCFG_CondTrue thus ?case by(fastforce elim:WCFG_elims)
next
case WCFG_CondFalse thus ?case by(fastforce elim:WCFG_elims)
next
case (WCFG_CondThen c1 n et n' b c2)
note IH = ‹c1 ⊨ n -et'→ n' ==> et = et'›
from ‹c1 ⊨ n -et→ n'› ‹n ≠ (_Entry_)› obtain l where "n = (_ l _)"
by (cases n) auto
with ‹c1 ⊨ n -et→ n'› have "l < #:c1"
by(fastforce intro:WCFG_sourcelabel_less_num_nodes)
with ‹if (b) c1 else c2 ⊨ n ⊕ 1 -et'→ n' ⊕ 1› ‹n = (_ l _)›
have "c1 ⊨ n -et'→ n'"
by -(erule WCFG_elims,(fastforce dest:label_incr_ge label_incr_inj)+)
from IH[OF this] show ?case .
next
case (WCFG_CondElse c2 n et n' b c1)
note IH = ‹c2 ⊨ n -et'→ n' ==> et = et'›
from ‹c2 ⊨ n -et→ n'› ‹n ≠ (_Entry_)› obtain l where "n = (_ l _)"
by (cases n) auto
with ‹c2 ⊨ n -et→ n'› have "l < #:c2"
by(fastforce intro:WCFG_sourcelabel_less_num_nodes)
with ‹if (b) c1 else c2 ⊨ n ⊕ (#:c1 + 1) -et'→ n' ⊕ (#:c1 + 1)› ‹n = (_ l _)›
have "c2 ⊨ n -et'→ n'"
by -(erule WCFG_elims,(fastforce dest:WCFG_sourcelabel_less_num_nodes
label_incr_inj label_incr_ge label_incr_simp_rev)+)
from IH[OF this] show ?case .
next
case WCFG_WhileTrue thus ?case by(fastforce elim:WCFG_elims)
next
case WCFG_WhileFalse thus ?case by(fastforce elim:WCFG_elims)
next
case WCFG_WhileFalseSkip thus ?case by(fastforce elim:WCFG_elims)
next
case (WCFG_WhileBody c' n et n' b)
note IH = ‹c' ⊨ n -et'→ n' ==> et = et'›
from ‹c' ⊨ n -et→ n'› ‹n ≠ (_Entry_)› obtain l where "n = (_ l _)"
by (cases n) auto
moreover
with ‹c' ⊨ n -et→ n'› have "l < #:c'"
by(fastforce intro:WCFG_sourcelabel_less_num_nodes)
moreover
from ‹c' ⊨ n -et→ n'› ‹n' ≠ (_Exit_)› obtain l' where "n' = (_ l' _)"
by (cases n') auto
moreover
with ‹c' ⊨ n -et→ n'› have "l' < #:c'"
by(fastforce intro:WCFG_targetlabel_less_num_nodes)
ultimately have "c' ⊨ n -et'→ n'" using ‹while (b) c' ⊨ n ⊕ 2 -et'→ n' ⊕ 2›
by(fastforce elim:WCFG_elims dest:label_incr_start_Node_smaller)
from IH[OF this] show ?case .
next
case (WCFG_WhileBodyExit c' n et b)
note IH = ‹c' ⊨ n -et'→ (_Exit_) ==> et = et'›
from ‹c' ⊨ n -et→ (_Exit_)› ‹n ≠ (_Entry_)› obtain l where "n = (_ l _)"
by (cases n) auto
with ‹c' ⊨ n -et→ (_Exit_)› have "l < #:c'"
by(fastforce intro:WCFG_sourcelabel_less_num_nodes)
with ‹while (b) c' ⊨ n ⊕ 2 -et'→ (_0_)› ‹n = (_ l _)›
have "c' ⊨ n -et'→ (_Exit_)"
by -(erule WCFG_elims,auto dest:label_incr_start_Node_smaller)
from IH[OF this] show ?case .
qed
(*<*)declare One_nat_def [simp] add_2_eq_Suc' [simp](*>*)
lemma less_num_nodes_edge_Exit:
obtains l et where "l < #:prog" and "prog ⊨ (_ l _) -et→ (_Exit_)"
proof -
have "∃l et. l < #:prog ∧ prog ⊨ (_ l _) -et→ (_Exit_)"
proof(induct prog)
case Skip
have "0 < #:Skip" by simp
moreover have "Skip ⊨ (_0_) -⇑id→ (_Exit_)" by(rule WCFG_Skip)
ultimately show ?case by blast
next
case (LAss V e)
have "1 < #:(V:=e)" by simp
moreover have "V:=e ⊨ (_1_) -⇑id→ (_Exit_)" by(rule WCFG_LAssSkip)
ultimately show ?case by blast
next
case (Seq prog1 prog2)
from ‹∃l et. l < #:prog2 ∧ prog2 ⊨ (_ l _) -et→ (_Exit_)›
obtain l et where "l < #:prog2" and "prog2 ⊨ (_ l _) -et→ (_Exit_)"
by blast
from ‹prog2 ⊨ (_ l _) -et→ (_Exit_)›
have "prog1;;prog2 ⊨ (_ l _) ⊕ #:prog1 -et→ (_Exit_) ⊕ #:prog1"
by(fastforce intro:WCFG_SeqSecond)
with ‹l < #:prog2› show ?case by(rule_tac x="l + #:prog1" in exI,auto)
next
case (Cond b prog1 prog2)
from ‹∃l et. l < #:prog1 ∧ prog1 ⊨ (_ l _) -et→ (_Exit_)›
obtain l et where "l < #:prog1" and "prog1 ⊨ (_ l _) -et→ (_Exit_)"
by blast
from ‹prog1 ⊨ (_ l _) -et→ (_Exit_)›
have "if (b) prog1 else prog2 ⊨ (_ l _) ⊕ 1 -et→ (_Exit_) ⊕ 1"
by(fastforce intro:WCFG_CondThen)
with ‹l < #:prog1› show ?case by(rule_tac x="l + 1" in exI,auto)
next
case (While b prog')
have "1 < #:(while (b) prog')" by simp
moreover have "while (b) prog' ⊨ (_1_) -⇑id→ (_Exit_)"
by(rule WCFG_WhileFalseSkip)
ultimately show ?case by blast
qed
with that show ?thesis by blast
qed
lemma less_num_nodes_edge:
"l < #:prog ==> ∃n et. prog ⊨ n -et→ (_ l _) ∨ prog ⊨ (_ l _) -et→ n"
proof(induct prog arbitrary:l)
case Skip
from ‹l < #:Skip› have "l = 0" by simp
hence "Skip ⊨ (_ l _) -⇑id→ (_Exit_)" by(fastforce intro:WCFG_Skip)
thus ?case by blast
next
case (LAss V e)
from ‹l < #:V:=e› have "l = 0 ∨ l = 1" by auto
thus ?case
proof
assume "l = 0"
hence "V:=e ⊨ (_Entry_) -(λs. True)\<surd>→ (_ l _)" by(fastforce intro:WCFG_Entry)
thus ?thesis by blast
next
assume "l = 1"
hence "V:=e ⊨ (_ l _) -⇑id→ (_Exit_)" by(fastforce intro:WCFG_LAssSkip)
thus ?thesis by blast
qed
next
case (Seq prog1 prog2)
note IH1 = ‹∧l. l < #:prog1 ==>
∃n et. prog1 ⊨ n -et→ (_ l _) ∨ prog1 ⊨ (_ l _) -et→ n›
note IH2 = ‹∧l. l < #:prog2 ==>
∃n et. prog2 ⊨ n -et→ (_ l _) ∨ prog2 ⊨ (_ l _) -et→ n›
show ?case
proof(cases "l < #:prog1")
case True
from IH1[OF this] obtain n et
where "prog1 ⊨ n -et→ (_ l _) ∨ prog1 ⊨ (_ l _) -et→ n" by blast
thus ?thesis
proof
assume "prog1 ⊨ n -et→ (_ l _)"
hence "prog1;; prog2 ⊨ n -et→ (_ l _)" by(fastforce intro:WCFG_SeqFirst)
thus ?thesis by blast
next
assume edge:"prog1 ⊨ (_ l _) -et→ n"
show ?thesis
proof(cases "n = (_Exit_)")
case True
with edge have "prog1;; prog2 ⊨ (_ l _) -et→ (_0_) ⊕ #:prog1"
by(fastforce intro:WCFG_SeqConnect)
thus ?thesis by blast
next
case False
with edge have "prog1;; prog2 ⊨ (_ l _) -et→ n"
by(fastforce intro:WCFG_SeqFirst)
thus ?thesis by blast
qed
qed
next
case False
hence "#:prog1 ≤ l" by simp
then obtain l' where "l = l' + #:prog1" and "l' = l - #:prog1" by simp
from ‹l = l' + #:prog1› ‹l < #:prog1;; prog2› have "l' < #:prog2" by simp
from IH2[OF this] obtain n et
where "prog2 ⊨ n -et→ (_ l' _) ∨ prog2 ⊨ (_ l' _) -et→ n" by blast
thus ?thesis
proof
assume "prog2 ⊨ n -et→ (_ l' _)"
show ?thesis
proof(cases "n = (_Entry_)")
case True
with ‹prog2 ⊨ n -et→ (_ l' _)› have "l' = 0" by(auto dest:WCFG_EntryD)
obtain l'' et'' where "l'' < #:prog1"
and "prog1 ⊨ (_ l'' _) -et''→ (_Exit_)"
by(erule less_num_nodes_edge_Exit)
hence "prog1;;prog2 ⊨ (_ l'' _) -et''→ (_0_) ⊕ #:prog1"
by(fastforce intro:WCFG_SeqConnect)
with ‹l' = 0› ‹l = l' + #:prog1› show ?thesis by simp blast
next
case False
with ‹prog2 ⊨ n -et→ (_ l' _)›
have "prog1;;prog2 ⊨ n ⊕ #:prog1 -et→ (_ l' _) ⊕ #:prog1"
by(fastforce intro:WCFG_SeqSecond)
with ‹l = l' + #:prog1› show ?thesis by simp blast
qed
next
assume "prog2 ⊨ (_ l' _) -et→ n"
hence "prog1;;prog2 ⊨ (_ l' _) ⊕ #:prog1 -et→ n ⊕ #:prog1"
by(fastforce intro:WCFG_SeqSecond)
with ‹l = l' + #:prog1› show ?thesis by simp blast
qed
qed
next
case (Cond b prog1 prog2)
note IH1 = ‹∧l. l < #:prog1 ==>
∃n et. prog1 ⊨ n -et→ (_ l _) ∨ prog1 ⊨ (_ l _) -et→ n›
note IH2 = ‹∧l. l < #:prog2 ==>
∃n et. prog2 ⊨ n -et→ (_ l _) ∨ prog2 ⊨ (_ l _) -et→ n›
show ?case
proof(cases "l = 0")
case True
have "if (b) prog1 else prog2 ⊨ (_Entry_) -(λs. True)\<surd>→ (_0_)"
by(rule WCFG_Entry)
with True show ?thesis by simp blast
next
case False
hence "0 < l" by simp
then obtain l' where "l = l' + 1" and "l' = l - 1" by simp
thus ?thesis
proof(cases "l' < #:prog1")
case True
from IH1[OF this] obtain n et
where "prog1 ⊨ n -et→ (_ l' _) ∨ prog1 ⊨ (_ l' _) -et→ n" by blast
thus ?thesis
proof
assume edge:"prog1 ⊨ n -et→ (_ l' _)"
show ?thesis
proof(cases "n = (_Entry_)")
case True
with edge have "l' = 0" by(auto dest:WCFG_EntryD)
have "if (b) prog1 else prog2 ⊨ (_0_) -(λs. interpret b s = Some true)\<surd>→
(_0_) ⊕ 1"
by(rule WCFG_CondTrue)
with ‹l' = 0› ‹l = l' + 1› show ?thesis by simp blast
next
case False
with edge have "if (b) prog1 else prog2 ⊨ n ⊕ 1 -et→ (_ l' _) ⊕ 1"
by(fastforce intro:WCFG_CondThen)
with ‹l = l' + 1› show ?thesis by simp blast
qed
next
assume "prog1 ⊨ (_ l' _) -et→ n"
hence "if (b) prog1 else prog2 ⊨ (_ l' _) ⊕ 1 -et→ n ⊕ 1"
by(fastforce intro:WCFG_CondThen)
with ‹l = l' + 1› show ?thesis by simp blast
qed
next
case False
hence "#:prog1 ≤ l'" by simp
then obtain l'' where "l' = l'' + #:prog1" and "l'' = l' - #:prog1"
by simp
from ‹l' = l'' + #:prog1› ‹l = l' + 1› ‹l < #:(if (b) prog1 else prog2)›
have "l'' < #:prog2" by simp
from IH2[OF this] obtain n et
where "prog2 ⊨ n -et→ (_ l'' _) ∨ prog2 ⊨ (_ l'' _) -et→ n" by blast
thus ?thesis
proof
assume "prog2 ⊨ n -et→ (_ l'' _)"
show ?thesis
proof(cases "n = (_Entry_)")
case True
with ‹prog2 ⊨ n -et→ (_ l'' _)› have "l'' = 0" by(auto dest:WCFG_EntryD)
have "if (b) prog1 else prog2 ⊨ (_0_) -(λs. interpret b s = Some false)\<surd>→
(_0_) ⊕ (#:prog1 + 1)"
by(rule WCFG_CondFalse)
with ‹l'' = 0› ‹l' = l'' + #:prog1› ‹l = l' + 1› show ?thesis by simp blast
next
case False
with ‹prog2 ⊨ n -et→ (_ l'' _)›
have "if (b) prog1 else prog2 ⊨ n ⊕ (#:prog1 + 1) -et→
(_ l'' _) ⊕ (#:prog1 + 1)"
by(fastforce intro:WCFG_CondElse)
with ‹l = l' + 1› ‹l' = l'' + #:prog1› show ?thesis by simp blast
qed
next
assume "prog2 ⊨ (_ l'' _) -et→ n"
hence "if (b) prog1 else prog2 ⊨ (_ l'' _) ⊕ (#:prog1 + 1) -et→
n ⊕ (#:prog1 + 1)"
by(fastforce intro:WCFG_CondElse)
with ‹l = l' + 1› ‹l' = l'' + #:prog1› show ?thesis by simp blast
qed
qed
qed
next
case (While b prog')
note IH = ‹∧l. l < #:prog'
==> ∃n et. prog' ⊨ n -et→ (_ l _) ∨ prog' ⊨ (_ l _) -et→ n›
show ?case
proof(cases "l < 1")
case True
have "while (b) prog' ⊨ (_Entry_) -(λs. True)\<surd>→ (_0_)" by(rule WCFG_Entry)
with True show ?thesis by simp blast
next
case False
hence "1 ≤ l" by simp
thus ?thesis
proof(cases "l < 2")
case True
with ‹1 ≤ l› have "l = 1" by simp
have "while (b) prog' ⊨ (_0_) -(λs. interpret b s = Some false)\<surd>→ (_1_)"
by(rule WCFG_WhileFalse)
with ‹l = 1› show ?thesis by simp blast
next
case False
with ‹1 ≤ l› have "2 ≤ l" by simp
then obtain l' where "l = l' + 2" and "l' = l - 2"
by(simp del:add_2_eq_Suc')
from ‹l = l' + 2› ‹l < #:while (b) prog'› have "l' < #:prog'" by simp
from IH[OF this] obtain n et
where "prog' ⊨ n -et→ (_ l' _) ∨ prog' ⊨ (_ l' _) -et→ n" by blast
thus ?thesis
proof
assume "prog' ⊨ n -et→ (_ l' _)"
show ?thesis
proof(cases "n = (_Entry_)")
case True
with ‹prog' ⊨ n -et→ (_ l' _)› have "l' = 0" by(auto dest:WCFG_EntryD)
have "while (b) prog' ⊨ (_0_) -(λs. interpret b s = Some true)\<surd>→
(_0_) ⊕ 2"
by(rule WCFG_WhileTrue)
with ‹l' = 0› ‹l = l' + 2› show ?thesis by simp blast
next
case False
with ‹prog' ⊨ n -et→ (_ l' _)›
have "while (b) prog' ⊨ n ⊕ 2 -et→ (_ l' _) ⊕ 2"
by(fastforce intro:WCFG_WhileBody)
with ‹l = l' + 2› show ?thesis by simp blast
qed
next
assume "prog' ⊨ (_ l' _) -et→ n"
show ?thesis
proof(cases "n = (_Exit_)")
case True
with ‹prog' ⊨ (_ l' _) -et→ n›
have "while (b) prog' ⊨ (_ l' _) ⊕ 2 -et→ (_0_)"
by(fastforce intro:WCFG_WhileBodyExit)
with ‹l = l' + 2› show ?thesis by simp blast
next
case False
with ‹prog' ⊨ (_ l' _) -et→ n›
have "while (b) prog' ⊨ (_ l' _) ⊕ 2 -et→ n ⊕ 2"
by(fastforce intro:WCFG_WhileBody)
with ‹l = l' + 2› show ?thesis by simp blast
qed
qed
qed
qed
qed
(*<*)declare One_nat_def [simp del](*>*)
lemma WCFG_deterministic:
"[prog ⊨ n1 -et1→ n1'; prog ⊨ n2 -et2→ n2'; n1 = n2; n1' ≠ n2']
==> ∃Q Q'. et1 = (Q)\<surd> ∧ et2 = (Q')\<surd> ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))"
proof(induct arbitrary:n2 n2' rule:WCFG_induct)
case (WCFG_Entry_Exit prog)
from ‹prog ⊨ n2 -et2→ n2'› ‹(_Entry_) = n2› ‹(_Exit_) ≠ n2'›
have "et2 = (λs. True)\<surd>" by(fastforce dest:WCFG_EntryD)
thus ?case by simp
next
case (WCFG_Entry prog)
from ‹prog ⊨ n2 -et2→ n2'› ‹(_Entry_) = n2› ‹(_0_) ≠ n2'›
have "et2 = (λs. False)\<surd>" by(fastforce dest:WCFG_EntryD)
thus ?case by simp
next
case WCFG_Skip
from ‹Skip ⊨ n2 -et2→ n2'› ‹(_0_) = n2› ‹(_Exit_) ≠ n2'›
have False by(fastforce elim:WCFG.While_CFG.cases)
thus ?case by simp
next
case (WCFG_LAss V e)
from ‹V:=e ⊨ n2 -et2→ n2'› ‹(_0_) = n2› ‹(_1_) ≠ n2'›
have False by -(erule WCFG.While_CFG.cases,auto)
thus ?case by simp
next
case (WCFG_LAssSkip V e)
from ‹V:=e ⊨ n2 -et2→ n2'› ‹(_1_) = n2› ‹(_Exit_) ≠ n2'›
have False by -(erule WCFG.While_CFG.cases,auto)
thus ?case by simp
next
case (WCFG_SeqFirst c1 n et n' c2)
note IH = ‹∧n2 n2'. [c1 ⊨ n2 -et2→ n2'; n = n2; n' ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹c1;;c2 ⊨ n2 -et2→ n2'› ‹c1 ⊨ n -et→ n'› ‹n = n2› ‹n' ≠ n2'›
have "c1 ⊨ n2 -et2→ n2' ∨ (c1 ⊨ n2 -et2→ (_Exit_) ∧ n2' = (_0_) ⊕ #:c1)"
apply hypsubst_thin apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
by(case_tac n,auto dest:WCFG_sourcelabel_less_num_nodes)+
thus ?case
proof
assume "c1 ⊨ n2 -et2→ n2'"
from IH[OF this ‹n = n2› ‹n' ≠ n2'›] show ?case .
next
assume "c1 ⊨ n2 -et2→ (_Exit_) ∧ n2' = (_0_) ⊕ #:c1"
hence edge:"c1 ⊨ n2 -et2→ (_Exit_)" and n2':"n2' = (_0_) ⊕ #:c1" by simp_all
from IH[OF edge ‹n = n2› ‹n' ≠ (_Exit_)›] show ?case .
qed
next
case (WCFG_SeqConnect c1 n et c2)
note IH = ‹∧n2 n2'. [c1 ⊨ n2 -et2→ n2'; n = n2; (_Exit_) ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹c1;;c2 ⊨ n2 -et2→ n2'› ‹c1 ⊨ n -et→ (_Exit_)› ‹n = n2› ‹n ≠ (_Entry_)›
‹(_0_) ⊕ #:c1 ≠ n2'› have "c1 ⊨ n2 -et2→ n2' ∧ (_Exit_) ≠ n2'"
apply hypsubst_thin apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
by(case_tac n,auto dest:WCFG_sourcelabel_less_num_nodes)+
from IH[OF this[THEN conjunct1] ‹n = n2› this[THEN conjunct2]]
show ?case .
next
case (WCFG_SeqSecond c2 n et n' c1)
note IH = ‹∧n2 n2'. [c2 ⊨ n2 -et2→ n2'; n = n2; n' ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹c1;;c2 ⊨ n2 -et2→ n2'› ‹c2 ⊨ n -et→ n'› ‹n ⊕ #:c1 = n2›
‹n' ⊕ #:c1 ≠ n2'› ‹n ≠ (_Entry_)›
obtain nx where "c2 ⊨ n -et2→ nx ∧ nx ⊕ #:c1 = n2'"
apply - apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
apply(cases n,auto dest:WCFG_sourcelabel_less_num_nodes)
apply(cases n,auto dest:WCFG_sourcelabel_less_num_nodes)
by(fastforce dest:label_incr_inj)
with ‹n' ⊕ #:c1 ≠ n2'› have edge:"c2 ⊨ n -et2→ nx" and neq:"n' ≠ nx"
by auto
from IH[OF edge _ neq] show ?case by simp
next
case (WCFG_CondTrue b c1 c2)
from ‹if (b) c1 else c2 ⊨ n2 -et2→ n2'› ‹(_0_) = n2› ‹(_0_) ⊕ 1 ≠ n2'›
show ?case by -(erule WCFG.While_CFG.cases,auto)
next
case (WCFG_CondFalse b c1 c2)
from ‹if (b) c1 else c2 ⊨ n2 -et2→ n2'› ‹(_0_) = n2› ‹(_0_) ⊕ #:c1 + 1 ≠ n2'›
show ?case by -(erule WCFG.While_CFG.cases,auto)
next
case (WCFG_CondThen c1 n et n' b c2)
note IH = ‹∧n2 n2'. [c1 ⊨ n2 -et2→ n2'; n = n2; n' ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹if (b) c1 else c2 ⊨ n2 -et2→ n2'› ‹c1 ⊨ n -et→ n'› ‹n ≠ (_Entry_)›
‹n ⊕ 1 = n2› ‹n' ⊕ 1 ≠ n2'›
obtain nx where "c1 ⊨ n -et2→ nx ∧ n' ≠ nx"
apply - apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
apply(drule label_incr_inj) apply auto
apply(drule label_incr_simp_rev[OF sym])
by(case_tac na,auto dest:WCFG_sourcelabel_less_num_nodes)
from IH[OF this[THEN conjunct1] _ this[THEN conjunct2]] show ?case by simp
next
case (WCFG_CondElse c2 n et n' b c1)
note IH = ‹∧n2 n2'. [c2 ⊨ n2 -et2→ n2'; n = n2; n' ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹if (b) c1 else c2 ⊨ n2 -et2→ n2'› ‹c2 ⊨ n -et→ n'› ‹n ≠ (_Entry_)›
‹n ⊕ #:c1 + 1 = n2› ‹n' ⊕ #:c1 + 1 ≠ n2'›
obtain nx where "c2 ⊨ n -et2→ nx ∧ n' ≠ nx"
apply - apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
apply(drule label_incr_simp_rev)
apply(case_tac na,auto,cases n,auto dest:WCFG_sourcelabel_less_num_nodes)
by(fastforce dest:label_incr_inj)
from IH[OF this[THEN conjunct1] _ this[THEN conjunct2]] show ?case by simp
next
case (WCFG_WhileTrue b c')
from ‹while (b) c' ⊨ n2 -et2→ n2'› ‹(_0_) = n2› ‹(_0_) ⊕ 2 ≠ n2'›
show ?case by -(erule WCFG.While_CFG.cases,auto)
next
case (WCFG_WhileFalse b c')
from ‹while (b) c' ⊨ n2 -et2→ n2'› ‹(_0_) = n2› ‹(_1_) ≠ n2'›
show ?case by -(erule WCFG.While_CFG.cases,auto)
next
case (WCFG_WhileFalseSkip b c')
from ‹while (b) c' ⊨ n2 -et2→ n2'› ‹(_1_) = n2› ‹(_Exit_) ≠ n2'›
show ?case by -(erule WCFG.While_CFG.cases,auto dest:label_incr_ge)
next
case (WCFG_WhileBody c' n et n' b)
note IH = ‹∧n2 n2'. [c' ⊨ n2 -et2→ n2'; n = n2; n' ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹while (b) c' ⊨ n2 -et2→ n2'› ‹c' ⊨ n -et→ n'› ‹n ≠ (_Entry_)›
‹n' ≠ (_Exit_)› ‹n ⊕ 2 = n2› ‹n' ⊕ 2 ≠ n2'›
obtain nx where "c' ⊨ n -et2→ nx ∧ n' ≠ nx"
apply - apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
apply(fastforce dest:label_incr_ge[OF sym])
apply(fastforce dest:label_incr_inj)
by(fastforce dest:label_incr_inj)
from IH[OF this[THEN conjunct1] _ this[THEN conjunct2]] show ?case by simp
next
case (WCFG_WhileBodyExit c' n et b)
note IH = ‹∧n2 n2'. [c' ⊨ n2 -et2→ n2'; n = n2; (_Exit_) ≠ n2']
==> ∃Q Q'. et = (Q)\√ ∧ et2 = (Q')\√ ∧ (∀s. (Q s ⟶ ¬ Q' s) ∧ (Q' s ⟶ ¬ Q s))›
from ‹while (b) c' ⊨ n2 -et2→ n2'› ‹c' ⊨ n -et→ (_Exit_)› ‹n ≠ (_Entry_)›
‹n ⊕ 2 = n2› ‹(_0_) ≠ n2'›
obtain nx where "c' ⊨ n -et2→ nx ∧ (_Exit_) ≠ nx"
apply - apply(erule WCFG.While_CFG.cases)
apply(auto intro:WCFG.While_CFG.intros)
apply(fastforce dest:label_incr_ge[OF sym])
by(fastforce dest:label_incr_inj)
from IH[OF this[THEN conjunct1] _ this[THEN conjunct2]] show ?case by simp
qed
(*<*)declare One_nat_def [simp](*>*)
end
¤ Dauer der Verarbeitung: 0.31 Sekunden
¤
*© Formatika GbR, Deutschland