Theory DynSlice

section ‹Dynamic Backward Slice›

theory DynSlice imports DependentLiveVariables BitVector "../Basic/SemanticsCFG" begin

subsection ‹Backward slice of paths›

context DynPDG begin

fun slice_path :: "'edge list  bit_vector"
  where "slice_path [] = []"
  | "slice_path (a#as) = (let n' = last(targetnodes (a#as)) in
                           (sourcenode a -a#asd* n')#slice_path as)"

(*<*)declare Let_def [simp](*>*)

lemma slice_path_length:
  "length(slice_path as) = length as"
by(induct as) auto


lemma slice_path_right_Cons:
  assumes slice:"slice_path as = x#xs"
  obtains a' as' where "as = a'#as'" and "slice_path as' = xs"
proof(atomize_elim)
  from slice show "a' as'. as = a'#as'  slice_path as' = xs"
    by(induct as) auto
qed


subsection ‹The proof of the fundamental property of (dynamic) slicing›

fun select_edge_kinds :: "'edge list  bit_vector  'state edge_kind list"
where "select_edge_kinds [] [] = []"
  | "select_edge_kinds (a#as) (b#bs) = (if b then kind a
      else (case kind a of f  id | (Q)  (λs. True)))#select_edge_kinds as bs"


definition slice_kinds :: "'edge list  'state edge_kind list"
  where "slice_kinds as = select_edge_kinds as (slice_path as)"


lemma select_edge_kinds_max_bv:
  "select_edge_kinds as (replicate (length as) True) = kinds as"
by(induct as,auto simp:kinds_def)


lemma slice_path_leqs_information_same_Uses:
  "n -as→* n'; bs b bs'; slice_path as = bs;
    select_edge_kinds as bs = es; select_edge_kinds as bs' = es'; 
    V xs. (V,xs,as)  dependent_live_vars n'  state_val s V = state_val s' V;
    preds es' s' 
   (V  Use n'. state_val (transfers es s) V =
      state_val (transfers es' s') V)  preds es s"
proof(induct bs bs' arbitrary:as es es' n s s' rule:bv_leqs.induct)
  case 1
  from slice_path as = [] have "as = []" by(cases as) auto
  with select_edge_kinds as [] = es select_edge_kinds as [] = es'
  have "es = []" and "es' = []" by simp_all
  { fix V assume "V  Use n'"
    hence "(V,[],[])  dependent_live_vars n'" by(rule dep_vars_Use)
    with V xs. (V,xs,as)  dependent_live_vars n' 
                  state_val s V = state_val s' V V  Use n' as = []
    have "state_val s V = state_val s' V" by blast }
  with es = [] es' = [] show ?case by simp
next
  case (2 x xs y ys)
  note all = V xs. (V,xs,as)  dependent_live_vars n' 
                     state_val s V = state_val s' V
  note IH = as es es' n s s'. n -as→* n'; xs b ys; slice_path as = xs; 
                        select_edge_kinds as xs = es; select_edge_kinds as ys = es';
                        V xs. (V,xs,as)  dependent_live_vars n' 
                                   state_val s V = state_val s' V; 
                           preds es' s'
             (V  Use n'. state_val (transfers es s) V =
                state_val (transfers es' s') V)  preds es s
  from x#xs b y#ys have "x  y" and "xs b ys" by simp_all
  from slice_path as = x#xs obtain a' as' where "as = a'#as'"
    and "slice_path as' = xs" by(erule slice_path_right_Cons)
  from as = a'#as' select_edge_kinds as (x#xs) = es
  obtain ex esx where "es = ex#esx"
    and ex:"ex = (if x then kind a'
                    else (case kind a' of f  id | (Q)  (λs. True)))"
    and "select_edge_kinds as' xs = esx" by auto
  from as = a'#as' select_edge_kinds as (y#ys) = es' obtain ex' esx' 
    where "es' = ex'#esx'"
    and ex':"ex' = (if y then kind a'
                    else (case kind a' of f  id | (Q)  (λs. True)))"
    and "select_edge_kinds as' ys = esx'" by auto
  from n -as→* n' as = a'#as' have [simp]:"n = sourcenode a'" 
    and "valid_edge a'" and "targetnode a' -as'→* n'"
    by(auto elim:path_split_Cons)
  from n -as→* n' as = a'#as' have "last(targetnodes as) = n'"
    by(fastforce intro:path_targetnode)
  from preds es' s' es' = ex'#esx' have "pred ex' s'"
    and "preds esx' (transfer ex' s')" by simp_all
  show ?case
  proof(cases "as' = []")
    case True
    hence [simp]:"as' = []" by simp
    with slice_path as' = xs xs b ys 
    have [simp]:"xs = []  ys = []" by auto(cases ys,auto)+
    with select_edge_kinds as' xs = esx select_edge_kinds as' ys = esx'
    have [simp]:"esx = []" and [simp]:"esx' = []" by simp_all
    from True targetnode a' -as'→* n' 
    have [simp]:"n' = targetnode a'" by(auto elim:path.cases)
    show ?thesis
    proof(cases x)
      case True
      with x  y ex ex' have [simp]:"ex = kind a'  ex' = kind a'" by simp
      have "pred ex s"
      proof(cases ex)
        case (Predicate Q)
        with ex ex' True x  y have [simp]:"transfer ex s = s" 
          and [simp]:"transfer ex' s' = s'"
          by(cases "kind a'",auto)+
        show ?thesis
        proof(cases "n -[a']cd n'")
          case True
          { fix V' assume "V'  Use n"
            with True valid_edge a'
            have "(V',[],a'#[]@[])  dependent_live_vars n'"
              by(fastforce intro:dep_vars_Cons_cdep DynPDG_path_Nil 
                          simp:targetnodes_def)
            with all as = a'#as' have "state_val s V' = state_val s' V'"
              by fastforce }
          with pred ex' s' valid_edge a'
          show ?thesis by(fastforce elim:CFG_edge_Uses_pred_equal)
        next
          case False
          from ex True Predicate have "kind a' = (Q)" by(auto split:if_split_asm)
          from True slice_path as = x#xs as = a'#as' have "n -[a']d* n'"
            by(auto simp:targetnodes_def)
          thus ?thesis
          proof(induct rule:DynPDG_path.cases)
            case (DynPDG_path_Nil nx)
            hence False by simp
            thus ?case by simp
          next
            case (DynPDG_path_Append_cdep nx asx n'' asx' nx')
            from [a'] = asx@asx' 
            have "(asx = [a']  asx' = [])  (asx = []  asx' = [a'])"
              by (cases asx) auto
            hence False
            proof
              assume "asx = [a']  asx' = []"
              with n'' -asx'cd nx' show False
                by(fastforce elim:DynPDG_edge.cases dest:dyn_control_dependence_path)
            next
              assume "asx = []  asx' = [a']"
              with nx -asxd* n'' have "nx = n''" and "asx' = [a']"
                by(auto intro:DynPDG_empty_path_eq_nodes)
              with n = nx n' = nx' n'' -asx'cd nx' False
              show False by simp
            qed
            thus ?thesis by simp
          next
            case (DynPDG_path_Append_ddep nx asx n'' V asx' nx')
            from [a'] = asx@asx' 
            have "(asx = [a']  asx' = [])  (asx = []  asx' = [a'])"
              by (cases asx) auto
            thus ?case
            proof
              assume "asx = [a']  asx' = []"
              with n'' -{V}asx'dd nx' have False
                by(fastforce elim:DynPDG_edge.cases simp:dyn_data_dependence_def)
              thus ?thesis by simp
            next
              assume "asx = []  asx' = [a']"
              with nx -asxd* n'' have "nx = n''"
                by(simp add:DynPDG_empty_path_eq_nodes)
              { fix V' assume "V'  Use n"
                from n'' -{V}asx'dd nx' asx = []  asx' = [a'] n' = nx'
                have "(V,[],[])  dependent_live_vars n'"
                  by(fastforce intro:dep_vars_Use elim:DynPDG_edge.cases
                    simp:dyn_data_dependence_def)
                with V'  Use n n'' -{V}asx'dd nx' asx = []  asx' = [a']
                  n = nx nx = n'' n' = nx'
                have "(V',[],[a'])  dependent_live_vars n'"
                  by(auto elim:dep_vars_Cons_ddep simp:targetnodes_def)
                with all as = a'#as' have "state_val s V' = state_val s' V'"
                  by fastforce }
              with pred ex' s' valid_edge a' ex ex' True x  y show ?thesis
                by(fastforce elim:CFG_edge_Uses_pred_equal)
            qed
          qed
        qed
      qed simp
      { fix V assume "V  Use n'"
        from V  Use n' have "(V,[],[])  dependent_live_vars n'" 
          by(rule dep_vars_Use)
        have "state_val (transfer ex s) V = state_val (transfer ex' s') V"
        proof(cases "n -{V}[a']dd n'")
          case True
          hence "V  Def n"
            by(auto elim:DynPDG_edge.cases simp:dyn_data_dependence_def)
          have "V. V  Use n  state_val s V = state_val s' V"
          proof -
            fix V' assume "V'  Use n"
            with (V,[],[])  dependent_live_vars n' True
            have "(V',[],[a'])  dependent_live_vars n'"
              by(fastforce intro:dep_vars_Cons_ddep simp:targetnodes_def)
            with all as = a'#as' show "state_val s V' = state_val s' V'" by auto
          qed
          with valid_edge a' pred ex' s' pred ex s
          have "V  Def n. state_val (transfer (kind a') s) V =
                              state_val (transfer (kind a') s') V"
            by simp(rule CFG_edge_transfer_uses_only_Use,auto)
          with V  Def n have "state_val (transfer (kind a') s) V = 
                         state_val (transfer (kind a') s') V"
            by simp
          thus ?thesis by fastforce
        next
          case False
          with last(targetnodes as) = n' as = a'#as'
            (V,[],[])  dependent_live_vars n'
          have "(V,[a'],[a'])  dependent_live_vars n'"
            by(fastforce intro:dep_vars_Cons_keep)
          from (V,[a'],[a'])  dependent_live_vars n' all as = a'#as'
          have states_eq:"state_val s V = state_val s' V"
            by auto
          from valid_edge a' V  Use n' False pred ex s
          have "state_val (transfers (kinds [a']) s) V = state_val s V"
            apply(auto intro!:no_ddep_same_state path_edge simp:targetnodes_def)
            apply(simp add:kinds_def)
            by(case_tac as',auto)
          moreover
          from valid_edge a' V  Use n' False pred ex' s'
          have "state_val (transfers (kinds [a']) s') V = state_val s' V"
            apply(auto intro!:no_ddep_same_state path_edge simp:targetnodes_def)
            apply(simp add:kinds_def)
            by(case_tac as',auto)
          ultimately show ?thesis using states_eq by(auto simp:kinds_def)
        qed }
      hence "V  Use n'. state_val (transfer ex s) V = 
                                state_val (transfer ex' s') V" by simp
      with pred ex s es = ex#esx es' = ex'#esx' show ?thesis by simp
    next
      case False
      with ex have cases_x:"ex = (case kind a' of f  id | (Q)  (λs. True))"
        by simp
      from cases_x have "pred ex s" by(cases "kind a'",auto)
      show ?thesis
      proof(cases y)
        case True
        with ex' have [simp]:"ex' = kind a'" by simp
        { fix V assume "V  Use n'"
          from V  Use n' have "(V,[],[])  dependent_live_vars n'"
            by(rule dep_vars_Use)
          from slice_path as = x#xs as = a'#as' ¬ x 
          have "¬ n -[a']d* n'" by(simp add:targetnodes_def)
          hence "¬ n -{V}[a']dd n'" by(fastforce dest:DynPDG_path_ddep)
          with last(targetnodes as) = n' as = a'#as'
            (V,[],[])  dependent_live_vars n'
          have "(V,[a'],[a'])  dependent_live_vars n'"
            by(fastforce intro:dep_vars_Cons_keep)
          with all as = a'#as' have "state_val s V = state_val s' V" by auto
          from valid_edge a' V  Use n' pred ex' s'
            ¬ n -{V}[a']dd n' last(targetnodes as) = n' as = a'#as'
          have "state_val (transfers (kinds [a']) s') V = state_val s' V"
            apply(auto intro!:no_ddep_same_state path_edge)
            apply(simp add:kinds_def)
            by(case_tac as',auto)
          with state_val s V = state_val s' V cases_x
          have "state_val (transfer ex s) V =
                state_val (transfer ex' s') V"
            by(cases "kind a'",simp_all add:kinds_def) }
        hence "V  Use n'. state_val (transfer ex s) V =
                           state_val (transfer ex' s') V" by simp
        with as = a'#as' es = ex#esx es' = ex'#esx' pred ex s 
        show ?thesis by simp
      next
        case False
        with ex' have cases_y:"ex' = (case kind a' of f  id | (Q)  (λs. True))"
          by simp
        with cases_x have [simp]:"ex = ex'" by(cases "kind a'") auto
        { fix V assume "V  Use n'"
          from V  Use n' have "(V,[],[])  dependent_live_vars n'"
            by(rule dep_vars_Use)
          from slice_path as = x#xs as = a'#as' ¬ x 
          have "¬ n -[a']d* n'" by(simp add:targetnodes_def)
          hence no_dep:"¬ n -{V}[a']dd n'" by(fastforce dest:DynPDG_path_ddep)
          with last(targetnodes as) = n' as = a'#as'
            (V,[],[])  dependent_live_vars n'
          have "(V,[a'],[a'])  dependent_live_vars n'"
            by(fastforce intro:dep_vars_Cons_keep)
          with all as = a'#as' have "state_val s V = state_val s' V" by auto }
        with as = a'#as' cases_x es = ex#esx es' = ex'#esx' pred ex s
        show ?thesis by(cases "kind a'",auto)
      qed
    qed
  next
    case False
    show ?thesis
    proof(cases "V xs. (V,xs,as')  dependent_live_vars n' 
                        state_val (transfer ex s) V = state_val (transfer ex' s') V")
      case True
      hence imp':"V xs. (V,xs,as')  dependent_live_vars n' 
                       state_val (transfer ex s) V = state_val (transfer ex' s') V" .
      from IH[OF targetnode a' -as'→* n' xs b ys slice_path as' = xs
        select_edge_kinds as' xs = esx select_edge_kinds as' ys = esx' 
        this preds esx' (transfer ex' s')]
      have all':"VUse n'. state_val (transfers esx (transfer ex s)) V =
                             state_val (transfers esx' (transfer ex' s')) V"
        and "preds esx (transfer ex s)" by simp_all
      have "pred ex s"
      proof(cases ex)
        case (Predicate Q)
        with slice_path as = x#xs as = a'#as' last(targetnodes as) = n' ex 
        have "ex = (λs. True)  n -a'#as'd* n'"
          by(cases "kind a'",auto split:if_split_asm) 
        thus ?thesis
        proof
          assume "ex = (λs. True)" thus ?thesis by simp
        next
          assume "n -a'#as'd* n'"
          with slice_path as = x#xs as = a'#as' last(targetnodes as) = n' ex
          have [simp]:"ex = kind a'" by clarsimp
          with x  y ex ex' have [simp]:"ex' = ex" by(cases x) auto
          from n -a'#as'd* n' show ?thesis
          proof(induct rule:DynPDG_path_rev_cases)
            case DynPDG_path_Nil
            hence False by simp
            thus ?thesis by simp
          next
            case (DynPDG_path_cdep_Append n'' asx asx')
            from n -asxcd n''have "asx  []"
              by(auto elim:DynPDG_edge.cases dest:dyn_control_dependence_path)
            with n -asxcd n'' n'' -asx'd* n' a'#as' = asx@asx'
            have cdep:"as1 as2 n''. n -a'#as1cd n''  
                                     n'' -as2d* n'  as' = as1@as2"
              by(cases asx) auto 
            { fix V assume "V  Use n"
              with cdep last(targetnodes as) = n' as = a'#as'
              have "(V,[],as)  dependent_live_vars n'"
                by(fastforce intro:dep_vars_Cons_cdep)
              with all have "state_val s V = state_val s' V" by blast }
            with valid_edge a' pred ex' s'
            show ?thesis by(fastforce elim:CFG_edge_Uses_pred_equal)
          next
            case (DynPDG_path_ddep_Append V n'' asx asx')
            from n -{V}asxdd n'' obtain ai ais where "asx = ai#ais"
              by(cases asx)(auto dest:DynPDG_ddep_edge_CFG_path)
            with n -{V}asxdd n'' have "sourcenode ai = n"
              by(fastforce dest:DynPDG_ddep_edge_CFG_path elim:path.cases)
            from n -{V}asxdd n'' asx = ai#ais
            have "last(targetnodes asx) = n''"
              by(fastforce intro:path_targetnode dest:DynPDG_ddep_edge_CFG_path)
            { fix V' assume "V'  Use n"
              from n -{V}asxdd n'' have "(V,[],[])  dependent_live_vars n''"
                by(fastforce elim:DynPDG_edge.cases dep_vars_Use 
                            simp:dyn_data_dependence_def)
              with n'' -asx'd* n' have "(V,[],[]@asx')  dependent_live_vars n'"
                by(rule dependent_live_vars_dep_dependent_live_vars)
              have "(V',[],as)  dependent_live_vars n'"
              proof(cases "asx' = []")
                case True
                with n'' -asx'd* n' have "n'' = n'"
                  by(fastforce intro:DynPDG_empty_path_eq_nodes)
                with n -{V}asxdd n'' V'  Use n True as = a'#as'
                  a'#as' = asx@asx'
                show ?thesis by(fastforce intro:dependent_live_vars_ddep_empty_fst)
              next
                case False
                with n -{V}asxdd n'' asx = ai#ais
                  (V,[],[]@asx')  dependent_live_vars n'
                have "(V,ais@[],ais@asx')  dependent_live_vars n'"
                  by(fastforce intro:ddep_dependent_live_vars_keep_notempty)
                from n'' -asx'd* n' False have "last(targetnodes asx') = n'"
                  by -(rule path_targetnode,rule DynPDG_path_CFG_path)
                with (V,ais@[],ais@asx')  dependent_live_vars n'
                  V'  Use n n -{V}asxdd n'' asx = ai#ais
                  sourcenode ai = n last(targetnodes asx) = n'' False
                have "(V',[],ai#ais@asx')  dependent_live_vars n'"
                  by(fastforce intro:dep_vars_Cons_ddep simp:targetnodes_def)
                with asx = ai#ais a'#as' = asx@asx' as = a'#as'
                show ?thesis by simp
              qed
              with all have "state_val s V' = state_val s' V'" by blast }
            with pred ex' s' valid_edge a'
            show ?thesis by(fastforce elim:CFG_edge_Uses_pred_equal)
          qed
        qed
      qed simp
      with all' preds esx (transfer ex s) es = ex#esx es' = ex'#esx'
      show ?thesis by simp
    next
      case False
      then obtain V' xs' where "(V',xs',as')  dependent_live_vars n'"
        and "state_val (transfer ex s) V'  state_val (transfer ex' s') V'"
        by auto
      show ?thesis
      proof(cases "n -a'#as'd* n'")
        case True
        with slice_path as = x#xs as = a'#as' last(targetnodes as) = n' ex
        have [simp]:"ex = kind a'" by clarsimp
        with x  y ex ex' have [simp]:"ex' = ex" by(cases x) auto
        { fix V assume "V  Use (sourcenode a')"
          hence "(V,[],[])  dependent_live_vars (sourcenode a')"
            by(rule dep_vars_Use)
          with n -a'#as'd* n' have "(V,[],[]@a'#as')  dependent_live_vars n'"
            by(fastforce intro:dependent_live_vars_dep_dependent_live_vars)
          with all as = a'#as' have "state_val s V = state_val s' V"
            by fastforce }
        with pred ex' s' valid_edge a' have "pred ex s"
          by(fastforce intro:CFG_edge_Uses_pred_equal)
        show ?thesis
        proof(cases "V'  Def n")
          case True
          with state_val (transfer ex s) V'  state_val (transfer ex' s') V'
            valid_edge a' pred ex' s' pred ex s
            CFG_edge_transfer_uses_only_Use[of a' s s']
          obtain V'' where "V''  Use n"
            and "state_val s V''  state_val s' V''"
            by auto
          from True (V',xs',as')  dependent_live_vars n'
            targetnode a' -as'→* n' last(targetnodes as) = n' as = a'#as'
            valid_edge a' n = sourcenode a'[THEN sym]
          have "n -{V'}a'#xs'dd last(targetnodes (a'#xs'))"
            by -(drule dependent_live_vars_dependent_edge,
              auto dest!: dependent_live_vars_dependent_edge 
                   dest:DynPDG_ddep_edge_CFG_path path_targetnode 
                   simp del:n = sourcenode a')
          with (V',xs',as')  dependent_live_vars n' V''  Use n
            last(targetnodes as) = n' as = a'#as'
          have "(V'',[],as)  dependent_live_vars n'" 
            by(fastforce intro:dep_vars_Cons_ddep)
          with all have "state_val s V'' = state_val s' V''" by blast
          with state_val s V''  state_val s' V'' have False by simp
          thus ?thesis by simp
        next
          case False
          with valid_edge a' pred ex s
          have "state_val (transfer (kind a') s) V' = state_val s V'"
            by(fastforce intro:CFG_edge_no_Def_equal)
          moreover
          from False valid_edge a' pred ex' s'
          have "state_val (transfer (kind a') s') V' = state_val s' V'"
            by(fastforce intro:CFG_edge_no_Def_equal)
          ultimately have "state_val s V'  state_val s' V'"
            using state_val (transfer ex s) V'  state_val (transfer ex' s') V'
            by simp
          from False have "¬ n -{V'}a'#xs'dd 
                           last(targetnodes (a'#xs'))"
            by(auto elim:DynPDG_edge.cases simp:dyn_data_dependence_def)
          with (V',xs',as')  dependent_live_vars n' last(targetnodes as) = n'
            as = a'#as'
          have "(V',a'#xs',a'#as')  dependent_live_vars n'"
            by(fastforce intro:dep_vars_Cons_keep)
          with as = a'#as' all have "state_val s V' = state_val s' V'" by auto
          with state_val s V'  state_val s' V' have False by simp
          thus ?thesis by simp
        qed
      next
        case False
        { assume "V'  Def n"
          with (V',xs',as')  dependent_live_vars n' targetnode a' -as'→* n'
            valid_edge a'
          have "n -a'#as'd* n'"
            by -(drule dependent_live_vars_dependent_edge,
              auto dest:DynPDG_path_ddep DynPDG_path_Append)
          with False have "False" by simp }
        hence "V'  Def (sourcenode a')" by fastforce
        from False slice_path as = x#xs as = a'#as'
          last(targetnodes as) = n' as'  []
        have "¬ x" by(auto simp:targetnodes_def)
        with ex have cases:"ex = (case kind a' of f  id | (Q)  (λs. True))"
          by simp
        have "state_val s V'  state_val s' V'"
        proof(cases y)
          case True
          with ex' have [simp]:"ex' = kind a'" by simp
          from V'  Def (sourcenode a') valid_edge a' pred ex' s'
          have states_eq:"state_val (transfer (kind a') s') V' = state_val s' V'"
            by(fastforce intro:CFG_edge_no_Def_equal)
          from cases have "state_val s V' = state_val (transfer ex s) V'"
            by(cases "kind a'") auto
          with states_eq
            state_val (transfer ex s) V'  state_val (transfer ex' s') V'
          show ?thesis by simp
        next
          case False
          with ex' have "ex' = (case kind a' of f  id | (Q)  (λs. True))"
            by simp
          with cases have "state_val s V' = state_val (transfer ex s) V'"
            and "state_val s' V' = state_val (transfer ex' s') V'"
            by(cases "kind a'",auto)+
          with state_val (transfer ex s) V'  state_val (transfer ex' s') V' 
          show ?thesis by simp
        qed
        from V'  Def (sourcenode a') 
        have "¬ n -{V'}a'#xs'dd last(targetnodes (a'#xs'))"
          by(auto elim:DynPDG_edge.cases simp:dyn_data_dependence_def)
        with (V',xs',as')  dependent_live_vars n' last(targetnodes as) = n'
          as = a'#as'
        have "(V',a'#xs',a'#as')  dependent_live_vars n'"
          by(fastforce intro:dep_vars_Cons_keep)
        with as = a'#as' all have "state_val s V' = state_val s' V'" by auto
        with state_val s V'  state_val s' V' have False by simp
        thus ?thesis by simp
      qed
    qed
  qed
qed simp_all


theorem fundamental_property_of_path_slicing:
  assumes "n -as→* n'" and "preds (kinds as) s"
  shows "(V  Use n'. state_val (transfers (slice_kinds as) s) V = 
                         state_val (transfers (kinds as) s) V)" 
  and "preds (slice_kinds as) s"
proof -
  have "length as = length (slice_path as)" by(simp add:slice_path_length)
  hence "slice_path as b replicate (length as) True"
    by(simp add:maximal_element)
  have "select_edge_kinds as (replicate (length as) True) = kinds as"
    by(rule select_edge_kinds_max_bv)
  with n -as→* n' slice_path as b replicate (length as) True
    preds (kinds as) s 
  have "(VUse n'. state_val (transfers (slice_kinds as) s) V =
       state_val (transfers (kinds as) s) V)  preds (slice_kinds as) s"
    by -(rule slice_path_leqs_information_same_Uses,simp_all add:slice_kinds_def)
  thus "VUse n'. state_val (transfers (slice_kinds as) s) V =
    state_val (transfers (kinds as) s) V" and "preds (slice_kinds as) s"
    by simp_all
qed

end


subsection ‹The fundamental property of (dynamic) slicing related to the semantics›

locale BackwardPathSlice_wf = 
  DynPDG sourcenode targetnode kind valid_edge Entry Def Use state_val Exit 
    dyn_control_dependence +
  CFG_semantics_wf sourcenode targetnode kind valid_edge Entry sem identifies
  for sourcenode :: "'edge  'node" and targetnode :: "'edge  'node"
  and kind :: "'edge  'state edge_kind" and valid_edge :: "'edge  bool"
  and Entry :: "'node" ("'('_Entry'_')") and Def :: "'node  'var set"
  and Use :: "'node  'var set" and state_val :: "'state  'var  'val"
  and dyn_control_dependence :: "'node  'node  'edge list  bool" 
    ("_ controls _ via _" [51, 0, 0] 1000)
  and Exit :: "'node" ("'('_Exit'_')") 
  and sem :: "'com  'state  'com  'state  bool" 
    ("((1_,/_) / (1_,/_))" [0,0,0,0] 81)
  and identifies :: "'node  'com  bool" ("_  _" [51, 0] 80) 

begin

theorem fundamental_property_of_path_slicing_semantically:
  assumes "n  c" and "c,s  c',s'"
  obtains n' as where "n -as→* n'" and "preds (slice_kinds as) s" 
  and "n'  c'" 
  and "V  Use n'. state_val (transfers (slice_kinds as) s) V = 
                     state_val s' V"
proof(atomize_elim)
  from n  c c,s  c',s' obtain n' as where "n -as→* n'"
    and "transfers (kinds as) s = s'"
    and "preds (kinds as) s"
    and "n'  c'"
    by(fastforce dest:fundamental_property)
  with n -as→* n' preds (kinds as) s 
  have "V  Use n'. state_val (transfers (slice_kinds as) s) V =
    state_val (transfers (kinds as) s) V" and "preds (slice_kinds as) s"
    by -(rule fundamental_property_of_path_slicing,simp_all)+
  with transfers (kinds as) s = s' have "V  Use n'. 
    state_val (transfers (slice_kinds as) s) V =
    state_val s' V" by simp
  with n -as→* n' preds (slice_kinds as) s n'  c'
  show "as n'. n -as→* n'  preds (slice_kinds as) s  n'  c' 
       (VUse n'. state_val (transfers (slice_kinds as) s) V = state_val s' V)"
    by blast
qed


end

end