File: Trace_Properties.thy

package info (click to toggle)
sail-ocaml 0.19.1%2Bdfsg5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,008 kB
  • sloc: ml: 75,941; ansic: 8,848; python: 1,342; exp: 560; sh: 474; makefile: 218; cpp: 36
file content (168 lines) | stat: -rw-r--r-- 8,446 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
theory Trace_Properties
  imports Sail2_monadic_combinators_lemmas
begin

locale Stateful_Trace_Property =
  fixes pred :: "'state \<Rightarrow> ('abort, 'barrier, 'cache_op, 'fault, 'pa, 'tlb_op, 'translation_summary, 'regval) trace \<Rightarrow> bool"
    and update_state :: "'state \<Rightarrow> ('abort, 'barrier, 'cache_op, 'fault, 'pa, 'tlb_op, 'translation_summary, 'regval) trace \<Rightarrow> 'state"
  assumes pred_append: "\<And>s t1 t2. pred s t1 \<Longrightarrow> pred (update_state s t1) t2 \<Longrightarrow> pred s (t1 @ t2)"
begin

definition traces_satisfy_pred :: "'state \<Rightarrow> ('abort, 'barrier, 'cache_op, 'fault, 'pa, 'tlb_op, 'translation_summary, 'regval, 'a, 'e) monad \<Rightarrow> bool"
  where "traces_satisfy_pred s m \<equiv> (\<forall>t m'. (m, t, m') \<in> Traces \<longrightarrow> pred s t)"

lemma traces_satisfy_pred_bind:
  assumes "traces_satisfy_pred s m"
    and "\<And>t a. Run m t a \<Longrightarrow> traces_satisfy_pred (update_state s t) (f a)"
  shows "traces_satisfy_pred s (m \<bind> f)"
  using assms
  unfolding traces_satisfy_pred_def
  by (fastforce elim!: bind_Traces_cases intro: pred_append)

lemma traces_satisfy_pred_return:
  "traces_satisfy_pred s (return a) \<longleftrightarrow> pred s []"
  by (auto simp: traces_satisfy_pred_def return_def)

lemma traces_satisfy_pred_throw:
  "traces_satisfy_pred s (throw e) \<longleftrightarrow> pred s []"
  by (auto simp: traces_satisfy_pred_def throw_def)

lemma traces_satisfy_pred_try_catch:
  assumes "traces_satisfy_pred s m"
    and "\<And>t e. (m, t, Exception e) \<in> Traces \<Longrightarrow> traces_satisfy_pred (update_state s t) (h e)"
  shows "traces_satisfy_pred s (try_catch m h)"
  using assms
  unfolding traces_satisfy_pred_def
  by (fastforce elim!: try_catch_Traces_cases intro: pred_append)

lemma traces_satisfy_pred_early_return:
  "traces_satisfy_pred s (early_return a) \<longleftrightarrow> pred s []"
  by (auto simp: early_return_def traces_satisfy_pred_throw)

lemma traces_satisfy_pred_catch_early_return:
  assumes "traces_satisfy_pred s m"
  shows "traces_satisfy_pred s (catch_early_return m)"
  using assms
  unfolding traces_satisfy_pred_def catch_early_return_def
  by (auto simp: return_def throw_def split: sum.splits elim!: try_catch_Traces_cases)

lemma traces_satisfy_pred_liftR:
  assumes "traces_satisfy_pred s m"
  shows "traces_satisfy_pred s (liftR m)"
  using assms
  unfolding traces_satisfy_pred_def liftR_def
  by (auto simp: throw_def split: sum.splits elim!: try_catch_Traces_cases)

lemma traces_satisfy_pred_try_catchR:
  assumes "traces_satisfy_pred s m"
    and "\<And>t e. (m, t, Exception (Inr e)) \<in> Traces \<Longrightarrow> traces_satisfy_pred (update_state s t) (h e)"
  shows "traces_satisfy_pred s (try_catchR m h)"
  using assms
  unfolding traces_satisfy_pred_def try_catchR_def
  by (fastforce elim!: try_catch_Traces_cases split: sum.splits simp: throw_def intro: pred_append)

lemma traces_satisfy_pred_maybe_fail:
  "traces_satisfy_pred s (maybe_fail msg x) \<longleftrightarrow> pred s []"
  by (auto simp: traces_satisfy_pred_def maybe_fail_def return_def split: option.splits)

lemma traces_satisfy_pred_assert_exp:
  "traces_satisfy_pred s (assert_exp e msg) \<longleftrightarrow> pred s []"
  by (auto simp: traces_satisfy_pred_def assert_exp_def)

(*lemma Read_reg_Traces_iff: "(Read_reg r k, t, m') \<in> Traces \<longleftrightarrow> (\<exists>v t'. t = E_read_reg r v # t' \<and> (k v, t', m') \<in> Traces) \<or> (t = [] \<and> m' = Read_reg r k)"
  by (auto elim: Traces_cases intro: Traces_ConsI)

abbreviation "trace_characterisation m P \<equiv> (\<forall>t m'. (m, t, m') \<in> Traces \<longleftrightarrow> P t m' \<or> (t = [] \<and> m' = m))"

lemma read_reg_trace_characterisation:
  "trace_characterisation (read_reg r) (\<lambda>t m'. \<exists>rv. t = [E_read_reg (name r) rv] \<and> m' = (maybe_fail ''read_reg: unrecognised value'' (of_regval r rv)))"
  unfolding read_reg_def maybe_fail_def return_def
  by (auto split: option.splits; fastforce intro: Traces_ConsI elim: Traces_cases)

lemma traces_satisfy_pred_read_reg:
  "traces_satisfy_pred s (read_reg r) \<longleftrightarrow> (\<forall>rv. pred s [E_read_reg (name r) rv]) \<and> pred s []"
  using read_reg_trace_characterisation[of r]
  by (auto simp: traces_satisfy_pred_def)*)

definition "primitive_exp m \<equiv> (\<forall>t m'. (m, t, m') \<in> Traces \<longrightarrow> t = [] \<or> final m')"

lemma final_bind_iff:
  "final (m \<bind> f) \<longleftrightarrow> final m \<and> (\<forall>a. m = Done a \<longrightarrow> final (f a))"
  by (cases m) (auto simp: final_def)

lemma final_Traces_Nil:
  assumes "final m" and "(m, t, m') \<in> Traces"
  shows "t = []" and "m' = m"
  using assms
  by (auto simp: final_def split: monad.splits)

lemma primitive_exp_bind_left:
  assumes "primitive_exp m" and f: "\<And>a. final (f a)"
  shows "primitive_exp (m \<bind> f)"
  using assms final_Traces_Nil[OF f]
  by (fastforce simp: primitive_exp_def final_bind_iff elim!: bind_Traces_cases)

(*lemma primitive_exp_read_reg: "primitive_exp (read_reg r)"
  by (auto simp: primitive_exp_def read_reg_def final_def elim: Traces_cases split: option.splits)*)

lemmas builtin_primitive_exp_defs =
  return_def throw_def early_return_def maybe_fail_def assert_exp_def headM_def tailM_def
  read_reg_def write_reg_def choose_regval_def choose_convert_def choose_convert_default_def
  choose_bool_def choose_bit_def choose_int_def choose_real_def choose_string_def
  sail_mem_read_request_def sail_mem_write_request_def sail_mem_write_announce_address_def

lemma builtin_primitive_exps:
  "\<And>r. primitive_exp (read_reg r)"
  "\<And>r v. primitive_exp (write_reg r v)"
  "\<And>descr. primitive_exp (choose_regval descr)"
  "\<And>of_rv descr. primitive_exp (choose_convert of_rv descr)"
  "\<And>of_rv x descr. primitive_exp (choose_convert_default of_rv x descr)"
  "\<And>RV descr. primitive_exp (choose_bool RV descr)"
  "\<And>RV descr. primitive_exp (choose_bit RV descr)"
  "\<And>RV descr. primitive_exp (choose_int RV descr)"
  "\<And>RV descr. primitive_exp (choose_real RV descr)"
  "\<And>RV descr. primitive_exp (choose_string RV descr)"
  "\<And>xs. primitive_exp (headM xs)"
  "\<And>xs. primitive_exp (tailM xs)"
  "\<And>BV req. primitive_exp (sail_mem_read_request BV req)"
  "\<And>req. primitive_exp (sail_mem_write_request req)"
  "\<And>req. primitive_exp (sail_mem_write_announce_address req)"
  unfolding builtin_primitive_exp_defs
  by (auto simp: primitive_exp_def final_def elim: Traces_cases
           split: option.splits list.splits result.splits)

lemma runTrace_final_case_simps:
  "runTrace t (Done a) = (case t of [] \<Rightarrow> Some (Done a) | _ \<Rightarrow> None)"
  "runTrace t (Fail msg) = (case t of [] \<Rightarrow> Some (Fail msg) | _ \<Rightarrow> None)"
  "runTrace t (Exception e) = (case t of [] \<Rightarrow> Some (Exception e) | _ \<Rightarrow> None)"
  by (auto split: list.splits Option.bind_splits elim: emitEvent_cases)

lemma builtin_primitive_exps_hasTrace_iffs:
  "\<And>r. hasTrace t (read_reg r) \<longleftrightarrow> (\<exists>rv. t = [E_read_reg (name r) rv])"
  "\<And>BV req. hasTrace t (sail_mem_read_request BV req) \<longleftrightarrow> (\<exists>v. t = [E_mem_read_request req v])"
  "\<And>RV descr. hasTrace t (choose_bool RV descr) \<longleftrightarrow> (\<exists>v. t = [E_choose descr v])"
  unfolding builtin_primitive_exp_defs
  by (auto simp: hasTrace_def emitEvent_intros final_def runTrace_final_case_simps
           split: option.splits Option.bind_splits list.splits result.splits
           elim!: runTrace.elims emitEvent_cases)

lemma primitive_exp_traces_satisfy_pred:
  assumes "primitive_exp m"
  shows "traces_satisfy_pred s m \<longleftrightarrow> (\<forall>t. hasTrace t m \<longrightarrow> pred s t) \<and> pred s []"
  using assms Traces.Nil[of m]
  unfolding primitive_exp_def traces_satisfy_pred_def hasTrace_iff_Traces_final
  by auto

lemmas builtin_primitive_exp_traces_satisfy_pred =
  builtin_primitive_exps[THEN primitive_exp_traces_satisfy_pred,
                         unfolded builtin_primitive_exps_hasTrace_iffs]

(*lemma
  "traces_satisfy_pred s (read_reg r) \<longleftrightarrow> (\<forall>rv. pred s [E_read_reg (name r) rv]) \<and> pred s []"
  using primitive_exp_read_reg[of r, THEN primitive_exp_traces_satisfy_pred, where s = s]
  unfolding hasTrace_read_reg
  by auto*)

end

end