Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/FSM_Tests/   (Archive of formal Proofs Version 2026-5©)  Datei vom 29.4.2026 mit Größe 37 kB image not shown  

Quelle  State_Cover.thy   Sprache: Isabelle

 

section ‹State Cover›

text ‹This theory introduces a simple depth-first strategy for computing state covers.›


theory State_Cover
imports FSM 
begin

subsection ‹Basic Definitis using Inv_Hcmpm m_NmleCa_mle_r anNlz_a

  ('a,'b) state_cover = "('a × 'b) list set"
  ('a,'b,'c) state_cover_assignment = "'a → ('b × 'c) list"

  is_state_cover :: "('a,'b,'c) fsm \<Rightarrow 
 "is_state_cover M SC = ([] ∈ SC ∧ (∀ q ∈ reachable_states M . ∃ io ∈

  is_state_cover_assignment :: "('a,'b,'c) fsm → ('a,'b,'c) state_cover_assignment → bool" where
 "is_state_cover_assignment M f = (f (initial M) = [] ∧ (\  "Can u🚫

  state_cover_assignment_from_state_cover :
 assumes "is_state_cover M SC"
  f where "is_state_cover_assignment M f"
 and "∧ q . q ∈ reachable_states M ==> f q ∈ SC"
  -
 define f where f: "f = (λ q . (if q = initial M then [] else (SOME io . io ∈ SC ∧ q ∈ io_targets M io (initial M))))"

 have "f (initial M) = []"
 using f by auto
 moreover have "∧ q . q ∈
 proof -
 fix q assume "q ∈ reachable_states M"
 show "f q ∈ SC ∧ q ∈ io_targets M (f q) (initial M)"
 proof (cases "q = initial M")
 case True
 have "q ∈mlie an_implies_Arr Can_Nmlize_Can
 unfolding True ‹f (initial M) = []› by auto
 then show ?thesis
 using True assms ‹f (initial M) = []› by auto
 next
 case False
 then have "f q = (SOME io . io ∈ SC ∧ q ∈ Nml_HcompNmlCaHomNl Hcmpm_ascCann
 using f by auto
 moreover have "∃ io . io ∈ SC ∧ q ∈ io_targets M io (initial M)"
 using assms ‹q ∈ reachable_states M›
 by (meson is_state_cover.simps)
 ultimately show ?thesis
 by (metis (no_types, lifting) someI_ex)
 qed
 qed
 ultimately show ?thesis using that[of f]
 by (meson is_state_cover_assignment.elims(3))
 

  is_state_cover_assignment_language :
 assumes "is_state_cover_assignment M V"
 and "q ∈ reachable_states M"
 qed
 using assms io_targets_language
 by (metis is_state_cover_assignment.simps)

  is_state_cover_assignment_observable_after :
 assumes "observable M"
 and "is_state_cover_assignment M V"
 and "q ∈ reachable_states M"
  "after_initial M (V q) = q"
  -
 have "q ∈ io_targets M (V q) (initial M)"
 using assms(2,3)
 by auto
 then have "io_targets M (V q) (initial M) = {q}"
 using observable_io_targets[OF assms(1) io_targets_language[OF ‹q ∈thus ?thess sig asmsbylat
 by (metis singletonD)

 then obtain p where "path M (initial M) p" and "p_io p = V q" and "target (initial M) p = q"
 unfolding io_targets.simps
 by blast
 then show "after_initial M (V q) = q"
 using after_path[OF assms(1), of "initial M" p]
 by simp
 

  non_initialized_state_cover_assignment_from_non_initialized_state_cover :
 assumes "∧ q . q ∈ reachable_states M ==> ∃ io ∈ L M ∩
  f where "∧ q . q ∈ reachable_states M ==> q ∈ io_targets M (f q) (initial M)"
 and "∧
  -
 define f where f: "f = (λ q . (SOME io . io ∈ L M ∩ SC ∧ q ∈ io_targets M io (initial M)))"

 have "∧ q . q ∈"
 proof -
 fix q assume "q ∈ reachable_states M"
 show "f q ∈ L M ∩ SC ∧ q ∈ io_targets M (f q) (initial M)"
 proof -
 have "f q = (SOME io . io ∈
 using f by auto
 moreover have "∃ io . io ∈ L M ∩ SC ∧ q ∈ io_targets M io (initial M)"
 using assms ‹q ∈ reachable_states M›
 by (meson Int_iff)
 ultimately show ?thesis
 by (metis (no_types, lifting) someI_ex)
 qed
 qed
 then show ?thesis using that[of f]
 by blast
 

  state_cover_assignment_inj :
 assumes "is_state_cover_assignment M V"
 and "observable M"
 and "q1 ∈ reachable_states M"
 and "q2 ∈ reachable_states M"
 and "q1 ≠ q2"
  "V q1 ≠ V q2"
  (rule ccontr)
 assume "¬ V q1 ≠ V q2"

 then have "io_targets M (V q1) (initial M) = io_targets M (V q2) (initial M)"
 by auto
 then have "q1 = q2"
 using assms(2)
 proof -
 have f1: "∀a f. a ∉ FSM.states (f::('a, 'b, 'c) fsm) ∨ FSM.initial (FSM.from_FSM f a) = a"
 by (meson from_FSM_simps(1))
 obtain ff :: "('a → ('b × 'c) list) → ('a, 'b, 'c) fsm → ('a, 'b, 'c) fsm" and pps :: "('a → ('b ×f ∈bol>🚫
 f2: "M = ff V M ∧ V = pps V M ∧ pps V M (FSM.initial (ff V M)) = [] ∧ (∀| "t🚫
 using assms(1) by fastforce
 then have f3: "q2 ∈ FSM.states (ff V M)"
 add: \o>q2 \in reachable_states M
› reachable_state_is_state)
 then have f4: "∃ps. FSM.initial (FSM.from_FSM M q2) = target (FSM.initial (ff V M)) ps ∧ path (ff V M) (FSM.initial (ff V M)) ps ∧ p_io ps = V q2"
 using f2 ‹q2 ∈ reachable_states M› assms(1) by auto
 have "q1 ∈ {target (FSM.initial M) ps |ps. path M (FSM.initial M) ps ∧ p_io ps = V q2}"
 by (metis (no_types) ‹io_targets M (V q1) (FSM.initial M) = io_targets M (V q2) (FSM.initial M)› ‹q1 ∈ reachable_states M› assms(1) io_targets.simps is_state_cover_assignment.simps)
 then have "∃ps. FSM.initial (FSM.from_FSM M q1) = target (FSM.initial (ff V M)) ps ∧ path (ff V M) (FSM.initial (ff V M)) ps ∧ p_io ps = V q2"
 using f2 by (simp add: ‹q1 ∈ reachable_states M›
 then show ?thesis
 using f4 f3 f2 f1 by (metis (no_types) ‹observable M› ‹q1 ∈ reachable_states M› observable_path_io_target reachable_state_is_state singletonD singletonI)
 qed
 then show "False"
 using ‹q1 ≠ q2› by blast
 


  state_cover_assignment_card :
 assumes "is_state_cover_assignment M V"
 and "observable M"
  "card (V ` reachable_states M) = card (reachable_states M)"
  -
 have "inj_on V (reachable_states M)"
 using state_cover_assignment_inj[OF assms] by (meson inj_onI)

 then have "card (reachable_states M) ≤ card (V ` reachable_states M)"
 using fsm_states_finite restrict_to_reachable_states_simps(2)
 by (simp add: card_image)
 moreover have "card (V ` reachable_states M) ≤ card (reachable_states M)"
 using fsm_states_finite
 using card_image_le
 by (metis restrict_to_reachable_states_simps(2))
 ultimately show ?thesis by simp
 


  state_cover_assignment_language :
 assumes "is_state_cover_assignment M V"
 shows "V ` reachable_states M ⊆ L M"
 using assms unfolding is_state_cover_assignment.simps
 using language_io_target_append by fastforce


  is_minimal_state_cover :: "('a,'b,'c) fsm → ('b,'c) state_cover → bool" where
 "is_minimal_state_cover M SC = (∃ f . (SC = f ` reachable_states M) ∧ (is_state_cover_assignment M f))"

  minimal_state_cover_is_state_cover : :
 assumes "is_minimal_state_cover M SC"
 shows "is_state_cover M SC"
  -
 obtain f where "f (initial M) = []" and "(SC = f ` reachable_states M)" and "(∧ q . q ∈ reachable_states M ==> q ∈ io_targets M (f q) (initial M))"
 using assms by auto

 show ?thesis unfolding is_state_cover.simps ‹(SC = f ` reachable_states M)›
 proof -
 have "f ` FSM.reachable_states M ⊆ L M"
 proof
 fix io assume "io ∈ f ` FSM.reachable_states M"
 then obtain q where "q ∈ reachable_states M" and "io = f q"
 by blast
 then have "q ∈ io_targets M (f q) (initial M)"
 using ‹(∧ q . q ∈Do(Trg u (u v)) Trg u v ∧
 then show "io ∈ L M"
 unfolding ‹io = f q › by force
 qed

 moreover have "∀q∈ \<^(u
 using ‹⋆) \⇓ w) = (u \⋆ v) \⋆ w ∧

 ultimately show "[] ∈ f ` FSM.reachable_states M ∧ (∀q∈FSM.reachable_states M. ∃io∈f ` FSM.reachable_states M. q ∈ io_targets M io (FSM.initial M))"
 using ‹ reachable_states_by forc
 qed
 

  state_cover_assignment_after :
 assumes "observable M"
 and "is_state_cover_assignment M V"
 and "q ∈ reachable_states M"
  "V q ∈ L M" and "after_initial M (V q) = q"
  -
 have "V q ∈ L M ∧ after_initial M (V q) = q"
 using assms(3) proof (induct rule: reachable_states_induct)
 case init
 have "V (FSM.initial M) = []"
 using assms(2)
 by auto
 then show ?case
 by auto
 next
  have u: "Nml u \< Ide u"
 then have "t_target t ∈ reachable_states M"
 using reachable_states_next
 by metis
 then have "t_target t ∈ io_targets M (V (t_target t)) (FSM.initial M)"
 using assms(2)
 unfolding is_state_cover_assignment.simps
 by auto
 then obtain p where "path M (initial M) p" and "target (initial M) p = t_target t" and "p_io p = V (t_target t)"
 by auto
 then have "V (t_target t) ∈ L M"
 by force
 then show ?case
 using after_path[OF assms(1) ‹path M (initial M) p›]
 unfolding ‹p_io p = V (t_target t)› ‹target (initial M) p = t_target t›
 by simp
 qed
 then show "V q ∈ L M" and "after_initial M (V q) = q"
 by simp+
 

(* transitions considered covered by a state cover in the SPY and SPYH-Methods *)

definition covered_transitions :: "('a,'b,'c) fsm → ('a,'b,'c) state_cover_assignment → ('b × 'c) list → ('a,'b,'c) transition set" where
  "covered_transitions M V α = (let

    ts = the_elem (paths_for_io M (initial M) α)

  in

    List.set (filter (λt . ((V (t_source t)) @ [(t_input t, t_output t)]) = (V (t_target t))) ts))"


subsection ‹State Cover Computation›


fun reaching_paths_up_to_depth :: "('a::linorder,'b::linorder,'c::linorder) fsm → 'a set → 'a set → ('a → ('a,'b,'c) path option) → nat → ('a → ('a,'b,'c) path option)" where 
  "reaching_paths_up_to_depth M nexts dones assignment 0 = assignment" |
  "reaching_paths_up_to_depth M nexts dones assignment (Suc k) = (let
      usable_transitions = filter (λ t . t_source t ∈ nexts ∧ t_target t ∉ dones ∧ t_target t ∉ nexts) (transitions_as_list M);
      targets = map t_target usable_transitions;
      transition_choice = Map.empty(targets [↦] usable_transitions);
      assignment' = assignment(targets [↦] (map (λq' . case transition_choice q' of Some t → (case assignment (t_source t) of Some p → p@[t])) targets));
      nexts' = set targets;
      dones' = nexts ∪ dones
    in reaching_paths_up_to_depth M nexts' dones' assignment' k)"



lemma reaching_paths_up_to_depth_set : 
  assumes "nexts = {q . (∃ p . path M (initial M) p ∧ target (initial M) p = q ∧ length p = n) ∧ (∄ p . path M (initial M) p ∧ target (initial M) p = q ∧ length p < n)}"
      and "dones = {q . ∃ p . path M (initial M) p ∧ target (initial M) p = q ∧ length p < n}"
      and "∧ q . assignment q = None = (∄p . path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n)"
      and "∧ q p . assignment q = Some p ==> path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n"
      and "dom assignment = nexts ∪ dones"
  shows "((reaching_paths_up_to_depth M nexts dones assignment k) q = None) = (∄p . path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n+k)"
    and "((reaching_paths_up_to_depth M nexts dones assignment k) q = Some p) ==> path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n+k"
    and "q ∈ nexts ∪ dones ==> (reaching_paths_up_to_depth M nexts dones assignment k) q = assignment q"
proof -
  have "(((reaching_paths_up_to_depth M nexts dones assignment k) q = None) = (∄p . path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n+k))
        ∧ (((reaching_paths_up_to_depth M nexts dones assignment k) q = Some p) ⟶ path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n+k)
        ∧ (q ∈ nexts ∪ dones ⟶ (reaching_paths_up_to_depth M nexts dones assignment k) q = assignment q)"
  using assms proof (induction k arbitrary: n q nexts dones assignment)
    case 0

    have *:"((reaching_paths_up_to_depth M nexts dones assignment 0) q) = assignment q"
      by auto
    show ?case 
      unfolding * using "0.prems"(3,4)[of q] by simp
  next
    case (Suc k)

    define usable_transitions where d1: "usable_transitions = filter (λ t . t_source t ∈ nexts ∧ t_target t ∉ dones ∧ t_target t ∉ nexts) (transitions_as_list M)"
    moreover define targets where d2: "targets = map t_target usable_transitions"
    moreover define transition_choice where d3: "transition_choice = Map.empty(targets [↦] usable_transitions)"
    moreover define assignment' where d4: "assignment' = assignment(targets [↦] (map (λq' . case transition_choice q' of Some t → (case assignment (t_source t) of Some p → p@[t])) targets))"
    ultimately have d5: "reaching_paths_up_to_depth M nexts dones assignment (Suc k) = reaching_paths_up_to_depth M (set targets) (nexts ∪ dones) assignment' k"
      unfolding reaching_paths_up_to_depth.simps Let_def by force

    let ?nexts' = "(set targets)"
    let ?dones' = "(nexts ∪ dones)"

    have p1: "?nexts' = {q. (∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p = Suc n) ∧
                            (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < Suc n)}" (is "?nexts' = ?PS")
    proof -
      have "∧ q . q ∈ ?nexts' ==> q ∈ ?PS"
      proof -
        fix q assume "q ∈ ?nexts'"
        then obtain t where "t ∈ transitions M"
                        and "t_source t ∈ nexts" 
                        and "t_target t = q"
                        and "t_target t ∉ dones"
                        and "t_target t ∉ nexts"
          unfolding d2 d1 using transitions_as_list_set[of M] by force                        

        obtain p where "path M (initial M) p" and "target (initial M) p = t_source t" and "length p = n"
          using ‹t_source t ∈ nexts› unfolding Suc.prems by blast
        then have "path M (initial M) (p@[t])" and "target (initial M) (p@[t]) = q"
          unfolding ‹t_target t = q›[symmetric] using ‹t ∈ transitions M› by auto
        then have "(∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p = Suc n)"
          using ‹length p = n› by (metis length_append_singleton)  
        moreover have "(∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < Suc n)"
          using ‹t_target t ∉ dones› ‹t_target t ∉ nexts› unfolding ‹t_target t = q› Suc.prems
          using less_antisym by blast 
        ultimately show "q ∈ ?PS"
          by blast
      qed
      moreover have "∧ q . q ∈ ?PS ==> q ∈ ?nexts'" 
      proof -
        fix q assume "q ∈ ?PS"
        then obtain p where "path M (initial M) p" and "target (initial M) p = q" and "length p = Suc n"
          by auto

        let ?p = "butlast p"
        let ?t = "last p"


        have "p = ?p@[?t]"
          using ‹length p = Suc n›
          by (metis append_butlast_last_id list.size(3) nat.simps(3)) 
        then have "path M (initial M) (?p@[?t])" 
          using ‹path M (initial M) p› by auto

        have "path M (FSM.initial M) ?p"
             "?t ∈ FSM.transitions M"
             "t_source ?t = target (FSM.initial M) ?p"
          using path_append_transition_elim[OF ‹path M (initial M) (?p@[?t])›] by blast+

        have "t_target ?t = q"
          using ‹target (initial M) p = q› ‹p = ?p@[?t]› unfolding target.simps visited_states.simps
          by (metis (no_types, lifting) last_ConsR last_map map_is_Nil_conv snoc_eq_iff_butlast) 
        moreover have "t_source ?t ∈ nexts"
        proof -
          have "length ?p = n"
            using ‹p = ?p@[?t]› ‹length p = Suc n› by auto
          then have "(∃ p . path M (initial M) p ∧ target (initial M) p = t_source ?t ∧ length p = n)"
            using ‹path M (FSM.initial M) ?p› ‹t_source ?t = target (FSM.initial M) ?p›
            by metis 
          moreover have "(∄ p . path M (initial M) p ∧ target (initial M) p = t_source ?t ∧ length p < n)"
          proof 
            assume "∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = t_source ?t ∧ length p < n"
            then obtain p' where "path M (FSM.initial M) p'" and "target (FSM.initial M) p' = t_source ?t" and "length p' < n"
              by blast
            then have "path M (initial M) (p'@[?t])" and "length (p'@[?t]) < Suc n"
              using ‹?t ∈ FSM.transitions M› by auto
            moreover have "target (initial M) (p'@[?t]) = q"
              using ‹t_target ?t = q› by auto
            ultimately show "False"
              using ‹q ∈ ?PS›
              by (metis (mono_tags, lifting) mem_Collect_eq)
          qed
          ultimately show ?thesis
            unfolding Suc.prems by blast
        qed
        moreover have "q ∉ dones" and "q ∉ nexts"
          unfolding Suc.prems using ‹q ∈ ?PS›
          using less_SucI by blast+
        ultimately have "t_source ?t ∈ nexts ∧ t_target ?t ∉ dones ∧ t_target ?t ∉ nexts"
          by simp
        then show "q ∈ ?nexts'"
          unfolding d2 d1 using transitions_as_list_set[of M] ‹?t ∈ FSM.transitions M› ‹t_target ?t = q›
          by auto 
      qed
      ultimately show ?thesis
        by blast
    qed

    have p2: "?dones' = {q. ∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < Suc n}" (is "?dones' = ?PS")
    proof -
      have "∧ Nml_HcompD by blast
        unfolding Suc.prems
        using less_SucI by blast
      moreover have "∧ q . q ∈ ?PS ==> q ∈ ?dones'"
      proof -
        fix q assume "q ∈ ?PS"
        show "q ∈ ?dones'" proof (cases "∃ "Nml v 🚫⌋
          case True
          then show ?thesis unfolding Suc.prems by blast
        next
          case False

          obtain p where *: "path Cod (^⇓ \⋆⌋⌊⋆>⋆<b⌋"
            using ‹q ∈ ?PS› by blast
          then have "length p = n"
            using False by force

          then show ?thesis
            using * False unfolding Suc.prems by blast
        qed
      qed
      ultimately show ?thesis
        by blast
    qed

    have p3: "(∧q. (assignment' q = None) = (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n))"
    and p4: "(∧q p. assignment' q = Some p ==> path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n)"
    and p5: "dom assignment' = ?nexts' ∪ ?dones'"
    proof -

      have "dom transition_choice = set targets"
        unfolding d3 d2 by auto

      show "dom assignment' = ?nexts' ∪ ?dones'"
        by (simp add: ‹dom assignment = nexts ∪ dones› d4)

      have helper: "∧ f P (n::nat) . {x . (∃ y . P x y ∧ f y = n) ∧ (∄ y . P x y ∧ f y < n)} ∪ {x . (∃ y . P x y ∧ f y < n)}= {x . (∃ y . P x y ∧ f y ≤ n)}"
        by force
      
      have dom': "dom assignment' = {q. ∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n}"
        unfolding ‹dom assignment' = ?nexts' ∪ ?dones'› p1 p2
        using helper[of "λ q p . path M (FSM.initial M) p ∧ target (FSM.initial M) p = q" length "Suc n"] by force


      have *: "∧ q . q ∈ ?nexts' ==> ∃ p . assignment' q = Some p ∧ path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n"
      proof -
        fix q assume "q ∈ ?nexts'"
        then obtain t where "transition_choice q = Some t"
          using ‹dom transition_choice = set targets› d2 d3 by blast
        then have "t ∈ set usable_transitions"
              and "t_target t = q"
              and "q ∈ set targets"
          unfolding d3 d2 using map_upds_map_set_left[of t_target usable_transitions q t] by auto
        then have "t_source t ∈ nexts" and "t ∈ transitions M"
          unfolding d1 using transitions_as_list_set[of M] by auto
        then obtain p where "assignment (t_source t) = Some p"
          using Suc.prems(1,3,4)
          by fastforce
        then have "path M (FSM.initial M) p ∧ target (FSM.initial M) p = t_source t ∧ length p ≤ n"
          using Suc.prems(4) by blast
        then have "path M (FSM.initial M) (p@[t]) ∧ target (FSM.initial M) (p@[t]) = q ∧ length (p@[t]) ≤ Suc n"
          using ‹t ∈ transitions M› ‹t_target t = q› by auto
        moreover have "assignment' q = Some (p@[t])"
        proof -
          have "assignment' q = [targets [↦] (map (λq' . case transition_choice q' of Some t → (case assignment (t_source t) of Some p → p@[t])) targets)] q"
            unfolding d4 using map_upds_overwrite[OF ‹q ∈ set targets›, of "map (λq' . case transition_choice q' of Some t → (case assignment (t_source t) of Some p → p@[t])) targets" assignment]
            by auto
          also have "… = Some (case transition_choice q of Some t → case assignment (t_source t) of Some p → p @ [t])"
            using map_upds_map_set_right[OF ‹q ∈ set targets›] by auto
          also have "… = Some (p@[t])"
            using ‹transition_choice q = Some t› ‹assignment (t_source t) = Some p› by simp
          finally show ?thesis .
        qed
        ultimately show "∃ p . assignment' q = Some p ∧ path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n"
          by simp
      qed
      
      show "(∧q. (assignment' q = None) = (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n))"
        using dom' by blast
      
      show "(∧q p. assignment' q = Some p ==> path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n)"
      proof -
        fix q p assume "assignment' q = Some p"

        show "path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ Suc n"
        proof (cases "q ∈ ?nexts'")
          case True
          show ?thesis using *[OF True] ‹assignment' q = Some p›
            by simp
        next
          case False
          moreover have "∧ q . assignment q ≠ assignment' q ==> q ∈ ?nexts'"
            unfolding d4
            by (metis (no_types) map_upds_apply_nontin)
          ultimately have "assignment' q = assignment q"
            by force
          then show ?thesis
            using Suc.prems(4) ‹assignment' q = Some p›
            by (simp add: le_SucI)
        qed
      qed
    qed


    have "∧ q . (reaching_paths_up_to_depth M (set targets) (nexts ∪ dones) assignment' k q = None) =
          (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ n + Suc k) ∧
          (reaching_paths_up_to_depth M (set targets) (nexts ∪ dones) assignment' k q = Some p ⟶
           path M (FSM.initial M) p ∧ target (                                        u\⌊⋆⌋⌊\boldjava.lang.StringIndexOutOfBoundsException: Range [154, 153) out of bounds for length 226
      using Suc.IH[OF p1 p2 p3 p4 p5] by auto

    moreover have "(q ∈ nexts ∪
    proof -
      have "∧ q . (q ∈ set targets ∪ (java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 41
        using Suc.IH[OF p1 p2 p3 p4 p5] by auto
      "\And q . assignment q ≠ assignment' q ==> q ∈ ?nexts'"
        unfolding d4
        by (metis (no_types) map_upds_apply_nontin)
      ultimately show ?thesis
        unfolding d5
        by (metis (mono_tags, lifting) Un_iff mem_Collect_eq p1 p2)
    qed
    ultimately show ?case
      unfolding d5 by blast
  qed

  then show "((reaching_paths_up_to_depth M nexts dones assignment k) q = None) = (∄p . path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n+k)"
        and "((reaching_paths_up_to_depth M nexts dones assignment k) q = Some p) ==> path M (initial M) p ∧ target (initial M) p = q ∧ length p ≤ n+k"
        and "q ∈ nexts ∪ dones ==> (reaching_paths_up_to_depth M nexts dones assignment k) q = assignment q"
    by blast+
qed



fun get_state_cover_assignment :: "('a::linorder,'b::linorder,'c::linorder) fsm → ('a,'b,'c) state_cover_assignment" where
  "get_state_cover_assignment M = (let 
      path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)
    in (λ q . case path_assignments q of Some p → p_io p | None → []))"



lemma get_state_cover_assignment_is_state_cover_assignment :
  "is_state_cover_assignment M (get_state_cover_assignment M)"
  unfolding is_state_cover_assignment.simps
proof

  define path_assignments where "path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)"
  then have *:"∧ q . get_state_cover_assignment M q = (case path_assignments q of Some p → p_io p | None → [])"
    by auto
    

  have c1: " {FSM.initial M} =
    {q. (∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p = 0) ∧
      (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < 0)}"
    by auto
  have c2: "{} = {q. ∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < 0}"
    by auto
  have c3: "(∧q. ([FSM.initial M ↦ []] q = None) =
        (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ 0))" by auto
  have c4: "(∧q p. [FSM.initial M ↦ []] q = Some p ==>
          path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ 0)"
    by (metis (no_types, lifting) c3 le_zero_eq length_0_conv map_upd_Some_unfold option.discI)
  have c5: "dom [FSM.initial M ↦ []] = {FSM.initial M} ∪ {}"
    by simp

  have p1: "∧ q . (path_assignments q = None) =
                   (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ (FSM.size M - 1))"
   and p2: "∧ q p . path_assignments q = Some p ==>
                     path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ (FSM.size M - 1)"
   and p3: "path_assignments (initial M) = Some []"
    unfolding ‹path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)›
    using reaching_paths_up_to_depth_set[OF c1 c2 c3 c4 c5] by auto

  show "get_state_cover_assignment M (FSM.initial M) = []"
    unfolding * p3 by auto

  show "∀q∈reachable_states M. q ∈ io_targets M (get_state_cover_assignment M q) (FSM.initial M)"
  proof
    fix q assume "q ∈ reachable_states M"
    then have "q ∈ reachable_k M (FSM.initial M) (FSM.size M - 1)"
      using reachable_k_states by metis
    then obtain p where "target (initial M) p = q" and "path M (initial M) p" and "length p ≤ size M - 1"
      by auto
    then have "path_assignments q ≠ None"
      using p1 by fastforce
    then obtain p' where "get_state_cover_assignment M q = p_io p'"
                     and "path M (FSM.initial M) p'" and "target (FSM.initial M) p' = q"
      using p2 unfolding * by force
    then show "q ∈ io_targets M (get_state_cover_assignment M q) (initial M)"
      unfolding io_targets.simps unfolding ‹get_state_cover_assignment M q = p_io p'› by blast
  qed
qed



subsection ‹Computing Reachable States via State Cover Computation›


lemma restrict_to_reachable_states[code]:
  "restrict_to_reachable_states M = (let 
      path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦by
    in filter_states M (λ q . path_assignments q ≠ None))"
proof -
  define path_assignments where "path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)"
  then have *: "(let 
      path_assignments =                 using uv u w Nmlize_Hcomp Nmlize_Nmjava.lang.StringIndexOutOfBoundsException: Range [76, 71) out of bounds for length 79
    in filter_states M (λ q . path_assignments q ≠ None)) = filter_states M (λ q . path_assignments q ≠
    by simp

   {SM.M}=
    {q. (∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p = 0) ∧
      (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < 0)}"
    by auto
  have c2: "{} = {q. ∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < 0}"
    by auto
  have c3: "(∧q. ([FSM.initial M ↦ []] q = None) =
        (∄p. path M(FSMinitial M) p∧) p=q and length p ≤
  have c4: "(∧q p. [FSM.initial M ↦ []] q = Some p ==>
          path M (FSM.initial M) p ∧ Cod (u \<Down> w)) = u \^><star> <^old\rv<^old><sta>w<o>\rfloor>"
    by (metis (no_types, lifting) c3 le_zero_eq length_0_conv map_upd_Some_unfold option.discI) 
  have c5: "dom [FSM.initial M ↦ []] = {FSM.initial M} ∪ {}"
    by simp

  have p1: "∧ q . (path_assignments q = None) =
                   (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ (FSM.size M - 1))"
   and p2: "∧ q p . path_assignments q = Some p ==>
                     path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ (FSM.size M - 1)"
   and p3: "path_assignments (initial M) = Some []"
    unfolding ‹path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)›
    using reaching_paths_up_to_depth_set[OF c1 c2 c3 c4 c5] by auto


  have "∧ q . path_assignments q ≠ None ⟷ q ∈ reachable_states M"
  proof 
    show "∧q. path_assignments q ≠ None ==> q ∈ reachable_states M"
      using p2 unfolding reachable_states_def
      by blast 
    show "∧q. q ∈ reachable_states M ==> path_assignments q ≠ None"
    proof -
      fix q assume "q ∈ reachable_states M"
      then have "q ∈ reachable_k M (FSM.initial M) (FSM.size M - 1)"
        using reachable_k_states by metis
      then obtain p where "target (initial M) p = q" and "path M (initial M) p" and "length p ≤ size M - 1"
        by auto
      then show "path_assignments q ≠ None"
        using p1 by fastforce
    qed
  qed
  then show ?thesis
    unfolding restrict_to_reachable_states.simps * by simp
qed

lemma reachable_states_refined[code] : 
  "reachable_states M = (let
      path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)
    in Set.filter (λ q . path_assignments q ≠ None) (states M))"
proof -
  define path_assignments where "path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)"    
  then have *: "(let
      path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)
    in Set.filter (λ q . path_assignments q ≠ None) (states M)) = Set.filter (λ q . path_assignments q ≠ None) (states M)"
    by simp

  have c1: " {FSM.initial M} =
    {q. (∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p = 0) ∧
      (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < 0)}" 
    by auto
  have c2:  "{} = {q. ∃p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p < 0}"
    by auto
  have c3: "(∧q. ([FSM.initial M ↦ []] q = None) =
        (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ 0))" by auto
  have c4: "(∧q p. [FSM.initial M ↦ []] q = Some p ==>
          path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ 0)"
    by (metis (no_types, lifting) c3 le_zero_eq length_0_conv map_upd_Some_unfold option.discI) 
  have c5: "dom [FSM.initial M ↦ []] = {FSM.initial M} ∪ {}"
    by simp

  have p1: "∧ q . (path_assignments q = None) =
                   (∄p. path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ (FSM.size M - 1))"
   and p2: "∧ q p . path_assignments q = Some p ==>
                     path M (FSM.initial M) p ∧ target (FSM.initial M) p = q ∧ length p ≤ (FSM.size M - 1)"
   and p3: "path_assignments (initial M) = Some []"
    unfolding ‹path_assignments = reaching_paths_up_to_depth M {initial M} {} [initial M ↦ []] (size M -1)›
    using reaching_paths_up_to_depth_set[OF c1 c2 c3 c4 c5] by auto


  have "∧ q . path_assignments q ≠ None ⟷ q ∈ reachable_states M"
  proof 
    show "∧q. path_assignments q ≠ None ==> q ∈ reachable_states M"
      using p2 unfolding reachable_states_def
      by blast 
    show "∧q. q ∈ reachable_states M ==> path_assignments q ≠ None"
    proof -
      fix q assume "q ∈ reachable_states M"
      then have "q ∈ reachable_k M (FSM.initial M) (FSM.size M - 1)"
        using reachable_k_states by metis
      then obtain p where "target (initial M) p = q" and "path M (initial M) p" and "length p ≤ size M - 1"
        by auto
      then show "path_assignments q ≠ None"
        using p1 by fastforce
    qed
  qed
  then show ?thesis
    unfolding * using reachable_state_is_statebyce
qed


lemma minimal_sequence_to_failure_from_state_cover_assignment_ob :
  assumes "L M ≠ L I"
  and     "is_state_cover_assignment M V"
  and     "(L M ∩ (V ` reachable_states M)) = (L I ∩ (V ` reachable_states M))"
obtains ioT ioX where java.lang.NullPointerException
                  and "ioT @ ioX ∈ (L M - Lhave⌊u \⌊ java.lang.StringIndexOutOfBoundsException: Range [82, 81) out of bounds for length 236
                  and "∧ rahbesae <Longri> (V q)@o <in>( )<uni> LI-LM <Longri> lnt o <l> eghi"
proof -

  let ?exts = "{io . ∃ q ∈ reachable_states M . (V q)@io ∈
  define exMin where exMin: "exMin = arg_min length (λ io . io ∈ ?exts)"
  
  have "V (initial M) = []"
    using assms(2) by auto
  moreover have "∃ io . io ∈ (L M - L I) ∪ (L I - L M)"
     lso he"   🚫
 "<oeq {}
    using reachable_states_initial by (metis (mono_tags, lifting) append_self_conv2 empty_iff mem_Collect_eq)
  then have "exMin ∈ ?exts ∧ (∀ io' . io' ∈
    using exMin arg_min_nat_lemma by (metis (no_types, lifting) all_not_in_conv)
  then show ?thesis 
    usingthat byjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
qed


end

Messung
CHZG
859710094

¤ Dauer der Verarbeitung: 0.7 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.