Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Rewriting.thy

  Sprache: Isabelle
 

(*
    Author:   Salomon Sickert
    Author:   Benedikt Seidl
    Author:   Alexander Schimpf (original entry: CAVA/LTL_Rewrite.thy)
    License:  BSD
*)


section Rewrite Rules for LTL Simplification

theory Rewriting
imports
  LTL "HOL-Library.Extended_Nat"
begin

text This theory provides rewrite rules for the simplification of LTL formulas. It supports:
 \begin{itemize}
 \item Constants Removal
 \item @{const Next_ltln}-Normalisation
 \item Modal Simplification (based on pure eventual, pure universal, or suspendable formulas)
 \item Syntactic Implication Checking
 \end{itemize}
 It reuses parts of LTL\_Rewrite.thy (CAVA, LTL\_TO\_GBA). Furthermore, some rules were taken from
 cite"DBLP:conf/cav/SomenziB00" and cite"DBLP:conf/tacas/BabiakKRS12". All functions are defined for @{type ltln}.




subsection Constant Eliminating Constructors

definition mk_and
where
  "mk_and x y case x of falsen ==> falsen | truen ==> y | _ ==> (case y of falsen ==> falsen | truen ==> x | _ ==> x andn y)"

definition mk_or
where
  "mk_or x y case x of falsen ==> y | truen ==> truen | _ ==> (case y of truen ==> truen | falsen ==> x | _ ==> x orn y)"

fun remove_strong_ops
where
  "remove_strong_ops (x Un y) = remove_strong_ops y"
"remove_strong_ops (x Mn y) = x andn y"
"remove_strong_ops (x orn y) = remove_strong_ops x orn remove_strong_ops y"
"remove_strong_ops x = x"

fun remove_weak_ops
where
  "remove_weak_ops (x Rn y) = remove_weak_ops y"
"remove_weak_ops (x Wn y) = x orn y"
"remove_weak_ops (x andn y) = remove_weak_ops x andn remove_weak_ops y"
"remove_weak_ops x = x"

definition mk_finally
where
  "mk_finally x case x of truen ==> truen | falsen ==> falsen | _ ==> Fn (remove_strong_ops x)"

definition mk_globally
where
  "mk_globally x case x of truen ==> truen | falsen ==> falsen | _ ==> Gn (remove_weak_ops x)"

definition mk_until
where
  "mk_until x y case x of falsen ==> y
    | truen ==> mk_finally y
    | _ ==> (case y of truen ==> truen | falsen ==> falsen | _ ==> x Un y)"

definition mk_release
where
  "mk_release x y case x of truen ==> y
    | falsen ==> mk_globally y
    | _ ==> (case y of truen ==> truen | falsen ==> falsen | _ ==> x Rn y)"

definition mk_weak_until
where
  "mk_weak_until x y case y of truen ==> truen
    | falsen ==> mk_globally x
    | _ ==> (case x of truen ==> truen | falsen ==> y | _ ==> x Wn y)"

definition mk_strong_release
where
  "mk_strong_release x y case y of falsen ==> falsen
    | truen ==> mk_finally x
    | _ ==> (case x of truen ==> y | falsen ==> falsen | _ ==> x Mn y)"

definition mk_next
where
  "mk_next x case x of truen ==> truen | falsen ==> falsen | _ ==> Xn x"

definition mk_next_pow (Xn'')
where
  "mk_next_pow n x case x of truen ==> truen | falsen ==> falsen | _ ==> (Next_ltln ^^ n) x"



lemma mk_and_semantics [simp]:
  "w n mk_and x y w n x andn y"
  unfolding mk_and_def by (cases x; cases y; simp)

lemma mk_or_semantics [simp]:
  "w n mk_or x y w n x orn y"
  unfolding mk_or_def by (cases x; cases y; simp)

lemma remove_strong_ops_sound [simp]:
  "w n Fn (remove_strong_ops y) w n Fn y"
  by (induction y arbitrary: w) (auto; force)+

lemma remove_weak_ops_sound [simp]:
  "w n Gn (remove_weak_ops y) w n Gn y"
  by (induction y arbitrary: w) (auto; force)+

lemma mk_finally_semantics [simp]:
  "w n mk_finally x w n Fn x"
  by (simp add: mk_finally_def del: semantics_ltln.simps(8,9) remove_strong_ops.simps split: ltln.splits)

lemma mk_globally_semantics [simp]:
  "w n mk_globally x w n Gn x"
  by (simp add: mk_globally_def del: semantics_ltln.simps(8,9) remove_weak_ops.simps split: ltln.splits)

lemma mk_until_semantics [simp]:
  "w n mk_until x y w n x Un y"
proof (cases x)
  case (True_ltln)
    show ?thesis
      unfolding True_ltln mk_until_def
      by (cases y) auto
next
  case (False_ltln)
    thus ?thesis
      by (force simp: mk_until_def)
qed (cases y; force simp: mk_until_def)+

lemma mk_release_semantics [simp]:
  "w n mk_release x y w n x Rn y"
proof (cases x)
  case (False_ltln)
    thus ?thesis
      unfolding False_ltln mk_release_def
      by (cases y) auto
next
  case (True_ltln)
    thus ?thesis
      by (force simp: mk_release_def)
qed (cases y; force simp: mk_release_def)+

lemma mk_weak_until_semantics [simp]:
  "w n mk_weak_until x y w n x Wn y"
proof (cases y)
  case (False_ltln)
    thus ?thesis
      unfolding False_ltln mk_weak_until_def
      by (cases x) auto
next
  case (True_ltln)
    thus ?thesis
      by (force simp: mk_weak_until_def)
qed (cases x; force simp: mk_weak_until_def)+

lemma mk_strong_release_semantics [simp]:
  "w n mk_strong_release x y w n x Mn y"
proof (cases y)
  case (True_ltln)
    show ?thesis
      unfolding True_ltln mk_strong_release_def
      by (cases x) auto
next
  case (False_ltln)
    thus ?thesis
      by (force simp: mk_strong_release_def)
qed (cases x; force simp: mk_strong_release_def)+

lemma mk_next_semantics [simp]:
  "w n mk_next x w n Xn x"
  unfolding mk_next_def by (cases x; auto)

lemma mk_next_pow_semantics [simp]:
  "w n mk_next_pow i x suffix i w n x"
  by (induction i arbitrary: w; cases x)
     (auto simp: mk_next_pow_def)

lemma mk_next_pow_simp [simp, code_unfold]:
  "mk_next_pow 0 x = x"
  "mk_next_pow 1 x = mk_next x"
  by (cases x; simp add: mk_next_pow_def mk_next_def)+



subsection Constant Propagation

fun is_constant :: "'a ltln ==> bool"
where
  "is_constant truen = True"
"is_constant falsen = True"
"is_constant _ = False"

lemma is_constant_constructorsI:
  "is_constant x ==> is_constant y ==> is_constant (mk_and x y)"
  "¬is_constant x ==> ¬is_constant y ==> ¬is_constant (mk_and x y)"
  "is_constant x ==> is_constant y ==> is_constant (mk_or x y)"
  "¬is_constant x ==> ¬is_constant y ==> ¬is_constant (mk_or x y)"
  "is_constant x ==> is_constant (mk_finally x)"
  "¬is_constant x ==> ¬is_constant (mk_finally x)"
  "is_constant x ==> is_constant (mk_globally x)"
  "¬is_constant x ==> ¬is_constant (mk_globally x)"
  "is_constant x ==> is_constant (mk_until y x)"
  "¬is_constant x ==> ¬is_constant (mk_until y x)"
  "is_constant x ==> is_constant (mk_release y x)"
  "¬is_constant x ==> ¬is_constant (mk_release y x)"
  "is_constant x ==> is_constant y ==> is_constant (mk_weak_until x y)"
  "¬is_constant x ==> ¬is_constant y ==> ¬is_constant (mk_weak_until x y)"
  "is_constant x ==> is_constant y ==> is_constant (mk_strong_release x y)"
  "¬is_constant x ==> ¬is_constant y ==> ¬is_constant (mk_strong_release x y)"
  "is_constant x ==> is_constant (mk_next x)"
  "¬is_constant x ==> ¬is_constant (mk_next x)"
  "is_constant x ==> is_constant (mk_next_pow n x)"
  by (cases x; cases y; simp add: mk_and_def mk_or_def mk_finally_def mk_globally_def mk_until_def mk_release_def mk_weak_until_def mk_strong_release_def mk_next_def mk_next_pow_def)+

lemma is_constant_constructors_simps:
  "mk_next_pow n x = falsen x = falsen"
  "mk_next_pow n x = truen x = truen"
  "is_constant (mk_next_pow n x) is_constant x"
  by (induction n) (cases x; simp add: mk_next_pow_def)+

lemma is_constant_constructors_simps2:
  "is_constant (mk_and x y) (x = truen y = truen x = falsen y = falsen)"
  "is_constant (mk_or x y) (x = falsen y = falsen x = truen y = truen)"
  "is_constant (mk_finally x) is_constant x"
  "is_constant (mk_globally x) is_constant x"
  "is_constant (mk_until y x) is_constant x"
  "is_constant (mk_release y x) is_constant x"
  "is_constant (mk_next x) is_constant x"
  by ((cases x; cases y; simp add: mk_and_def),
      (cases x; cases y; simp add: mk_or_def),
      (meson is_constant_constructorsI)+)

lemma is_constant_constructors_simps3:
  "is_constant (mk_weak_until x y) (x = falsen y = falsen x = truen y = truen)"
  "is_constant (mk_strong_release x y) (x = truen y = truen x = falsen y = falsen)"
  by (cases x; cases y; simp add: mk_weak_until_def mk_strong_release_def is_constant_constructors_simps2)+

lemma is_constant_semantics:
  "is_constant φ ==> ((w. w n φ) ¬(w. w n φ))"
  by (cases φ) auto

lemma until_constant_simp:
  "is_constant ψ ==> w n φ Un ψ w n ψ"
  by (cases ψ) auto

lemma release_constant_simp:
  "is_constant ψ ==> w n φ Rn ψ w n ψ"
  by (cases ψ) auto

lemma mk_next_pow_dist:
  "mk_next_pow (i + j) φ = mk_next_pow i (mk_next_pow j φ)"
  by (cases j; simp) (cases φ; simp add: mk_next_pow_def funpow_add; simp add: funpow_swap1)

lemma mk_next_pow_until:
  "suffix (min i j) w n (mk_next_pow (i - j) φ) Un (mk_next_pow (j - i) ψ) w n (mk_next_pow i φ) Un (mk_next_pow j ψ)"
  by (simp add: mk_next_pow_dist min_def add.commute)

lemma mk_next_pow_release:
  "suffix (min i j) w n (mk_next_pow (i - j) φ) Rn (mk_next_pow (j - i) ψ) w n (mk_next_pow i φ) Rn (mk_next_pow j ψ)"
  by (simp add: mk_next_pow_dist min_def add.commute)

subsection X-Normalisation

text The following rewrite functions pulls the X-operator up in the syntax tree. This preprocessing
 step enables the removal of X-operators in front of suspendable formulas. Furthermore constants are
 removed as far as possible.


fun the_enat_0 :: "enat ==> nat"
where
  "the_enat_0 i = i"
"the_enat_0 = 0"

lemma the_enat_0_simp [simp]:
  "the_enat_0 0 = 0"
  "the_enat_0 1 = 1"
  by (simp add: zero_enat_def one_enat_def)+

fun combine :: "('a ltln ==> 'a ltln ==> 'a ltln) ==> ('a ltln * enat) ==> ('a ltln * enat) ==> ('a ltln * enat)"
where
  "combine binop (φ, i) (ψ, j) = (
    let
      χ = binop (mk_next_pow (the_enat_0 (i - j)) φ) (mk_next_pow (the_enat_0 (j - i)) ψ)
    in
      (χ, if is_constant χ then else min i j))"

lemma fst_combine:
  "fst (combine binop (φ, i) (ψ, j)) = binop (mk_next_pow (the_enat_0 (i - j)) φ) (mk_next_pow (the_enat_0 (j - i)) ψ)"
  unfolding combine.simps by (meson fstI)

abbreviation to_ltln :: "('a ltln * enat) ==> 'a ltln"
where
  "to_ltln x mk_next_pow (the_enat_0 (snd x)) (fst x)"

fun rewrite_X_enat :: "'a ltln ==> ('a ltln * enat)"
where
  "rewrite_X_enat truen = (truen, )"
"rewrite_X_enat falsen = (falsen, )"
"rewrite_X_enat propn(a) = (propn(a), 0)"
"rewrite_X_enat npropn(a) = (npropn(a), 0)"
"rewrite_X_enat (φ andn ψ) = combine mk_and (rewrite_X_enat φ) (rewrite_X_enat ψ)"
"rewrite_X_enat (φ orn ψ) = combine mk_or (rewrite_X_enat φ) (rewrite_X_enat ψ)"
"rewrite_X_enat (φ Un ψ) = combine mk_until (rewrite_X_enat φ) (rewrite_X_enat ψ)"
"rewrite_X_enat (φ Rn ψ) = combine mk_release (rewrite_X_enat φ) (rewrite_X_enat ψ)"
"rewrite_X_enat (φ Wn ψ) = combine mk_weak_until (rewrite_X_enat φ) (rewrite_X_enat ψ)"
"rewrite_X_enat (φ Mn ψ) = combine mk_strong_release (rewrite_X_enat φ) (rewrite_X_enat ψ)"
"rewrite_X_enat (Xn φ) = (λ(φ, n). (φ, eSuc n)) (rewrite_X_enat φ)"

definition
  "rewrite_X φ = to_ltln (rewrite_X_enat φ)"

lemma combine_infinity_invariant:
  assumes "i = is_constant x"
  assumes "j = is_constant y"
  shows "combine mk_and (x, i) (y, j) = (z, k) ==> (k = is_constant z)"
    and "combine mk_or (x, i) (y, j) = (z, k) ==> (k = is_constant z)"
    and "combine mk_until (x, i) (y, j) = (z, k) ==> (k = is_constant z)"
    and "combine mk_release (x, i) (y, j) = (z, k) ==> (k = is_constant z)"
    and "combine mk_weak_until (x, i) (y, j) = (z, k) ==> (k = is_constant z)"
    and "combine mk_strong_release (x, i) (y, j) = (z, k) ==> (k = is_constant z)"
  by (cases i; cases j; simp add: assms Let_def; force intro: is_constant_constructorsI)+

lemma combine_and_or_semantics:
  assumes "i = is_constant φ"
  assumes "j = is_constant ψ"
  shows "w n to_ltln (combine mk_and (φ, i) (ψ, j)) w n to_ltln (φ, i) andn to_ltln (ψ, j)"
    and "w n to_ltln (combine mk_or (φ, i) (ψ, j)) w n to_ltln (φ, i) orn to_ltln (ψ, j)"
  by ((cases i; cases j; simp add: min_def is_constant_constructors_simps is_constant_constructors_simps2 assms),
      (cases ψ; insert assms; auto),
      (cases φ; insert assms; auto),
      (blast elim!: is_constant.elims))+

lemma combine_until_release_semantics:
  assumes "i = is_constant φ"
  assumes "j = is_constant ψ"
  shows "w n to_ltln (combine mk_until (φ, i) (ψ, j)) w n to_ltln (φ, i) Un to_ltln (ψ, j)"
    and "w n to_ltln (combine mk_release (φ, i) (ψ, j)) w n to_ltln (φ, i) Rn to_ltln (ψ, j)"
  by ((cases i; cases j; simp add: is_constant_constructors_simps is_constant_constructors_simps2
       until_constant_simp release_constant_simp mk_next_pow_until mk_next_pow_release del: semantics_ltln.simps),
      (blast dest: is_constant_semantics),
      (cases ψ; simp add: assms),
      (cases φ; insert assms; auto simp: add.commute))+

(* TODO this proof is a bit slow and could be optimized *)
lemma combine_weak_until_strong_release_semantics:
  assumes "i = is_constant φ"
  assumes "j = is_constant ψ"
  shows "w n to_ltln (combine mk_weak_until (φ, i) (ψ, j)) w n to_ltln (φ, i) Wn to_ltln (ψ, j)"
    and "w n to_ltln (combine mk_strong_release (φ, i) (ψ, j)) w n to_ltln (φ, i) Mn to_ltln (ψ, j)"
  by ((cases i; cases j; simp add: min_def is_constant_constructors_simps is_constant_constructors_simps3 del: semantics_ltln.simps),
      (cases φ; simp add: assms),
      (cases ψ; insert assms; auto simp: add.commute))+



lemma rewrite_X_enat_infinity_invariant:
  "snd (rewrite_X_enat φ) = is_constant (fst (rewrite_X_enat φ))"
proof (induction φ)
  case (And_ltln φ ψ)
    thus ?case
      by (simp add: combine_infinity_invariant[OF And_ltln(1,2), unfolded prod.collapse])
next
  case (Or_ltln φ ψ)
    thus ?case
      by (simp add: combine_infinity_invariant[OF Or_ltln(1,2), unfolded prod.collapse])
next
  case (Until_ltln φ ψ)
    thus ?case
      by (simp add: combine_infinity_invariant[OF Until_ltln(1,2), unfolded prod.collapse])
next
  case (Release_ltln φ ψ)
    thus ?case
      by (simp add: combine_infinity_invariant[OF Release_ltln(1,2), unfolded prod.collapse])
next
  case (WeakUntil_ltln φ ψ)
    thus ?case
      by (simp add: combine_infinity_invariant[OF WeakUntil_ltln(1,2), unfolded prod.collapse])
next
  case (StrongRelease_ltln φ ψ)
    thus ?case
      by (simp add: combine_infinity_invariant[OF StrongRelease_ltln(1,2), unfolded prod.collapse])
next
  case (Next_ltln φ)
    thus ?case
      by (simp add: split_def) (metis eSuc_infinity eSuc_inject)
qed auto

lemma rewrite_X_enat_correct:
  "w n φ w n to_ltln (rewrite_X_enat φ)"
proof (induction φ arbitrary: w)
  case (And_ltln φ ψ)
    thus ?case
      using combine_and_or_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant] by fastforce
next
  case (Or_ltln φ ψ)
    thus ?case
      using combine_and_or_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant] by fastforce
next
  case (Until_ltln φ ψ)
    thus ?case
      unfolding rewrite_X_enat.simps combine_until_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce
next
  case (Release_ltln φ ψ)
    thus ?case
      unfolding rewrite_X_enat.simps combine_until_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce
next
  case (WeakUntil_ltln φ ψ)
    thus ?case
      unfolding rewrite_X_enat.simps combine_weak_until_strong_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce
next
  case (StrongRelease_ltln φ ψ)
    thus ?case
      unfolding rewrite_X_enat.simps combine_weak_until_strong_release_semantics[OF rewrite_X_enat_infinity_invariant rewrite_X_enat_infinity_invariant, unfolded prod.collapse] by fastforce
next
  case (Next_ltln φ)
  moreover
    have " w n to_ltln (rewrite_X_enat (Xn φ)) suffix 1 w n to_ltln (rewrite_X_enat φ)"
      by (simp add: split_def; cases "snd (rewrite_X_enat φ) ")
         (auto simp: eSuc_def, auto simp: rewrite_X_enat_infinity_invariant eSuc_def dest: is_constant_semantics)
    ultimately
    show ?case
       using semantics_ltln.simps(7by blast
qed auto

lemma rewrite_X_sound [simp]:
  "w n rewrite_X φ w n φ"
  using rewrite_X_enat_correct unfolding rewrite_X_def Let_def by auto

subsection Pure Eventual, Pure Universal, and Suspendable Formulas

fun pure_eventual :: "'a ltln ==> bool"
where
  "pure_eventual truen = True"
"pure_eventual falsen = True"
"pure_eventual (μ andn μ') = (pure_eventual μ pure_eventual μ')"
"pure_eventual (μ orn μ') = (pure_eventual μ pure_eventual μ')"
"pure_eventual (μ Un μ') = (μ = truen pure_eventual μ')"
"pure_eventual (μ Rn μ') = (pure_eventual μ pure_eventual μ')"
"pure_eventual (μ Wn μ') = (pure_eventual μ pure_eventual μ')"
"pure_eventual (μ Mn μ') = (pure_eventual μ pure_eventual μ' μ' = truen)"
"pure_eventual (Xn μ) = pure_eventual μ"
"pure_eventual _ = False"

fun pure_universal :: "'a ltln ==> bool"
where
  "pure_universal truen = True"
"pure_universal falsen = True"
"pure_universal (ν andn ν') = (pure_universal ν pure_universal ν')"
"pure_universal (ν orn ν') = (pure_universal ν pure_universal ν')"
"pure_universal (ν Un ν') = (pure_universal ν pure_universal ν')"
"pure_universal (ν Rn ν') = (ν = falsen pure_universal ν')"
"pure_universal (ν Wn ν') = (pure_universal ν pure_universal ν' ν' = falsen)"
"pure_universal (ν Mn ν') = (pure_universal ν pure_universal ν')"
"pure_universal (Xn ν) = pure_universal ν"
"pure_universal _ = False"

fun suspendable :: "'a ltln ==> bool"
where
  "suspendable truen = True"
"suspendable falsen = True"
"suspendable (ξ andn ξ') = (suspendable ξ suspendable ξ')"
"suspendable (ξ orn ξ') = (suspendable ξ suspendable ξ')"
"suspendable (φ Un ξ) = (φ = truen pure_universal ξ suspendable ξ)"
"suspendable (φ Rn ξ) = (φ = falsen pure_eventual ξ suspendable ξ)"
"suspendable (φ Wn ξ) = (suspendable φ suspendable ξ pure_eventual φ ξ = falsen)"
"suspendable (φ Mn ξ) = (suspendable φ suspendable ξ pure_universal φ ξ = truen)"
"suspendable (Xn ξ) = suspendable ξ"
"suspendable _ = False"

lemma pure_eventual_left_append:
  "pure_eventual μ ==> w n μ ==> (u w) n μ"
proof (induction μ arbitrary: u w)
  case (Until_ltln μ μ')
    moreover
    then obtain i where "suffix i w n μ'"
      by auto
    hence "μ = truen ==> ?case"
      by simp (metis suffix_conc_length suffix_suffix)
    moreover
    have "pure_eventual μ' ==> (u w) n μ'"
      by (metis suffix i w n μ' Until_ltln(2) prefix_suffix)
    hence "pure_eventual μ' ==> ?case"
      by force
    ultimately
    show ?case
      by fastforce
next
  case (Release_ltln μ μ')
    thus ?case
      by (cases "i. suffix i w n μ'"; simp_all)
         (metis linear suffix_conc_snd gr0I not_less0 prefix_suffix suffix_0)+
next
  case (WeakUntil_ltln μ μ')
    thus ?case
      by (cases "i. suffix i w n μ'"; simp_all)
         (metis zero_le le0 nat_le_linear prefix_suffix suffix_0 suffix_conc_length suffix_conc_snd suffix_subseq_join)+
next
  case (StrongRelease_ltln μ μ')
    moreover
    then obtain i where "suffix i w n μ andn μ'"
      by auto
    hence "μ' = truen ==> ?case"
      by simp (metis suffix_conc_length suffix_suffix)
    moreover
    have "pure_eventual μ ==> pure_eventual μ' ==> (u w) n μ andn μ'"
      by (metis suffix i w n μ andn μ' calculation(1) calculation(2) prefix_suffix semantics_ltln.simps(5))
    hence "pure_eventual μ ==> pure_eventual μ' ==> ?case"
      by force
    ultimately
    show ?case
      by fastforce
qed (auto, metis diff_zero le_0_eq not_less_eq_eq suffix_conc_length suffix_conc_snd word_split)

lemma pure_universal_suffix_closed:
  "pure_universal ν ==> (u w) n ν ==> w n ν"
proof (induction ν arbitrary: u w)
  case (Until_ltln ν ν')
    hence "i. suffix i (u w) n ν' (j<i. suffix j (u w) n ν)"
      using semantics_ltln.simps(8by blast
    thus ?case
      by simp (metis Until_ltln(1-3) le_0_eq le_eq_less_or_eq le_less_linear prefix_suffix pure_universal.simps(5) suffix_conc_fst suffix_conc_snd)
next
  case (Release_ltln ν ν')
    moreover
    hence "i. suffix i (u w) n ν' (j<i. suffix j (u w) n ν)"
      by simp
    ultimately
    show ?case
      by simp (metis semantics_ltln.simps(2) not_less0 prefix_suffix suffix_0 suffix_conc_length suffix_suffix)
next
  case (WeakUntil_ltln ν ν')
    moreover
    hence "i. suffix i (u w) n ν (ji. suffix j (u w) n ν')"
      by simp
    ultimately
    show ?case
      by simp (metis (full_types) le_antisym prefix_suffix semantics_ltln.simps(2) suffix_0 suffix_conc_length suffix_suffix zero_le)
next
  case (StrongRelease_ltln ν ν')
    hence "i. suffix i (u w) n ν (ji. suffix j (u w) n ν')"
      using semantics_ltln.simps(11by blast
    thus ?case
      by simp (metis StrongRelease_ltln(1-3) diff_is_0_eq nat_le_linear prefix_conc_length prefix_suffix pure_universal.simps(8) subsequence_length suffix_conc_snd suffix_subseq_join)
next
  case (Next_ltln μ)
    thus ?case
      by (metis prefix_suffix pure_universal.simps(9) semantics_ltln.simps(7) semiring_normalization_rules(24) suffix_conc_length suffix_suffix)
qed auto

lemma suspendable_prefix_invariant:
  "suspendable ξ ==> (u w) n ξ w n ξ"
proof (induction ξ arbitrary: u w)
  case (Until_ltln ξ ξ')
    show ?case
    proof (cases "suspendable ξ'")
      case False
        hence "ξ = truen" and "pure_universal ξ'"
          using Until_ltln by simp+
        thus ?thesis
          by (simp; metis (no_types) linear pure_universal_suffix_closed suffix_conc_fst suffix_conc_length suffix_conc_snd suffix_suffix)
    qed (simp; metis Until_ltln(2) not_less0 prefix_suffix)
next
  case (Release_ltln ξ ξ')
    show ?case
    proof (cases "suspendable ξ'")
      case False
        hence "ξ = falsen" and "pure_eventual ξ'"
          using Release_ltln by simp+
        thus ?thesis
          by (simp; metis (no_types) le_iff_add add_diff_cancel_left' linear pure_eventual_left_append suffix_0 suffix_conc_fst suffix_conc_snd)
    qed (simp; metis Release_ltln(2) not_less0 prefix_suffix)
next
  case (WeakUntil_ltln ξ ξ')
    show ?case
    proof (cases "suspendable ξ suspendable ξ'")
      case False
        hence "ξ' = falsen" and "pure_eventual ξ"
          using WeakUntil_ltln by simp+
        thus ?thesis
          by (simp; metis (no_types) le_iff_add add_diff_cancel_left' linear pure_eventual_left_append suffix_0 suffix_conc_fst suffix_conc_snd)
      qed (simp; metis (full_types) WeakUntil_ltln.IH prefix_suffix)
next
  case (StrongRelease_ltln ξ ξ')
    show ?case
    proof (cases "suspendable ξ suspendable ξ'")
      case False
        hence "ξ' = truen" and "pure_universal ξ"
          using StrongRelease_ltln by simp+
        thus ?thesis
          by (simp; metis (no_types) linear pure_universal_suffix_closed suffix_conc_fst suffix_conc_length suffix_conc_snd suffix_suffix)
    qed (simp; metis (full_types) StrongRelease_ltln.IH(1) StrongRelease_ltln.IH(2) prefix_suffix)
qed (simp_all, metis prefix_suffix)

theorem pure_eventual_until_simp:
  assumes "pure_eventual μ"
  shows "w n φ Un μ w n μ"
proof -
  have "i. suffix i w n μ ==> w n μ"
    using pure_eventual_left_append[OF assms] prefix_suffix by metis
  thus ?thesis
    by force
qed

theorem pure_universal_release_simp:
  assumes "pure_universal ν"
  shows "w n φ Rn ν w n ν"
proof -
  have "i. w n ν ==> suffix i w n ν"
    using pure_universal_suffix_closed[OF assms] prefix_suffix by metis
  thus ?thesis
    by force
qed

theorem pure_universal_weak_until_simp:
  assumes "pure_universal φ" and "pure_universal ψ"
  shows "w n φ Wn ψ w n φ orn ψ"
proof -
  have "i. w n φ ==> suffix i w n φ" and "i. w n ψ ==> suffix i w n ψ"
    using assms pure_universal_suffix_closed prefix_suffix by metis+
  thus ?thesis
    by force
qed

theorem pure_eventual_strong_release_simp:
  assumes "pure_eventual φ" and "pure_eventual ψ"
  shows "w n φ Mn ψ w n φ andn ψ"
proof -
  have "i. suffix i w n φ ==> w n φ" and "i. suffix i w n ψ ==> w n ψ"
    using assms pure_eventual_left_append prefix_suffix by metis+
  thus ?thesis
    by force
qed


theorem suspendable_formula_simp:
  assumes "suspendable ξ"
  shows "w n Xn ξ w n ξ" (is ?t1)
    and "w n φ Un ξ w n ξ" (is ?t2)
    and "w n φ Rn ξ w n ξ" (is ?t3)
proof -
  have "i. suffix i w n ξ w n ξ"
    using suspendable_prefix_invariant[OF assms] prefix_suffix by metis
  thus ?t1 ?t2 ?t3
    by force+
qed

theorem suspendable_formula_simp2:
  assumes "suspendable φ" and "suspendable ψ"
  shows "w n φ Wn ψ w n φ orn ψ" (is ?t1)
    and "w n φ Mn ψ w n φ andn ψ" (is ?t2)
proof -
  have "i. suffix i w n φ w n φ" and "i. suffix i w n ψ w n ψ"
    using assms suspendable_prefix_invariant prefix_suffix by metis+
  thus ?t1 ?t2
    by force+
qed

fun rewrite_modal :: "'a ltln ==> 'a ltln"
where
  "rewrite_modal truen = truen"
"rewrite_modal falsen = falsen"
"rewrite_modal (φ andn ψ) = (rewrite_modal φ andn rewrite_modal ψ)"
"rewrite_modal (φ orn ψ) = (rewrite_modal φ orn rewrite_modal ψ)"
"rewrite_modal (φ Un ψ) = (if pure_eventual ψ suspendable ψ then rewrite_modal ψ else (rewrite_modal φ Un rewrite_modal ψ))"
"rewrite_modal (φ Rn ψ) = (if pure_universal ψ suspendable ψ then rewrite_modal ψ else (rewrite_modal φ Rn rewrite_modal ψ))"
"rewrite_modal (φ Wn ψ) = (if pure_universal φ pure_universal ψ suspendable φ suspendable ψ then (rewrite_modal φ orn rewrite_modal ψ) else (rewrite_modal φ Wn rewrite_modal ψ))"
"rewrite_modal (φ Mn ψ) = (if pure_eventual φ pure_eventual ψ suspendable φ suspendable ψ then (rewrite_modal φ andn rewrite_modal ψ) else (rewrite_modal φ Mn rewrite_modal ψ))"
"rewrite_modal (Xn φ) = (if suspendable φ then rewrite_modal φ else Xn (rewrite_modal φ))"
"rewrite_modal φ = φ"

lemma rewrite_modal_sound [simp]:
  "w n rewrite_modal φ w n φ"
proof (induction φ arbitrary: w)
  case (Until_ltln φ ψ)
    thus ?case
      apply (cases "pure_eventual ψ suspendable ψ")
      apply (insert pure_eventual_until_simp[of ψ] suspendable_formula_simp[of ψ])
      apply fastforce+
      done
next
  case (Release_ltln φ ψ)
    thus ?case
      apply (cases "pure_universal ψ suspendable ψ")
      apply (insert pure_universal_release_simp[of ψ] suspendable_formula_simp[of ψ])
      apply fastforce+
      done
next
  case (WeakUntil_ltln φ ψ)
    thus ?case
      apply (cases "pure_universal φ pure_universal ψ suspendable φ suspendable ψ")
      apply (insert pure_universal_weak_until_simp[of φ ψ] suspendable_formula_simp2[of φ ψ])
      apply fastforce+
      done
next
  case (StrongRelease_ltln φ ψ)
    thus ?case
      apply (cases "pure_eventual φ pure_eventual ψ suspendable φ suspendable ψ")
      apply (insert pure_eventual_strong_release_simp[of φ ψ] suspendable_formula_simp2[of φ ψ])
      apply fastforce+
      done
next
  case (Next_ltln φ)
    thus ?case
      apply (cases "suspendable φ")
      apply (insert suspendable_formula_simp[of φ])
      apply fastforce+
      done
qed auto

lemma rewrite_modal_size:
  "size (rewrite_modal φ) size φ"
  by (induction φ) auto

subsection Syntactical Implication Based Simplification

inductive syntactical_implies :: "'a ltln ==> 'a ltln ==> bool" (_ s _ [8080])
where
  "_ s truen"
"falsen s _"
"φ = φ ==> φ s φ"

s χ ==> (φ andn ψ) s χ"
s χ ==> (φ andn ψ) s χ"
s ψ ==> φ s χ ==> φ s (ψ andn χ)"

s ψ ==> φ s (ψ orn χ)"
s χ ==> φ s (ψ orn χ)"
s χ ==> ψ s χ ==> (φ orn ψ) s χ"

s χ ==> φ s (ψ Un χ)"
s χ ==> ψ s χ ==> (φ Un ψ) s χ"
s χ ==> ψ s ν ==> (φ Un ψ) s (χ Un ν)"

s φ ==> (ψ Rn χ) s φ"
s φ ==> χ s ψ ==> χ s (φ Rn ψ)"
s χ ==> ψ s ν ==> (φ Rn ψ) s (χ Rn ν)"

"(falsen Rn φ) s ψ ==> (falsen Rn φ) s Xn ψ"
s (truen Un ψ) ==> (Xn φ) s (truen Un ψ)"
s ψ ==> (Xn φ) s (Xn ψ)"

lemma syntactical_implies_correct:
  s ψ ==> w n φ ==> w n ψ"
  by (induction arbitrary: w rule: syntactical_implies.induct; auto; force)

fun rewrite_syn_imp
where
  "rewrite_syn_imp (φ andn ψ) = (
    if φ s ψ then
      rewrite_syn_imp φ
    else if ψ s φ then
      rewrite_syn_imp ψ
    else if φ s (notn ψ) ψ s (notn φ) then
      falsen
    else
      mk_and (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
"rewrite_syn_imp (φ orn ψ) = (
    if φ s ψ then
      rewrite_syn_imp ψ
    else if ψ s φ then
      rewrite_syn_imp φ
    else if (notn φ) s ψ (notn ψ) s φ then
      truen
    else
      mk_or (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
"rewrite_syn_imp (φ Un ψ) = (
    if φ s ψ then
      rewrite_syn_imp ψ
    else if (notn φ) s ψ then
      mk_finally (rewrite_syn_imp ψ)
    else
      mk_until (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
"rewrite_syn_imp (φ Rn ψ) = (
    if ψ s φ then
      rewrite_syn_imp ψ
    else if ψ s (notn φ) then
      mk_globally (rewrite_syn_imp ψ)
    else
      mk_release (rewrite_syn_imp φ) (rewrite_syn_imp ψ))"
"rewrite_syn_imp (Xn φ) = mk_next (rewrite_syn_imp φ)"
"rewrite_syn_imp φ = φ"

lemma rewrite_syn_imp_sound:
  "w n rewrite_syn_imp φ w n φ"
proof (induction φ arbitrary: w)
  case And_ltln
    thus ?case
      by (simp add: Let_def; metis syntactical_implies_correct notn_semantics)
next
  case (Or_ltln φ ψ)
    moreover
    have "(notn φ) s ψ ==> w. w n φ orn ψ"
      by (auto intro: syntactical_implies_correct[of "notn φ"])
    moreover
    have "(notn ψ) s φ ==> w. w n φ orn ψ"
      by (auto intro: syntactical_implies_correct[of "notn ψ"])
    ultimately
    show ?case
      by (auto intro: syntactical_implies_correct)
next
  case (Until_ltln φ ψ)
    moreover
    have s ψ ==> ?case"
      by (force simp add: Until_ltln dest: syntactical_implies_correct)
    moreover
    {
      assume A: "(notn φ) s ψ" and B: "¬ φ s ψ"
      hence [simp]: "rewrite_syn_imp (φ Un ψ) = mk_finally (rewrite_syn_imp ψ)"
        by simp
      {
        assume "i. suffix i w n ψ"
        moreover
        define i where "i LEAST i. suffix i w n ψ"
        ultimately
        have "j < i. ¬suffix j w n ψ" and "suffix i w n ψ"
          by (blast dest: not_less_Least , metis LeastI i. suffix i w n ψ i_def)
        hence "j < i. suffix j w n φ" and "suffix i w n ψ"
          using syntactical_implies_correct[OF A] by auto
      }
      hence ?case
        by (simp del: rewrite_syn_imp.simps; unfold Until_ltln(2)) blast
    }
    ultimately
    show ?case
      by fastforce
next
  case (Release_ltln φ ψ)
    moreover
    have s φ ==> ?case"
      by (force simp add: Release_ltln dest: syntactical_implies_correct)
    moreover
    {
      assume A: s (notn φ)" and B: "¬ ψ s φ"
      hence [simp]: "rewrite_syn_imp (φ Rn ψ) = mk_globally (rewrite_syn_imp ψ)"
        by simp
      {
        assume "i. ¬suffix i w n ψ"
        moreover
        define i where "i LEAST i. ¬suffix i w n ψ"
        ultimately
        have "j < i. suffix j w n ψ" and "¬ suffix i w n ψ"
          by (blast dest: not_less_Least , metis LeastI i. ¬suffix i w n ψ i_def)
        hence "j < i. ¬suffix j w n φ" and "¬ suffix i w n ψ"
          using syntactical_implies_correct[OF A] by auto
      }
      hence ?case
        by (simp del: rewrite_syn_imp.simps; unfold Release_ltln(2)) blast
    }
    ultimately
    show ?case
      by fastforce
qed auto

subsection Iterated Rewriting

fun iterate
where
  "iterate f x 0 = x"
"iterate f x (Suc n) = (let x' = f x in if x = x' then x else iterate f x' n)"

definition
  "rewrite_iter_fast φ iterate (rewrite_modal o rewrite_X) φ (size φ)"

definition
  "rewrite_iter_slow φ iterate (rewrite_syn_imp o rewrite_modal o rewrite_X) φ (size φ)"

text The rewriting functions defined in the previous subsections can be used as-is. However, in the
 most cases one wants to iterate these rules until the formula cannot be simplified further.
 @{const rewrite_iter_fast} pulls X operators up in the syntax tree and the uses the
 "modal" simplification rules. @{const rewrite_iter_slow} additionally tries to simplify the
 formula using syntactic implication checking.


lemma iterate_sound:
  assumes "φ. w n f φ w n φ"
  shows "w n iterate f φ n w n φ"
  by (induction n arbitrary: φ; simp add: assms Let_def)

theorem rewrite_iter_fast_sound [simp]:
  "w n rewrite_iter_fast φ w n φ"
  using iterate_sound[of _ "rewrite_modal o rewrite_X"]
  unfolding comp_def rewrite_modal_sound rewrite_X_sound rewrite_iter_fast_def
  by blast

theorem rewrite_iter_slow_sound [simp]:
  "w n rewrite_iter_slow φ w n φ"
  using iterate_sound[of _ "rewrite_syn_imp o rewrite_modal o rewrite_X"]
  unfolding comp_def rewrite_modal_sound rewrite_X_sound rewrite_syn_imp_sound rewrite_iter_slow_def
  by blast

subsection Preservation of atoms

lemma iterate_atoms:
  assumes
    "φ. atoms_ltln (f φ) atoms_ltln φ"
  shows
    "atoms_ltln (iterate f φ n) atoms_ltln φ"
  by (induction n arbitrary: φ) (auto, metis (mono_tags, lifting) assms in_mono)

lemma rewrite_modal_atoms:
  "atoms_ltln (rewrite_modal φ) atoms_ltln φ"
  by (induction φ) auto

lemma mk_and_atoms:
  "atoms_ltln (mk_and φ ψ) atoms_ltln φ atoms_ltln ψ"
  by (auto simp: mk_and_def split: ltln.splits)

lemma mk_or_atoms:
  "atoms_ltln (mk_or φ ψ) atoms_ltln φ atoms_ltln ψ"
  by (auto simp: mk_or_def split: ltln.splits)

lemma remove_strong_ops_atoms:
  "atoms_ltln (remove_strong_ops φ) atoms_ltln φ"
  by (induction φ) auto

lemma remove_weak_ops_atoms:
  "atoms_ltln (remove_weak_ops φ) atoms_ltln φ"
  by (induction φ) auto

lemma mk_finally_atoms:
  "atoms_ltln (mk_finally φ) atoms_ltln φ"
  by (auto simp: mk_finally_def split: ltln.splits) (insert remove_strong_ops_atoms, fast+)

lemma mk_globally_atoms:
  "atoms_ltln (mk_globally φ) atoms_ltln φ"
  by (auto simp: mk_globally_def split: ltln.splits) (insert remove_weak_ops_atoms, fast+)

lemma mk_until_atoms:
  "atoms_ltln (mk_until φ ψ) atoms_ltln φ atoms_ltln ψ"
  by (auto simp: mk_until_def split: ltln.splits) (insert mk_finally_atoms, fastforce+)

lemma mk_release_atoms:
  "atoms_ltln (mk_release φ ψ) atoms_ltln φ atoms_ltln ψ"
  by (auto simp: mk_release_def split: ltln.splits) (insert mk_globally_atoms, fastforce+)

lemma mk_weak_until_atoms:
  "atoms_ltln (mk_weak_until φ ψ) atoms_ltln φ atoms_ltln ψ"
  by (auto simp: mk_weak_until_def split: ltln.splits) (insert mk_globally_atoms, fastforce+)

lemma mk_strong_release_atoms:
  "atoms_ltln (mk_strong_release φ ψ) atoms_ltln φ atoms_ltln ψ"
  by (auto simp: mk_strong_release_def split: ltln.splits) (insert mk_finally_atoms, fastforce+)

lemma mk_next_atoms:
  "atoms_ltln (mk_next φ) = atoms_ltln φ"
  by (auto simp: mk_next_def split: ltln.splits)

lemma mk_next_pow_atoms:
  "atoms_ltln (mk_next_pow n φ) = atoms_ltln φ"
  by (induction n) (auto simp: mk_next_pow_def split: ltln.splits)

lemma combine_atoms:
  assumes
    "φ ψ. atoms_ltln (f φ ψ) atoms_ltln φ atoms_ltln ψ"
  shows
    "atoms_ltln (fst (combine f x y)) atoms_ltln (fst x) atoms_ltln (fst y)"
  by (metis assms fst_combine mk_next_pow_atoms prod.collapse)

lemmas combine_mk_atoms =
  combine_atoms[OF mk_and_atoms]
  combine_atoms[OF mk_or_atoms]
  combine_atoms[OF mk_until_atoms]
  combine_atoms[OF mk_release_atoms]
  combine_atoms[OF mk_weak_until_atoms]
  combine_atoms[OF mk_strong_release_atoms]

lemma rewrite_X_enat_atoms:
  "atoms_ltln (fst (rewrite_X_enat φ)) atoms_ltln φ"
  by (induction φ) (simp_all add: case_prod_beta, insert combine_mk_atoms, fast+)

lemma rewrite_X_atoms:
  "atoms_ltln (rewrite_X φ) atoms_ltln φ"
  by (induction φ) (simp_all add: rewrite_X_def mk_next_pow_atoms case_prod_beta, insert combine_mk_atoms, fast+)

lemma rewrite_syn_imp_atoms:
  "atoms_ltln (rewrite_syn_imp φ) atoms_ltln φ"
proof (induction φ)
  case (And_ltln φ1 φ2)
  then show ?case
    using mk_and_atoms by simp fast
next
  case (Or_ltln φ1 φ2)
  then show ?case
    using mk_or_atoms by simp fast
next
  case (Next_ltln φ)
  then show ?case
    using mk_next_atoms by simp fast
next
  case (Until_ltln φ1 φ2)
  then show ?case
    using mk_finally_atoms mk_until_atoms by simp fast
next
  case (Release_ltln φ1 φ2)
  then show ?case
    using mk_globally_atoms mk_release_atoms by simp fast
qed simp_all

lemma rewrite_iter_fast_atoms:
  "atoms_ltln (rewrite_iter_fast φ) atoms_ltln φ"
proof -
  have 1"φ. atoms_ltln (rewrite_modal (rewrite_X φ)) atoms_ltln φ"
    using rewrite_modal_atoms rewrite_X_atoms by force

  show ?thesis
    by (simp add: rewrite_iter_fast_def 1 iterate_atoms)
qed

lemma rewrite_iter_slow_atoms:
  "atoms_ltln (rewrite_iter_slow φ) atoms_ltln φ"
proof -
  have 1"φ. atoms_ltln (rewrite_syn_imp (rewrite_modal (rewrite_X φ))) atoms_ltln φ"
    using rewrite_syn_imp_atoms rewrite_modal_atoms rewrite_X_atoms by force

  show ?thesis
    by (simp add: rewrite_iter_slow_def 1 iterate_atoms)
qed

subsection Simplifier

text We now define a convenience wrapper for the rewriting engine

datatype mode = Nop | Fast | Slow

fun simplify :: "mode ==> 'a ltln ==> 'a ltln"
where
  "simplify Nop = id"
"simplify Fast = rewrite_iter_fast"
"simplify Slow = rewrite_iter_slow"

theorem simplify_correct:
  "w n simplify m φ w n φ"
  by (cases m) simp+

lemma simplify_atoms:
  "atoms_ltln (simplify m φ) atoms_ltln φ"
  by (cases m) (insert rewrite_iter_fast_atoms rewrite_iter_slow_atoms, fastforce+)

subsection Code Generation

code_pred syntactical_implies .

export_code simplify checking

lemma "rewrite_iter_fast (Fn (Gn (Xn propn(''a'')))) = (Fn (Gn propn(''a'')))"
  by eval

lemma "rewrite_iter_fast (Xn propn(''a'') Un (Xn npropn(''a''))) = Xn (propn(''a'') Un npropn(''a''))"
  by eval

lemma "rewrite_iter_slow (Xn propn(''a'') Un (Xn npropn(''a''))) = Xn (Fn npropn(''a''))"
  by eval

end

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

¤ Dauer der Verarbeitung: 0.28 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge