@@ -70,12 +70,6 @@ val _ = type_abbrev("arith_policy_typ", “:((string# num list) action_expr) ari
7070(* ***************************************************************)
7171(* ***************************************************************)
7272
73- (*
74- x ∧ y : fwd(1)
75- z : fwd(2)
76- T : drop()
77- *)
78-
7973
8074(* policy 1: arith POLICY representation *)
8175
@@ -111,149 +105,109 @@ val arith_policy1 = “[^arith_policy1_rule1 ;
111105 ^arith_policy1_rule3]:((string# num list) action_expr) arith_policy”;
112106
113107
114-
115- val arith_policy1_eval = EVAL “convert_arith_to_var_policy ^arith_policy1 ^policy1_me1”;
116-
117-
118- val var_policy1 = optionSyntax.dest_some (rhs (concl arith_policy1_eval));
119108
120- (* first establish distinction *)
121- val policy1_me1_fst_distinct = EVAL ``ALL_DISTINCT (MAP FST ^policy1_me1)``;
122- val policy1_me1_snd_distinct = EVAL ``ALL_DISTINCT (MAP SND ^policy1_me1)``;
123109
124110
125- val all_distinct_conj = CONJ policy1_me1_fst_distinct policy1_me1_snd_distinct;
126-
111+ (* *******************************)
127112
113+
114+ (* convert arith policy to var policy*)
115+ val arith_policy1_eval = EVAL “convert_arith_to_var_policy ^arith_policy1 ^policy1_me1”;
116+ val var_policy1 = optionSyntax.dest_some (rhs (concl arith_policy1_eval));
128117
129- val alookup_cond_thm = EVAL “∀var atom. ALOOKUP ^policy1_me1 var = SOME atom ⇒
130- ALOOKUP m_v var = eval_arithm_atom packet_input atom”;
118+
119+ (* first establish distinction of domain and range of me*)
120+ val policy1_me1_fst_distinct = EVAL “ALL_DISTINCT (MAP FST ^policy1_me1)”;
121+ val policy1_me1_snd_distinct = EVAL “ALL_DISTINCT (MAP SND ^policy1_me1)”;
131122
123+ val all_distinct_conj = CONJ policy1_me1_fst_distinct policy1_me1_snd_distinct;
132124
125+
126+ (* Theorem of correctness for conversion from arith policy to var policy *)
133127val arith_policy1_var_policy1_thm = REWRITE_RULE[all_distinct_conj, arith_policy1_eval]
134128(ISPECL[arith_policy1, var_policy1, policy1_me1] policy_airth_to_var_sem_conversion_correct);
135129
136-
137-
138-
139- (* policy 1: var POLICY representation *)
140- (*
141- val var_policy1_rule1 = ``(And (Var "x") (Var "y"), action ("fwd",[1])): action_rule_type``;
142- val var_policy1_rule2 = ``(Var "z", action ("fwd",[2])): action_rule_type``;
143- val var_policy1_rule3 = ``(True, action ("drop",[])): action_rule_type``;
144-
145-
146- val var_policy1 = ``[^var_policy1_rule1; ^var_policy1_rule2; ^var_policy1_rule3 ] : action_policy_type``;
147- *)
148-
149- val eval_policy1_full_opt = EVAL ``mk_BDDPred_opt policy_structure (0 ,[],[(0 , non_termn (NONE , ^var_policy1))]) [] [" x" ;" y" ;" z" ] 1 ``;
130+
131+ (* create BDD of var policy *)
132+ val eval_policy1_full_opt = EVAL “mk_BDDPred_opt policy_structure (0 ,[],[(0 , non_termn (NONE , ^var_policy1))]) [] ^policy1_order 1 ”;
150133val eval_policy1_full_opt_rhs = optionSyntax.dest_some (rhs (concl eval_policy1_full_opt));
151134
152135
153- (* automatically generate a table*)
136+ (* automatically generate a var table from the var policy's BDD via sml *)
154137val test_groupings1 = rhs(concl(EVAL policy1_full_order));
155138val test_action_table1_auto = BDDUtils.bdd_to_tables_iterative eval_policy1_full_opt_rhs test_groupings1;
156139
140+
157141(* now create a BDD for the table*)
158- val eval_table1_full_opt_auto = EVAL “mk_BDDPred_opt table_structure (0 ,[],[(0 , non_termn (NONE , ^test_action_table1_auto))]) [] [ " x " ; " y " ; " z " ] 1 ”;
142+ val eval_table1_full_opt_auto = EVAL “mk_BDDPred_opt table_structure (0 ,[],[(0 , non_termn (NONE , ^test_action_table1_auto))]) [] ^policy1_order 1 ”;
159143val eval_table1_full_opt_auto_rhs = optionSyntax.dest_some (rhs (concl eval_table1_full_opt_auto));
160144
161- (* get I, and check if isisIsomorph *)
145+
146+ (* get I (pairs isomorphic in the graph), and check if isisIsomorph *)
162147val get_i_policy1 = BDDUtils.pairBDDs (eval_table1_full_opt_auto_rhs , eval_table1_full_opt_auto_rhs);
163148val is_tbl_policy1_iso = EVAL “isIsomorph_exec ^get_i_policy1 ^eval_table1_full_opt_auto_rhs ^eval_table1_full_opt_auto_rhs”;
164149
165- (* get a theorem out*)
166- val policy1_thm_init = computeLib.RESTR_EVAL_CONV [“sem_tables”,“sem_policy”, “mv_dom_vars”] “correct_var_policy_var_tables_exec ^var_policy1 ^test_action_table1_auto [" x" ;" y" ;" z" ] ^get_i_policy1 ”;
150+
151+ (* Theorem of correctness for conversion from var policy to var table *)
152+ val policy1_thm_init = computeLib.RESTR_EVAL_CONV [“sem_tables”,“sem_policy”, “mv_dom_vars”] “correct_var_policy_var_tables_exec ^var_policy1 ^test_action_table1_auto ^policy1_order ^get_i_policy1 ”;
167153val policy1_thm = SIMP_RULE bool_ss [correct_var_policy_var_tables_exec_thm1] policy1_thm_init;
168154
169155
170- (* from var tables to final single interval table*)
171-
172-
156+ (* covert var table to interval table *)
173157val only_var_table1 = fst (dest_pair test_action_table1_auto);
174-
175-
176-
177158val convert_to_interval1 = EVAL “convert_var_to_sinterval_tables ^only_var_table1 ^policy1_me1 ^test_pd_type1”;
178-
179-
180159val only_interval_table1 = optionSyntax.dest_some(rhs (concl convert_to_interval1));
181160
161+
162+ (* Theorem of correctness for conversion from var table to inteval table *)
163+ val final_table1_thm =
164+ REWRITE_RULE [convert_to_interval1] (ISPECL[only_var_table1, only_interval_table1, “0 :num”, policy1_me1, test_pd_type1 ] correct_tables_from_var_to_sinterval_thm);
182165
183166
184-
185- val convert_var_to_sinterval_tables1_thm =
186- REWRITE_RULE [] (ISPECL[only_var_table1, only_interval_table1, “0 :num”, policy1_me1, test_pd_type1 ] correct_tables_from_var_to_sinterval_thm);
187-
188-
189-
190- val final_table1_thm = SIMP_RULE bool_ss [convert_to_interval1] convert_var_to_sinterval_tables1_thm;
191-
192-
193-
194-
195- (* condition1 *)
196-
167+
168+ (* to glue the theorems we need to take care of the conditions/ assumptions *)
169+
170+ (* condition1 *)
197171val every_lval_in_me_in_type_thm = EVAL “every_lval_in_me_in_type ^test_pd_type1 ^policy1_me1”;
198- val all_distinct_fst_me_thm = EVAL “ALL_DISTINCT (MAP FST ^policy1_me1)”;
199-
200- val cond1_thm = REWRITE_RULE [every_lval_in_me_in_type_thm, all_distinct_fst_me_thm] (ISPECL[policy1_me1, test_pd_type1 ] lval_in_me_distinct_imp_cond1);
201-
202-
172+ val cond1_thm = REWRITE_RULE [every_lval_in_me_in_type_thm, policy1_me1_fst_distinct] (ISPECL[policy1_me1, test_pd_type1 ] lval_in_me_distinct_imp_cond1);
203173
204-
205-
206- (* condition2 *)
207-
174+
175+ (* condition2 *)
208176val in_order_then_in_me_thm = EVAL “in_order_then_in_me ^policy1_order ^policy1_me1”;
209177val ops_in_me_length_format_thm = EVAL “ops_in_me_length_format ^test_pd_type1 ^policy1_me1”;
210178
211- val cond2_thm = REWRITE_RULE [every_lval_in_me_in_type_thm, all_distinct_fst_me_thm ,
179+ val cond2_thm = REWRITE_RULE [every_lval_in_me_in_type_thm, policy1_me1_fst_distinct ,
212180 in_order_then_in_me_thm, ops_in_me_length_format_thm]
213181 (ISPECL[policy1_me1, test_pd_type1, policy1_order ]
214182 wf_format_imp_cond2);
215-
216-
217-
183+
218184(* condition3 *)
219-
220-
221-
222-
223- val cond3_thm = REWRITE_RULE [every_lval_in_me_in_type_thm, all_distinct_fst_me_thm,
185+ val cond3_thm = REWRITE_RULE [every_lval_in_me_in_type_thm, policy1_me1_fst_distinct,
224186 in_order_then_in_me_thm, ops_in_me_length_format_thm]
225187 (ISPECL[policy1_me1, test_pd_type1]
226188 wf_format_imp_cond3);
227189
228-
229-
230-
231-
232-
190+
233191val final_thm = prove(
234- “! packet_input .
235- wf_packet ^test_pd_type1 packet_input ⇒
236- sem_arith_policy ^arith_policy1 packet_input =
237- sem_sinterval_tables (^only_interval_table1,0 ) packet_input”
238- ,
239-
240- rpt strip_tac >>
241- assume_tac arith_policy1_var_policy1_thm >>
242- first_x_assum (strip_assume_tac o (Q.SPECL [‘packet_input’,‘(create_mv ^policy1_me1 packet_input)’])) >>
243-
244- gvs[cond1_thm] >>
245-
246- assume_tac policy1_thm >>
247- first_x_assum (strip_assume_tac o (Q.SPECL [‘(create_mv ^policy1_me1 packet_input)’])) >>
248-
249- imp_res_tac cond2_thm >>
250- gvs[] >>
251-
252- assume_tac final_table1_thm >>
253- first_x_assum (strip_assume_tac o (Q.SPECL [‘packet_input’,‘(create_mv ^policy1_me1 packet_input)’])) >>
254- gvs[cond1_thm] >>
192+ “! packet_input .
193+ wf_packet ^test_pd_type1 packet_input ⇒
194+ sem_arith_policy ^arith_policy1 packet_input =
195+ sem_sinterval_tables (^only_interval_table1,0 ) packet_input”
196+ ,
197+
198+ rpt strip_tac >>
199+
200+ assume_tac arith_policy1_var_policy1_thm >>
201+ first_x_assum (strip_assume_tac o (Q.SPECL [‘packet_input’,‘(create_mv ^policy1_me1 packet_input)’])) >>
202+
203+ assume_tac policy1_thm >>
204+ first_x_assum (strip_assume_tac o (Q.SPECL [‘(create_mv ^policy1_me1 packet_input)’])) >>
255205
256- gvs[cond3_thm]
206+
207+ assume_tac final_table1_thm >>
208+ first_x_assum (strip_assume_tac o (Q.SPECL [‘packet_input’,‘(create_mv ^policy1_me1 packet_input)’])) >>
209+
210+ fs[cond1_thm, cond2_thm, cond3_thm]
257211);
258212
259213
@@ -263,11 +217,13 @@ gvs[cond3_thm]
263217
264218
265219
266-
267-
268-
269-
270-
220+ (*
221+ TODO:
222+ 1. sota review: why is this work more complete than anything we have found
223+ 2. complexity: stage2 complexity. [stage1 and 3 are linear wrt. size of input probably?]
224+ 3. Can we handle practical tables, and deploy them?
225+ 4. performance and scalability (WCET) + synthetic examples that reflects the complexity of the three stages of the pipeline
226+ *)
271227
272228
273229
0 commit comments