Theory SD_Unwinding
section ‹Secret-Directed Unwinding›
text ‹ This theory formalizes the secret-directed unwinding disproof method
for relative security. ›
theory SD_Unwinding
imports Relative_Security.Relative_Security
begin
context Rel_Sec
begin
fun lvalidEtransO where "lvalidEtransO (s,secl) (s',secl') ⟷
validTransV (s,s') ∧
(¬ isSecV s ∧ secl = secl' ∨
isSecV s ∧ secl = LCons (getSecV s) secl')"
definition "lmove1 Γ sv1 secl1 sv2 secl2 ≡
∀ sv1' secl1'. lvalidEtransO (sv1,secl1) (sv1',secl1') ⟶ Γ sv1' secl1' sv2 secl2"
definition "lmove2 Γ sv1 secl1 sv2 secl2 ≡
∀ sv2' secl2'. lvalidEtransO (sv2,secl2) (sv2',secl2') ⟶ Γ sv1 secl1 sv2' secl2'"
definition "lmove12 Γ sv1 secl1 sv2 secl2 ≡
∀ sv1' secl1' sv2' secl2'.
lvalidEtransO (sv1,secl1) (sv1',secl1') ∧ lvalidEtransO (sv2,secl2) (sv2',secl2')
⟶ Γ sv1' secl1' sv2' secl2'"
definition lunwindSDCond ::
"('stateV ⇒ 'secret llist ⇒ 'stateV ⇒ 'secret llist ⇒ bool) ⇒ bool"
where
"lunwindSDCond Γ ≡ ∀sv1 secl1 sv2 secl2.
reachV sv1 ∧ reachV sv2 ∧
Γ sv1 secl1 sv2 secl2
⟶
(isIntV sv1 ⟷ isIntV sv2) ∧
(¬ isIntV sv1 ⟶ lmove1 Γ sv1 secl1 sv2 secl2 ∧ lmove2 Γ sv1 secl1 sv2 secl2) ∧
(isIntV sv1 ∧ getActV sv1 = getActV sv2 ⟶ getObsV sv1 = getObsV sv2 ∧
lmove12 Γ sv1 secl1 sv2 secl2)"
lemma lunwindSDCond_imp:
assumes "lunwindSDCond Γ" "reachV sv1" "reachV sv2" "Γ sv1 secl1 sv2 secl2"
shows
"(isIntV sv1 ⟷ isIntV sv2) ∧
(¬ isIntV sv1 ⟶ lmove1 Γ sv1 secl1 sv2 secl2 ∧ lmove2 Γ sv1 secl1 sv2 secl2) ∧
(isIntV sv1 ∧ getActV sv1 = getActV sv2 ⟶ getObsV sv1 = getObsV sv2 ∧
lmove12 Γ sv1 secl1 sv2 secl2)"
using assms unfolding lunwindSDCond_def by auto
lemma lunwindSDCond_lmove12:
assumes unw: "lunwindSDCond Γ" and gam: "reachV sv1" "reachV sv2" "Γ sv1 secl1 sv2 secl2"
and i: "isIntV sv1 ⟶ getActV sv1 = getActV sv2"
shows "lmove12 Γ sv1 secl1 sv2 secl2"
proof(cases "isIntV sv1")
case True
then show ?thesis using unw gam i unfolding lunwindSDCond_def by blast
next
case False
then show ?thesis using unw gam unfolding lunwindSDCond_def
by (smt (verit) Van.reach.Step fst_conv lmove12_def lmove1_def lmove2_def
lvalidEtransO.simps snd_conv)
qed
proposition unwindSDCond_aux_inductive:
assumes unw: "lunwindSDCond Γ"
and 1: "Γ sv1 secl1 sv2 secl2"
"reachV sv1" "Van.validFromS sv1 (trv1 @ [ssv1])" "never isIntV trv1" and 11: "isIntV ssv1" and
2: "reachV sv2" "Van.validFromS sv2 (trv2 @ [ssv2])" "never isIntV trv2" and 22: "isIntV ssv2" and
3: "lappend (llist_of (Van.S trv1)) ssecl1 = secl1" "lappend (llist_of (Van.S trv2)) ssecl2 = secl2"
shows "Γ (lastt sv1 trv1) ssecl1 (lastt sv2 trv2) ssecl2"
using 1 2 3 proof(induct "length trv1 + length trv2" arbitrary: sv1 sv2 trv1 trv2 secl1 secl2 rule: nat_less_induct)
case (1 trv1 trv2 sv1 sv2 secl1 secl2)
show ?case
proof(cases "isIntV sv1")
case True hence sv2: "isIntV sv2" using 1(2-) unw unfolding lunwindSDCond_def by auto
note isv12 = True this
have trv1: "trv1 = []" using True 1(4,5) unfolding list_all_nth apply(cases trv1, auto)
by (metis Van.validFromS_Cons_iff nth_Cons_0 zero_less_Suc)
have trv2: "trv2 = []" using sv2 1(7,8) unfolding list_all_nth apply(cases trv2, auto)
by (metis Van.validFromS_Cons_iff nth_Cons_0 zero_less_Suc)
show ?thesis using 1(2-) by (simp add: trv1 trv2 Van.S_def)
next
case False hence "¬ isIntV sv2" using 1(2-) unw unfolding lunwindSDCond_def by auto
note isv12 = False this
have trv1ne: "trv1 ≠ []" using isv12 "1.prems"(3) "11" by force
then obtain sv1' trv1' where trv1: "trv1 = sv1 # trv1'" "validTransV (sv1,sv1')"
"Van.validFromS sv1' trv1'" "never isIntV trv1'"
using `Van.validFromS sv1 (trv1 @ [ssv1])` `never isIntV trv1`
by (metis Simple_Transition_System.validFromS_Cons_iff Simple_Transition_System.validFromS_def
Simple_Transition_System.validS_append1
Simple_Transition_System.validS_validTrans hd_append2 list_all_simps(1) neq_Nil_conv snoc_eq_iff_butlast)
have trv2ne: "trv2 ≠ []" using isv12 "1.prems"(6) "22" by force
then obtain sv2' trv2' where trv2: "trv2 = sv2 # trv2'" "validTransV (sv2,sv2')"
"Van.validFromS sv2' trv2'" "never isIntV trv2'"
using `Van.validFromS sv2 (trv2 @ [ssv2])` `never isIntV trv2`
by (metis Simple_Transition_System.validFromS_Cons_iff Simple_Transition_System.validFromS_def
Simple_Transition_System.validS_append1
Simple_Transition_System.validS_validTrans hd_append2 list_all_simps(1) neq_Nil_conv snoc_eq_iff_butlast)
show ?thesis
proof(cases "length trv1 = Suc 0 ∧ length trv2 = Suc 0")
case True
hence trv12: "trv1 = [sv1] ∧ trv2 = [sv2]" apply(intro conjI)
subgoal using 1(4) Van.validFromS_Cons_iff by (cases trv1, auto)
subgoal using 1(7) Van.validFromS_Cons_iff by (cases trv2, auto) .
show ?thesis using 1(2) "1.prems"(8,9) trv12 unfolding lastt_def
using Van.S.FiltermapBL FiltermapBL.simps(4) by fastforce
next
case False note f = False
show ?thesis
proof(cases "length trv1 = Suc 0")
case True
hence "length trv2 > Suc 0" using f trv2ne by (simp add: Suc_lessI)
hence trv2'ne: "trv2' ≠ []" by (simp add: trv2(1))
define secl2' where "secl2' ≡ if isSecV sv2 then ltl secl2 else secl2"
have v2: "lvalidEtransO (sv2,secl2) (sv2',secl2')"
using trv2 unfolding lvalidEtransO.simps secl2'_def
using "1.prems"(9) trv2'ne Van.S.FiltermapBL FiltermapBL.simps(3) by fastforce
have sl2': "secl2' = lappend (llist_of (Van.S trv2')) ssecl2"
using "1.prems"(9) trv2(1) v2 by (auto simp: trv2'ne)
have r2': "reachV sv2'"
by (metis "1.prems"(5) Van.reach.Step fst_conv snd_conv trv2(2))
have gam: "Γ sv1 secl1 sv2' secl2'"
using `Γ sv1 secl1 sv2 secl2` v2 unw r2' isv12 unfolding lunwindSDCond_def lmove2_def
using 1(2-) by blast
have gam': "Γ (lastt sv1 trv1) ssecl1 (lastt sv2' trv2') ssecl2"
apply(rule 1(1)[rule_format, OF _ _ gam])
using trv2 gam sl2' `reachV sv1` `reachV sv2` r2'
using "1.prems"(3,4,6,8)
by auto (metis Van.validFromS_Cons_iff Van.validFromS_def hd_append trv2'ne)
show ?thesis unfolding trv2 using gam' trv2'ne unfolding lastt_def by auto
next
case False
hence "length trv1 > Suc 0" using f trv1ne by (simp add: Suc_lessI)
hence trv1'ne: "trv1' ≠ []" by (simp add: trv1(1))
define secl1' where "secl1' ≡ if isSecV sv1 then ltl secl1 else secl1"
have v1: "lvalidEtransO (sv1,secl1) (sv1',secl1')"
using trv1 unfolding lvalidEtransO.simps secl1'_def
using "1.prems"(8) trv1'ne Van.S.FiltermapBL FiltermapBL.Cons_unfold by fastforce
have sl1': "secl1' = lappend (llist_of (Van.S trv1')) ssecl1"
using "1.prems"(8) trv1(1) v1 by (auto simp: trv1'ne)
have r1': "reachV sv1'"
by (metis "1.prems"(2) Van.reach.Step fst_conv snd_conv trv1(2))
have gam: "Γ sv1' secl1' sv2 secl2"
using `Γ sv1 secl1 sv2 secl2` v1 unw r1' isv12 unfolding lunwindSDCond_def lmove1_def
using 1(2-) by blast
have gam': "Γ (lastt sv1' trv1') ssecl1 (lastt sv2 trv2) ssecl2"
apply(rule 1(1)[rule_format, OF _ _ gam])
using trv1 gam sl1' `reachV sv2` `reachV sv1` r1'
using "1.prems"
by auto (metis Van.validFromS_Cons_iff Van.validFromS_def hd_append trv1'ne)
show ?thesis unfolding trv1 using gam' trv1'ne unfolding lastt_def by auto
qed
qed
qed
qed
proposition unwindSDCond_inductive:
assumes unw: "lunwindSDCond Γ"
and gam: "Γ sv1 secl1 sv2 secl2" and
trv1: "reachV sv1" "Van.validFromS sv1 (trv1 @ [ssv1])" "never isIntV trv1" "isIntV ssv1" and
trv2: "reachV sv2" "Van.validFromS sv2 (trv2 @ [ssv2])" "never isIntV trv2" "isIntV ssv2" and
s: "lappend (llist_of (map getSecV (filter isSecV trv1))) ssecl1 = secl1"
"lappend (llist_of (map getSecV (filter isSecV trv2))) ssecl2 = secl2"
shows "(getActV ssv1 = getActV ssv2 ⟶ Γ ssv1 ssecl1 ssv2 ssecl2) ∧
(getActV ssv1 = getActV ssv2 ⟶ getObsV ssv1 = getObsV ssv2)"
proof-
define ssecl1' where "ssecl1' = (if trv1 = [] ∨ (trv1 ≠ [] ∧ ¬ isSecV (last trv1)) then ssecl1 else (getSecV (last trv1)) $ ssecl1)"
define ssecl2' where "ssecl2' = (if trv2 = [] ∨ (trv2 ≠ [] ∧ ¬ isSecV (last trv2)) then ssecl2 else (getSecV (last trv2)) $ ssecl2)"
have s': "lappend (llist_of (Van.S trv1)) ssecl1' = secl1"
"lappend (llist_of (Van.S trv2)) ssecl2' = secl2"
subgoal unfolding ssecl1'_def s[symmetric] Van.S.map_filter
by simp (metis List_Filtermap.filtermap_def filtermap_butlast holds_filtermap_RCons lappend_llist_of_LCons snoc_eq_iff_butlast)
subgoal unfolding ssecl2'_def s[symmetric] Van.S.map_filter
by simp (metis List_Filtermap.filtermap_def append_butlast_last_id filtermap_butlast holds_filtermap_RCons lappend_llist_of_LCons) .
have gg: "Γ (lastt sv1 trv1) ssecl1' (lastt sv2 trv2) ssecl2'"
using unwindSDCond_aux_inductive[OF unw gam trv1 trv2 s'] .
have rsv1: "reachV (lastt sv1 trv1)"
by (metis Van.reach_validFromS_reach Van.validFromS_def Van.validS_append1
append_is_Nil_conv assms(3) assms(4) hd_append lastt_def)
have rsv2: "reachV (lastt sv2 trv2)"
by (metis Van.lvalidFromS_lappend_finite Van.lvalidFromS_llist_of_validFromS
Van.reach_validFromS_reach assms(7) assms(8) lappend_llist_of_llist_of lastt_def)
have "trv1 = [] ⟷ trv2 = []" using trv1(2-4) trv2(2-4) unfolding list_all_nth
apply safe
subgoal by simp (smt (verit) Simple_Transition_System.validFromS_def assms(3) assms(7) gam
hd_append hd_conv_nth length_greater_0_conv lunwindSDCond_def snoc_eq_iff_butlast unw)
subgoal by simp (smt (verit) Simple_Transition_System.validFromS_def assms(3) assms(7) gam
hd_append hd_conv_nth length_greater_0_conv lunwindSDCond_def snoc_eq_iff_butlast unw) .
hence ddd: "(trv1 = [] ∧ trv2 = []) ∨ (trv1 ≠ [] ∧ trv2 ≠ [])" by blast
show ?thesis
using ddd proof(elim conjE disjE)
assume trv12: "trv1 = []" "trv2 = []"
hence sv12: "ssv1 = lastt sv1 trv1" "ssv2 = lastt sv2 trv2" and sv12': "ssv1 = sv1" "ssv2 = sv2"
and secl: "ssecl1 = ssecl1'" "ssecl2 = ssecl2'"
using trv1(2) trv2(2) ssecl1'_def ssecl2'_def by auto
show ?thesis proof safe
show g: "Γ ssv1 ssecl1 ssv2 ssecl2" unfolding sv12 secl using gg .
assume "getActV ssv1 = getActV ssv2"
thus "getObsV ssv1 = getObsV ssv2"
using lunwindSDCond_imp[OF unw rsv1 rsv2, unfolded sv12[symmetric], OF g] trv1(4) by auto
qed
next
assume trv12: "trv1 ≠ []" "trv2 ≠ []"
have n: "¬ isIntV (last trv1)"
by (metis append_butlast_last_id list.pred_inject(2) list_all_append trv1(3) trv12(1))
have v1: "validTransV (lastt sv1 trv1, ssv1)"
by (metis Van.validFromS_def Van.validS_validTrans lastt_def list.sel(1) not_Cons_self snoc_eq_iff_butlast trv1(2) trv12(1))
have v2: "validTransV (lastt sv2 trv2, ssv2)"
by (metis Nil_is_append_conv Van.validFromS_def Van.validS_validTrans lastt_def list.discI list.sel(1) trv12(2) trv2(2))
show ?thesis proof safe
assume gssv12: "getActV ssv1 = getActV ssv2"
show g: "Γ ssv1 ssecl1 ssv2 ssecl2"
apply(rule lunwindSDCond_lmove12[OF unw rsv1 rsv2 gg, unfolded lmove12_def, rule_format])
unfolding lvalidEtransO.simps ssecl1'_def ssecl2'_def
using trv12 v1 v2 n by (auto simp: lastt_def)
show "getObsV ssv1 = getObsV ssv2" using gssv12
using lunwindSDCond_imp[OF unw _ _ g]
by (metis Van.reach.Step fst_conv rsv1 rsv2 snd_conv trv1(4) v1 v2)
qed
qed
qed
proposition lunwindSDCond_aux:
assumes unw: "lunwindSDCond Γ"
and 1: "Γ sv1 secl1 sv2 secl2"
"reachV sv1" "Van.lvalidFromS sv1 trv1" "lcompletedFromV sv1 trv1"
"reachV sv2" "Van.lvalidFromS sv2 trv2" "lcompletedFromV sv2 trv2"
"Van.lS trv1 = secl1" "Van.lS trv2 = secl2"
"Van.lA trv1 = Van.lA trv2"
shows "Van.lO trv1 = Van.lO trv2"
proof-
{fix obl1 obl2
assume "∃sv1 trv1 secl1 sv2 trv2 secl2. obl1 = Van.lO trv1 ∧ obl2 = Van.lO trv2 ∧
Γ sv1 secl1 sv2 secl2 ∧
reachV sv1 ∧ Van.lvalidFromS sv1 trv1 ∧ lcompletedFromV sv1 trv1 ∧
reachV sv2 ∧ Van.lvalidFromS sv2 trv2 ∧ lcompletedFromV sv2 trv2 ∧
Van.lS trv1 = secl1 ∧ Van.lS trv2 = secl2 ∧ Van.lA trv1 = Van.lA trv2"
hence "obl1 = obl2"
proof (coinduct rule: llist.coinduct)
case (Eq_llist obl1 obl2)
then obtain sv1 trv1 secl1 sv2 trv2 secl2 where obl: "obl1 = Van.lO trv1" "obl2 = Van.lO trv2"
and gam: "Γ sv1 secl1 sv2 secl2"
and trv1: "reachV sv1" "Van.lvalidFromS sv1 trv1" "lcompletedFromV sv1 trv1"
and trv2: "reachV sv2" "Van.lvalidFromS sv2 trv2" "lcompletedFromV sv2 trv2"
and Str: "Van.lS trv1 = secl1" "Van.lS trv2 = secl2" and Atr: "Van.lA trv1 = Van.lA trv2"
by blast
show ?case proof(intro conjI impI)
show lnull: "lnull obl1 = lnull obl2"
using obl Atr unfolding lnull_def
by (metis LNil_eq_lmap Van.lA.lmap_lfilter Van.lO.lmap_lfilter)
assume ln: "¬ lnull obl1" "¬ lnull obl2"
then obtain ob1 obl1' ob2 obl2' where
obl1: "obl1 = LCons ob1 obl1'" and obl2: "obl2 = LCons ob2 obl2'"
unfolding lnull_def using llist.exhaust_sel by blast
hence lhd: "lhd obl1 = ob1" "lhd obl2 = ob2"
and ltl: "ltl obl1 = obl1'" "ltl obl2 = obl2'"
by auto
obtain ftrv1 sv1' trv1' where
trv1_eq: "trv1 = lappend (llist_of ftrv1) (sv1' $ trv1')" and ftrv1a: "never isIntV ftrv1"
and sv1': "isIntV sv1'" "getObsV sv1' = ob1" and trv1': "Van.lO trv1' = obl1'"
using Van.lO.eq_LCons[OF obl(1)[symmetric, unfolded obl1]] by auto
define sv11 where "sv11 = lastt sv1 ftrv1"
have trv11': "Van.lvalidFromS sv1' (sv1' $ trv1')"
and ftrv1b: "Van.validFromS sv1 ftrv1"
"(ftrv1 = [] ∧ sv1 = sv1' ∧ sv11 = sv1) ∨ (ftrv1 ≠ [] ∧ validTransV (sv11, sv1'))"
using trv1(2)
unfolding trv1_eq unfolding Van.lvalidFromS_lappend_LCons
unfolding lastt_def sv11_def by auto
note ftrv1 = ftrv1a ftrv1b
have fftrv1: "filter isIntV ftrv1 = []" by (metis ftrv1(1) never_Nil_filter)
have ftrv1c: "Van.validFromS sv1 (ftrv1 @ [sv1'])"
by (metis Van.lvalidFromS_lappend_finite lappend_llist_of_LCons trv1(2) trv1_eq)
define ssv1' where "ssv1' ≡ if trv1' = [[]] then sv1' else lhd trv1'"
obtain ftrv2 sv2' trv2' where
trv2_eq: "trv2 = lappend (llist_of ftrv2) (sv2' $ trv2')" and ftrv2a: "never isIntV ftrv2"
and sv2': "isIntV sv2'" "getObsV sv2' = ob2" and trv2': "Van.lO trv2' = obl2'"
using Van.lO.eq_LCons[OF obl(2)[symmetric, unfolded obl2]] by auto
define sv22 where "sv22 = lastt sv2 ftrv2"
have trv22': "Van.lvalidFromS sv2' (sv2' $ trv2')"
and ftrv2b: "Van.validFromS sv2 ftrv2"
"(ftrv2 = [] ∧ sv2 = sv2' ∧ sv22 = sv2) ∨ (ftrv2 ≠ [] ∧ validTransV (sv22, sv2'))"
using trv2(2)
unfolding trv2_eq unfolding Van.lvalidFromS_lappend_LCons
unfolding lastt_def sv22_def by auto
note ftrv2 = ftrv2a ftrv2b
have fftrv2: "filter isIntV ftrv2 = []" by (metis ftrv2(1) never_Nil_filter)
have ftrv2c: "Van.validFromS sv2 (ftrv2 @ [sv2'])"
by (metis Van.lvalidFromS_lappend_finite lappend_llist_of_LCons trv2(2) trv2_eq)
define ssv2' where "ssv2' ≡ if trv2' = [[]] then sv2' else lhd trv2'"
have rsv1': "reachV sv1'"
by (metis Van.reach.Step Van.reach_validFromS_reach
fst_conv ftrv1b(1) ftrv1b(2) lastt_def sv11_def snd_conv trv1(1))
have rsv2': "reachV sv2'"
by (metis Van.reach.Step Van.reach_validFromS_reach fst_conv ftrv2b(1)
ftrv2b(2) lastt_def sv22_def snd_conv trv2(1))
have rsv11: "reachV sv11"
by (metis Van.reach_validFromS_reach ftrv1b(1) lastt_def sv11_def trv1(1))
have rsv22: "reachV sv22"
by (metis Van.reach_validFromS_reach ftrv2b(1) lastt_def sv22_def trv2(1))
define secl1' secl2' where secl1': "secl1' ≡ Van.lS trv1'" and secl2': "secl2' ≡ Van.lS trv2'"
define ssecl1' where "ssecl1' ≡ Van.lS (sv1' $ trv1')"
define ssecl2' where "ssecl2' ≡ Van.lS (sv2' $ trv2')"
have trv12'ne: "trv1' ≠ [[]] ∧ trv2' ≠ [[]]"
by (metis Van.lO.lmap_lfilter Van.lO.simps(4) fftrv1 fftrv2 lappend_LNil2 lbutlast_lappend
lbutlast_singl lfilter_LNil lfilter_llist_of llist.distinct(1) llist_of.simps(1) obl(1) obl(2) obl1 obl2 trv1_eq trv2_eq)
have gasv12': "getActV sv1' = getActV sv2'" using Atr trv12'ne unfolding trv1_eq trv2_eq
unfolding Van.lA.lmap_lfilter
using fftrv1 fftrv2 sv1'(1) sv2'(1)
by (auto simp: lbutlast_lappend lmap_lappend_distrib lappend_eq_LNil_iff split: if_splits)
have ggam_gao: "(getActV sv1' = getActV sv2' ⟶ Γ sv1' ssecl1' sv2' ssecl2') ∧ (getActV sv1' = getActV sv2' ⟶ getObsV sv1' = getObsV sv2')"
apply(rule unwindSDCond_inductive[OF unw gam
trv1(1) ftrv1c ftrv1(1) sv1'(1)
trv2(1) ftrv2c ftrv2(1) sv2'(1)
])
subgoal unfolding Str(1)[symmetric] unfolding trv1_eq
unfolding ssecl1'_def sv11_def Van.S.map_filter Van.lS.lmap_lfilter
by (auto simp: lastt_def lbutlast_lappend lmap_lappend_distrib lappend_eq_LNil_iff split: if_splits)
subgoal unfolding Str(2)[symmetric] unfolding trv2_eq
unfolding ssecl2'_def sv11_def Van.S.map_filter Van.lS.lmap_lfilter
by (auto simp: lastt_def lbutlast_lappend lmap_lappend_distrib lappend_eq_LNil_iff) .
note ggam = ggam_gao[THEN conjunct1, rule_format, OF gasv12'] note gao = ggam_gao[THEN conjunct2, rule_format, OF gasv12']
have "getObsV sv1' = getObsV sv2'" using gao gasv12' by simp
thus "lhd obl1 = lhd obl2"
unfolding lhd sv1'(2)[symmetric] sv2'(2)[symmetric] .
show "∃sv1 trv1 secl1 sv2 trv2 secl2.
ltl obl1 = Van.lO trv1 ∧ ltl obl2 = Van.lO trv2 ∧
Γ sv1 secl1 sv2 secl2 ∧
reachV sv1 ∧ Van.lvalidFromS sv1 trv1 ∧ lcompletedFromV sv1 trv1 ∧
reachV sv2 ∧ Van.lvalidFromS sv2 trv2 ∧ lcompletedFromV sv2 trv2 ∧
Van.lS trv1 = secl1 ∧ Van.lS trv2 = secl2 ∧ Van.lA trv1 = Van.lA trv2"
proof(intro exI[of _ ssv1'] exI[of _ trv1'], rule exI[of _ secl1'],
intro exI[of _ ssv2'] exI[of _ trv2'], rule exI[of _ secl2'],
intro conjI)
show "reachV ssv1'"
unfolding ssv1'_def using rsv1' apply(cases "trv1' = [[]]", simp_all)
by (metis Van.lvalidFromS_Cons_iff Van.reach.simps fst_conv snd_conv trv11')
show "reachV ssv2'"
unfolding ssv2'_def using rsv2' apply(cases "trv2' = [[]]", simp_all)
by (metis Van.lvalidFromS_Cons_iff Van.reach.simps fst_conv snd_conv trv22')
show "ltl obl1 = Van.lO trv1'" unfolding ltl trv1' ..
show "ltl obl2 = Van.lO trv2'" unfolding ltl trv2' ..
show "Van.lvalidFromS ssv1' trv1'" using trv11' Van.lvalidFromS_Cons_iff ssv1'_def by auto
show lc1': "lcompletedFromV ssv1' trv1'" using trv1(3) unfolding trv1_eq
unfolding Van.lcompletedFrom_def
by (metis lfinite_code(2) lfinite_lappend lfinite_llist_of llast_LCons2
llast_lappend_LCons llast_last_llist_of llist.exhaust_sel trv12'ne)
show "Van.lvalidFromS ssv2' trv2'" using trv22' Van.lvalidFromS_Cons_iff ssv2'_def by auto
show lc2': "lcompletedFromV ssv2' trv2'" using trv2(3) unfolding trv2_eq
unfolding Van.lcompletedFrom_def
by (metis lfinite_code(2) lfinite_lappend lfinite_llist_of llast_LCons2 llast_lappend_LCons llast_last_llist_of llist.exhaust_sel trv12'ne)
show "Van.lA trv1' = Van.lA trv2'"
using Atr unfolding trv1_eq trv2_eq using ftrv1(1) ftrv2(1) sv1'(1) sv2'(1)
unfolding Van.lA.lmap_lfilter
by (simp add: fftrv1 fftrv2 lbutlast_lappend trv12'ne)
show "Van.lS trv1' = secl1'" unfolding secl1' ..
show "Van.lS trv2' = secl2'" unfolding secl2' ..
show "Γ ssv1' secl1' ssv2' secl2'"
apply(rule lunwindSDCond_lmove12[OF unw rsv1' rsv2' ggam, unfolded lmove12_def, rule_format, OF gasv12'])
apply(rule conjI)
subgoal unfolding lvalidEtransO.simps apply(rule conjI)
subgoal using trv12'ne Van.lvalidFromS_Cons_iff trv11' unfolding ssv1'_def by auto
subgoal using trv12'ne unfolding ssecl1'_def secl1' by (auto simp: Van.lS.lmap_lfilter) .
subgoal unfolding lvalidEtransO.simps apply(rule conjI)
subgoal using trv12'ne Van.lvalidFromS_Cons_iff trv22' unfolding ssv2'_def by auto
subgoal using trv12'ne unfolding ssecl2'_def secl2' by (auto simp: Van.lS.lmap_lfilter) . .
qed
qed
qed
}
thus ?thesis using assms by blast
qed
theorem unwindSD_lrsecure:
assumes tr14: "istateO s1" "Opt.lvalidFromS s1 tr1" "lcompletedFromO s1 tr1"
"istateO s2" "Opt.lvalidFromS s2 tr2" "lcompletedFromO s2 tr2"
"Opt.lA tr1 = Opt.lA tr2" "Opt.lO tr1 ≠ Opt.lO tr2"
and init: "⋀sv1 sv2. istateV sv1 ⟹ corrState sv1 s1 ⟹ istateV sv2 ⟹ corrState sv2 s2 ⟹
Γ sv1 (Opt.lS tr1) sv2 (Opt.lS tr2)"
and unw: "lunwindSDCond Γ"
shows "¬ lrsecure"
unfolding lrsecure_def2 unfolding not_all not_imp
apply(rule exI[of _ s1]) apply(rule exI[of _ tr1])
apply(rule exI[of _ s2]) apply(rule exI[of _ tr2])
apply(rule conjI)
subgoal using tr14 by auto
subgoal unfolding not_ex apply safe
subgoal for sv1 trv1 sv2 trv2 apply(erule cnf.clause2raw_notE[of "Van.lO trv1 ≠ Van.lO trv2"], simp)
apply(rule lunwindSDCond_aux[OF unw, OF init])
using Van.Istate by auto . .
end
end