@@ -48,8 +48,8 @@ val _ = Hol_datatype `
4848`;
4949
5050
51- Type intvl_row = “:airth_key # interval # num # 'a action_expr”;
52- Type intvl_table = “:('a intvl_row) list”;
51+ Type intvl_row = “:( interval # num # 'a action_expr) ”;
52+ Type intvl_table = “:(airth_key # 'a intvl_row list) ”;
5353Type intvl_table_list = “:('a intvl_table ) list”;
5454
5555
@@ -311,15 +311,15 @@ End
311311
312312
313313Definition convert_line_with_key_def:
314- (convert_line_with_key key_type m_e min max ([], s, res) = NONE ) ∧
315- (convert_line_with_key key_type m_e min max (var_guards, s, res) =
316- SOME (key_type, process_guards_rec m_e min max var_guards (Single min max) , s, res))
314+ (convert_line_with_key m_e min max ([], s, res) = NONE ) ∧
315+ (convert_line_with_key m_e min max (var_guards, s, res) =
316+ SOME (process_guards_rec m_e min max var_guards (Single min max) , s, res))
317317End
318318
319319
320320Definition convert_lines_map_with_key_def:
321- convert_lines_map_with_key key_type m_e min max lines =
322- MAP (\line. convert_line_with_key key_type m_e min max line) lines
321+ convert_lines_map_with_key m_e min max lines =
322+ MAP (\line. convert_line_with_key m_e min max line) lines
323323End
324324
325325
@@ -430,27 +430,24 @@ Definition analyze_table_type_def:
430430End
431431
432432
433-
433+ (* ==================================*)
434+ (* Tables conversion *)
435+ (* ==================================*)
436+
434437Definition convert_single_table_def:
435438 (convert_single_table [] m_e pd_type = NONE ) ∧
436439 (convert_single_table lines m_e pd_type =
437440 case analyze_table_type m_e pd_type lines of
438441 | SOME (T, key_type, min, max) => (* Convert all lines with the same key_type and max *)
439- (case (EVERY IS_SOME (convert_lines_map_with_key key_type m_e min max lines)) of
440- | T => SOME (MAP THE (convert_lines_map_with_key key_type m_e min max lines))
442+ (case (EVERY IS_SOME (convert_lines_map_with_key m_e min max lines)) of
443+ | T => SOME (key_type, MAP THE (convert_lines_map_with_key m_e min max lines))
441444 | F => NONE
442445 )
443446 | _ => NONE (* Inconsistent table *)
444447 )
445448End
446449
447450
448-
449-
450-
451-
452-
453-
454451Definition convert_tables_def:
455452 (convert_tables [] _ _ = SOME []) ∧
456453 (convert_tables (tbl::tbls) m_e pd_type =
@@ -515,46 +512,88 @@ EVAL ``convert_tables (^policy1_var) ^test_m_e ^test_pd_nested``;
515512*)
516513
517514
518- (*
515+
519516
520517
521- (* SEMANTICS *)
518+ (* ==================================*)
519+ (* interval table semantics *)
520+ (* ==================================*)
521+
522+
523+
524+
522525Definition is_intvl_match_row_def:
523- is_intvl_match_row (s_in:num) (packet_input:pd) (row:('a intvl_row)) =
524- case row of
525- ( key_val lval, Single a b, s, res) =>
526- (case resolve_lval packet_input lval of
527- | SOME (val_num v) => (a ≤ v ∧ v ≤ b ∧ (s_in = s))
528- | SOME _ => F (* non-numeric value *)
529- | NONE => F ) (* lval not found *)
530- | (key_val lval, Empty, s, res) => F
531- | (key_const a, _ , s, _) => (s_in = s)
526+ is_intvl_match_row key (s_in:num) (packet_input:pd) (row:('a intvl_row)) =
527+ case (key, row) of
528+ | (key_val lval, (Single a b, s, res)) =>
529+ (let (a_v,a_w) = a in
530+ let (b_v,b_w) = b in
531+ (case resolve_lval packet_input lval of
532+ | SOME (val_bs (v,v_w)) =>
533+ (if (a_w = b_w) ∧ (b_w = v_w) then
534+ (case (bv_lt_than (v,v_w) (a_v,a_w), bv_lt_than (b_v,b_w) (v,v_w)) of
535+ | (SOME F, SOME F) => (s_in = s) (* a ≤ v ≤ b *)
536+ | (_, _) => F)
537+ else F
538+ )
539+ | SOME _ => F (* non-numeric value *)
540+ | NONE => F)) (* lval not found *)
541+ | (key_val lval, (Empty, s, res)) => F
542+ | (key_const (c,c_w), (_, s, _)) => (s_in = s)
532543End
533544
545+ (*
546+ (* Test bitvectors - all 4-bit width for consistency *)
547+ val test_v0 = “(n2v 0, (4:num))”; (* 0 *)
548+ val test_v2 = “(n2v 2, (4:num))”; (* 2 *)
549+ val test_v4 = “(n2v 4, (4:num))”; (* 4 *)
550+ val test_v6 = “(n2v 6, (4:num))”; (* 6 *)
551+ val test_v15 = “(n2v 15, (4:num))”; (* 15 *)
552+
553+ val test_packet = ``[("x", val_bs ^test_v4)]``;
554+
555+ val test_row_match = “(Single ^test_v2 ^test_v6, (1:num), action ("fwd", [(1:num)]))”;
556+ val test_row_nomatch = “(Single ^test_v6 ^test_v15, (1:num), action ("fwd", [(1:num)]))”;
557+ val test_row_empty = “(Empty, (1:num), action ("fwd", [(1:num)]))”;
558+ val test_row_edge = “(Single ^test_v4 ^test_v4, (1:num), action ("fwd", [(1:num)]))”;
559+
560+ val test_key_val = “key_val (lv_x "x")”;
561+ val test_key_const = “key_const ^test_v0”;
562+
563+ EVAL “is_intvl_match_row ^test_key_val 1 ^test_packet ^test_row_match”; (* T*)
564+ EVAL “is_intvl_match_row ^test_key_val 1 ^test_packet ^test_row_nomatch”; (* F*)
565+ EVAL “is_intvl_match_row ^test_key_val 1 ^test_packet ^test_row_empty”; (* F*)
566+ EVAL “is_intvl_match_row ^test_key_val 1 ^test_packet ^test_row_edge”; (* T*)
567+ EVAL “is_intvl_match_row ^test_key_const 1 ^test_packet ^test_row_match”; (* T*)
568+
569+ val test_v4_8bit = “(n2v 4, (8:num))”;
570+ val test_row_width_mismatch = “(Single ^test_v2 ^test_v4_8bit, (1:num), action ("fwd", [(1:num)]))”;
571+ EVAL “is_intvl_match_row ^test_key_val 1 ^test_packet ^test_row_width_mismatch”; (* F (width mismatch between 4 and 8) *)
572+
573+ val test_packet_missing = ``[("y", val_bs ^test_v4)]``;
574+ EVAL “is_intvl_match_row ^test_key_val 1 ^test_packet_missing ^test_row_match”;
575+ *)
534576
535577
536578(* Process all rows in an interval table *)
537579Definition check_all_intvl_rows_match_def:
538- check_all_intvl_rows_match st_in intvl_tbl packet_input =
539- MAP (λ(lval_opt, intervall, st_num, res).
540- (is_intvl_match_row st_in (packet_input:pd) (lval_opt , intervall, st_num, res)),
541- (res:'a action_expr)) intvl_tbl
580+ check_all_intvl_rows_match key st_in rows packet_input =
581+ MAP (λ(interval,s,res). is_intvl_match_row key (st_in:num) (packet_input:pd) (interval,s,res), res) rows
542582End
543583
544584
545585
546586(* Find first matching line in a converted table *)
547587Definition match_intvl_tbl_def:
548- match_intvl_tbl (intvl_tbl: (('a intvl_row) list)) packet_input st_in =
549- let lines_res = check_all_intvl_rows_match st_in intvl_tbl packet_input in
550- case min_idx_till lines_res T of
551- | SOME (idx, line) => SOME (SND line)
552- | NONE => NONE
588+ match_intvl_tbl (intvl_tbl: 'a intvl_table) packet_input st_in =
589+ let (key, rows) = intvl_tbl in
590+ let lines_res = check_all_intvl_rows_match key st_in rows packet_input in
591+ case min_idx_till lines_res T of
592+ | SOME (idx, line) => SOME (SND line)
593+ | NONE => NONE
553594End
554595
555596
556-
557-
558597(* Process list of interval tables with state propagation *)
559598Definition match_intvl_tbll_def:
560599 (match_intvl_tbll ([]: 'a intvl_table_list) packet_input st_in = NONE ) ∧
570609
571610
572611
573-
574612(* Top-level interval table semantics *)
575613Definition sem_intvl_tables_def:
576614 sem_intvl_tables ((intvl_tbll: (('a intvl_table ) list)), st_in) (packet_input:pd) =
@@ -623,7 +661,7 @@ val test1 = EVAL ``sem_intvl_tables (^test_tables, ^initial_state) ^test_packet`
623661(* proof *)
624662(* *********)
625663
626-
664+ (*
627665
628666
629667
@@ -1096,12 +1134,8 @@ QED
10961134*)
10971135
10981136
1099-
1100-
1101-
11021137*)
11031138
1104-
11051139
11061140
11071141
0 commit comments