section\Temporal Properties\ text\This theory presents some examples of temporal properties over the simple drinks machine.\ theory Drinks_Machine_LTL imports "Drinks_Machine" "Extended_Finite_State_Machines.EFSM_LTL" begin declare One_nat_def [simp del] lemma P_ltl_step_0: assumes invalid: "P (None, [], <>)" assumes select: "l = STR ''select'' \ P (Some 1, [], <1 $:= Some (hd i), 2 $:= Some (Num 0)>)" shows "P (ltl_step drinks (Some 0) <> (l, i))" proof- have length_i: "\d. (l, i) = (STR ''select'', [d]) \ length i = 1" by (induct i, auto) have length_i_2: "\d. i \ [d] \ length i \ 1" by (induct i, auto) show ?thesis apply (case_tac "\d. (l, i) = (STR ''select'', [d])") apply (simp add: possible_steps_0 length_i select_def apply_updates_def) using select apply auto[1] by (simp add: possible_steps_0_invalid length_i_2 invalid) qed lemma P_ltl_step_1: assumes invalid: "P (None, [], r)" assumes coin: "l = STR ''coin'' \ P (Some 1, [value_plus (r $ 2) (Some (hd i))], r(2 $:= value_plus (r $ 2) (Some (i ! 0))))" assumes vend_fail: "value_gt (Some (Num 100)) (r $ 2) = trilean.true \ P (Some 1, [],r)" assumes vend: "\? value_gt (Some (Num 100)) (r $ 2) = trilean.true \ P (Some 2, [r$1], r)" shows "P (ltl_step drinks (Some 1) r (l, i))" proof- have length_i: "\s. \d. (l, i) = (s, [d]) \ length i = 1" by (induct i, auto) have length_i_2: "\d. i \ [d] \ length i \ 1" by (induct i, auto) show ?thesis apply (case_tac "\d. (l, i) = (STR ''coin'', [d])") apply (simp add: possible_steps_1_coin length_i coin_def apply_outputs_def apply_updates_def) using coin apply auto[1] apply (case_tac "(l, i) = (STR ''vend'', [])") apply (case_tac "\n. r $ 2 = Some (Num n)") apply clarsimp subgoal for n apply (case_tac "n \ 100") apply (simp add: drinks_vend_sufficient vend_def apply_updates_def apply_outputs_def) apply (metis finfun_upd_triv possible_steps_2_vend vend vend_ge_100) apply (simp add: drinks_vend_insufficient vend_fail_def apply_updates_def apply_outputs_def) apply (metis MaybeBoolInt.simps(1) finfun_upd_triv not_less value_gt_def vend_fail) done apply (simp add: drinks_vend_invalid invalid) by (simp add: drinks_no_possible_steps_1 length_i_2 invalid) qed lemma LTL_r2_not_always_gt_100: "not (alw (check_exp (Gt (V (Rg 2)) (L (Num 100))))) (watch drinks i)" using value_gt_def by auto lemma drinks_step_2_none: "ltl_step drinks (Some 2) r e = (None, [], r)" by (simp add: drinks_end ltl_step_none_2) lemma one_before_two_2: "alw (\x. statename (shd (stl x)) = Some 2 \ statename (shd x) = Some 1) (make_full_observation drinks (Some 2) r [r $ 1] x2a)" proof(coinduction) case alw then show ?case apply (simp add: drinks_step_2_none) by (metis (mono_tags, lifting) alw_mono nxt.simps once_none_nxt_always_none option.distinct(1)) qed lemma one_before_two_aux: assumes "\ p r i. j = nxt (make_full_observation drinks (Some 1) r p) i" shows "alw (\x. nxt (state_eq (Some 2)) x \ state_eq (Some 1) x) j" using assms apply(coinduct) apply simp apply clarify apply standard apply simp apply simp subgoal for r i apply (case_tac "shd (stl i)") apply (simp del: ltl_step.simps) apply (rule P_ltl_step_1) apply (rule disjI2) apply (rule alw_mono[of "nxt (state_eq None)"]) apply (simp add: once_none_nxt_always_none) apply simp apply auto[1] apply auto[1] apply simp by (simp add: one_before_two_2) done lemma LTL_nxt_2_means_vend: "alw (nxt (state_eq (Some 2)) impl (state_eq (Some 1))) (watch drinks i)" proof(coinduction) case alw then show ?case apply (case_tac "shd i") apply (simp del: ltl_step.simps) apply (rule P_ltl_step_0) apply simp apply (rule disjI2) apply (rule alw_mono[of "nxt (state_eq None)"]) apply (simp add: once_none_nxt_always_none) using one_before_two_aux by auto qed lemma costsMoney_aux: assumes "\p r i. j = (nxt (make_full_observation drinks (Some 1) r p) i)" shows "alw (\xs. nxt (state_eq (Some 2)) xs \ check_exp (Ge (V (Rg 2)) (L (Num 100))) xs) j" using assms apply coinduct apply clarsimp subgoal for r i apply (case_tac "shd (stl i)") apply (simp del: ltl_step.simps) apply (rule P_ltl_step_1) apply simp apply (rule disjI2) apply (rule alw_mono[of "nxt (state_eq None)"]) apply (simp add: once_none_nxt_always_none) apply simp apply auto[1] apply auto[1] apply simp apply standard apply (rule disjI2) apply (rule alw_mono[of "nxt (state_eq None)"]) apply (metis (no_types, lifting) drinks_step_2_none fst_conv make_full_observation.sel(2) nxt.simps nxt_alw once_none_always_none_aux) by simp done (* costsMoney: THEOREM drinks |- G(X(cfstate=State_2) => gval(value_ge(r_2, Some(NUM(100))))); *) lemma LTL_costsMoney: "(alw (nxt (state_eq (Some 2)) impl (check_exp (Ge (V (Rg 2)) (L (Num 100)))))) (watch drinks i)" proof(coinduction) case alw then show ?case apply (cases "shd i") subgoal for l ip apply (case_tac "l = STR ''select'' \ length ip = 1") defer apply (simp add: possible_steps_0_invalid) apply (rule disjI2) apply (rule alw_mono[of "nxt (state_eq None)"]) apply (simp add: once_none_nxt_always_none) apply (simp add: ) apply (simp add: possible_steps_0 select_def) apply (rule disjI2) apply (simp only: nxt.simps[symmetric]) using costsMoney_aux by auto done qed lemma LTL_costsMoney_aux: "(alw (not (check_exp (Ge (V (Rg 2)) (L (Num 100)))) impl (not (nxt (state_eq (Some 2)))))) (watch drinks i)" by (metis (no_types, lifting) LTL_costsMoney alw_mono) lemma implode_select: "String.implode ''select'' = STR ''select''" by (metis Literal.rep_eq String.implode_explode_eq zero_literal.rep_eq) lemma implode_coin: "String.implode ''coin'' = STR ''coin''" by (metis Literal.rep_eq String.implode_explode_eq zero_literal.rep_eq) lemma implode_vend: "String.implode ''vend'' = STR ''vend''" by (metis Literal.rep_eq String.implode_explode_eq zero_literal.rep_eq) lemmas implode_labels = implode_select implode_coin implode_vend lemma LTL_neverReachS2:"(((((action_eq (''select'', [Str ''coke'']))) aand (nxt ((action_eq (''coin'', [Num 100]))))) aand (nxt (nxt((label_eq ''vend'' aand (input_eq [])))))) impl (nxt (nxt (nxt (state_eq (Some 2)))))) (watch drinks i)" apply (simp add: implode_labels) apply (cases i) apply clarify apply simp apply (simp add: possible_steps_0 select_def) apply (case_tac "shd x2", clarify) apply (simp add: possible_steps_1_coin coin_def value_plus_def finfun_update_twist apply_updates_def) apply (case_tac "shd (stl x2)", clarify) by (simp add: drinks_vend_sufficient ) lemma ltl_step_not_select: "\i. e = (STR ''select'', [i]) \ ltl_step drinks (Some 0) r e = (None, [], r)" apply (cases e, clarify) subgoal for a b apply (rule ltl_step_none) apply (simp add: possible_steps_empty drinks_def can_take_transition_def can_take_def select_def) by (cases e, case_tac b, auto) done lemma ltl_step_select: "ltl_step drinks (Some 0) <> (STR ''select'', [i]) = (Some 1, [], <1 $:= Some i, 2 $:= Some (Num 0)>)" apply (rule ltl_step_some[of _ _ _ _ _ _ select]) apply (simp add: possible_steps_0) apply (simp add: select_def) by (simp add: select_def finfun_update_twist apply_updates_def) lemma ltl_step_not_coin_or_vend: "\i. e = (STR ''coin'', [i]) \ e \ (STR ''vend'', []) \ ltl_step drinks (Some 1) r e = (None, [], r)" apply (cases e) subgoal for a b apply (simp del: ltl_step.simps) apply (rule ltl_step_none) apply (simp add: possible_steps_empty drinks_def can_take_transition_def can_take_def transitions) by (case_tac e, case_tac b, auto) done lemma ltl_step_coin: "\p r'. ltl_step drinks (Some 1) r (STR ''coin'', [i]) = (Some 1, p, r')" by (simp add: possible_steps_1_coin) lemma alw_tl: "alw \ (make_full_observation e (Some 0) <> [] xs) \ alw \ (make_full_observation e (fst (ltl_step e (Some 0) <> (shd xs))) (snd (snd (ltl_step e (Some 0) <> (shd xs)))) (fst (snd (ltl_step e (Some 0) <> (shd xs)))) (stl xs))" by auto lemma stop_at_none: "alw (\xs. output (shd (stl xs)) = [Some (EFSM.Str drink)] \ check_exp (Ge (V (Rg 2)) (L (Num 100))) xs) (make_full_observation drinks None r p t)" apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: no_output_none_nxt) by simp lemma drink_costs_money_aux: assumes "\p r t. j = make_full_observation drinks (Some 1) r p t" shows "alw (\xs. output (shd (stl xs)) = [Some (EFSM.Str drink)] \ check_exp (Ge (V (Rg 2)) (L (Num 100))) xs) j" using assms apply coinduct apply clarsimp apply (case_tac "shd t") apply (simp del: ltl_step.simps) apply (rule P_ltl_step_1) apply simp apply (rule disjI2) apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: no_output_none_nxt) apply simp apply (simp add: Str_def value_plus_never_string) apply auto[1] apply auto[1] apply simp apply standard apply (rule disjI2) apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: drinks_step_2_none no_output_none_if_empty nxt_alw) by simp lemma LTL_drinks_cost_money: "alw (nxt (output_eq [Some (Str drink)]) impl (check_exp (Ge (V (Rg 2)) (L (Num 100))))) (watch drinks t)" proof(coinduction) case alw then show ?case apply (case_tac "shd t") apply (simp del: ltl_step.simps) apply (rule P_ltl_step_0) apply simp apply (rule disjI2) apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: no_output_none_nxt) apply simp apply simp using drink_costs_money_aux apply simp by blast qed lemma steps_1_invalid: "\i. (a, b) = (STR ''coin'', [i]) \ \i. (a, b) = (STR ''vend'', []) \ possible_steps drinks 1 r a b = {||}" apply (simp add: possible_steps_empty drinks_def transitions can_take_transition_def can_take_def) by (induct b, auto) lemma output_vend_aux: assumes "\p r t. j = make_full_observation drinks (Some 1) r p t" shows "alw (\xs. label_eq ''vend'' xs \ output (shd (stl xs)) = [Some d] \ check_exp (Ge (V (Rg 2)) (L (Num 100))) xs) j" using assms apply coinduct apply clarsimp subgoal for r t apply (case_tac "shd t") apply (simp add: implode_vend del: ltl_step.simps) apply (rule P_ltl_step_1) apply simp apply (rule disjI2) apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: no_output_none_nxt) apply simp apply auto[1] apply auto[1] apply simp apply standard apply (rule disjI2) apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: drinks_step_2_none no_output_none_if_empty nxt_alw) by simp done text_raw\\snip{outputVend}{1}{2}{%\ lemma LTL_output_vend: "alw (((label_eq ''vend'') aand (nxt (output_eq [Some d]))) impl (check_exp (Ge (V (Rg 2)) (L (Num 100))))) (watch drinks t)" text_raw\}%endsnip\ proof(coinduction) case alw then show ?case apply (simp add: implode_vend) apply (case_tac "shd t") apply (simp del: ltl_step.simps) apply (rule P_ltl_step_0) apply simp apply (rule disjI2) apply (rule alw_mono[of "nxt (output_eq [])"]) apply (simp add: no_output_none_nxt) apply simp apply simp subgoal for a b using output_vend_aux[of "(make_full_observation drinks (Some 1) <1 $:= Some (hd b), 2 $:= Some (Num 0)> [] (stl t))" d] using implode_vend by auto done qed text_raw\\snip{outputVendUnfolded}{1}{2}{%\ lemma LTL_output_vend_unfolded: "alw (\xs. (label (shd xs) = STR ''vend'' \ nxt (\s. output (shd s) = [Some d]) xs) \ \? value_gt (Some (Num 100)) (datastate (shd xs) $ 2) = trilean.true) (watch drinks t)" text_raw\}%endsnip\ apply (insert LTL_output_vend[of d t]) by (simp add: implode_vend) end