(*<*)
―‹ ********************************************************************
* Project : HOL-CSP - A Shallow Embedding of CSP in Isabelle/HOL
* Version : 2.0
*
* Author : Benoît Ballenghien, Safouan Taha, Burkhart Wolff, Lina Ye.
* (Based on HOL-CSP 1.0 by Haykal Tej and Burkhart Wolff)
*
* This file : The notion of processes
*
* Copyright (c) 2009 Université Paris-Sud, France
* Copyright (c) 2025 Université Paris-Saclay, France
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* * Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************› (*>*)
chapter‹The Notion of Processes›
text‹As mentioned earlier, we base the theory of CSP on HOLCF, a Isabelle/HOL library
a theory of continuous functions, fixpoint induction and recursion.›
(*<*) theory Process imports HOLCF "HOL-Library.Prefix_Order""HOL-Eisbach.Eisbach" begin (*>*)
text‹HOLCF sets the default type class to @{class cpo}, while our
theory establishes links between standard types and @{class pcpo}
. Consequently, we reset the default type class to the default in HOL.›
default_sort type
section‹Pre-Requisite: Basic Traces and tick-Freeness›
text‹The denotational semantics of CSP assumes a distinguishable
event, called \verb+tick+ and written $\checkmark$, that is required
occur only in the end of traces in order to signalize successful termination of
process. (In the original text of Hoare, this treatment was more
and lead to foundational problems: the process invariant
not be established for the sequential composition operator
CSP; see cite‹"tej.ea:corrected:1997"› for details.)›
text‹From the Isabelle-2025 version on, the classical constant tick (‹🍋›) of the CSP theory
has been replaced by a parameterized version carrying a kind of return value.›
text‹This type 🍋‹('a, 'r) eventptick› is of course isomorphic to the sum type ??‹'a + 'r›.› text‹``ptick'' stands for parameterized tick, and we introduce the type synonym for
the classical process event type.›
free_constructorseventforis_ev:evof_ev|is_tick:tickof_tick prooftransfer show\<open>(\<And>x1.y=Inlx1\<Longrightarrow>P)\<Longrightarrow>(\<And>x2.y=Inrx2\<Longrightarrow>P)\<Longrightarrow>P\<close>fory::\<open>'a+'b\<close>andP by(metisisl_defsum.collapse(2)) next show\<open>evx=evy\<longleftrightarrow>x=y\<close>forxy::'aby(metisev.rep_eqsum.inject(1)) next show\<open>\<checkmark>(x)=\<checkmark>(y)\<longleftrightarrow>x=y\<close>forxy::'rby(metissum.inject(2)tick.rep_eq) next show\<open>evx\<noteq>\<checkmark>(y)\<close>forx::'aandy::'r by(metisInl_Inr_Falseev.rep_eqtick.rep_eq) qed
text‹We recover the classical version with 🍋‹unit›.›
type_synonym 'a trace = ‹('a, unit) traceptick›
text‹We chose as standard ordering on traces the prefix ordering.›
text‹Some facts on the prefix ordering.›
lemma nil_le [simp]: ‹[] ≤ s› and nil_le2 [simp]: ‹s ≤ [] ⟷ s = []› and nil_less [simp]: ‹¬ t < []› and nil_less2 [simp]: ‹[] < t @ [a]› and less_self [simp]: ‹t < t @ [a]› and le_cons [simp]: ‹a # s ≤ a # t ⟷ s ≤ t› and le_append [simp]: ‹b @ s ≤ b @ t ⟷ s ≤ t› and less_cons [simp]: ‹a # s < a # t ⟷ s < t› and less_append[simp]: ‹b @ s < b @ t ⟷ s < t›
and le_length_mono: ‹s ≤ t ==> length s ≤ length t› and less_length_mono: ‹s < t ==> length s < length t› and le_tail: ‹s ≠ [] ==> s ≤ t ==> tl s ≤ tl t› and less_tail: ‹s ≠ [] ==> s < t ==> tl s < tl t› apply (simp_all add: less_eq_list_def less_list_def prefix_length_le) apply (metis prefix_length_less prefix_order.dual_order.not_eq_order_implies_strict) apply (metis prefix_def tl_append2) by (metis prefix_def prefix_order.eq_iff self_append_conv tl_append2)
lemma le_same_imp_eq_or_less: ‹(s :: 'a list) ≤ u ==> t ≤ u ==> t = s ∨ s < t ∨ t < s› by (metis less_eq_list_def linorder_le_cases nless_le prefix_length_prefix)
lemma append_eq_first_pref_spec: ‹s @ t = r @ [x] ==> t ≠ [] ==> s ≤ r› by (metis butlast_append butlast_snoc less_eq_list_def prefix_def)
lemma prefixes_fin: ‹finite {t. t ≤ s} ∧ card {t. t ≤ s} = Suc (length s)› proof (induct s) show‹finite {t. t ≤ []} ∧ card {t. t ≤ []} = Suc (length [])›by simp next case (Cons x s) have * : ‹{t. t ≤ x # s} = {[]} ∪ (λt. x # t) ` {t. t ≤ s}› by (simp add: image_def less_eq_list_def set_eq_iff)
(meson Sublist.prefix_Cons) show‹finite {t. t ≤ x # s} ∧ card {t. t ≤ x # s} = Suc (length (x # s))› proof (intro conjI) show‹finite {t. t ≤ x # s}›by (simp add: "*" Cons.hyps) next have‹finite ((λt. x # t) ` {t. t ≤ s})›by (simp add: Cons.hyps) show‹card {t. t ≤ x # s} = Suc (length (x # s))› by (subst card_Un_disjoint[of ‹{[]}›‹(λt. x # t) ` {t. t ≤ s}›, folded "*"])
(auto simp add: card_image Cons.hyps) qed qed
lemma sublists_fin: ‹finite {t. ∃t1 t2. s = t1 @ t @ t2}› proof (induct s) show‹finite {t. ∃t1 t2. [] = t1 @ t @ t2}›by simp next case (Cons x s) have‹{t. t ≤ x # s} = {t. ∃t2. x # s = t @ t2}› by (simp add: less_eq_list_def prefix_def) with prefixes_fin[of ‹x # s›] have‹finite {t. ∃t2. x # s = t @ t2}›by simp have‹{t. ∃t1 t2. x # s = t1 @ t @ t2} ⊆
{t. ∃t1 t2. s = t1 @ t @ t2} ∪ {t. ∃t2. x # s = t @ t2}› by (simp add: subset_iff) (meson Cons_eq_append_conv) show‹finite {t. ∃t1 t2. x # s = t1 @ t @ t2}› by (rule finite_subset[OF ‹?this›], rule finite_UnI)
(simp_all add: Cons.hyps ‹finite {t. ∃t2. x # s = t @ t2}›) qed
lemma suffixes_fin: ‹finite {t. ∃t1. s = t1 @ t}› by (rule finite_subset[of _ ‹{t. ∃t1 t2. s = t1 @ t @ t2}›];
simp add: subset_iff sublists_fin) blast
text‹For the process invariant, it is a key element to
the notion of traces to traces that may only contain
tick event at the very end. This is captured by the definition
the predicate \verb+front_tickFree+ and its stronger version
verb+tickFree+. Here is the theory of this concept.›
definition tickFree :: ‹('a, 'r) traceptick==> bool› (‹tF›) where‹tF s ≡ range tick ∩ set s = {}›
definition front_tickFree :: ‹('a, 'r) traceptick==> bool› (‹ftF›) where‹ftF s ≡ s = [] ∨ tickFree (tl (rev s))›
lemma tickFree_Nil [simp] : ‹tF []› and tickFree_Cons_iff [simp] : ‹tF (a # t) ⟷ is_ev a ∧ tF t› and tickFree_append_iff [simp] : ‹tF (s @ t) ⟷ tF s ∧ tF t› and tickFree_rev_iff [simp] : ‹tF (rev t) ⟷ tF t› and non_tickFree_tick [simp] : ‹¬ tF [🍋(r)]› by (cases a; auto simp add: tickFree_def)+
lemma tickFree_iff_is_map_ev : ‹tF t ⟷ (∃u. t = map ev u)› by (induct t) (simp_all add: Cons_eq_map_conv is_ev_def)
lemma front_tickFree_Nil [simp] : ‹ftF []› and front_tickFree_single[simp] : ‹ftF [a]› by (simp_all add: front_tickFree_def)
lemma tickFree_tl : ‹tF s ==> tF (tl s)› by (cases s) simp_all
lemma non_tickFree_imp_not_Nil: ‹¬ tF s ==> s ≠ []› using tickFree_Nil by blast
lemma tickFree_butlast: ‹tF s ⟷ tF (butlast s) ∧ (s ≠ [] ⟶ is_ev (last s))› by (induct s) simp_all
lemma front_tickFree_iff_tickFree_butlast: ‹ftF s ⟷ tF (butlast s)› by (induct s) (auto simp add: front_tickFree_def)
lemma front_tickFree_Cons_iff: ‹ftF (a # s) ⟷ s = [] ∨ is_ev a ∧ ftF s› by (simp add: front_tickFree_iff_tickFree_butlast)
lemma front_tickFree_append_iff: ‹ftF (s @ t) ⟷ (if t = [] then ftF s else tF s ∧ ftF t)› by (simp add: butlast_append front_tickFree_iff_tickFree_butlast)
lemma tickFree_imp_front_tickFree [simp] : ‹tF s ==> ftF s› by (simp add: front_tickFree_def tickFree_tl)
lemma front_tickFree_charn: ‹ftF s ⟷ s = [] ∨ (∃a t. s = t @ [a] ∧ tF t)› by (cases s rule: rev_cases) (simp_all add: front_tickFree_def)
lemma nonTickFree_n_frontTickFree: ‹¬ tF s ==> ftF s ==>∃t r. s = t @ [🍋(r)]› by (metis eventptick.disc(1) eventptick.exhaust front_tickFree_append_iff list.distinct(1)
rev_exhaust tickFree_Cons_iff tickFree_Nil tickFree_append_iff)
lemma front_tickFree_dw_closed : ‹ftF (s @ t) ==> ftF s› by (metis front_tickFree_append_iff tickFree_imp_front_tickFree)
lemma front_tickFree_append: ‹tF s ==> ftF t ==> ftF (s @ t)› by (simp add: front_tickFree_append_iff)
lemma tickFree_imp_front_tickFree_snoc: ‹tF s ==> ftF (s @ [a])› by (simp add: front_tickFree_append)
lemma front_tickFree_nonempty_append_imp: ‹ftF (t @ r) ==> r ≠ [] ==> tF t ∧ ftF r› by (simp add: front_tickFree_append_iff)
lemma tickFree_map_ev [simp] : ‹tF (map ev t)› by (induct t) simp_all
lemma tickFree_map_tick_iff [simp] : ‹tF (map tick t) ⟷ t = []› by (induct t) simp_all
lemma front_tickFree_map_tick_iff [simp] : ‹ftF (map tick t) ⟷ t = [] ∨ (∃r. t = [r])› by (simp add: front_tickFree_iff_tickFree_butlast map_butlast[symmetric])
(metis append_Nil append_butlast_last_id butlast.simps(1, 2))
― ‹term‹map ev (map f t)› if automatically simplified into term‹map (ev ∘ f) t› by the
simplified, so we need to add the following versions.›
definition is_process :: ‹('a, 'r) process0==> bool›where ‹is_process P ≡
([], {}) ∈ FAILURES P ∧
(∀s X. (s, X) ∈ FAILURES P ⟶ ftF s) ∧
(∀s t. (s @ t, {}) ∈ FAILURES P ⟶ (s, {}) ∈ FAILURES P) ∧
(∀s X Y. (s, Y) ∈ FAILURES P ∧ X ⊆ Y ⟶ (s, X) ∈ FAILURES P) ∧
(∀s X Y. (s, X) ∈ FAILURES P ∧ (∀c. c ∈ Y ⟶ (s @ [c], {}) ∉ FAILURES P) ⟶ (s, X ∪ Y) ∈ FAILURES P) ∧
(∀s r X. (s @ [🍋(r)], {}) ∈ FAILURES P ⟶ (s, X - {🍋(r)}) ∈ FAILURES P) ∧
(∀s t. s ∈ DIVERGENCES P ∧ tF s ∧ ftF t ⟶ s @ t ∈ DIVERGENCES P) ∧
(∀s X. s ∈ DIVERGENCES P ⟶ (s, X) ∈ FAILURES P) ∧
(∀s r. s @ [🍋(r)] ∈ DIVERGENCES P ⟶ s ∈ DIVERGENCES P)›
lemma is_process_spec: ‹is_process P ⟷
([], {}) ∈ FAILURES P ∧
(∀s X. (s, X) ∈ FAILURES P ⟶ ftF s) ∧
(∀s t. (s @ t, {}) ∉ FAILURES P ∨ (s, {}) ∈ FAILURES P) ∧
(∀s X Y. (s, Y) ∉ FAILURES P ∨¬ X ⊆ Y ∨ (s, X) ∈ FAILURES P) ∧
(∀s X Y. (s, X) ∈ FAILURES P ∧ (∀c. c ∈ Y ⟶ (s @ [c], {}) ∉ FAILURES P) ⟶ (s, X ∪ Y) ∈ FAILURES P) ∧
(∀s r X. (s @ [🍋(r)], {}) ∈ FAILURES P ⟶ (s, X - {🍋(r)}) ∈ FAILURES P) ∧
(∀s t. s ∉ DIVERGENCES P ∨¬ tF s ∨¬ ftF t ∨ s @ t ∈ DIVERGENCES P) ∧
(∀s X. s ∉ DIVERGENCES P ∨ (s, X) ∈ FAILURES P) ∧
(∀s r. s @ [🍋(r)] ∉ DIVERGENCES P ∨ s ∈ DIVERGENCES P)› by (simp only: is_process_def HOL.nnf_simps(1)
HOL.nnf_simps(3) [symmetric] HOL.imp_conjL[symmetric])
lemma Process_eqI : ‹FAILURES P = FAILURES Q ==> DIVERGENCES P = DIVERGENCES Q ==> P = Q› by (metis DIVERGENCES_def FAILURES_def prod_eq_iff)
lemma process_eq_spec: ‹P = Q ⟷ FAILURES P = FAILURES Q ∧ DIVERGENCES P = DIVERGENCES Q› by (meson Process_eqI)
lemma Refusals_def_bis : ‹R P = {X. ([], X) ∈F P}› by (simp add: Failures.rep_eq REFUSALS_def Refusals.rep_eq)
lemma Refusals_iff : ‹X ∈R P ⟷ ([], X) ∈F P› by (simp add: Failures_def Refusals_def_bis)
lemma T_def_spec: ‹T P = {tr. ∃f. f ∈F P ∧ tr = fst f}› by (simp add: Traces_def TRACES_def Failures_def)
lemma T_F_spec : ‹(t, {}) ∈F P ⟷ t ∈T P› by transfer (auto simp add: TRACES_def intro: is_process4)
lemma Process_spec: ‹process_of_process0 (F P, D P) = P› by (simp add: Divergences.rep_eq Failures.rep_eq
process0_of_process_inverse process_surj_pair)
lemma Process_eq_spec: ‹P = Q ⟷F P = F Q ∧D P = D Q› by (metis Process_spec)
lemma Process_eq_spec_optimized: ‹P = Q ⟷D P = D Q ∧ (D P = D Q ⟶F P = F Q)› using Process_eq_spec by auto
lemma is_processT: ‹([], {}) ∈F P ∧
(∀s X. (s, X) ∈F P ⟶ ftF s) ∧
(∀s t. (s @ t, {}) ∈F P ⟶ (s, {}) ∈F P) ∧
(∀s X Y. (s, Y) ∈F P ∧ X ⊆ Y ⟶ (s, X) ∈F P) ∧
(∀s X Y. (s, X) ∈F P ∧ (∀c. c ∈ Y ⟶ (s @ [c], {}) ∉F P) ⟶ (s, X ∪ Y) ∈F P) ∧
(∀s r X. (s @ [🍋(r)], {}) ∈F P ⟶ (s, X - {🍋(r)}) ∈F P) ∧
(∀s t. s ∈D P ∧ tF s ∧ ftF t ⟶ s @ t ∈D P) ∧
(∀s r X. s ∈D P ⟶ (s, X) ∈F P) ∧ (∀s. s @ [🍋(r)] ∈D P ⟶ s ∈D P)› by transfer (unfold is_process_def, fast)
text‹When the second type is set to 🍋‹unit›, we recover the classical definition
as defined in the book by Roscoe.›
lemma is_processT_unit: ‹([], {}) ∈F P ∧
(∀s X. (s, X) ∈F P ⟶ ftF s) ∧
(∀s t. (s @ t, {}) ∈F P ⟶ (s, {}) ∈F P) ∧
(∀s X Y. (s, Y) ∈F P ∧ X ⊆ Y ⟶ (s, X) ∈F P) ∧
(∀s X Y. (s, X) ∈F P ∧ (∀c. c ∈ Y ⟶ (s @ [c], {}) ∉F P) ⟶ (s, X ∪ Y) ∈F P) ∧
(∀s X. (s @ [🍋], {}) ∈F P ⟶ (s, X - {🍋}) ∈F P) ∧
(∀s t. s ∈D P ∧ tF s ∧ ftF t ⟶ s @ t ∈D P) ∧
(∀s X. s ∈D P ⟶ (s, X) ∈F P) ∧ (∀s. s @ [🍋] ∈D P ⟶ s ∈D P)› by transfer (unfold is_process_def, fast)
lemma process_charn: ‹([], {}) ∈F P ∧
(∀s X. (s, X) ∈F P ⟶ ftF s) ∧
(∀s t. (s @ t, {}) ∉F P ∨ (s, {}) ∈F P) ∧
(∀s X Y. (s, Y) ∉F P ∨¬ X ⊆ Y ∨ (s, X) ∈F P) ∧
(∀s X Y. (s, X) ∈F P ∧ (∀c. c ∈ Y ⟶ (s @ [c], {}) ∉F P) ⟶ (s, X ∪ Y) ∈F P) ∧
(∀s r X. (s @ [🍋(r)], {}) ∈F P ⟶ (s, X - {🍋(r)}) ∈F P) ∧
(∀s t. s ∉D P ∨¬ tF s ∨¬ ftF t ∨ s @ t ∈D P) ∧
(∀s r X. s ∉D P ∨ (s, X) ∈F P) ∧ (∀s. s @ [🍋(r)] ∉D P ∨ s ∈D P)› by (meson is_processT)
text‹ split of \verb+is_processT+: ›
lemma is_processT1 : ‹([], {}) ∈F P› and is_processT1_TR : ‹[] ∈T P› and is_processT2 : ‹(s, X) ∈F P ==> ftF s› and is_processT2_TR : ‹s ∈T P ==> ftF s› and is_processT3 : ‹(s @ t, {}) ∈F P ==> (s, {}) ∈F P› and is_processT3_pref : ‹(t, {}) ∈F P ==> s ≤ t ==> (s, {}) ∈F P› and is_processT3_TR : ‹t ∈T P ==> s ≤ t ==> s ∈T P› and is_processT3_TR_pref : ‹(t, {}) ∈F P ==> s ≤ t ==> (s, {}) ∈F P› and is_processT4 : ‹(s, Y) ∈F P ==> X ⊆ Y ==> (s, X) ∈F P› and is_processT5 : ‹(s, X) ∈F P ==>∀c. c ∈ Y ⟶ (s @ [c], {}) ∉F P ==> (s, X ∪ Y) ∈F P› and is_processT6 : ‹(s @ [🍋(r)], {}) ∈F P ==> (s, X - {🍋(r)}) ∈F P› and is_processT6_TR : ‹s @ [🍋(r)] ∈T P ==> (s, X - {🍋(r)}) ∈F P› and is_processT7 : ‹s ∈D P ==> tF s ==> ftF t ==> s @ t ∈D P› and is_processT8 : ‹s ∈D P ==> (s, X) ∈F P› and is_processT9 : ‹s @ [🍋(r)] ∈D P ==> s ∈D P› by (fold T_F_spec)
(use is_processT in‹metis [[metis_verbose=false]] prefixE›)+
lemma is_processT6_notin : ‹(s @ [🍋(r)], {}) ∈F P ==>🍋(r) ∉ X ==> (s, X) ∈F P› and is_processT6_TR_notin : ‹s @ [🍋(r)] ∈T P ==>🍋(r) ∉ X ==> (s, X) ∈F P› by (metis Diff_insert_absorb is_processT6)
(metis Diff_insert_absorb is_processT6_TR)
lemma is_processT3_TR_append : ‹t @ u ∈T P ==> t ∈T P› using is_processT3_TR by fastforce
lemma nonempty_divE : ‹D P ≠ {} ==> (∧t. tF t ==> t ∈D P ==> thesis) ==> thesis› by (metis ex_in_conv front_tickFree_nonempty_append_imp is_processT2 is_processT8
is_processT9 neq_Nil_conv nonTickFree_n_frontTickFree)
lemma div_butlast_when_non_tickFree_iff : ‹ftF s ==> (if tF s then s else butlast s) ∈D P ⟷ s ∈D P› by (cases s rule: rev_cases; simp add: front_tickFree_iff_tickFree_butlast)
(metis front_tickFree_Cons_iff is_processT7 is_processT9 is_tick_def)
(* lemma is_processT8_Pair: \<open>fst s \<in> \<D> P \<Longrightarrow> s \<in> \<F> P\<close> by(metiseq_fst_iffis_processT8)
lemma is_processT5_S7: ‹t ∈T P ==> (t, A) ∉F P ==>∃x. x ∈ A ∧ t @ [x] ∈T P› by (metis T_F_spec is_processT5 sup_bot_left)
lemma is_processT5_S7': ‹(t, X) ∈F P ==> (t, X ∪ A) ∉F P ==>∃x. x ∈ A ∧ x ∉ X ∧ t @ [x] ∈T P› by (erule contrapos_np, subst Un_Diff_cancel[symmetric])
(rule is_processT5, auto simp: T_F_spec)
lemma trace_tick_continuation_or_all_tick_failuresE: ‹[(s, {}) ∈F P; ∧r. s @ [🍋(r)] ∈T P ==> thesis; (s, range tick) ∈F P ==> thesis]==> thesis› by (metis F_T f_inv_into_f is_processT5_S7)
(* corollary append_single_T_imp_tickFree : \<open>t @ [a] \<in> \<T> P \<Longrightarrow> tickFree t\<close>
by (simp add: append_T_imp_tickFree) *)
(* lemma F_subset_imp_T_subset: \<open>\<F> P \<subseteq> \<F> Q \<Longrightarrow> \<T> P \<subseteq> \<T> Q\<close>
by (auto simp: subsetD T_F_spec[symmetric]) *)
(* lemma is_processT6_S2: \<open>\<checkmark>(r) \<notin> X \<Longrightarrow> [\<checkmark>(r)] \<in> \<T> P \<Longrightarrow> ([], X) \<in> \<F> P\<close>
by (metis Diff_insert_absorb append_Nil is_processT6_TR) *)
lemma is_processT9_tick: ‹[🍋(r)] ∈D P ==> ftF s ==> s ∈D P› by (metis append_Nil is_processT7 is_processT9 tickFree_Nil)
lemma T_nonTickFree_imp_decomp: ‹t ∈T P ==>¬ tF t ==>∃s r. t = s @ [🍋(r)]› by (simp add: is_processT2_TR nonTickFree_n_frontTickFree)
section‹ Process Approximation is a Partial Ordering, a Cpo, and a Pcpo › text‹The Failure/Divergence Model of CSP Semantics provides two orderings: \emph{approximation ordering} (also called \emph{process ordering})
be used for giving semantics to recursion (fixpoints) over processes, \emph{refinement ordering} captures our intuition that a more concrete
is more deterministic and more defined than an abstract one.
start with the key-concepts of the approximation ordering, namely
predicates $min\_elems$ and ‹Ra› (abbreviating \emph{refusals after}).
former provides just a set of minimal elements from a given set
elements of type-class $ord$ \ldots›
lemma min_elems5 : ‹(s :: 'a list) ∈ A ==>∃t≤s. t ∈ min_elems A› proof - have * : ‹x ∈ A ==> length x ≤ n ==>∃s≤x. s ∈ min_elems A›for x :: ‹'a list›and A n proof (induct n arbitrary: x rule: nat_induct) show‹x ∈ A ==> length x ≤ 0 ==>∃s≤x. s ∈ min_elems A›for x by (simp add: Nil_min_elems) next fix n x assume‹x ∈ A›‹length x ≤ Suc n› assume hyp : ‹x ∈ A ==> length x ≤ n ==>∃s≤x. s ∈ min_elems A›for x show‹∃s≤x. s ∈ min_elems A› proof (cases ‹∃y ∈ A. y < x›) show‹∃y∈A. y < x ==>∃s≤x. s ∈ min_elems A› by (elim bexE, frule hyp, drule less_length_mono, use‹length x ≤ Suc n›in simp)
(meson dual_order.strict_trans2 less_list_def) next show‹¬ (∃y∈A. y < x) ==>∃s≤x. s ∈ min_elems A› using‹x ∈ A›unfolding min_elems_def by auto qed qed thus‹s ∈ A ==>∃t≤s. t ∈ min_elems A›by auto qed
lemma min_elems4: ‹A ≠ {} ==>∃s. (s :: ('a, 'r) traceptick) ∈ min_elems A› by (auto dest: min_elems5)
lemma min_elems_charn: ‹t ∈ A ==>∃ t' r. t = (t' @ r) ∧ t' ∈ min_elems A› by (meson prefixE min_elems5)
lemma min_elems_no: ‹(s::'a list) ∈ min_elems A ==> t ∈ A ==> t ≤ s ==> s = t› by (metis (mono_tags, lifting) mem_Collect_eq min_elems_def order_neq_le_trans)
text‹\ldots while the second returns the set of possible
sets after a given trace $s$ and a given process
P$: ›
text‹ In the following, we link the process theory to the underlying
/domain theory of HOLCF by identifying the approximation ordering
HOLCF's pcpo's. ›
instantiation
processptick :: (type, type) below begin text‹ declares approximation ordering $\_\sqsubseteq\_$ also written \verb+_ << _+. ›
definition le_approx_def : ‹P ⊑ Q ≡D Q ⊆D P ∧
(∀s. s ∉D P ⟶Ra P s = Ra Q s) ∧
min_elems (D P) ⊆T Q›
text‹ The approximation ordering captures the fact that more concrete
should be more defined by ordering the divergence sets
. For defined positions in a process, the failure
must coincide pointwise; moreover, the minimal elements
wrt.~prefix ordering on traces, i.e.~lists) must be contained in
trace set of the more concrete process.›
lemma proc_ord2a : ‹P ⊑ Q ==> s ∉D P ==> (s, X) ∈F P ⟷ (s, X) ∈F Q› by (auto simp: le_approx_def Refusals_after_def)
instance processptick :: (type, type) po proof intro_classes show‹P ⊑ P›for P :: ‹('a, 'r) processptick› by (metis D_T elem_min_elems le_approx_def subsetI) next show‹P ⊑ Q ==> Q ⊑ P ==> P = Q›for P Q :: ‹('a, 'r) processptick› by (simp add: Process_eq_spec le_approx1 le_approx_lemma_F subset_antisym) next fix P Q R :: ‹('a, 'r) processptick› assume‹P ⊑ Q›and‹Q ⊑ R› show‹P ⊑ R› proof (unfold le_approx_def, intro conjI allI impI) show‹D R ⊆D P›by (meson ‹P ⊑ Q›‹Q ⊑ R› dual_order.trans le_approx1) next show‹s ∉D P ==>Ra P s = Ra R s›for s by (metis ‹P ⊑ Q›‹Q ⊑ R› le_approx_def subsetD) next from‹P ⊑ Q›[THEN le_approx1] ‹P ⊑ Q›[THEN le_approx3] ‹Q ⊑ R›[THEN le_approx2T] ‹Q ⊑ R›[THEN le_approx3] show‹min_elems (D P) ⊆T R› by (simp add: min_elems_def subset_iff) blast qed qed
text‹ At this point, we inherit quite a number of facts from the underlying
theory, which comprises a library of facts such as \verb+chain+,
verb+directed+(sets), upper bounds and least upper bounds, etc. ›
lemma min_elems3: ‹s @ [c] ∈D P ==> s @ [c] ∉ min_elems (D P) ==> s ∈D P› by (simp add: min_elems_def less_eq_list_def less_list_def)
(metis D_imp_front_tickFree append.right_neutral front_tickFree_append_iff
front_tickFree_dw_closed is_processT7 prefix_def)
lemma min_elems1: ‹s ∉D P ==> s @ [c] ∈D P ==> s @ [c] ∈ min_elems (D P)› using min_elems3 by blast
lemma min_elems2: ‹s ∉D P ==> s @ [c] ∈D P ==> P ⊑ S ==> Q ⊑ S ==> (s @ [c], {})∈F Q› by (meson T_F in_mono le_approx3 le_approx_lemma_F min_elems3)
lemma min_elems6: ‹s ∉D P ==> s @ [c] ∈D P ==> P ⊑ S ==> (s @ [c], {}) ∈F S› by (auto intro!: min_elems2)
lemma ND_F_dir2: ‹s ∉D P ==> (s, {}) ∈F P ==> P ⊑ S ==> Q ⊑ S ==> (s, {}) ∈F Q› by (meson is_processT8 le_approx2)
lemma ND_F_dir2': ‹s ∉D P ==> s ∈T P ==> P ⊑ S ==> Q ⊑ S ==> s ∈T Q› by (meson D_T le_approx2T)
lemma chain_lemma: ‹chain S ==> S i ⊑ S k ∨ S k ⊑ S i› by (metis chain_mono_less not_le_imp_less po_class.chain_mono)
contextfixes S :: ‹nat ==> ('a, 'r) processptick› assumes‹chain S› begin
lift_definition lim_proc :: ‹('a, 'r) processptick› is‹(∩ (F ` range S), ∩ (D ` range S))› proof (unfold is_process_def FAILURES_def DIVERGENCES_def fst_conv snd_conv, intro conjI allI impI) show‹([], {}) ∈∩ (F ` range S)›by (simp add: is_processT) next show‹(s, X) ∈∩ (F ` range S) ==> ftF s›for s X by (meson INT_iff UNIV_I image_eqI is_processT2) next show‹(s @ t, {}) ∈∩ (F ` range S) ==>
(s, {}) ∈∩ (F ` range S)›for s t by (auto intro: is_processT3) next show‹(s, Y) ∈∩ (F ` range S) ∧ X ⊆ Y ==> (s, X) ∈∩ (F ` range S)›for s X Y by (metis (full_types) INT_iff is_processT4) next show‹(s, X ∪ Y) ∈∩ (F ` range S)› if assm : ‹(s, X) ∈∩ (F ` range S) ∧
(∀c. c ∈ Y ⟶ (s @ [c], {}) ∉∩ (F ` range S))›for s X Y proof (rule ccontr) assume‹(s, X ∪ Y) ∉∩ (F ` range S)› thenobtain i where‹(s, X ∪ Y) ∉F (S i)›by blast moreoverhave‹(s, X) ∈F (S j)›for j using assm by blast ultimatelyobtain c where‹c ∈ Y›and * : ‹(s @ [c], {}) ∈F (S i)› using is_processT5 by blast from‹(s, X ∪ Y) ∉F (S i)› is_processT8 have‹s ∉D (S i)›by blast from assm ‹c ∈ Y›obtain j where ** : ‹(s @ [c], {}) ∉F (S j)›by blast
from chain_lemma[OF ‹chain S›, of i j] "*""**"show False by (elim disjE; use‹s ∉D (S i)› is_processT8 min_elems6 proc_ord2a in blast) qed next show‹(s @ [🍋(r)], {}) ∈∩ (F ` range S) ==>
(s, X - {🍋(r)}) ∈∩ (F ` range S)›for s r X by (simp add: is_processT6) next show‹s ∈∩ (D ` range S) ∧ tF s ∧ ftF t ==>
s @ t ∈∩ (D ` range S)›for s t by (simp add: is_processT7) next show‹s ∈∩ (D ` range S) ==> (s, X) ∈∩ (F ` range S)›for s X by (simp add: is_processT8) next show‹s @ [🍋(r)] ∈∩ (D ` range S) ==> s ∈∩ (D ` range S)›for s r by (auto intro: is_processT9) qed
lemma F_LUB: ‹F lim_proc = ∩ (F ` range S)› by (metis Failures.rep_eq lim_proc.rep_eq process_surj_pair prod.sel(1))
lemma D_LUB: ‹D lim_proc = ∩ (D ` range S)› by (metis Divergences.rep_eq lim_proc.rep_eq process_surj_pair prod.inject)
lemma T_LUB: ‹T lim_proc = ∩ (T ` range S)› by (insert F_LUB, auto simp add: T_def_spec) (meson F_T T_F)
lemmas LUB_projs = F_LUB D_LUB T_LUB
lemma Refusals_LUB: ‹R lim_proc = ∩ (R ` range S)› by (auto simp add: Refusals_def_bis F_LUB)
lemma Refusals_after_LUB: ‹Ra lim_proc s = (∩i. (Ra (S i) s))› by (auto simp add: Refusals_after_def F_LUB)
lemma F_LUB_2: ‹(s, X) ∈F lim_proc ⟷ (∀i. (s, X) ∈F (S i))› and D_LUB_2: ‹t ∈D lim_proc ⟷ (∀i. t ∈D (S i))› and T_LUB_2: ‹t ∈T lim_proc ⟷ (∀i. t ∈T (S i))› and Refusals_LUB_2: ‹X ∈R lim_proc ⟷ (∀i. X ∈R (S i))› and Refusals_after_LUB_2: ‹X ∈Ra lim_proc s ⟷ (∀i. X ∈Ra (S i) s)› by (simp_all add: F_LUB D_LUB T_LUB Refusals_LUB Refusals_after_LUB)
end
text‹By exiting the context, terms like ‹F lim_proc› will become term‹F (lim_proc S)›
and the assumption term‹chain S› will be added.›
section‹ Process Refinement is a Partial Ordering›
text‹ The following type instantiation declares the refinement order \_\le\_ $ written \verb+_ <= _+. It captures the intuition that more
processes should be more deterministic and more defined.›
instantiation processptick :: (type, type) ord begin
definition less_processptick :: ‹('a, 'r) processptick==> ('a, 'r) processptick==> bool› where‹less_processptick P Q ≡ P ≤ Q ∧ P ≠ Q›
instance ..
end
text‹Note that this just another syntax to our standard process refinement order
defined in the theory Process. ›
lemma le_ref1 : ‹P ≤ Q ==>D Q ⊆D P› and le_ref2 : ‹P ≤ Q ==>F Q ⊆F P› and le_ref2T : ‹P ≤ Q ==>T Q ⊆T P› and le_approx_imp_le_ref: ‹(P::('a, 'r) processptick) ⊑ Q ==> P ≤ Q› by (simp_all add: less_eq_processptick_def le_approx1 le_approx_lemma_F)
(use T_F_spec in blast)
lemma F_subset_imp_T_subset : ‹F P ⊆F Q ==>T P ⊆T Q› using T_F_spec by blast
lemma D_extended_is_D : ‹{t @ u |t u. t ∈D P ∧ tF t ∧ ftF u} = D P› by (auto simp add: is_processT7)
(metis D_imp_front_tickFree append.right_neutral butlast_snoc front_tickFree_append_iff
front_tickFree_charn is_processT9 nonTickFree_n_frontTickFree tickFree_Nil)
lemma Process_eq_optimizedI : ‹[∧t. t ∈D P ==> t ∈D Q; ∧t. t ∈D Q ==> t ∈D P; ∧t X. (t, X) ∈F P ==> t ∉D P ==> t ∉D Q ==> (t, X) ∈F Q; ∧t X. (t, X) ∈F Q ==> t ∉D Q ==> t ∉D P ==> (t, X) ∈F P]==> P = Q› by (simp add: Process_eq_spec_optimized, safe, auto intro: is_processT8)
instance processptick :: (type, type) order by intro_classes (auto simp: less_eq_processptick_def less_processptick_def Process_eq_spec)
lemma lim_proc_is_ub: ‹chain S ==> range S <| lim_proc S› by (simp add: is_ub_def le_approx_def F_LUB D_LUB T_LUB Refusals_after_def)
(intro allI conjI, blast, use chain_lemma is_processT8 le_approx2 in blast, use D_T chain_lemma le_approx2T le_approx_def in blast)
lemma chain_min_elem_div_is_min_for_sequel: ‹chain S ==> s ∈ min_elems (D (S i)) ==> i ≤ j ==> s ∈D (S j) ==> s ∈ min_elems (D (S j))› by (metis elem_min_elems insert_absorb insert_subset le_approx1
min_elems5 min_elems_no po_class.chain_mono)
lemma limproc_is_lub: ‹range S <<| lim_proc S›if‹chain S› proof (unfold is_lub_def, intro conjI allI impI) show‹range S <| lim_proc S›by (simp add: lim_proc_is_ub ‹chain S›) next show‹lim_proc S ⊑ P›if‹range S <| P›for P proof (unfold le_approx_def, intro conjI allI impI subsetI) show‹s ∈D P ==> s ∈D (lim_proc S)›for s by (meson D_LUB_2 ‹chain S›‹range S <| P› is_ub_def le_approx1 rangeI subsetD) next show‹s ∉D (lim_proc S) ==>Ra (lim_proc S) s = Ra P s›for s by (metis ‹chain S›‹range S <| P› D_LUB_2 le_approx_def lim_proc_is_ub ub_rangeD) next fix s assume‹s ∈ min_elems (D (lim_proc S))› from elem_min_elems[OF this] have‹∀i. s ∈D (S i)› by (simp add: ‹chain S› D_LUB) have‹∃i. ∀j≥i. s ∈ min_elems (D (S j))› proof (rule ccontr) assume‹∄i. ∀j≥i. s ∈ min_elems (D (S j))› hence‹∀i. ∃j≥i. s ∉ min_elems (D (S j))›by simp with‹∀i. s ∈D (S i)› chain_min_elem_div_is_min_for_sequel ‹chain S› have‹∀j. s ∉ min_elems (D (S j))›by blast from‹s ∈ min_elems (D (lim_proc S))›‹∀i. s ∈D (S i)›show False by (cases s rule: rev_cases; simp add: min_elems_def D_LUB ‹chain S›)
(use Nil_min_elems ‹∀j. s ∉ min_elems (D (S j))›in blast,
metis (no_types, lifting) INT_iff ‹∀j. s ∉ min_elems (D (S j))› less_self min_elems3) qed thus‹s ∈T P›by (meson le_approx3 order.refl subset_eq ‹range S <| P› ub_rangeD) qed qed
lemma limproc_is_thelub: ‹chain S ==> (⊔i. S i) = lim_proc S› by (frule limproc_is_lub, frule po_class.lub_eqI, simp)
instance processptick :: (type, type) cpo by intro_classes (use limproc_is_lub in blast)
show‹∃x :: ('a, 'r) processptick. ∀ y. x ⊑ y› proof (intro exI allI) show‹bot ⊑ y›for y proof (unfold le_approx_def, intro conjI allI impI subsetI) show‹s ∈D y ==> s ∈D bot›for s by (simp add: D_bot D_imp_front_tickFree) next from F_imp_front_tickFree show‹s ∉D bot ==>Ra bot s = Ra y s›for s by (auto simp add: D_bot Refusals_after_def F_bot) next show‹s ∈ min_elems (D bot) ==> s ∈T y›for s by (simp add: D_bot min_elems_Collect_ftF_is_Nil) qed qed qed
section‹ Process Refinement is Admissible ›
lemma le_FD_adm : ‹cont (u :: ('b::cpo) ==> ('a, 'r) processptick) ==> monofun v ==> adm (λx. u x ≤ v x)› apply (unfold less_eq_processptick_def adm_def) apply (simp add: cont2contlubE D_LUB F_LUB ch2ch_cont limproc_is_thelub monofun_def) by (meson INF_greatest dual_order.trans is_ub_thelub le_approx1 le_approx_lemma_F)
section‹ The Conditional Statement is Continuous › text‹The conditional operator of CSP is obtained by a direct shallow embedding. Here we prove it continuous›
lemma if_then_else_cont[simp]: ‹[∧x. P x ==> cont (f x); ∧x. ¬ P x ==> cont (g x)]==>
cont (λy. if P x then f x y else g x y)› for f :: ‹'c ==> 'b :: cpo ==> ('a, 'r) processptick› by (auto simp: cont_def)
section‹Tools for proving continuity›
― ‹The following result is very useful (especially for ProcOmata).›
lemma cont_process_rec: ‹P = (μ X. f X) ==> cont f ==> P = f P› by (simp add: def_cont_fix_eq)
lemma Inter_nonempty_finite_chained_sets: ‹(∩i. S i) ≠ {}› if‹∧i. j ≤ i ==> S i ≠ {}›‹finite (S j)›‹∧i. S (Suc i) ⊆ S i›for S :: ‹nat ==> 'a set› proof - have * : ‹∀i. S i ≠ {} ==> finite (S 0) ==>∀i. S (Suc i) ⊆ S i ==> (∩i. S i) ≠ {}› for S :: ‹nat ==> 'a set› proof (induct ‹card (S 0)› arbitrary: S rule: nat_less_induct) case1 show ?case proof (cases ‹∀i. S i = S 0›) case True thus ?thesis by (metis "1.prems"(1) INT_iff ex_in_conv) next case False have f1: ‹i ≤ j ==> S j ⊆ S i›for i j by (simp add: "1.prems"(3) lift_Suc_antimono_le) with False obtain j m where f2: ‹m < card (S 0)›and f3: ‹m = card (S j)› by (metis "1.prems"(2) psubsetI psubset_card_mono zero_le)
define T where‹T i ≡ S (i + j)›for i have f4: ‹m = card (T 0)›unfolding T_def by (simp add: f3) from f1 have f5: ‹(∩i. S i) = (∩i. T i)›unfolding T_def by (auto intro: le_add1) show ?thesis apply (subst f5) apply (rule "1.hyps"[rule_format, OF f2, of T, OF f4], unfold T_def) by (simp_all add: "1.prems"(1, 3) lift_Suc_antimono_le)
(metis "1.prems"(2) add_0 f1 finite_subset le_add1) qed qed
define S' where‹S' i ≡ S (j + i)›for i have‹∀i. S' i ≠ {}›by (simp add: S'_def‹∧i. j ≤ i ==> S i ≠ {}›) moreoverhave‹finite (S' 0)›by (simp add: ‹S' ≡ λi. S (j + i)›‹finite (S j)›) moreoverhave‹∀i. S' (Suc i) ⊆ S' i›by (simp add: S'_def‹∧i. S (Suc i) ⊆ S i›) ultimatelyhave‹(∩i. S' i) ≠ {}›by (fact "*") alsofrom lift_Suc_antimono_le[where f = S, OF ‹∧i. S (Suc i) ⊆ S i›] have‹(∩i. S' i) = (∩i. S i)› by (simp add: INF_greatest INF_lower INF_mono' S'_def equalityI) finallyshow‹(∩i. S i) ≠ {}› . qed
method prove_finite_subset_of_prefixes for t :: ‹('a, 'r) traceptick› =
―‹Useful for establishing the second hypothesis›
solves ‹(rule finite_UnI; prove_finite_subset_of_prefixes t) |
(rule finite_subset[of _ ‹{u. u ≤ t}›],
use prefixI in blast, simp add: prefixes_fin)›
(*<*) end (*>*)
Messung V0.5 in Prozent
¤ 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.0.99Bemerkung:
(vorverarbeitet am 2026-06-10)
¤
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.