header {* Representing a state in TLA* *} theory State imports Liveness begin typedecl state instance state :: world .. types 'a statefun = "(state,'a) stfun" statepred = "bool statefun" 'a tempfun = "(state,'a) formfun" temporal = "state formula" consts (* Formalizing type "state" would require formulas to be tagged with their underlying state space and would result in a system that is much harder to use. (Unlike Hoare logic or Unity, TLA has quantification over state variables, and therefore one usually works with different state spaces within a single specification.) Instead, "state" is just an anonymous type whose only purpose is to provide "Skolem" constants. Moreover, we do not define a type of state variables separate from that of arbitrary state functions, again in order to simplify the definition of flexible quantification later on. Nevertheless, we need to distinguish state variables, mainly to define the enabledness of actions. The user identifies (tuples of) "base" state variables in a specification via the "meta predicate" basevars, which is defined here. *) stvars :: "'a statefun => bool" syntax "PRED" :: "lift => 'a" ("PRED _") "_stvars" :: "lift => bool" ("basevars _") translations "PRED P" => "(P::state => _)" "_stvars" == "stvars" defs (* Base variables may be assigned arbitrary (type-correct) values. Note that vs may be a tuple of variables. The correct identification of base variables is up to the user who must take care not to introduce an inconsistency. For example, "basevars (x,x)" would definitely be inconsistent. *) basevars_def: "stvars vs \ range vs = UNIV" lemma basevars: "\ vs. basevars vs \ \ u. vs u = c" proof - fix vs :: "state \ 'a" assume H1: "basevars vs" from H1 have "range vs = UNIV" by (unfold basevars_def) from this show "\ u. vs u = c" proof (rule_tac b=c and f=vs in rangeE) assume "range vs = UNIV" from this show "c \ range vs" by simp next fix x assume a1:"range vs = UNIV" and a2: "c = vs x" from a2 have "vs x = c" by blast thus "\u. vs u = c" by (auto simp add: exI) qed qed ML "set show_types" lemma basevars_range: "\ vs. range vs = UNIV \ \ u. vs u = c" proof - fix vs :: "'a \ 'b" assume H1: "range vs = UNIV" from H1 show "\ u. vs u = c" proof (rule_tac b=c and f=vs in rangeE) assume "range vs = UNIV" from this show "c \ range vs" by simp next fix x assume a1:"range vs = UNIV" and a2: "c = vs x" from a2 have "vs x = c" by blast thus "\u. vs u = c" by (auto simp add: exI) qed qed (* lemma used in base_pair1 :: FIX ME: should encorporate it *) lemma bpair1: "\(x \ state \ 'b) y \ state \ 'c. range (LIFT(x, y)) = UNIV \ UNIV \ range x" proof (rule subsetI) fix x :: "state \ 'b" fix y :: "state \ 'c" fix xa :: "'b" assume a2: "range (LIFT(x,y))=UNIV" from a2 have g1: "\ u. (LIFT(x, y)) u = (xa, arbitrary)" by (drule_tac c="(xa,arbitrary)" in basevars_range) from g1 show "xa \ range x" by auto qed lemma base_pair1: "basevars (x,y) \ basevars x " proof - fix x :: "state \ 'a" fix y :: "state \ 'b" assume H1: "basevars (x,y)" from H1 have H2: "range (LIFT(x, y)) = UNIV" by (unfold basevars_def) have S1: "range x \ UNIV" by (rule subset_UNIV) moreover from H2 have S2: "UNIV \ range x" by (rule bpair1) (* FIXME: replace with proof (bpair1) - doesn't work *) ultimately have "range x = UNIV" by (rule equalityI) thus "basevars x" by (unfold basevars_def) qed lemma bpair2: "\(x \ state \ 'a) y \ state \ 'b. range (LIFT(x, y)) = UNIV \ UNIV \ range y" proof (rule subsetI) fix x :: "state \ 'a" fix y :: "state \ 'b" fix xa :: "'b" assume a2: "range (LIFT(x,y))=UNIV" from a2 have g1: "\ u. (LIFT(x, y)) u = (arbitrary,xa)" by (drule_tac c="(arbitrary,xa)" in basevars_range) from this obtain u where "(LIFT(x, y)) u = (arbitrary,xa)" .. thus "xa \ range y" by auto qed lemma base_pair2: "basevars (x,y) \ basevars y" proof - fix x :: "state \ 'a" fix y :: "state \ 'b" assume H1: "basevars (x,y)" from H1 have H2: "range (LIFT(x, y)) = UNIV" by (unfold basevars_def) have S1: "range y \ UNIV" by (rule subset_UNIV) moreover from H2 have S2: "UNIV \ range y" by (rule bpair2) (* FIXME: replace with proof - doesn't work *) ultimately have "range y = UNIV" by (rule equalityI) thus "basevars y" by (unfold basevars_def) qed lemma base_pair: "basevars (x,y) \ basevars x \ basevars y" proof - fix x :: "state \ 'a" fix y :: "state \ 'b" assume H1: "basevars (x,y)" show "basevars x \ basevars y" proof (rule conjI) from H1 show "basevars x" by (rule base_pair1) next from H1 show "basevars y" by (rule base_pair2) qed qed lemma base_pair: "\ x y. basevars (x,y) \ basevars x \ basevars y" proof - fix x :: "state \ 'a" fix y :: "state \ 'b" assume H1: "basevars (x,y)" show "basevars x \ basevars y" proof (rule conjI) from H1 show "basevars x" by (rule base_pair1) next from H1 show "basevars y" by (rule base_pair2) qed qed text{* Since the @{typ unit} type has just one value, any state function can be regarded as @{term base}. The following axiom can sometimes be useful because it gives a trivial solution for @{text basevars} premises. *} lemma unit_base: "basevars (v::state \ unit)" proof - have "range v = UNIV \ basevars (v::state \ unit)" by (auto simp add: basevars_def) thus ?thesis by auto qed lemma baseE: assumes H1: "basevars v" and H2:"\ x. v x = c \ Q" shows "Q" proof - from H1 have "\ u. v u = c" by (rule basevars) from this obtain u where "v u = c" .. with H2 show "Q" by auto qed lemma fixes x :: "state \ bool" assumes h1: "basevars (x,x)" shows "False" proof - thm "basevars" from h1 have "\ u. (LIFT (x,x)) u = (False,True)" by (rule basevars) thus False by auto qed (* Cannot prove for type variable !! *) lemma fixes x :: "state \ nat" assumes h1: "basevars (x,x)" shows "False" proof - thm "basevars" from h1 have "\ u. (LIFT (x,x)) u = (0,1)" by (rule basevars) thus False by auto qed lemma first_baseE: assumes H1: "basevars v" and H2: "\ x. v (first x) = c \ Q" shows "Q" proof - from H2 have H2': "\ x. v (x (0::nat)) = c \ Q" by (simp add: first_def) from H1 have "\ u. v u = c" by (rule basevars) from this obtain u where "v u = c" .. with H2' show "Q" by auto qed lemma base_enabled: assumes h1: "basevars vs" and h2: "\ c. \ u. vs (first u) = c \ (((first s) ## u) \ F )" shows "s \ Enabled F" proof (unfold enabled_def) from h2 obtain c where g1: "\ u. vs (first u) = c \ (((first s) ## u) \ F)" .. from h1 have "\ u. vs u = c" by (rule basevars) from this obtain u where "vs u = c" .. hence "\ k. vs (k (0::nat)) = c" by auto then obtain k where "vs (k (0::nat)) = c" .. hence g2: "vs (first k) = c" by (simp add: first_def) from g1 have "vs (first k) = c \ (((first s) ## k) \ F)" .. with g2 have "(((first s) ## k) \ F)" by auto thus "\ k. ((first s) ## k) \ F" by blast qed section "Temporal Quantifiers" consts EEx :: "('a statefun \ temporal) \ temporal" (binder "Eex " 10) AAll :: "('a statefun \ temporal) \ temporal" (binder "Aall " 10) syntax "_EEx" :: "[idts, lift] \ lift" ("(3EEX _./ _)" [0,10] 10) "_AAll" :: "[idts, lift] \ lift" ("(3AALL _./ _)" [0,10] 10) translations "_EEx v A" == "Eex v. A" "_AAll v A" == "Aall v. A" syntax (xsymbols) "_EEx" :: "[idts, lift] => lift" ("(3\\ _./ _)" [0,10] 10) "_AAll" :: "[idts, lift] => lift" ("(3\\ _./ _)" [0,10] 10) axioms eexI: "\ F x \ (\\ x. F x)" eexE: "\s \ (\\ x. F x) ; basevars vs; (!! x. \ basevars (x,vs); s \ F x \ \ s \ G)\ \ (s \ G)" eexSTUT: "STUTINV F x \ STUTINV (\\ x. F x)" history: "\ (I \ \[A]_v) = (\\ h. ($h = ha) \ I \ \[A \ h$=hb]_(h,v))" end