(* FIXME: Redo also this properly using the function update lens *)
text‹UTP variables represented by record fields are shallow, nameless entities. They are fundamentally
static in nature, since a new record field can only be introduced definitionally and cannot be
otherwise arbitrarily created. They are nevertheless very useful as proof automation is excellent,
and they can fully make use of the Isabelle type system. However, for constructs like alphabet
extension that can introduce new variables they are inadequate. As a result we also introduce
a notion of deep variables to complement them. A deep variable is not a record field, but
rather a key within a store map that records the values of all deep variables. As such the
Isabelle type system is agnostic of them, and the creation of a new deep variable does not
change the portion of the alphabet specified by the type system.
In order to create a type of stores (or bindings) for variables, we must fix a universe
for the variable valuations. This is the major downside of deep variables -- they cannot
have any type, but only a type whose cardinality is up to $\mathfrak{c}$, the cardinality
of the continuum. This is why we need both deep and shallow variables, as the latter are
unrestricted in this respect. Each deep variable will therefore specify the cardinality
of the type it possesses.›
subsection‹Cardinalities›
text‹We first fix a datatype representing all possible cardinalities for a deep variable. These
include finite cardinalities, $\aleph_0$ (countable), and $\mathfrak{c}$ (uncountable up
to the continuum).›
text‹Our universe is simply the set of natural numbers; this is sufficient for all types up
to cardinality $\mathfrak{c}$.›
type_synonym uuniv = "nat set"
text‹We introduce a function that gives the set of values within our universe of the given
cardinality. Since a cardinality of 0 is no proper type, we use finite cardinality 0 to
mean cardinality 1, 1 to mean 2 etc.›
fun uuniv :: "ucard ==> uuniv set" ("U'(_')") where "U(fin n) = {{x} | x. x ≤ n}" | "U(ℵ0) = {{x} | x. True}" | "U(c) = UNIV"
text‹We also define the following function that gives the cardinality of a type within
the @{class continuum} type class.›
definition ucard_of :: "'a::continuum itself ==> ucard"where "ucard_of x = (if (finite (UNIV :: 'a set)) then fin(card(UNIV :: 'a set) - 1) else if (countable (UNIV :: 'a set)) then ℵ0 else c)"
definition uinject :: "'a::continuum ==> uuniv"where "uinject x = (if (finite (UNIV :: 'a set)) then {to_nat_fin x} else if (countable (UNIV :: 'a set)) then {to_nat_on (UNIV :: 'a set) x} else to_nat_set x)"
lemma uinject_finite: "finite (UNIV :: 'a::continuum set) ==> uinject = (λ x :: 'a. {to_nat_fin x})" by (rule ext, auto simp add: uinject_def)
lemma uinject_uncountable: "uncountable (UNIV :: 'a::continuum set) ==> (uinject :: 'a ==> uuniv) = to_nat_set" by (rule ext, auto simp add: uinject_def countable_finite)
lemma card_finite_lemma: assumes"finite (UNIV :: 'a set)" shows"x < card (UNIV :: 'a set) ⟷ x ≤ card (UNIV :: 'a set) - Suc 0" proof - have"card (UNIV :: 'a set) > 0" by (simp add: assms finite_UNIV_card_ge_0) thus ?thesis by linarith qed
text‹This is a key theorem that shows that the injection function provides a bijection between
any continuum type and the subuniverse of types with a matching cardinality.›
lemma uinject_bij: "bij_betw (uinject :: 'a::continuum ==> uuniv) UNIV U(UCARD('a))" proof (cases "finite (UNIV :: 'a set)") case True thus ?thesis apply (auto simp add: uinject_def bij_betw_def inj_on_def image_def card_finite_lemma[THEN sym]) apply (auto simp add: inj_eq to_nat_fin_inj to_nat_fin_bounded) using to_nat_fin_ex apply blast done next case False note infinite = this thus ?thesis proof (cases "countable (UNIV :: 'a set)") case True thus ?thesis apply (auto simp add: uinject_def bij_betw_def inj_on_def infinite image_def card_finite_lemma[THEN sym]) apply (meson image_to_nat_on infinite surj_def) done next case False note uncount = this thus ?thesis apply (simp add: uinject_uncountable) using to_nat_set_bij apply blast done qed qed
text‹A deep variable name stores both a name and the cardinality of the type it points to›
record dname =
dname_name :: "string"
dname_card :: "ucard"
declare dname.splits [alpha_splits]
text‹A vstore is a function mapping deep variable names to corresponding values in the universe, such
that the deep variables specified cardinality is matched by the value it points to.›
text‹Deep variables with different names are independent›
lemma dvar_lift_indep_iff: fixes x :: "'a::{continuum,two} dvar"and y :: "'b::{continuum,two} dvar" shows"x↑⋈ y↑⟷ dvar_dname x ≠ dvar_dname y" proof - have"x↑⋈ y↑⟷ dvar_lens x ⋈ dvar_lens y" by (metis dvar_lift_def lens_comp_indep_cong_left lens_indep_left_comp vst_class.vstore_vwb_lens vwb_lens_mwb) alsohave"... ⟷ dvar_dname x ≠ dvar_dname y" by (simp add: dvar_lens_indep_iff) finallyshow ?thesis . qed
lemma dvar_indep_diff_name' [simp]: "x ≠ y ==>⌈x⌉d↑⋈⌈y⌉d↑" by (simp add: dvar_lift_indep_iff mk_dvar.rep_eq)
text‹A basic record structure for vstores›
record vstore_d =
vstore :: vstore
instantiation vstore_d_ext :: (type) vst begin definition"vstore_lens_vstore_d_ext = VAR vstore" instance by (intro_classes, unfold_locales, simp_all add: vstore_lens_vstore_d_ext_def) end
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.