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

Quelle  FSM_Impl.thy

  Sprache: Isabelle
 

section Underlying FSM Representation

text This theory contains the underlying datatype for (possibly not well-formed) finite state machines.

theory FSM_Impl
  imports Util Datatype_Order_Generator.Order_Generator "HOL-Library.FSet"
begin


text A finite state machine (FSM) is represented using its classical definition:

datatype ('state, 'input, 'output) fsm_impl = FSMI (initial : 'state)  
                                                  (states  : "'state set")
                                                  (inputs  : "'input set")
                                                  (outputs : "'output set")
                                                  (transitions : "('state × 'input × 'output × 'state) set")


subsection Types for Transitions and Paths

type_synonym ('a,'b,'c) transition = "('a × 'b × 'c × 'a)"
type_synonym ('a,'b,'c) path = "('a,'b,'c) transition list"

abbreviation "t_source (a :: ('a,'b,'c) transition) fst a" 
abbreviation "t_input (a :: ('a,'b,'c) transition) fst (snd a)"
abbreviation "t_output (a :: ('a,'b,'c) transition) fst (snd (snd a))"
abbreviation "t_target (a :: ('a,'b,'c) transition) snd (snd (snd a))"

subsection Basic Algorithms on FSM

subsubsection Reading FSMs from Lists

fun fsm_impl_from_list :: "'a ==>
                           ('a,'b,'c) transition list ==>
                           ('a, 'b, 'c) fsm_impl" 
  where
  "fsm_impl_from_list q [] = FSMI q {q} {} {} {}" |
  "fsm_impl_from_list q (t#ts) =
    (let ts' = set (t#ts)
     in FSMI (t_source t)
             ((image t_source ts') (image t_target ts'))
             (image t_input ts')
             (image t_output ts')
             (ts'))"

fun fsm_impl_from_list' :: "'a ==> ('a,'b,'c) transition list ==> ('a, 'b, 'c) fsm_impl" where
  "fsm_impl_from_list' q [] = FSMI q {q} {} {} {}" |
  "fsm_impl_from_list' q (t#ts) = (let tsr = (remdups (t#ts))
                                   in FSMI (t_source t)
                                      (set (remdups ((map t_source tsr) @ (map t_target tsr))))
                                      (set (remdups (map t_input tsr)))
                                      (set (remdups (map t_output tsr)))
                                      (set tsr))"

lemma fsm_impl_from_list_code[code] :
  "fsm_impl_from_list q ts = fsm_impl_from_list' q ts" 
  by (cases ts; auto)


subsubsection Changing the initial State

fun from_FSMI :: "('a,'b,'c) fsm_impl ==> 'a ==> ('a,'b,'c) fsm_impl" where
  "from_FSMI M q = (if q states M then FSMI q (states M) (inputs M) (outputs M) (transitions M) else M)"


subsubsection Product Construction

fun product :: "('a,'b,'c) fsm_impl ==> ('d,'b,'c) fsm_impl ==> ('a × 'd,'b,'c) fsm_impl" where
  "product A B = FSMI ((initial A, initial B))
                     ((states A) × (states B))
                     (inputs A inputs B)
                     (outputs A outputs B)
                     {((qA,qB),x,y,(qA',qB')) | qA qB x y qA' qB' . (qA,x,y,qA') transitions A (qB,x,y,qB') transitions B}"

lemma product_code_naive[code] :
  "product A B = FSMI ((initial A, initial B))
                     ((states A) × (states B))
                     (inputs A inputs B)
                     (outputs A outputs B)
                     (image (λ((qA,x,y,qA'), (qB,x',y',qB')) . ((qA,qB),x,y,(qA',qB'))) (Set.filter (λ((qA,x,y,qA'), (qB,x',y',qB')) . x = x' y = y') ((image (λ tA . image (λ tB . (tA,tB)) (transitions B)) (transitions A)))))"
  (is "?P1 = ?P2")
proof -
  have "((image (λ tA . image (λ tB . (tA,tB)) (transitions B)) (transitions A))) = {(tA,tB) | tA tB . tA transitions A tB transitions B}"
    by auto
  then have "(Set.filter (λ((qA,x,y,qA'), (qB,x',y',qB')) . x = x' y = y') ((image (λ tA . image (λ tB . (tA,tB)) (transitions B)) (transitions A)))) = {((qA,x,y,qA'),(qB,x,y,qB')) | qA qB x y qA' qB' . (qA,x,y,qA') transitions A (qB,x,y,qB') transitions B}"
    by auto
  then have "image (λ((qA,x,y,qA'), (qB,x',y',qB')) . ((qA,qB),x,y,(qA',qB'))) (Set.filter (λ((qA,x,y,qA'), (qB,x',y',qB')) . x = x' y = y') ((image (λ tA . image (λ tB . (tA,tB)) (transitions B)) (transitions A))))
              = image (λ((qA,x,y,qA'), (qB,x',y',qB')) . ((qA,qB),x,y,(qA',qB'))) {((qA,x,y,qA'),(qB,x,y,qB')) | qA qB x y qA' qB' . (qA,x,y,qA') transitions A (qB,x,y,qB') transitions B}"
    by auto
  moreover have "image (λ((qA,x,y,qA'), (qB,x',y',qB')) . ((qA,qB),x,y,(qA',qB'))) {((qA,x,y,qA'),(qB,x,y,qB')) | qA qB x y qA' qB' . (qA,x,y,qA') transitions A (qB,x,y,qB') transitions B} = {((qA,qB),x,y,(qA',qB')) | qA qB x y qA' qB' . (qA,x,y,qA') transitions A (qB,x,y,qB') transitions B}"
    by force
  ultimately have "transitions ?P1 = transitions ?P2" 
    unfolding product.simps by auto
  moreover have "initial ?P1 = initial ?P2" by auto
  moreover have "states ?P1 = states ?P2" by auto
  moreover have "inputs ?P1 = inputs ?P2" by auto
  moreover have "outputs ?P1 = outputs ?P2" by auto
  ultimately show ?thesis by auto
qed


subsubsection Filtering Transitions

fun filter_transitions :: "('a,'b,'c) fsm_impl ==> (('a,'b,'c) transition ==> bool) ==> ('a,'b,'c) fsm_impl" where
  "filter_transitions M P = FSMI (initial M)
                                (states M)
                                (inputs M)
                                (outputs M)
                                (Set.filter P (transitions M))"


subsubsection Filtering States

fun filter_states :: "('a,'b,'c) fsm_impl ==> ('a ==> bool) ==> ('a,'b,'c) fsm_impl" where
  "filter_states M P = (if P (initial M) then FSMI (initial M)
                                                  (Set.filter P (states M))
                                                  (inputs M)
                                                  (outputs M)
                                                  (Set.filter (λ t . P (t_source t) P (t_target t)) (transitions M))
                                         else M)"
 
subsubsection Initial Singleton FSMI (For Trivial Preamble)    

fun initial_singleton :: "('a,'b,'c) fsm_impl ==> ('a,'b,'c) fsm_impl" where
  "initial_singleton M = FSMI (initial M)
                             {initial M}
                             (inputs M)
                             (outputs M)
                             {}"


subsubsection Canonical Separator

abbreviation "shift_Inl t (Inl (t_source t),t_input t, t_output t, Inl (t_target t))"

definition shifted_transitions :: "(('a × 'a) × 'b × 'c × ('a × 'a)) set ==> ((('a × 'a) + 'd) × 'b × 'c × (('a × 'a) + 'd)) set" where
  "shifted_transitions ts = image shift_Inl ts"

definition distinguishing_transitions :: "(('a × 'b) ==> 'c set) ==> 'a ==> 'a ==> ('a × 'a) set ==> 'b set ==> ((('a × 'a) + 'a) × 'b × 'c × (('a × 'a) + 'a)) set" where
  "distinguishing_transitions f q1 q2 stateSet inputSet = (Set.image (λ((q1',q2'),x) .
                                                                (image (λy . (Inl (q1',q2'),x,y,Inr q1)) (f (q1',x) - f (q2',x)))
                                                                 (image (λy . (Inl (q1',q2'),x,y,Inr q2)) (f (q2',x) - f (q1',x))))
                                                            (stateSet × inputSet))"



(* Note: parameter P is added to allow usage of different restricted versions of the product machine *)
fun canonical_separator' :: "('a,'b,'c) fsm_impl ==> (('a × 'a),'b,'c) fsm_impl ==> 'a ==> 'a ==> (('a × 'a) + 'a,'b,'c) fsm_impl" where
  "canonical_separator' M P q1 q2 = (if initial P = (q1,q2)
  then
    (let f' = set_as_map (image (λ(q,x,y,q') . ((q,x),y)) (transitions M));
         f = (λqx . (case f' qx of Some yqs ==> yqs | None ==> {}));
         shifted_transitions' = shifted_transitions (transitions P);
         distinguishing_transitions_lr = distinguishing_transitions f q1 q2 (states P) (inputs P);
         ts = shifted_transitions' distinguishing_transitions_lr
     in
  
      FSMI (Inl (q1,q2))
      ((image Inl (states P)) {Inr q1, Inr q2})
      (inputs M inputs P)
      (outputs M outputs P)
      (ts))
  else FSMI (Inl (q1,q2)) {Inl (q1,q2)} {} {} {})"

lemma h_out_impl_helper: "(λ (q,x) . {y . q' . (q,x,y,q') A}) = (λqx . (case (set_as_map (image (λ(q,x,y,q') . ((q,x),y)) A)) qx of Some yqs ==> yqs | None ==> {}))"
proof 
  fix qx 
  show "(λ (q,x) . {y . q' . (q,x,y,q') A}) qx = (λqx . (case (set_as_map (image (λ(q,x,y,q') . ((q,x),y)) A)) qx of Some yqs ==> yqs | None ==> {})) qx"
  proof -
    obtain q x where "qx = (q,x)" using prod.exhaust by metis
    have **: " z . ((q, x), z) (λ(q, x, y, q'). ((q, x), y)) ` A = (z {y . q' . (q,x,y,q') A})"
      by force
    show ?thesis unfolding qx = (q,x) case_prod_conv set_as_map_def 
      unfolding ** by auto
  qed
qed

lemma canonical_separator'_simps :
        "initial (canonical_separator' M P q1 q2) = Inl (q1,q2)"
        "states (canonical_separator' M P q1 q2) = (if initial P = (q1,q2) then (image Inl (states P)) {Inr q1, Inr q2} else {Inl (q1,q2)})"
        "inputs (canonical_separator' M P q1 q2) = (if initial P = (q1,q2) then inputs M inputs P else {})"
        "outputs (canonical_separator' M P q1 q2) = (if initial P = (q1,q2) then outputs M outputs P else {})"
        "transitions (canonical_separator' M P q1 q2) = (if initial P = (q1,q2) then shifted_transitions (transitions P) distinguishing_transitions (λ (q,x) . {y . q' . (q,x,y,q') transitions M}) q1 q2 (states P) (inputs P) else {})"
  unfolding h_out_impl_helper by (simp add: Let_def)+



subsubsection Generalised Canonical Separator

text A variation on the state separator that uses states @{text "L"} and @{text "R"} instead of
 @{text "Inr q1"} and @{text "Inr q2"} to indicate targets of transitions in the
 canonical separator that are available only for the left or right component of a state pair


text Note: this definition of a canonical separator might serve as a way to avoid recalculation
 of state separators for different pairs of states, but is currently not fully
 implemented


datatype LR = Left | Right
derive linorder LR

definition distinguishing_transitions_LR :: "(('a × 'b) ==> 'c set) ==> ('a × 'a) set ==> 'b set ==> ((('a × 'a) + LR) × 'b × 'c × (('a × 'a) + LR)) set" where
  "distinguishing_transitions_LR f stateSet inputSet = (Set.image (λ((q1',q2'),x) .
                                                                (image (λy . (Inl (q1',q2'),x,y,Inr Left)) (f (q1',x) - f (q2',x)))
                                                                 (image (λy . (Inl (q1',q2'),x,y,Inr Right)) (f (q2',x) - f (q1',x))))
                                                            (stateSet × inputSet))"


fun canonical_separator_complete' :: "('a,'b,'c) fsm_impl ==> (('a × 'a) + LR,'b,'c) fsm_impl" where
  "canonical_separator_complete' M =
    (let P = product M M;
         f' = set_as_map (image (λ(q,x,y,q') . ((q,x),y)) (transitions M));
         f = (λqx . (case f' qx of Some yqs ==> yqs | None ==> {}));
         shifted_transitions' = shifted_transitions (transitions P);
         distinguishing_transitions_lr = distinguishing_transitions_LR f (states P) (inputs P);
         ts = shifted_transitions' distinguishing_transitions_lr
     in
      FSMI (Inl (initial P))
          ((image Inl (states P)) {Inr Left, Inr Right})
          (inputs M inputs P)
          (outputs M outputs P)
          ts )"



subsubsection Adding Transitions

fun add_transitions :: "('a,'b,'c) fsm_impl ==> ('a,'b,'c) transition set ==> ('a,'b,'c) fsm_impl" where
  "add_transitions M ts = (if ( t ts . t_source t states M t_input t inputs M t_output t outputs M t_target t states M)
    then FSMI (initial M)
             (states M)
             (inputs M)
             (outputs M)
             ((transitions M) ts)
    else M)"


subsubsection Creating an FSMI without transitions

fun create_unconnected_FSMI :: "'a ==> 'a set ==> 'b set ==> 'c set ==> ('a,'b,'c) fsm_impl" where
  "create_unconnected_FSMI q ns ins outs = (if (finite ns finite ins finite outs)
    then FSMI q (insert q ns) ins outs {}
    else FSMI q {q} {} {} {})"

fun create_unconnected_fsm_from_lists :: "'a ==> 'a list ==> 'b list ==> 'c list ==> ('a,'b,'c) fsm_impl" where
  "create_unconnected_fsm_from_lists q ns ins outs = FSMI q (insert q (set ns)) (set ins) (set outs) {}"

fun create_unconnected_fsm_from_fsets :: "'a ==> 'a fset ==> 'b fset ==> 'c fset ==> ('a,'b,'c) fsm_impl" where
  "create_unconnected_fsm_from_fsets q ns ins outs = FSMI q (insert q (fset ns)) (fset ins) (fset outs) {}"

fun create_fsm_from_sets :: "'a ==> 'a set ==> 'b set ==> 'c set ==> ('a,'b,'c) transition set ==> ('a,'b,'c) fsm_impl" where
  "create_fsm_from_sets q qs ins outs ts = (if q qs finite qs finite ins finite outs
    then add_transitions (FSMI q qs ins outs {}) ts
    else FSMI q {q} {} {} {})"
 

subsection Transition Function h

text Function @{text "h"} represents the classical view of the transition relation of an FSM @{text "M"} as a
 function: given a state @{text "q"} and an input @{text "x"}, @{text "(h M) (q,x)"} returns all
 possibly reactions @{text "(y,q')"} of @{text "M"} in state @{text "q"} to @{text "x"}, where
 @{text "y"} is the produced output and @{text "q'"} the target state of the reaction transition.


fun h :: "('state, 'input, 'output) fsm_impl ==> ('state × 'input) ==> ('output × 'state) set" where
  "h M (q,x) = { (y,q') . (q,x,y,q') transitions M }"

fun h_obs :: "('a,'b,'c) fsm_impl ==> 'a ==> 'b ==> 'c ==> 'a option" where
  "h_obs M q x y = (let
      tgts = snd ` Set.filter (λ (y',q') . y' = y) (h M (q,x))
    in if card tgts = 1
      then Some (the_elem tgts)
      else None)"

lemma h_code[code] : 
  "h M (q,x) = (let m = set_as_map (image (λ(q,x,y,q') . ((q,x),y,q')) (transitions M))
                 in (case m (q,x) of Some yqs ==> yqs | None ==> {}))"
  unfolding set_as_map_def by force


subsection Extending FSMs by single elements

fun add_transition :: "('a,'b,'c) fsm_impl ==>
                       ('a,'b,'c) transition ==>
                       ('a,'b,'c) fsm_impl" 
  where
  "add_transition M t =
    (if t_source t states M t_input t inputs M
        t_output t outputs M t_target t states M
     then FSMI (initial M)
               (states M)
               (inputs M)
               (outputs M)
               (insert t (transitions M))
     else M)"

fun add_state :: "('a,'b,'c) fsm_impl ==> 'a ==> ('a,'b,'c) fsm_impl" where
  "add_state M q = FSMI (initial M) (insert q (states M)) (inputs M) (outputs M) (transitions M)"

fun add_input :: "('a,'b,'c) fsm_impl ==> 'b ==> ('a,'b,'c) fsm_impl" where
  "add_input M x = FSMI (initial M) (states M) (insert x (inputs M)) (outputs M) (transitions M)"

fun add_output :: "('a,'b,'c) fsm_impl ==> 'c ==> ('a,'b,'c) fsm_impl" where
  "add_output M y = FSMI (initial M) (states M) (inputs M) (insert y (outputs M)) (transitions M)"

fun add_transition_with_components :: "('a,'b,'c) fsm_impl ==> ('a,'b,'c) transition ==> ('a,'b,'c) fsm_impl" where
  "add_transition_with_components M t = add_transition (add_state (add_state (add_input (add_output M (t_output t)) (t_input t)) (t_source t)) (t_target t)) t"

subsection Renaming elements

fun rename_states :: "('a,'b,'c) fsm_impl ==> ('a ==> 'd) ==> ('d,'b,'c) fsm_impl" where
  "rename_states M f = FSMI (f (initial M))
                            (f ` states M)
                            (inputs M)
                            (outputs M)
                            ((λt . (f (t_source t), t_input t, t_output t, f (t_target t))) ` transitions M)"
                              

end

Messung V0.5 in Prozent
C=92 H=98 G=94

¤ Dauer der Verarbeitung: 0.6 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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.