From 0e6e714cc2e305ce7b641866425a7af042b011ee Mon Sep 17 00:00:00 2001 From: smolkaj Date: Wed, 21 Apr 2021 11:41:02 -0700 Subject: [PATCH 01/10] [p4-symbolic] Fix implementation of shift and add support forbitvector slicing. --- p4_symbolic/symbolic/guarded_map.cc | 23 ++++++------------- p4_symbolic/symbolic/guarded_map.h | 2 +- p4_symbolic/symbolic/operators.cc | 34 ++++++++++++++++------------- p4_symbolic/symbolic/operators.h | 3 ++- 4 files changed, 29 insertions(+), 33 deletions(-) diff --git a/p4_symbolic/symbolic/guarded_map.cc b/p4_symbolic/symbolic/guarded_map.cc index e0d4ff90..b24fe741 100644 --- a/p4_symbolic/symbolic/guarded_map.cc +++ b/p4_symbolic/symbolic/guarded_map.cc @@ -43,8 +43,7 @@ absl::StatusOr SymbolicGuardedMap::Get(const std::string &key) const { absl::StrCat("Cannot find key \"", key, "\" in SymbolicGuardedMap!")); } -absl::Status SymbolicGuardedMap::Set(const std::string &key, - const z3::expr &value, +absl::Status SymbolicGuardedMap::Set(const std::string &key, z3::expr value, const z3::expr &guard) { if (!this->ContainsKey(key)) { return absl::InvalidArgumentError(absl::StrCat( @@ -53,20 +52,12 @@ absl::Status SymbolicGuardedMap::Set(const std::string &key, z3::expr &old_value = this->map_.at(key); - // operators::Ite will check for sort compatibility and pad when needed. - // However, Ite() does not have a notion of pre-defined size, and will padd - // to the maximum bitsize of the two operands. We perform that check - // explicitly here. - if (old_value.get_sort().is_bv() && value.get_sort().is_bv()) { - unsigned int new_size = value.get_sort().bv_size(); - unsigned int old_size = old_value.get_sort().bv_size(); - if (new_size > old_size) { - return absl::InvalidArgumentError( - absl::StrFormat("Cannot assign to key \"%s\" a value whose bit size " - "%d is greater than the pre-defined bit size %d in " - "SymbolicGuardedMap!", - key, new_size, old_size)); - } + // Ite will pad bitvectors to the same size, but this is not the right + // semantics if we assign a larger bitvector into a smaller one. Instead, the + // assigned value needs to be truncated to the bitsize of the asignee. + if (old_value.get_sort().is_bv() && value.get_sort().is_bv() && + old_value.get_sort().bv_size() < value.get_sort().bv_size()) { + value = value.extract(old_value.get_sort().bv_size() - 1, 0); } // This will return an absl error if the sorts are incompatible, and will pad diff --git a/p4_symbolic/symbolic/guarded_map.h b/p4_symbolic/symbolic/guarded_map.h index 2f6b3da5..5f351efe 100644 --- a/p4_symbolic/symbolic/guarded_map.h +++ b/p4_symbolic/symbolic/guarded_map.h @@ -70,7 +70,7 @@ class SymbolicGuardedMap { // Guarded setter. // Returns an error if the assigned value has incompatible sort with the // pre-defined value. - absl::Status Set(const std::string &key, const z3::expr &value, + absl::Status Set(const std::string &key, z3::expr value, const z3::expr &guard); // Constant iterators. diff --git a/p4_symbolic/symbolic/operators.cc b/p4_symbolic/symbolic/operators.cc index d941ac22..c90e2d2c 100644 --- a/p4_symbolic/symbolic/operators.cc +++ b/p4_symbolic/symbolic/operators.cc @@ -131,55 +131,55 @@ absl::StatusOr FreeVariable(const std::string &variable_base_name, absl::StatusOr Plus(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr + b_expr; } absl::StatusOr Minus(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr - b_expr; } absl::StatusOr Times(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr * b_expr; } absl::StatusOr Eq(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr == b_expr; } absl::StatusOr Neq(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr != b_expr; } absl::StatusOr Lt(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return z3::ult(a_expr, b_expr); } absl::StatusOr Lte(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return z3::ule(a_expr, b_expr); } absl::StatusOr Gt(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return z3::ugt(a_expr, b_expr); } absl::StatusOr Gte(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return z3::uge(a_expr, b_expr); } absl::StatusOr Not(const z3::expr &a) { return !a; } @@ -224,27 +224,31 @@ absl::StatusOr BitNeg(const z3::expr &a) { return ~a; } absl::StatusOr BitAnd(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndExtract(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr & b_expr; } absl::StatusOr BitOr(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr | b_expr; } absl::StatusOr BitXor(const z3::expr &a, const z3::expr &b) { ASSIGN_OR_RETURN(auto pair, p4_symbolic::symbolic::operators::SortCheckAndPad(a, b)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return a_expr ^ b_expr; } absl::StatusOr LShift(const z3::expr &bits, const z3::expr &shift) { - return z3::shl(bits, shift); + ASSIGN_OR_RETURN(auto pair, SortCheckAndPad(bits, shift)); + auto &[a_expr, b_expr] = pair; + return z3::shl(a_expr, b_expr); } absl::StatusOr RShift(const z3::expr &bits, const z3::expr &shift) { - return z3::lshr(bits, shift); + ASSIGN_OR_RETURN(auto pair, SortCheckAndPad(bits, shift)); + auto &[a_expr, b_expr] = pair; + return z3::lshr(a_expr, b_expr); } // If then else. @@ -260,7 +264,7 @@ absl::StatusOr Ite(const z3::expr &condition, // Values in both cases must have the same sort and signedness. ASSIGN_OR_RETURN(auto pair, SortCheckAndPad(true_value, false_value)); - auto [a_expr, b_expr] = pair; + auto &[a_expr, b_expr] = pair; return z3::ite(condition, a_expr, b_expr); } diff --git a/p4_symbolic/symbolic/operators.h b/p4_symbolic/symbolic/operators.h index 5bd3c2c3..01768d75 100644 --- a/p4_symbolic/symbolic/operators.h +++ b/p4_symbolic/symbolic/operators.h @@ -65,8 +65,9 @@ absl::StatusOr Ite(const z3::expr &condition, const z3::expr &true_value, const z3::expr &false_value); -// Converts the expression into a semantically equivalent boolean expression. +// Converts the given expression to a boolean expression. absl::StatusOr ToBoolSort(const z3::expr &a); +// Converts the given expression to a bit vector expression. absl::StatusOr ToBitVectorSort(const z3::expr &a, unsigned int size); // Prefix equality: this is the basis for evaluating LPMs. From f1fb6cc380f198a3ed4c85d4beb2aeb47bab43ed Mon Sep 17 00:00:00 2001 From: kishanps Date: Tue, 27 Apr 2021 16:07:55 -0700 Subject: [PATCH 02/10] [P4-Symbolic] no-op --- p4_fuzzer/BUILD.bazel | 1 + p4_symbolic/bmv2/BUILD.bazel | 5 ++++- p4_symbolic/ir/BUILD.bazel | 5 ++++- p4_symbolic/symbolic/BUILD.bazel | 5 ++++- p4_symbolic/testdata/BUILD.bazel | 2 ++ p4_symbolic/util/BUILD.bazel | 5 ++++- 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/p4_fuzzer/BUILD.bazel b/p4_fuzzer/BUILD.bazel index 30cd2e65..c3ba3d19 100644 --- a/p4_fuzzer/BUILD.bazel +++ b/p4_fuzzer/BUILD.bazel @@ -2,6 +2,7 @@ load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test") package( + default_visibility = ["//visibility:public"], licenses = ["notice"], ) diff --git a/p4_symbolic/bmv2/BUILD.bazel b/p4_symbolic/bmv2/BUILD.bazel index d2691a73..bfe70047 100644 --- a/p4_symbolic/bmv2/BUILD.bazel +++ b/p4_symbolic/bmv2/BUILD.bazel @@ -18,7 +18,10 @@ load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_symbolic/bmv2:test.bzl", "bmv2_protobuf_parsing_test") -package(licenses = ["notice"]) +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], +) cc_proto_library( name = "bmv2_cc_proto", diff --git a/p4_symbolic/ir/BUILD.bazel b/p4_symbolic/ir/BUILD.bazel index 1751702a..26f11de1 100644 --- a/p4_symbolic/ir/BUILD.bazel +++ b/p4_symbolic/ir/BUILD.bazel @@ -18,7 +18,10 @@ load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_symbolic/ir:test.bzl", "ir_parsing_test") -package(licenses = ["notice"]) +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], +) cc_library( name = "pdpi_driver", diff --git a/p4_symbolic/symbolic/BUILD.bazel b/p4_symbolic/symbolic/BUILD.bazel index 5e26e7ab..a9d99d26 100644 --- a/p4_symbolic/symbolic/BUILD.bazel +++ b/p4_symbolic/symbolic/BUILD.bazel @@ -18,7 +18,10 @@ load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_symbolic/symbolic:test.bzl", "end_to_end_test") -package(licenses = ["notice"]) +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], +) cc_library( name = "symbolic", diff --git a/p4_symbolic/testdata/BUILD.bazel b/p4_symbolic/testdata/BUILD.bazel index e7678c0d..7ec79468 100644 --- a/p4_symbolic/testdata/BUILD.bazel +++ b/p4_symbolic/testdata/BUILD.bazel @@ -17,6 +17,8 @@ load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") +package(default_visibility = ["//visibility:public"]) + # Make sure programs under p4-samples are visible to other # bazel packages. exports_files( diff --git a/p4_symbolic/util/BUILD.bazel b/p4_symbolic/util/BUILD.bazel index 26a66f27..b8070667 100644 --- a/p4_symbolic/util/BUILD.bazel +++ b/p4_symbolic/util/BUILD.bazel @@ -17,7 +17,10 @@ load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") -package(licenses = ["notice"]) +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], +) cc_library( name = "util", From 91f176fcf2da6f5c8003da037e07cc4b0f1c8728 Mon Sep 17 00:00:00 2001 From: smolkaj Date: Wed, 5 May 2021 13:42:23 -0700 Subject: [PATCH 03/10] [p4-symbolic] Use absl maps. Handle drops more cleanly, avoiding macros and making things reusable. Fix a few subtle bugs related to dropping packets and ports. Move Z3 utility functions into z3_util. Make evaluation functions only return a set of matches instead of an entire trace. --- p4_symbolic/BUILD.bazel | 16 + p4_symbolic/main.cc | 4 +- p4_symbolic/sai/BUILD.bazel | 2 + p4_symbolic/sai/fields.cc | 2 +- p4_symbolic/sai/parser.cc | 2 +- p4_symbolic/symbolic/BUILD.bazel | 5 + p4_symbolic/symbolic/action.cc | 5 +- p4_symbolic/symbolic/conditional.cc | 9 +- p4_symbolic/symbolic/conditional.h | 2 +- p4_symbolic/symbolic/control.cc | 40 +- p4_symbolic/symbolic/control.h | 6 +- p4_symbolic/symbolic/expected/basic.smt2 | 447 ++++++++++--------- p4_symbolic/symbolic/expected/hardcoded.smt2 | 72 +-- p4_symbolic/symbolic/expected/reflector.smt2 | 19 +- p4_symbolic/symbolic/expected/reflector.txt | 4 +- p4_symbolic/symbolic/expected/table.smt2 | 137 +++--- p4_symbolic/symbolic/guarded_map.cc | 1 + p4_symbolic/symbolic/guarded_map.h | 10 +- p4_symbolic/symbolic/operators.cc | 1 + p4_symbolic/symbolic/packet.cc | 1 - p4_symbolic/symbolic/symbolic.cc | 118 ++--- p4_symbolic/symbolic/symbolic.h | 39 +- p4_symbolic/symbolic/table.cc | 13 +- p4_symbolic/symbolic/table.h | 2 +- p4_symbolic/symbolic/util.cc | 72 ++- p4_symbolic/symbolic/util.h | 16 +- p4_symbolic/symbolic/values.cc | 21 +- p4_symbolic/symbolic/values.h | 2 +- p4_symbolic/z3_util.cc | 50 +++ p4_symbolic/z3_util.h | 62 +++ 30 files changed, 652 insertions(+), 528 deletions(-) create mode 100644 p4_symbolic/z3_util.cc create mode 100644 p4_symbolic/z3_util.h diff --git a/p4_symbolic/BUILD.bazel b/p4_symbolic/BUILD.bazel index 6b5da50f..753fa143 100644 --- a/p4_symbolic/BUILD.bazel +++ b/p4_symbolic/BUILD.bazel @@ -69,3 +69,19 @@ cc_library( "@com_google_absl//absl/types:span", ], ) + +cc_library( + name = "z3_util", + srcs = ["z3_util.cc"], + hdrs = ["z3_util.h"], + visibility = ["//visibility:public"], + deps = [ + "//gutil:status", + "//p4_pdpi/string_encodings:hex_string", + "@com_github_z3prover_z3//:api", + "@com_gnu_gmp//:gmp", + "@com_google_absl//absl/status", + "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", + ], +) diff --git a/p4_symbolic/main.cc b/p4_symbolic/main.cc index 283afd1b..434f0c53 100644 --- a/p4_symbolic/main.cc +++ b/p4_symbolic/main.cc @@ -82,8 +82,8 @@ absl::Status ParseAndEvaluate() { // Loop over tables in a deterministic order for output consistency (important // for ci tests). std::string debug_smt_formula = ""; - std::map ordered_tables(dataplane.program.tables().cbegin(), - dataplane.program.tables().cend()); + auto ordered_tables = absl::btree_map( + dataplane.program.tables().cbegin(), dataplane.program.tables().cend()); for (const auto &[name, table] : ordered_tables) { int row_count = static_cast(dataplane.entries[name].size()); for (int i = -1; i < row_count; i++) { diff --git a/p4_symbolic/sai/BUILD.bazel b/p4_symbolic/sai/BUILD.bazel index ae881aff..93d15ead 100644 --- a/p4_symbolic/sai/BUILD.bazel +++ b/p4_symbolic/sai/BUILD.bazel @@ -25,6 +25,7 @@ cc_library( hdrs = ["fields.h"], deps = [ "//gutil:status", + "//p4_symbolic:z3_util", "//p4_symbolic/symbolic", "@com_github_z3prover_z3//:api", "@com_google_absl//absl/strings", @@ -39,6 +40,7 @@ cc_library( deps = [ ":fields", "//gutil:status", + "//p4_symbolic:z3_util", "//p4_symbolic/symbolic", "@com_github_z3prover_z3//:api", "@com_google_absl//absl/status", diff --git a/p4_symbolic/sai/fields.cc b/p4_symbolic/sai/fields.cc index b1255dd9..02145369 100644 --- a/p4_symbolic/sai/fields.cc +++ b/p4_symbolic/sai/fields.cc @@ -18,6 +18,7 @@ #include "absl/strings/str_join.h" #include "gutil/status.h" #include "p4_symbolic/symbolic/symbolic.h" +#include "p4_symbolic/z3_util.h" #include "z3++.h" namespace p4_symbolic { @@ -25,7 +26,6 @@ namespace p4_symbolic { namespace { using ::p4_symbolic::symbolic::SymbolicPerPacketState; -using ::p4_symbolic::symbolic::Z3Context; // The p4c compiler mangles field names from the local_metadata struct. // As a workaround, we unmangle the names, best effort. diff --git a/p4_symbolic/sai/parser.cc b/p4_symbolic/sai/parser.cc index a46e3213..b6d5d372 100644 --- a/p4_symbolic/sai/parser.cc +++ b/p4_symbolic/sai/parser.cc @@ -18,12 +18,12 @@ #include "p4_symbolic/sai/fields.h" #include "p4_symbolic/symbolic/operators.h" #include "p4_symbolic/symbolic/symbolic.h" +#include "p4_symbolic/z3_util.h" #include "z3++.h" namespace p4_symbolic { using ::p4_symbolic::symbolic::SymbolicPerPacketState; -using ::p4_symbolic::symbolic::Z3Context; absl::StatusOr> EvaluateSaiParser( const SymbolicPerPacketState& state) { diff --git a/p4_symbolic/symbolic/BUILD.bazel b/p4_symbolic/symbolic/BUILD.bazel index a9d99d26..7dbad4ae 100644 --- a/p4_symbolic/symbolic/BUILD.bazel +++ b/p4_symbolic/symbolic/BUILD.bazel @@ -57,12 +57,17 @@ cc_library( "//p4_pdpi/netaddr:ipv6_address", "//p4_pdpi/netaddr:mac_address", "//p4_pdpi/utils:ir", + "//p4_symbolic:z3_util", "//p4_symbolic/ir:ir_cc_proto", "//p4_symbolic/ir:table_entries", "@com_github_google_glog//:glog", "@com_github_p4lang_p4runtime//:p4info_cc_proto", "@com_github_z3prover_z3//:api", "@com_gnu_gmp//:gmp", + "@com_google_absl//absl/algorithm:container", + "@com_google_absl//absl/cleanup", + "@com_google_absl//absl/container:btree", + "@com_google_absl//absl/memory", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", diff --git a/p4_symbolic/symbolic/action.cc b/p4_symbolic/symbolic/action.cc index 769bb3ba..d253c933 100644 --- a/p4_symbolic/symbolic/action.cc +++ b/p4_symbolic/symbolic/action.cc @@ -19,6 +19,7 @@ #include "absl/strings/str_format.h" #include "glog/logging.h" #include "p4_symbolic/symbolic/operators.h" +#include "p4_symbolic/z3_util.h" namespace p4_symbolic { namespace symbolic { @@ -39,10 +40,8 @@ absl::Status EvaluateStatement(const ir::Statement &statement, // TODO: conditonal needed to interpret clone as drop. statement.has_drop() ? statement.drop().header().header_name() : "standard_metadata"; - z3::expr dropped_value = Z3Context().bv_val(DROPPED_EGRESS_SPEC_VALUE, - DROPPED_EGRESS_SPEC_LENGTH); RETURN_IF_ERROR(state->Set(absl::StrFormat("%s.egress_spec", header_name), - dropped_value, guard)); + EgressSpecDroppedValue(), guard)); RETURN_IF_ERROR(state->Set(absl::StrFormat("%s.mcast_grp", header_name), Z3Context().bv_val(0, 1), guard)); return absl::OkStatus(); diff --git a/p4_symbolic/symbolic/conditional.cc b/p4_symbolic/symbolic/conditional.cc index 06969812..aa2c8681 100644 --- a/p4_symbolic/symbolic/conditional.cc +++ b/p4_symbolic/symbolic/conditional.cc @@ -17,6 +17,7 @@ #include "p4_symbolic/symbolic/conditional.h" +#include "gutil/status.h" #include "p4_symbolic/symbolic/action.h" #include "p4_symbolic/symbolic/operators.h" #include "p4_symbolic/symbolic/util.h" @@ -26,7 +27,7 @@ namespace p4_symbolic { namespace symbolic { namespace conditional { -absl::StatusOr EvaluateConditional( +absl::StatusOr EvaluateConditional( const Dataplane &data_plane, const ir::Conditional &conditional, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard) { @@ -43,11 +44,11 @@ absl::StatusOr EvaluateConditional( operators::And(guard, negated_condition)); // Evaluate both branches. - ASSIGN_OR_RETURN(SymbolicTrace if_trace, + ASSIGN_OR_RETURN(SymbolicTableMatches if_matches, control::EvaluateControl(data_plane, conditional.if_branch(), state, translator, if_guard)); ASSIGN_OR_RETURN( - SymbolicTrace else_trace, + SymbolicTableMatches else_matches, control::EvaluateControl(data_plane, conditional.else_branch(), state, translator, else_guard)); @@ -55,7 +56,7 @@ absl::StatusOr EvaluateConditional( // We should merge in a way such that the value of a field in the trace is // the one from the if branch if the condition is true, and the else branch // otherwise. - return util::MergeTracesOnCondition(condition, if_trace, else_trace); + return util::MergeMatchesOnCondition(condition, if_matches, else_matches); } } // namespace conditional diff --git a/p4_symbolic/symbolic/conditional.h b/p4_symbolic/symbolic/conditional.h index afd46073..e877e23d 100644 --- a/p4_symbolic/symbolic/conditional.h +++ b/p4_symbolic/symbolic/conditional.h @@ -29,7 +29,7 @@ namespace p4_symbolic { namespace symbolic { namespace conditional { -absl::StatusOr EvaluateConditional( +absl::StatusOr EvaluateConditional( const Dataplane &data_plane, const ir::Conditional &conditional, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard); diff --git a/p4_symbolic/symbolic/control.cc b/p4_symbolic/symbolic/control.cc index 31ba72f5..c320f985 100644 --- a/p4_symbolic/symbolic/control.cc +++ b/p4_symbolic/symbolic/control.cc @@ -29,39 +29,33 @@ #include "p4_symbolic/symbolic/conditional.h" #include "p4_symbolic/symbolic/symbolic.h" #include "p4_symbolic/symbolic/table.h" +#include "p4_symbolic/z3_util.h" namespace p4_symbolic::symbolic::control { -absl::StatusOr EvaluateV1model( +absl::StatusOr EvaluateV1model( const Dataplane &data_plane, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator) { - // Initial, empty trace. - auto trace = SymbolicTrace{.dropped = Z3Context().bool_val(false)}; + SymbolicTableMatches matches; - // Extend trace by evaluating the v1model pipelines. std::vector v1model_pipelines = {"ingress", "egress"}; for (const auto &pipeline : v1model_pipelines) { - ASSIGN_OR_RETURN(SymbolicTrace suffix_trace, + // TODO: The conditional here is not needed, but without it there + // will be a lot of changes to the SMT golden files, making this CL hard to + // review. I am removing this comment and the coniditional in a separate CL. + ASSIGN_OR_RETURN(z3::expr dropped, pipeline == "ingress" + ? Z3Context().bool_val(false) + : IsDropped(*state)); + ASSIGN_OR_RETURN(SymbolicTableMatches additional_matches, EvaluatePipeline(data_plane, pipeline, state, translator, - !trace.dropped)); - - // Extend existing trace with suffix. - trace.dropped = suffix_trace.dropped; - for (auto &[table, match] : suffix_trace.matched_entries) { - if (trace.matched_entries.count(table) != 0) { - return gutil::UnimplementedErrorBuilder() - << "table '" << table << "' was executed in '" << pipeline - << "' pipeline after already being executed in an earlier " - "pipeline; this is not supported by p4-symbolic"; - } - trace.matched_entries.insert({table, match}); - } + /*guard=*/!dropped)); + matches.merge(std::move(additional_matches)); } - return trace; + return matches; } -absl::StatusOr EvaluatePipeline( +absl::StatusOr EvaluatePipeline( const Dataplane &data_plane, const std::string &pipeline_name, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard) { @@ -74,14 +68,12 @@ absl::StatusOr EvaluatePipeline( << "cannot evaluate unknown pipeline: '" << pipeline_name << "'"; } -absl::StatusOr EvaluateControl( +absl::StatusOr EvaluateControl( const Dataplane &data_plane, const std::string &control_name, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard) { // Base case: we got to the end of the evaluation, no more controls! - if (control_name.empty()) { - return SymbolicTrace{{}, Z3Context().bool_val(false)}; - } + if (control_name.empty()) return SymbolicTableMatches(); // Find out what type of control we need to evaluate. if (data_plane.program.tables().count(control_name) == 1) { diff --git a/p4_symbolic/symbolic/control.h b/p4_symbolic/symbolic/control.h index 14dd5e53..fc3e308d 100644 --- a/p4_symbolic/symbolic/control.h +++ b/p4_symbolic/symbolic/control.h @@ -73,18 +73,18 @@ namespace control { // Note: This only evaluates the ingress and egress pipelines, but doesn't // evaluate the parser or deparser. // TODO: Also add support for executing the parser. -absl::StatusOr EvaluateV1model( +absl::StatusOr EvaluateV1model( const Dataplane &data_plane, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator); // Evaluate the passed pipeline. -absl::StatusOr EvaluatePipeline( +absl::StatusOr EvaluatePipeline( const Dataplane &data_plane, const std::string &pipeline_name, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard); // Evaluate the passed control construct. -absl::StatusOr EvaluateControl( +absl::StatusOr EvaluateControl( const Dataplane &data_plane, const std::string &control_name, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard); diff --git a/p4_symbolic/symbolic/expected/basic.smt2 b/p4_symbolic/symbolic/expected/basic.smt2 index 44687382..8e1f00cf 100644 --- a/p4_symbolic/symbolic/expected/basic.smt2 +++ b/p4_symbolic/symbolic/expected/basic.smt2 @@ -5,52 +5,53 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x145 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x145))) + (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) (assert - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x82 (and $x78 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let (($x83 (and $x51 $x82))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let (($x69 (and $x51 $x55))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (or (or (= ?x132 (_ bv455 9)) (= ?x132 (_ bv0 9))) (= ?x132 (_ bv1 9)))))))))))))))))))))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let (($x75 (and $x43 $x74))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let (($x61 (and $x43 $x47))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let ((?x108 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x51 $x68) 2 (- 1))))) - (let ((?x120 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x108))) - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x69 (and $x51 $x55))) - (let ((?x139 (ite ipv4.$valid$ (ite $x69 1 ?x120) (- 1)))) - (let (($x138 (ite ipv4.$valid$ $x51 false))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x83 (and $x51 (and $x78 (not $x68))))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (let (($x50 (= ?x132 (_ bv455 9)))) - (and (and (not $x50) $x138) (= ?x139 (- 1)))))))))))))))))))))))))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) + (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x61 (and $x43 $x47))) + (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) + (let (($x131 (ite ipv4.$valid$ $x43 false))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x75 (and $x43 (and $x70 (not $x60))))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (and (and (not $x42) $x131) (= ?x132 (- 1)))))))))))))))))))))))))) (check-sat) ; @@ -60,53 +61,54 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x145 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x145))) + (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) (assert - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x82 (and $x78 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let (($x83 (and $x51 $x82))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let (($x69 (and $x51 $x55))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (or (or (= ?x132 (_ bv455 9)) (= ?x132 (_ bv0 9))) (= ?x132 (_ bv1 9)))))))))))))))))))))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let (($x75 (and $x43 $x74))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let (($x61 (and $x43 $x47))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let ((?x108 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x51 $x68) 2 (- 1))))) - (let ((?x120 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x108))) - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x69 (and $x51 $x55))) - (let ((?x139 (ite ipv4.$valid$ (ite $x69 1 ?x120) (- 1)))) - (let (($x138 (ite ipv4.$valid$ $x51 false))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x83 (and $x51 (and $x78 (not $x68))))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (let (($x50 (= ?x132 (_ bv455 9)))) - (let (($x252 (and (not $x50) $x138))) - (and $x252 (= ?x139 0)))))))))))))))))))))))))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) + (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x61 (and $x43 $x47))) + (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) + (let (($x131 (ite ipv4.$valid$ $x43 false))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x75 (and $x43 (and $x70 (not $x60))))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (let (($x256 (and (not $x42) $x131))) + (and $x256 (= ?x132 0)))))))))))))))))))))))))) (check-sat) ; @@ -116,52 +118,53 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x145 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x145))) + (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) (assert - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x82 (and $x78 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let (($x83 (and $x51 $x82))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let (($x69 (and $x51 $x55))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (or (or (= ?x132 (_ bv455 9)) (= ?x132 (_ bv0 9))) (= ?x132 (_ bv1 9)))))))))))))))))))))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let (($x75 (and $x43 $x74))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let (($x61 (and $x43 $x47))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let ((?x108 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x51 $x68) 2 (- 1))))) - (let ((?x120 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x108))) - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x69 (and $x51 $x55))) - (let ((?x139 (ite ipv4.$valid$ (ite $x69 1 ?x120) (- 1)))) - (let (($x138 (ite ipv4.$valid$ $x51 false))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x83 (and $x51 (and $x78 (not $x68))))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (let (($x50 (= ?x132 (_ bv455 9)))) - (and (and (not $x50) $x138) (= ?x139 1))))))))))))))))))))))))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) + (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x61 (and $x43 $x47))) + (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) + (let (($x131 (ite ipv4.$valid$ $x43 false))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x75 (and $x43 (and $x70 (not $x60))))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (and (and (not $x42) $x131) (= ?x132 1))))))))))))))))))))))))) (check-sat) ; @@ -171,52 +174,53 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x145 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x145))) + (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) (assert - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x82 (and $x78 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let (($x83 (and $x51 $x82))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let (($x69 (and $x51 $x55))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (or (or (= ?x132 (_ bv455 9)) (= ?x132 (_ bv0 9))) (= ?x132 (_ bv1 9)))))))))))))))))))))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let (($x75 (and $x43 $x74))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let (($x61 (and $x43 $x47))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let ((?x108 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x51 $x68) 2 (- 1))))) - (let ((?x120 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x108))) - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x69 (and $x51 $x55))) - (let ((?x139 (ite ipv4.$valid$ (ite $x69 1 ?x120) (- 1)))) - (let (($x138 (ite ipv4.$valid$ $x51 false))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x83 (and $x51 (and $x78 (not $x68))))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (let (($x50 (= ?x132 (_ bv455 9)))) - (and (and (not $x50) $x138) (= ?x139 2))))))))))))))))))))))))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) + (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x61 (and $x43 $x47))) + (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) + (let (($x131 (ite ipv4.$valid$ $x43 false))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x75 (and $x43 (and $x70 (not $x60))))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (and (and (not $x42) $x131) (= ?x132 2))))))))))))))))))))))))) (check-sat) ; @@ -226,51 +230,52 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x145 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x145))) + (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) (assert - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x82 (and $x78 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let (($x83 (and $x51 $x82))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let (($x69 (and $x51 $x55))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (or (or (= ?x132 (_ bv455 9)) (= ?x132 (_ bv0 9))) (= ?x132 (_ bv1 9)))))))))))))))))))))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let (($x75 (and $x43 $x74))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let (($x61 (and $x43 $x47))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x68 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x51 (and (not false) ipv4.$valid$))) - (let ((?x108 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x51 $x68) 2 (- 1))))) - (let ((?x120 (ite (and $x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x108))) - (let (($x54 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x55 (and true $x54))) - (let (($x69 (and $x51 $x55))) - (let ((?x139 (ite ipv4.$valid$ (ite $x69 1 ?x120) (- 1)))) - (let (($x138 (ite ipv4.$valid$ $x51 false))) - (let (($x70 (not $x55))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x78 (and $x74 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x83 (and $x51 (and $x78 (not $x68))))) - (let ((?x97 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x80 (and (and $x51 $x78) $x68))) - (let (($x63 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x76 (and (and $x51 $x74) $x63))) - (let ((?x110 (ite $x76 ?x97 (ite $x80 ?x97 (ite $x83 (_ bv455 9) standard_metadata.egress_spec))))) - (let (($x59 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x72 (and (and $x51 $x70) $x59))) - (let ((?x132 (ite $x69 ?x97 (ite $x72 (concat (_ bv0 8) (_ bv0 1)) ?x110)))) - (let (($x50 (= ?x132 (_ bv455 9)))) - (and (and (not $x50) $x138) (= ?x139 3))))))))))))))))))))))))) + (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x43 (and (not false) ipv4.$valid$))) + (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) + (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) + (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x47 (and true $x46))) + (let (($x61 (and $x43 $x47))) + (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) + (let (($x131 (ite ipv4.$valid$ $x43 false))) + (let (($x62 (not $x47))) + (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x75 (and $x43 (and $x70 (not $x60))))) + (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x72 (and (and $x43 $x70) $x60))) + (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x68 (and (and $x43 $x66) $x55))) + (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x64 (and (and $x43 $x62) $x51))) + (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) + (let (($x42 (= ?x125 (_ bv511 9)))) + (and (and (not $x42) $x131) (= ?x132 3))))))))))))))))))))))))) (check-sat) diff --git a/p4_symbolic/symbolic/expected/hardcoded.smt2 b/p4_symbolic/symbolic/expected/hardcoded.smt2 index 794530d9..aac8f501 100644 --- a/p4_symbolic/symbolic/expected/hardcoded.smt2 +++ b/p4_symbolic/symbolic/expected/hardcoded.smt2 @@ -3,26 +3,27 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x55 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x55))) + (let (($x47 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x47)))) (assert - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x36 (= standard_metadata.ingress_port ?x35))) - (let (($x32 (not false))) - (let (($x38 (and $x32 $x36))) - (let (($x39 (and $x32 (not $x36)))) - (let ((?x44 (ite $x39 ?x35 (ite $x38 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (or (or (= ?x44 (_ bv455 9)) (= ?x44 (_ bv0 9))) (= ?x44 (_ bv1 9)))))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x28 (= standard_metadata.ingress_port ?x27))) + (let (($x24 (not false))) + (let (($x30 (and $x24 $x28))) + (let (($x31 (and $x24 (not $x28)))) + (let ((?x36 (ite $x31 ?x27 (ite $x30 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x40 (= ?x36 (_ bv511 9)))) + (or $x40 (or (or false (= ?x36 (_ bv0 9))) (= ?x36 (_ bv1 9)))))))))))) (assert - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x36 (= standard_metadata.ingress_port ?x35))) - (let (($x32 (not false))) - (let (($x38 (and $x32 $x36))) - (let (($x45 (ite $x36 $x38 false))) - (let (($x39 (and $x32 (not $x36)))) - (let ((?x44 (ite $x39 ?x35 (ite $x38 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (let (($x48 (= ?x44 (_ bv455 9)))) - (and (and (not $x48) $x45) (= (- 1) (- 1)))))))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x28 (= standard_metadata.ingress_port ?x27))) + (let (($x24 (not false))) + (let (($x30 (and $x24 $x28))) + (let (($x37 (ite $x28 $x30 false))) + (let (($x31 (and $x24 (not $x28)))) + (let ((?x36 (ite $x31 ?x27 (ite $x30 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x40 (= ?x36 (_ bv511 9)))) + (and (and (not $x40) $x37) (= (- 1) (- 1)))))))))))) (check-sat) ; @@ -30,24 +31,25 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x55 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x55))) + (let (($x47 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x47)))) (assert - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x36 (= standard_metadata.ingress_port ?x35))) - (let (($x32 (not false))) - (let (($x38 (and $x32 $x36))) - (let (($x39 (and $x32 (not $x36)))) - (let ((?x44 (ite $x39 ?x35 (ite $x38 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (or (or (= ?x44 (_ bv455 9)) (= ?x44 (_ bv0 9))) (= ?x44 (_ bv1 9)))))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x28 (= standard_metadata.ingress_port ?x27))) + (let (($x24 (not false))) + (let (($x30 (and $x24 $x28))) + (let (($x31 (and $x24 (not $x28)))) + (let ((?x36 (ite $x31 ?x27 (ite $x30 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x40 (= ?x36 (_ bv511 9)))) + (or $x40 (or (or false (= ?x36 (_ bv0 9))) (= ?x36 (_ bv1 9)))))))))))) (assert - (let (($x32 (not false))) - (let (($x39 (and $x32 (not (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1))))))) - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x36 (= standard_metadata.ingress_port ?x35))) - (let (($x46 (ite $x36 false $x39))) - (let ((?x44 (ite $x39 ?x35 (ite (and $x32 $x36) (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (let (($x48 (= ?x44 (_ bv455 9)))) - (and (and (not $x48) $x46) (= (- 1) (- 1))))))))))) + (let (($x24 (not false))) + (let (($x31 (and $x24 (not (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x28 (= standard_metadata.ingress_port ?x27))) + (let (($x38 (ite $x28 false $x31))) + (let ((?x36 (ite $x31 ?x27 (ite (and $x24 $x28) (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x40 (= ?x36 (_ bv511 9)))) + (and (and (not $x40) $x38) (= (- 1) (- 1))))))))))) (check-sat) diff --git a/p4_symbolic/symbolic/expected/reflector.smt2 b/p4_symbolic/symbolic/expected/reflector.smt2 index a0e5526a..f554d766 100644 --- a/p4_symbolic/symbolic/expected/reflector.smt2 +++ b/p4_symbolic/symbolic/expected/reflector.smt2 @@ -3,16 +3,17 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x43 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x43))) + (let (($x35 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x35)))) (assert - (let (($x32 (not false))) - (let ((?x34 (ite $x32 standard_metadata.ingress_port standard_metadata.egress_spec))) - (or (or (= ?x34 (_ bv455 9)) (= ?x34 (_ bv0 9))) (= ?x34 (_ bv1 9)))))) + (let (($x24 (not false))) + (let ((?x26 (ite $x24 standard_metadata.ingress_port standard_metadata.egress_spec))) + (let (($x28 (= ?x26 (_ bv511 9)))) + (or $x28 (or (or false (= ?x26 (_ bv0 9))) (= ?x26 (_ bv1 9)))))))) (assert - (let (($x32 (not false))) - (let ((?x34 (ite $x32 standard_metadata.ingress_port standard_metadata.egress_spec))) - (let (($x36 (= ?x34 (_ bv455 9)))) - (and (and (not $x36) $x32) (= (- 1) (- 1))))))) + (let (($x24 (not false))) + (let ((?x26 (ite $x24 standard_metadata.ingress_port standard_metadata.egress_spec))) + (let (($x28 (= ?x26 (_ bv511 9)))) + (and (and (not $x28) $x24) (= (- 1) (- 1))))))) (check-sat) diff --git a/p4_symbolic/symbolic/expected/reflector.txt b/p4_symbolic/symbolic/expected/reflector.txt index fd7908fd..d2c79b26 100644 --- a/p4_symbolic/symbolic/expected/reflector.txt +++ b/p4_symbolic/symbolic/expected/reflector.txt @@ -1,5 +1,5 @@ Finding packet for table tbl_reflector54 and row -1 Dropped = 0 - standard_metadata.ingress_port = #b000000001 - standard_metadata.egress_spec = #b000000001 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000000 diff --git a/p4_symbolic/symbolic/expected/table.smt2 b/p4_symbolic/symbolic/expected/table.smt2 index a68cd0f9..28ce7728 100644 --- a/p4_symbolic/symbolic/expected/table.smt2 +++ b/p4_symbolic/symbolic/expected/table.smt2 @@ -3,30 +3,31 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x62 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x62))) + (let (($x54 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x54)))) (assert - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x32 (not false))) - (let (($x45 (and (and $x32 (not (and true (= standard_metadata.ingress_port ?x35)))) $x41))) - (let ((?x39 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x37 (and true (= standard_metadata.ingress_port ?x35)))) - (let (($x42 (and $x32 $x37))) - (let ((?x56 (ite $x42 ?x39 (ite $x45 ?x35 standard_metadata.egress_spec)))) - (or (or (= ?x56 (_ bv455 9)) (= ?x56 (_ bv0 9))) (= ?x56 (_ bv1 9)))))))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x24 (not false))) + (let (($x37 (and (and $x24 (not (and true (= standard_metadata.ingress_port ?x27)))) $x33))) + (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x29 (and true (= standard_metadata.ingress_port ?x27)))) + (let (($x34 (and $x24 $x29))) + (let ((?x48 (ite $x34 ?x31 (ite $x37 ?x27 standard_metadata.egress_spec)))) + (let (($x39 (= ?x48 (_ bv511 9)))) + (or $x39 (or (or false (= ?x48 (_ bv0 9))) (= ?x48 (_ bv1 9)))))))))))))) (assert - (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x32 (not false))) - (let (($x37 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) - (let (($x42 (and $x32 $x37))) - (let ((?x55 (ite $x42 0 (ite (and $x32 $x41) 1 (- 1))))) - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let ((?x53 (ite (and (and $x32 (not $x37)) $x41) ?x35 standard_metadata.egress_spec))) - (let ((?x39 (concat (_ bv0 8) (_ bv1 1)))) - (let ((?x56 (ite $x42 ?x39 ?x53))) - (let (($x47 (= ?x56 (_ bv455 9)))) - (and (and (not $x47) $x32) (= ?x55 (- 1)))))))))))))) + (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x24 (not false))) + (let (($x29 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x34 (and $x24 $x29))) + (let ((?x47 (ite $x34 0 (ite (and $x24 $x33) 1 (- 1))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x45 (ite (and (and $x24 (not $x29)) $x33) ?x27 standard_metadata.egress_spec))) + (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x48 (ite $x34 ?x31 ?x45))) + (let (($x39 (= ?x48 (_ bv511 9)))) + (and (and (not $x39) $x24) (= ?x47 (- 1)))))))))))))) (check-sat) ; @@ -34,31 +35,32 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x62 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x62))) + (let (($x54 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x54)))) (assert - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x32 (not false))) - (let (($x45 (and (and $x32 (not (and true (= standard_metadata.ingress_port ?x35)))) $x41))) - (let ((?x39 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x37 (and true (= standard_metadata.ingress_port ?x35)))) - (let (($x42 (and $x32 $x37))) - (let ((?x56 (ite $x42 ?x39 (ite $x45 ?x35 standard_metadata.egress_spec)))) - (or (or (= ?x56 (_ bv455 9)) (= ?x56 (_ bv0 9))) (= ?x56 (_ bv1 9)))))))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x24 (not false))) + (let (($x37 (and (and $x24 (not (and true (= standard_metadata.ingress_port ?x27)))) $x33))) + (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x29 (and true (= standard_metadata.ingress_port ?x27)))) + (let (($x34 (and $x24 $x29))) + (let ((?x48 (ite $x34 ?x31 (ite $x37 ?x27 standard_metadata.egress_spec)))) + (let (($x39 (= ?x48 (_ bv511 9)))) + (or $x39 (or (or false (= ?x48 (_ bv0 9))) (= ?x48 (_ bv1 9)))))))))))))) (assert - (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x32 (not false))) - (let (($x37 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) - (let (($x42 (and $x32 $x37))) - (let ((?x55 (ite $x42 0 (ite (and $x32 $x41) 1 (- 1))))) - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let ((?x53 (ite (and (and $x32 (not $x37)) $x41) ?x35 standard_metadata.egress_spec))) - (let ((?x39 (concat (_ bv0 8) (_ bv1 1)))) - (let ((?x56 (ite $x42 ?x39 ?x53))) - (let (($x47 (= ?x56 (_ bv455 9)))) - (let (($x114 (and (not $x47) $x32))) - (and $x114 (= ?x55 0)))))))))))))) + (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x24 (not false))) + (let (($x29 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x34 (and $x24 $x29))) + (let ((?x47 (ite $x34 0 (ite (and $x24 $x33) 1 (- 1))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x45 (ite (and (and $x24 (not $x29)) $x33) ?x27 standard_metadata.egress_spec))) + (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x48 (ite $x34 ?x31 ?x45))) + (let (($x39 (= ?x48 (_ bv511 9)))) + (let (($x117 (and (not $x39) $x24))) + (and $x117 (= ?x47 0)))))))))))))) (check-sat) ; @@ -66,29 +68,30 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x62 (= standard_metadata.ingress_port (_ bv1 9)))) - (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x62))) + (let (($x54 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x54)))) (assert - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x32 (not false))) - (let (($x45 (and (and $x32 (not (and true (= standard_metadata.ingress_port ?x35)))) $x41))) - (let ((?x39 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x37 (and true (= standard_metadata.ingress_port ?x35)))) - (let (($x42 (and $x32 $x37))) - (let ((?x56 (ite $x42 ?x39 (ite $x45 ?x35 standard_metadata.egress_spec)))) - (or (or (= ?x56 (_ bv455 9)) (= ?x56 (_ bv0 9))) (= ?x56 (_ bv1 9)))))))))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x24 (not false))) + (let (($x37 (and (and $x24 (not (and true (= standard_metadata.ingress_port ?x27)))) $x33))) + (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x29 (and true (= standard_metadata.ingress_port ?x27)))) + (let (($x34 (and $x24 $x29))) + (let ((?x48 (ite $x34 ?x31 (ite $x37 ?x27 standard_metadata.egress_spec)))) + (let (($x39 (= ?x48 (_ bv511 9)))) + (or $x39 (or (or false (= ?x48 (_ bv0 9))) (= ?x48 (_ bv1 9)))))))))))))) (assert - (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x32 (not false))) - (let (($x37 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) - (let (($x42 (and $x32 $x37))) - (let ((?x55 (ite $x42 0 (ite (and $x32 $x41) 1 (- 1))))) - (let ((?x35 (concat (_ bv0 8) (_ bv0 1)))) - (let ((?x53 (ite (and (and $x32 (not $x37)) $x41) ?x35 standard_metadata.egress_spec))) - (let ((?x39 (concat (_ bv0 8) (_ bv1 1)))) - (let ((?x56 (ite $x42 ?x39 ?x53))) - (let (($x47 (= ?x56 (_ bv455 9)))) - (and (and (not $x47) $x32) (= ?x55 1))))))))))))) + (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x24 (not false))) + (let (($x29 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x34 (and $x24 $x29))) + (let ((?x47 (ite $x34 0 (ite (and $x24 $x33) 1 (- 1))))) + (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x45 (ite (and (and $x24 (not $x29)) $x33) ?x27 standard_metadata.egress_spec))) + (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x48 (ite $x34 ?x31 ?x45))) + (let (($x39 (= ?x48 (_ bv511 9)))) + (and (and (not $x39) $x24) (= ?x47 1))))))))))))) (check-sat) diff --git a/p4_symbolic/symbolic/guarded_map.cc b/p4_symbolic/symbolic/guarded_map.cc index b24fe741..24f885e4 100644 --- a/p4_symbolic/symbolic/guarded_map.cc +++ b/p4_symbolic/symbolic/guarded_map.cc @@ -16,6 +16,7 @@ #include "p4_symbolic/symbolic/guarded_map.h" +#include "absl/container/btree_map.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "p4_symbolic/symbolic/operators.h" diff --git a/p4_symbolic/symbolic/guarded_map.h b/p4_symbolic/symbolic/guarded_map.h index 5f351efe..7e5c4aec 100644 --- a/p4_symbolic/symbolic/guarded_map.h +++ b/p4_symbolic/symbolic/guarded_map.h @@ -17,9 +17,9 @@ #ifndef P4_SYMBOLIC_SYMBOLIC_GUARDED_MAP_H_ #define P4_SYMBOLIC_SYMBOLIC_GUARDED_MAP_H_ -#include #include +#include "absl/container/btree_map.h" #include "absl/status/status.h" #include "google/protobuf/map.h" #include "gutil/status.h" @@ -29,7 +29,7 @@ namespace p4_symbolic { namespace symbolic { -// This class wraps around an internal std::map instance, +// This class wraps around an internal absl::btree_map instance, // while enforcing the following: // 1. This class can only be instantiated with an instance of the IR // header definitions. The resulting instance will be initialized @@ -74,16 +74,16 @@ class SymbolicGuardedMap { const z3::expr &guard); // Constant iterators. - using const_iterator = std::map::const_iterator; + using const_iterator = absl::btree_map::const_iterator; const_iterator begin() const noexcept { return this->map_.cbegin(); } const_iterator end() const noexcept { return this->map_.cend(); } private: // The underlying map storing the keys and their values. - std::map map_; + absl::btree_map map_; // Private constructor used by factory. - explicit SymbolicGuardedMap(std::map map) + explicit SymbolicGuardedMap(absl::btree_map map) : map_(map) {} }; diff --git a/p4_symbolic/symbolic/operators.cc b/p4_symbolic/symbolic/operators.cc index c90e2d2c..31b76d58 100644 --- a/p4_symbolic/symbolic/operators.cc +++ b/p4_symbolic/symbolic/operators.cc @@ -25,6 +25,7 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "p4_symbolic/symbolic/symbolic.h" +#include "p4_symbolic/z3_util.h" namespace p4_symbolic { namespace symbolic { diff --git a/p4_symbolic/symbolic/packet.cc b/p4_symbolic/symbolic/packet.cc index 6a3da7cd..12c75a74 100644 --- a/p4_symbolic/symbolic/packet.cc +++ b/p4_symbolic/symbolic/packet.cc @@ -32,7 +32,6 @@ z3::expr GetOrDefault(SymbolicPerPacketState state, const std::string &field, if (state.ContainsKey(field)) { return state.Get(field).value(); } - return Z3Context().bv_val(-1, default_value_bit_size); } } // namespace diff --git a/p4_symbolic/symbolic/symbolic.cc b/p4_symbolic/symbolic/symbolic.cc index 0f4e4151..026e9ded 100644 --- a/p4_symbolic/symbolic/symbolic.cc +++ b/p4_symbolic/symbolic/symbolic.cc @@ -16,19 +16,35 @@ #include +#include "absl/algorithm/container.h" +#include "absl/cleanup/cleanup.h" +#include "absl/memory/memory.h" #include "absl/types/optional.h" #include "glog/logging.h" +#include "gutil/status.h" #include "p4_symbolic/symbolic/control.h" #include "p4_symbolic/symbolic/operators.h" #include "p4_symbolic/symbolic/packet.h" #include "p4_symbolic/symbolic/util.h" +#include "p4_symbolic/z3_util.h" namespace p4_symbolic { namespace symbolic { -z3::context &Z3Context() { - static z3::context *z3_context = new z3::context(); - return *z3_context; +// A port reserved to encode dropping packets. +// The value is arbitrary; we choose the same value as BMv2: +// https://github.com/p4lang/behavioral-model/blob/main/docs/simple_switch.md#standard-metadata +constexpr int kDropPort = 511; // 2^9 - 1. +constexpr int kPortBitwidth = 9; + +z3::expr EgressSpecDroppedValue() { + return Z3Context().bv_val(kDropPort, kPortBitwidth); +} + +absl::StatusOr IsDropped(const SymbolicPerPacketState &state) { + ASSIGN_OR_RETURN(z3::expr egress_spec, + state.Get("standard_metadata.egress_spec")); + return operators::Eq(egress_spec, EgressSpecDroppedValue()); } absl::StatusOr> EvaluateP4Pipeline( @@ -37,13 +53,6 @@ absl::StatusOr> EvaluateP4Pipeline( std::unique_ptr z3_solver = std::make_unique(Z3Context()); - // Create free/unconstrainted headers variables, and then - // put constraints on them matching the hardcoded behavior of the parser - // for programs we are interested in. - ASSIGN_OR_RETURN(SymbolicPerPacketState ingress_headers, - SymbolicGuardedMap::CreateSymbolicGuardedMap( - data_plane.program.headers())); - // Initially, the p4runtime translator has empty state. values::P4RuntimeTranslator translator; @@ -51,62 +60,63 @@ absl::StatusOr> EvaluateP4Pipeline( // This is used to evaluate the P4 program. // Initially free/unconstrained and contains symbolic variables for // every header field. - SymbolicPerPacketState egress_headers(ingress_headers); - - ASSIGN_OR_RETURN(z3::expr ingress_port, - ingress_headers.Get("standard_metadata.ingress_port")); - // TODO: Function hardcoded. - SymbolicPacket ingress_packet = - packet::ExtractSymbolicPacket(ingress_headers); + ASSIGN_OR_RETURN(SymbolicPerPacketState ingress_headers, + SymbolicGuardedMap::CreateSymbolicGuardedMap( + data_plane.program.headers())); + SymbolicPerPacketState egress_headers = ingress_headers; // Evaluate the main program. ASSIGN_OR_RETURN( - SymbolicTrace trace, + SymbolicTableMatches matched_entries, control::EvaluateV1model(data_plane, &egress_headers, &translator)); - // Alias the event that the packet is dropped for ease of use in assertions. - z3::expr dropped_value = - Z3Context().bv_val(DROPPED_EGRESS_SPEC_VALUE, DROPPED_EGRESS_SPEC_LENGTH); - ASSIGN_OR_RETURN(trace.dropped, - egress_headers.Get("standard_metadata.egress_spec")); - ASSIGN_OR_RETURN(trace.dropped, operators::Eq(trace.dropped, dropped_value)); + // Alias the event that the packet is dropped for ease of use in assertions + ASSIGN_OR_RETURN(z3::expr dropped, IsDropped(egress_headers)); - // Construct a symbolic context, containing state and trace information - // from evaluating the tables. + // Restrict ports to the available physical ports. + if (absl::c_find(physical_ports, kDropPort) != physical_ports.end()) { + return gutil::InvalidArgumentErrorBuilder() + << "cannot use physical port " << kDropPort + << " as p4-symbolic reserves it to encode dropping a packet; see " + "the documentation of `mark_to_drop` in v1mode.p4 for details"; + } + ASSIGN_OR_RETURN(z3::expr ingress_port, + ingress_headers.Get("standard_metadata.ingress_port")); ASSIGN_OR_RETURN(z3::expr egress_port, egress_headers.Get("standard_metadata.egress_spec")); - - // Restrict ports to the available physical ports. - if (!physical_ports.empty()) { - z3::expr ingress_port_domain = Z3Context().bool_val(false); - z3::expr egress_port_domain = trace.dropped; - unsigned int port_size = ingress_port.get_sort().bv_size(); + if (physical_ports.empty()) { + z3_solver->add(ingress_port != kDropPort); + } else { + z3::expr ingress_port_is_physical = Z3Context().bool_val(false); + z3::expr egress_port_is_physical = Z3Context().bool_val(false); for (int port : physical_ports) { - ASSIGN_OR_RETURN( - z3::expr ingress_port_eq, - operators::Eq(ingress_port, Z3Context().bv_val(port, port_size))); - ASSIGN_OR_RETURN( - z3::expr egress_port_eq, - operators::Eq(egress_port, Z3Context().bv_val(port, port_size))); - - ASSIGN_OR_RETURN(ingress_port_domain, - operators::Or(ingress_port_domain, ingress_port_eq)); - ASSIGN_OR_RETURN(egress_port_domain, - operators::Or(egress_port_domain, egress_port_eq)); + ingress_port_is_physical = + ingress_port_is_physical || ingress_port == port; + egress_port_is_physical = egress_port_is_physical || egress_port == port; } - z3_solver->add(ingress_port_domain); - z3_solver->add(egress_port_domain); + z3_solver->add(ingress_port != kDropPort && ingress_port_is_physical); + z3_solver->add(dropped || egress_port_is_physical); } - // Construct solver state for this program. - SymbolicPacket egress_packet = packet::ExtractSymbolicPacket(egress_headers); - SymbolicContext symbolic_context = { - ingress_port, egress_port, ingress_packet, egress_packet, - ingress_headers, egress_headers, trace}; - - return std::make_unique(data_plane.program, data_plane.entries, - symbolic_context, std::move(z3_solver), - translator); + // Assemble and return result. + auto trace = SymbolicTrace{ + .matched_entries = std::move(matched_entries), + .dropped = dropped, + }; + auto context = SymbolicContext{ + .ingress_port = ingress_port, + .egress_port = egress_port, + .ingress_headers = std::move(ingress_headers), + .egress_headers = std::move(egress_headers), + .trace = std::move(trace), + }; + return std::make_unique(SolverState{ + .program = data_plane.program, + .entries = data_plane.entries, + .context = std::move(context), + .solver = std::move(z3_solver), + .translator = std::move(translator), + }); } absl::StatusOr> Solve( diff --git a/p4_symbolic/symbolic/symbolic.h b/p4_symbolic/symbolic/symbolic.h index c11655b4..0966e574 100644 --- a/p4_symbolic/symbolic/symbolic.h +++ b/p4_symbolic/symbolic/symbolic.h @@ -18,18 +18,13 @@ #ifndef P4_SYMBOLIC_SYMBOLIC_SYMBOLIC_H_ #define P4_SYMBOLIC_SYMBOLIC_SYMBOLIC_H_ -// A reserved special value assigned to standard_metadata.egress_spec when -// the packet is dropped. -#define DROPPED_EGRESS_SPEC_VALUE "111111111" -#define DROPPED_EGRESS_SPEC_LENGTH 9 - -#include #include #include #include #include #include +#include "absl/container/btree_map.h" #include "absl/strings/str_cat.h" #include "gutil/status.h" #include "p4_symbolic/ir/ir.pb.h" @@ -41,12 +36,8 @@ namespace p4_symbolic { namespace symbolic { -// Global z3::context used for creating symbolic expressions during symbolic -// evaluation. -z3::context &Z3Context(); - // Maps the name of a header field in the p4 program to its concrete value. -using ConcretePerPacketState = std::map; +using ConcretePerPacketState = absl::btree_map; // The symbolic counterpart of ConcretePerPacketState. // Maps the name of a header field in the p4 program to its symbolic value. @@ -62,6 +53,12 @@ using ConcretePerPacketState = std::map; // responsible for symbolically evaluating the program. using SymbolicPerPacketState = SymbolicGuardedMap; +// V1model's `mark_to_drop` primitive sets the `egress_spec` field to this +// value to indicate the packet should be dropped at the end of ingress/egress +// processing. See v1model.p4 for details. +z3::expr EgressSpecDroppedValue(); +absl::StatusOr IsDropped(const SymbolicPerPacketState &state); + // Expresses a concrete match for a corresponding concrete packet with a // table in the program. struct ConcreteTableMatch { @@ -90,10 +87,13 @@ struct SymbolicTableMatch { z3::expr entry_index; }; +// `SymbolicTableMatch`es by table name. +using SymbolicTableMatches = absl::btree_map; + // Specifies the expected trace in the program that the corresponding // concrete packet is expected to take. struct ConcreteTrace { - std::map matched_entries; + absl::btree_map matched_entries; // Can be extended more in the future to include useful // flags about dropping the packet, taking specific code (e.g. if) // branches, vrf, other interesting events, etc. @@ -111,7 +111,8 @@ struct ConcreteTrace { // to take in the program. struct SymbolicTrace { // Full table name to its symbolic match. - std::map matched_entries; + // TODO: Rename to matches_by_table_name. + SymbolicTableMatches matched_entries; z3::expr dropped; }; @@ -208,8 +209,6 @@ struct ConcreteContext { struct SymbolicContext { z3::expr ingress_port; z3::expr egress_port; - SymbolicPacket ingress_packet; - SymbolicPacket egress_packet; SymbolicPerPacketState ingress_headers; SymbolicPerPacketState egress_headers; SymbolicTrace trace; @@ -245,16 +244,6 @@ struct SolverState { std::unique_ptr solver; // Store the p4 runtime translator state for use by .Solve(...). values::P4RuntimeTranslator translator; - // Need this constructor to be defined explicity to be able to use make_unique - // on this struct. - SolverState(ir::P4Program program, ir::TableEntries entries, - SymbolicContext context, std::unique_ptr &&solver, - values::P4RuntimeTranslator translator) - : program(program), - entries(entries), - context(context), - solver(std::move(solver)), - translator(translator) {} }; // An assertion is a user defined function that takes a symbolic context diff --git a/p4_symbolic/symbolic/table.cc b/p4_symbolic/symbolic/table.cc index 0398df51..dfbc0ee8 100644 --- a/p4_symbolic/symbolic/table.cc +++ b/p4_symbolic/symbolic/table.cc @@ -35,6 +35,7 @@ #include "p4_symbolic/symbolic/operators.h" #include "p4_symbolic/symbolic/symbolic.h" #include "p4_symbolic/symbolic/values.h" +#include "p4_symbolic/z3_util.h" #include "z3++.h" namespace p4_symbolic { @@ -330,7 +331,7 @@ absl::Status EvaluateTableEntryAction( } // namespace -absl::StatusOr EvaluateTable( +absl::StatusOr EvaluateTable( const Dataplane &data_plane, const ir::Table &table, const std::vector &entries, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, @@ -478,20 +479,22 @@ absl::StatusOr EvaluateTable( } // Evaluate the next control. - ASSIGN_OR_RETURN(SymbolicTrace result, + ASSIGN_OR_RETURN(SymbolicTableMatches result, control::EvaluateControl(data_plane, next_control, state, translator, guard)); // The trace should not contain information for this table, otherwise, it // means we visited the table twice in the same execution path! - if (result.matched_entries.count(table_name) == 1) { + if (result.contains(table_name)) { return absl::InvalidArgumentError(absl::StrCat( "Table \"", table_name, "\" was executed twice in the same path.")); } // Add this table's match to the trace, and return it. - SymbolicTableMatch table_match = {guard, match_index}; - result.matched_entries.insert({table_name, table_match}); + result.insert({table_name, SymbolicTableMatch{ + .matched = guard, + .entry_index = match_index, + }}); return result; } diff --git a/p4_symbolic/symbolic/table.h b/p4_symbolic/symbolic/table.h index 69676773..94b27423 100644 --- a/p4_symbolic/symbolic/table.h +++ b/p4_symbolic/symbolic/table.h @@ -36,7 +36,7 @@ namespace p4_symbolic { namespace symbolic { namespace table { -absl::StatusOr EvaluateTable( +absl::StatusOr EvaluateTable( const Dataplane &data_plane, const ir::Table &table, const std::vector &entries, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, diff --git a/p4_symbolic/symbolic/util.cc b/p4_symbolic/symbolic/util.cc index 163e1060..a0d7adf2 100644 --- a/p4_symbolic/symbolic/util.cc +++ b/p4_symbolic/symbolic/util.cc @@ -21,7 +21,7 @@ #include "absl/strings/str_format.h" #include "p4_pdpi/utils/ir.h" #include "p4_symbolic/symbolic/operators.h" -#include "p4_symbolic/symbolic/packet.h" +#include "p4_symbolic/z3_util.h" namespace p4_symbolic { namespace symbolic { @@ -40,12 +40,12 @@ bool Z3BooltoBool(Z3_lbool z3_bool) { } // namespace -absl::StatusOr> FreeSymbolicHeaders( +absl::StatusOr> FreeSymbolicHeaders( const google::protobuf::Map &headers) { // Loop over every header instance in the p4 program. // Find its type, and loop over every field in it, creating a symbolic free // variable for every field in every header instance. - std::map symbolic_headers; + absl::btree_map symbolic_headers; for (const auto &[header_name, header_type] : headers) { // Special validity field. std::string valid_field_name = absl::StrFormat("%s.$valid$", header_name); @@ -88,12 +88,6 @@ absl::StatusOr ExtractFromModel( std::string ingress_port = model.eval(context.ingress_port, true).to_string(); std::string egress_port = model.eval(context.egress_port, true).to_string(); - // Extract an input packet and its predicted output. - ConcretePacket ingress_packet = - packet::ExtractConcretePacket(context.ingress_packet, model); - ConcretePacket egress_packet = - packet::ExtractConcretePacket(context.egress_packet, model); - // Extract the ingress and egress headers. ConcretePerPacketState ingress_headers; for (const auto &[name, expr] : context.ingress_headers) { @@ -109,20 +103,20 @@ absl::StatusOr ExtractFromModel( } // Extract the trace (matches on every table). - bool dropped = - Z3BooltoBool(model.eval(context.trace.dropped, true).bool_value()); - std::map matched_entries; + ASSIGN_OR_RETURN(bool dropped, EvalZ3Bool(context.trace.dropped, model)); + absl::btree_map matched_entries; for (const auto &[table, match] : context.trace.matched_entries) { - matched_entries[table] = { - Z3BooltoBool(model.eval(match.matched, true).bool_value()), - model.eval(match.entry_index, true).get_numeral_int()}; + ASSIGN_OR_RETURN(bool matched, EvalZ3Bool(match.matched, model)); + ASSIGN_OR_RETURN(int entry_index, EvalZ3Int(match.entry_index, model)); + matched_entries[table] = ConcreteTableMatch{ + .matched = matched, + .entry_index = entry_index, + }; } return ConcreteContext{ .ingress_port = ingress_port, .egress_port = egress_port, - .ingress_packet = ingress_packet, - .egress_packet = egress_packet, .ingress_headers = ingress_headers, .egress_headers = egress_headers, .trace = @@ -133,49 +127,47 @@ absl::StatusOr ExtractFromModel( }; } -absl::StatusOr MergeTracesOnCondition( - const z3::expr &condition, const SymbolicTrace &true_trace, - const SymbolicTrace &false_trace) { - ASSIGN_OR_RETURN( - z3::expr merged_dropped, - operators::Ite(condition, true_trace.dropped, false_trace.dropped)); - - // The merged trace is initially empty. - SymbolicTrace merged = {{}, merged_dropped}; +absl::StatusOr MergeMatchesOnCondition( + const z3::expr &condition, const SymbolicTableMatches &true_matches, + const SymbolicTableMatches &false_matches) { + SymbolicTableMatches merged; // Merge all tables matches in true_trace (including ones in both traces). - for (const auto &[name, true_match] : true_trace.matched_entries) { + for (const auto &[name, true_match] : true_matches) { // Find match in other trace (or use default). - SymbolicTableMatch false_match = DefaultTableMatch(); - if (false_trace.matched_entries.count(name) > 0) { - false_match = false_trace.matched_entries.at(name); - } + SymbolicTableMatch false_match = false_matches.contains(name) + ? false_matches.at(name) + : DefaultTableMatch(); // Merge this match. ASSIGN_OR_RETURN( z3::expr matched, operators::Ite(condition, true_match.matched, false_match.matched)); - ASSIGN_OR_RETURN(z3::expr index, + ASSIGN_OR_RETURN(z3::expr entry_index, operators::Ite(condition, true_match.entry_index, false_match.entry_index)); - merged.matched_entries.insert({name, {matched, index}}); + merged.insert({name, SymbolicTableMatch{ + .matched = matched, + .entry_index = entry_index, + }}); } - // Merge all tables matches in false_trace only. - for (const auto &[name, false_match] : false_trace.matched_entries) { + // Merge all tables matches in false_matches only. + for (const auto &[name, false_match] : false_matches) { + if (true_matches.contains(name)) continue; // Already covered. SymbolicTableMatch true_match = DefaultTableMatch(); - if (true_trace.matched_entries.count(name) > 0) { - continue; // Already covered. - } // Merge this match. ASSIGN_OR_RETURN( z3::expr matched, operators::Ite(condition, true_match.matched, false_match.matched)); - ASSIGN_OR_RETURN(z3::expr index, + ASSIGN_OR_RETURN(z3::expr entry_index, operators::Ite(condition, true_match.entry_index, false_match.entry_index)); - merged.matched_entries.insert({name, {matched, index}}); + merged.insert({name, SymbolicTableMatch{ + .matched = matched, + .entry_index = entry_index, + }}); } return merged; diff --git a/p4_symbolic/symbolic/util.h b/p4_symbolic/symbolic/util.h index 754dec31..87a932cb 100644 --- a/p4_symbolic/symbolic/util.h +++ b/p4_symbolic/symbolic/util.h @@ -34,7 +34,7 @@ namespace util { // Free (unconstrained) symbolic headers consisting of free symbolic variables // for every field in every header instance defined in the P4 program. -absl::StatusOr> FreeSymbolicHeaders( +absl::StatusOr> FreeSymbolicHeaders( const google::protobuf::Map &headers); // Returns an symbolic table match containing default values. @@ -48,13 +48,13 @@ absl::StatusOr ExtractFromModel( SymbolicContext context, z3::model model, const values::P4RuntimeTranslator &translator); -// Merges two symbolic traces into a single trace. A field in the new trace -// has the value of the changed trace if the condition is true, and the value -// of the original one otherwise. -// Assertion: both traces must contain matches for the same set of table names. -absl::StatusOr MergeTracesOnCondition( - const z3::expr &condition, const SymbolicTrace &true_trace, - const SymbolicTrace &false_trace); +// Merges two maps of table matches into a single map. A field in the returned +// map has the value of `true_matches` if the condition is true, and the +// value of `false_matches` otherwise. Assertion: both maps must contain +// matches for the same set of table names. +absl::StatusOr MergeMatchesOnCondition( + const z3::expr &condition, const SymbolicTableMatches &true_matches, + const SymbolicTableMatches &false_matches); } // namespace util } // namespace symbolic diff --git a/p4_symbolic/symbolic/values.cc b/p4_symbolic/symbolic/values.cc index c795bbeb..8dfbfe3c 100644 --- a/p4_symbolic/symbolic/values.cc +++ b/p4_symbolic/symbolic/values.cc @@ -37,6 +37,7 @@ #include "p4_pdpi/utils/ir.h" #include "p4_symbolic/symbolic/operators.h" #include "p4_symbolic/symbolic/symbolic.h" +#include "p4_symbolic/z3_util.h" namespace p4_symbolic { namespace symbolic { @@ -96,19 +97,9 @@ uint64_t StringToInt(std::string value) { return std::stoull(binary); } -z3::expr HexStringToZ3Expr(const std::string &hex_string, - absl::optional bitwidth = absl::nullopt) { - mpz_class integer = mpz_class(hex_string, /*base=*/0); - std::string decimal = integer.get_str(/*base=*/10); - if (!bitwidth.has_value()) { - bitwidth = integer.get_str(/*base=*/2).size(); - } - return Z3Context().bv_val(decimal.c_str(), *bitwidth); -} - } // namespace -absl::StatusOr ParseIrValue(std::string value) { +absl::StatusOr ParseIrValue(const std::string &value) { // Format according to type. if (absl::StartsWith(value, "0x")) { return pdpi::FormattedStringToIrValue(value, pdpi::Format::HEX_STRING); @@ -122,21 +113,21 @@ absl::StatusOr ParseIrValue(std::string value) { absl::StatusOr FormatBmv2Value(const pdpi::IrValue &value) { switch (value.format_case()) { case pdpi::IrValue::kHexStr: - return HexStringToZ3Expr(value.hex_str()); + return HexStringToZ3Bitvector(value.hex_str()); case pdpi::IrValue::kIpv4: { ASSIGN_OR_RETURN(netaddr::Ipv4Address ipv4, netaddr::Ipv4Address::OfString(value.ipv4())); - return HexStringToZ3Expr(ipv4.ToHexString(), 32); + return HexStringToZ3Bitvector(ipv4.ToHexString(), 32); } case pdpi::IrValue::kIpv6: { ASSIGN_OR_RETURN(netaddr::Ipv6Address ipv6, netaddr::Ipv6Address::OfString(value.ipv6())); - return HexStringToZ3Expr(ipv6.ToHexString(), 128); + return HexStringToZ3Bitvector(ipv6.ToHexString(), 128); } case pdpi::IrValue::kMac: { ASSIGN_OR_RETURN(netaddr::MacAddress mac, netaddr::MacAddress::OfString(value.mac())); - return HexStringToZ3Expr(mac.ToHexString(), 48); + return HexStringToZ3Bitvector(mac.ToHexString(), 48); } default: return absl::UnimplementedError( diff --git a/p4_symbolic/symbolic/values.h b/p4_symbolic/symbolic/values.h index 43557cad..4e7d78bb 100644 --- a/p4_symbolic/symbolic/values.h +++ b/p4_symbolic/symbolic/values.h @@ -79,7 +79,7 @@ struct P4RuntimeTranslator { }; // Transforms a hex string literal from bmv2 json to a pdpi::IrValue -absl::StatusOr ParseIrValue(std::string value); +absl::StatusOr ParseIrValue(const std::string &value); // Transforms a value read from bmv2 (e.g. hardcoded in the program) // to a z3::expr. diff --git a/p4_symbolic/z3_util.cc b/p4_symbolic/z3_util.cc new file mode 100644 index 00000000..b290e893 --- /dev/null +++ b/p4_symbolic/z3_util.cc @@ -0,0 +1,50 @@ +#include "p4_symbolic/z3_util.h" + +#include "absl/status/statusor.h" +#include "gmpxx.h" +#include "gutil/status.h" +#include "p4_pdpi/string_encodings/hex_string.h" +#include "z3++.h" + +namespace p4_symbolic { + +z3::context& Z3Context() { + static z3::context* z3_context = new z3::context(); + return *z3_context; +} + +absl::StatusOr EvalZ3Bool(const z3::expr& bool_expr, + const z3::model& model) { + // TODO: Ensure this doesn't crash by checking sort first. + auto value = model.eval(bool_expr, true).bool_value(); + switch (value) { + case Z3_L_FALSE: + return false; + case Z3_L_TRUE: + return true; + default: + break; + } + return gutil::InternalErrorBuilder() + << "boolean expression '" << bool_expr + << "' evaluated to unexpected Boolean value " << value; +} + +absl::StatusOr EvalZ3Int(const z3::expr& int_expr, + const z3::model& model) { + // TODO: Ensure this doesn't crash by checking sort first. + return model.eval(int_expr, true).get_numeral_int(); +} + +absl::StatusOr HexStringToZ3Bitvector(const std::string& hex_string, + absl::optional bitwidth) { + // TODO: Insert check to ensure this won't throw an exception. + mpz_class integer = mpz_class(hex_string, /*base=*/0); + std::string decimal = integer.get_str(/*base=*/10); + if (!bitwidth.has_value()) { + bitwidth = integer.get_str(/*base=*/2).size(); + } + return Z3Context().bv_val(decimal.c_str(), *bitwidth); +} + +} // namespace p4_symbolic diff --git a/p4_symbolic/z3_util.h b/p4_symbolic/z3_util.h new file mode 100644 index 00000000..f993babc --- /dev/null +++ b/p4_symbolic/z3_util.h @@ -0,0 +1,62 @@ +#ifndef PINS_P4_SYMBOLIC_Z3_UTIL_H_ +#define PINS_P4_SYMBOLIC_Z3_UTIL_H_ + +#include + +#include "absl/status/statusor.h" +#include "absl/strings/strip.h" +#include "gutil/status.h" +#include "p4_pdpi/string_encodings/hex_string.h" +#include "z3++.h" + +namespace p4_symbolic { + +// Global z3::context used for creating symbolic expressions during symbolic +// evaluation. +z3::context& Z3Context(); + +// -- Evaluation --------------------------------------------------------------- + +absl::StatusOr EvalZ3Bool(const z3::expr& bool_expr, + const z3::model& model); + +absl::StatusOr EvalZ3Int(const z3::expr& int_expr, const z3::model& model); + +template +absl::StatusOr> EvalZ3Bitvector(const z3::expr& bv_expr, + const z3::model& model); + +// -- Constructing Z3 expressions ---------------------------------------------- + +// Returns Z3 bitvector of the given `hex_string` value. +// If no bitwidth is +absl::StatusOr HexStringToZ3Bitvector( + const std::string& hex_string, + absl::optional bitwidth = absl::nullopt); + +// == END OF PUBLIC INTERFACE ================================================== + +template +absl::StatusOr> EvalZ3Bitvector(const z3::expr& bv_expr, + const z3::model& model) { + if (!bv_expr.is_bv() || bv_expr.get_sort().bv_size() != num_bits) { + return gutil::InvalidArgumentErrorBuilder() + << "expected bitvector of " << num_bits << " bits, but got " + << bv_expr.get_sort() << ": " << bv_expr; + } + + std::string value_with_prefix = model.eval(bv_expr, true).to_string(); + absl::string_view value = value_with_prefix; + if (absl::ConsumePrefix(&value, "#x")) { + return pdpi::HexStringToBitset(absl::StrCat("0x", value)); + } + if (absl::ConsumePrefix(&value, "#b")) { + return std::bitset(std::string(value)); + } + return gutil::InvalidArgumentErrorBuilder() + << "invalid Z3 bitvector value '" << value_with_prefix << "'"; +} + +} // namespace p4_symbolic + +#endif // PINS_P4_SYMBOLIC_Z3_UTIL_H_ From 20a40a928542f40118ad51ec96289bd44c54b873 Mon Sep 17 00:00:00 2001 From: smolkaj Date: Fri, 14 May 2021 18:36:19 -0700 Subject: [PATCH 04/10] [p4-symbolic] Simplify code, paying tech debt introduced in previous change. PiperOrigin-RevId: 373903553 --- p4_symbolic/symbolic/control.cc | 28 +- p4_symbolic/symbolic/expected/basic.smt2 | 452 +++++++++---------- p4_symbolic/symbolic/expected/hardcoded.smt2 | 71 ++- p4_symbolic/symbolic/expected/reflector.smt2 | 18 +- p4_symbolic/symbolic/expected/table.smt2 | 134 +++--- 5 files changed, 344 insertions(+), 359 deletions(-) diff --git a/p4_symbolic/symbolic/control.cc b/p4_symbolic/symbolic/control.cc index c320f985..576940e2 100644 --- a/p4_symbolic/symbolic/control.cc +++ b/p4_symbolic/symbolic/control.cc @@ -36,22 +36,18 @@ namespace p4_symbolic::symbolic::control { absl::StatusOr EvaluateV1model( const Dataplane &data_plane, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator) { - SymbolicTableMatches matches; - - std::vector v1model_pipelines = {"ingress", "egress"}; - for (const auto &pipeline : v1model_pipelines) { - // TODO: The conditional here is not needed, but without it there - // will be a lot of changes to the SMT golden files, making this CL hard to - // review. I am removing this comment and the coniditional in a separate CL. - ASSIGN_OR_RETURN(z3::expr dropped, pipeline == "ingress" - ? Z3Context().bool_val(false) - : IsDropped(*state)); - ASSIGN_OR_RETURN(SymbolicTableMatches additional_matches, - EvaluatePipeline(data_plane, pipeline, state, translator, - /*guard=*/!dropped)); - matches.merge(std::move(additional_matches)); - } - + // TODO: This is a simplification that omits a lot of features, e.g. + // cloning, digests, resubmit, and multicast. The full semantics we should + // implement is documented here: + // https://github.com/p4lang/behavioral-model/blob/main/docs/simple_switch.md#pseudocode-for-what-happens-at-the-end-of-ingress-and-egress-processing + ASSIGN_OR_RETURN(SymbolicTableMatches matches, + EvaluatePipeline(data_plane, "ingress", state, translator, + /*guard=*/Z3Context().bool_val(true))); + ASSIGN_OR_RETURN(z3::expr dropped, IsDropped(*state)); + ASSIGN_OR_RETURN(SymbolicTableMatches egress_matches, + EvaluatePipeline(data_plane, "egress", state, translator, + /*guard=*/!dropped)); + matches.merge(std::move(egress_matches)); return matches; } diff --git a/p4_symbolic/symbolic/expected/basic.smt2 b/p4_symbolic/symbolic/expected/basic.smt2 index 8e1f00cf..7bb25971 100644 --- a/p4_symbolic/symbolic/expected/basic.smt2 +++ b/p4_symbolic/symbolic/expected/basic.smt2 @@ -5,53 +5,53 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) + (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) (assert - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let (($x75 (and $x43 $x74))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let (($x61 (and $x43 $x47))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x42 (and true ipv4.$valid$))) + (let (($x74 (and $x42 $x73))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let (($x60 (and $x42 $x46))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) - (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x61 (and $x43 $x47))) - (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) - (let (($x131 (ite ipv4.$valid$ $x43 false))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x75 (and $x43 (and $x70 (not $x60))))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (and (and (not $x42) $x131) (= ?x132 (- 1)))))))))))))))))))))))))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x42 (and true ipv4.$valid$))) + (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x60 (and $x42 $x46))) + (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) + (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x42 (and $x69 (not $x59))))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (and (and (not $x41) $x130) (= ?x131 (- 1)))))))))))))))))))))))))) (check-sat) ; @@ -61,54 +61,54 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) + (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) (assert - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let (($x75 (and $x43 $x74))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let (($x61 (and $x43 $x47))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x42 (and true ipv4.$valid$))) + (let (($x74 (and $x42 $x73))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let (($x60 (and $x42 $x46))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) - (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x61 (and $x43 $x47))) - (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) - (let (($x131 (ite ipv4.$valid$ $x43 false))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x75 (and $x43 (and $x70 (not $x60))))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (let (($x256 (and (not $x42) $x131))) - (and $x256 (= ?x132 0)))))))))))))))))))))))))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x42 (and true ipv4.$valid$))) + (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x60 (and $x42 $x46))) + (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) + (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x42 (and $x69 (not $x59))))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (let (($x255 (and (not $x41) $x130))) + (and $x255 (= ?x131 0)))))))))))))))))))))))))) (check-sat) ; @@ -118,53 +118,53 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) + (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) (assert - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let (($x75 (and $x43 $x74))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let (($x61 (and $x43 $x47))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x42 (and true ipv4.$valid$))) + (let (($x74 (and $x42 $x73))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let (($x60 (and $x42 $x46))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) - (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x61 (and $x43 $x47))) - (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) - (let (($x131 (ite ipv4.$valid$ $x43 false))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x75 (and $x43 (and $x70 (not $x60))))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (and (and (not $x42) $x131) (= ?x132 1))))))))))))))))))))))))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x42 (and true ipv4.$valid$))) + (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x60 (and $x42 $x46))) + (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) + (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x42 (and $x69 (not $x59))))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (and (and (not $x41) $x130) (= ?x131 1))))))))))))))))))))))))) (check-sat) ; @@ -174,53 +174,53 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) + (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) (assert - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let (($x75 (and $x43 $x74))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let (($x61 (and $x43 $x47))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x42 (and true ipv4.$valid$))) + (let (($x74 (and $x42 $x73))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let (($x60 (and $x42 $x46))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) - (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x61 (and $x43 $x47))) - (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) - (let (($x131 (ite ipv4.$valid$ $x43 false))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x75 (and $x43 (and $x70 (not $x60))))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (and (and (not $x42) $x131) (= ?x132 2))))))))))))))))))))))))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x42 (and true ipv4.$valid$))) + (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x60 (and $x42 $x46))) + (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) + (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x42 (and $x69 (not $x59))))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (and (and (not $x41) $x130) (= ?x131 2))))))))))))))))))))))))) (check-sat) ; @@ -230,52 +230,52 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x138 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x138)))) + (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) (assert - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x70 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let (($x75 (and $x43 $x74))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let (($x61 (and $x43 $x47))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (or $x42 (or (or false (= ?x125 (_ bv0 9))) (= ?x125 (_ bv1 9)))))))))))))))))))))))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) + (let (($x42 (and true ipv4.$valid$))) + (let (($x74 (and $x42 $x73))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let (($x60 (and $x42 $x46))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) (assert - (let (($x60 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) - (let (($x43 (and (not false) ipv4.$valid$))) - (let ((?x101 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x43 $x60) 2 (- 1))))) - (let ((?x113 (ite (and $x43 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x101))) - (let (($x46 (= ipv4.dstAddr (_ bv168427520 32)))) - (let (($x47 (and true $x46))) - (let (($x61 (and $x43 $x47))) - (let ((?x132 (ite ipv4.$valid$ (ite $x61 1 ?x113) (- 1)))) - (let (($x131 (ite ipv4.$valid$ $x43 false))) - (let (($x62 (not $x47))) - (let (($x66 (and $x62 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) - (let (($x70 (and $x66 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x75 (and $x43 (and $x70 (not $x60))))) - (let ((?x89 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x72 (and (and $x43 $x70) $x60))) - (let (($x55 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) - (let (($x68 (and (and $x43 $x66) $x55))) - (let ((?x103 (ite $x68 ?x89 (ite $x72 ?x89 (ite $x75 (_ bv511 9) standard_metadata.egress_spec))))) - (let (($x51 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) - (let (($x64 (and (and $x43 $x62) $x51))) - (let ((?x125 (ite $x61 ?x89 (ite $x64 (concat (_ bv0 8) (_ bv0 1)) ?x103)))) - (let (($x42 (= ?x125 (_ bv511 9)))) - (and (and (not $x42) $x131) (= ?x132 3))))))))))))))))))))))))) + (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) + (let (($x42 (and true ipv4.$valid$))) + (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) + (let (($x46 (and true $x45))) + (let (($x60 (and $x42 $x46))) + (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) + (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let (($x61 (not $x46))) + (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) + (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) + (let (($x74 (and $x42 (and $x69 (not $x59))))) + (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x71 (and (and $x42 $x69) $x59))) + (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) + (let (($x67 (and (and $x42 $x65) $x54))) + (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) + (let (($x63 (and (and $x42 $x61) $x50))) + (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) + (let (($x41 (= ?x124 (_ bv511 9)))) + (and (and (not $x41) $x130) (= ?x131 3))))))))))))))))))))))))) (check-sat) diff --git a/p4_symbolic/symbolic/expected/hardcoded.smt2 b/p4_symbolic/symbolic/expected/hardcoded.smt2 index aac8f501..9b7c35f0 100644 --- a/p4_symbolic/symbolic/expected/hardcoded.smt2 +++ b/p4_symbolic/symbolic/expected/hardcoded.smt2 @@ -3,27 +3,25 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x47 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x47)))) + (let (($x46 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x46)))) (assert - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x28 (= standard_metadata.ingress_port ?x27))) - (let (($x24 (not false))) - (let (($x30 (and $x24 $x28))) - (let (($x31 (and $x24 (not $x28)))) - (let ((?x36 (ite $x31 ?x27 (ite $x30 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (let (($x40 (= ?x36 (_ bv511 9)))) - (or $x40 (or (or false (= ?x36 (_ bv0 9))) (= ?x36 (_ bv1 9)))))))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x27 (= standard_metadata.ingress_port ?x26))) + (let (($x29 (and true $x27))) + (let (($x30 (and true (not $x27)))) + (let ((?x35 (ite $x30 ?x26 (ite $x29 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x39 (= ?x35 (_ bv511 9)))) + (or $x39 (or (or false (= ?x35 (_ bv0 9))) (= ?x35 (_ bv1 9))))))))))) (assert - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x28 (= standard_metadata.ingress_port ?x27))) - (let (($x24 (not false))) - (let (($x30 (and $x24 $x28))) - (let (($x37 (ite $x28 $x30 false))) - (let (($x31 (and $x24 (not $x28)))) - (let ((?x36 (ite $x31 ?x27 (ite $x30 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (let (($x40 (= ?x36 (_ bv511 9)))) - (and (and (not $x40) $x37) (= (- 1) (- 1)))))))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x27 (= standard_metadata.ingress_port ?x26))) + (let (($x29 (and true $x27))) + (let (($x36 (ite $x27 $x29 false))) + (let (($x30 (and true (not $x27)))) + (let ((?x35 (ite $x30 ?x26 (ite $x29 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x39 (= ?x35 (_ bv511 9)))) + (and (and (not $x39) $x36) (= (- 1) (- 1))))))))))) (check-sat) ; @@ -31,25 +29,24 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x47 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x47)))) + (let (($x46 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x46)))) (assert - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x28 (= standard_metadata.ingress_port ?x27))) - (let (($x24 (not false))) - (let (($x30 (and $x24 $x28))) - (let (($x31 (and $x24 (not $x28)))) - (let ((?x36 (ite $x31 ?x27 (ite $x30 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (let (($x40 (= ?x36 (_ bv511 9)))) - (or $x40 (or (or false (= ?x36 (_ bv0 9))) (= ?x36 (_ bv1 9)))))))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x27 (= standard_metadata.ingress_port ?x26))) + (let (($x29 (and true $x27))) + (let (($x30 (and true (not $x27)))) + (let ((?x35 (ite $x30 ?x26 (ite $x29 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x39 (= ?x35 (_ bv511 9)))) + (or $x39 (or (or false (= ?x35 (_ bv0 9))) (= ?x35 (_ bv1 9))))))))))) (assert - (let (($x24 (not false))) - (let (($x31 (and $x24 (not (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1))))))) - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x28 (= standard_metadata.ingress_port ?x27))) - (let (($x38 (ite $x28 false $x31))) - (let ((?x36 (ite $x31 ?x27 (ite (and $x24 $x28) (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) - (let (($x40 (= ?x36 (_ bv511 9)))) - (and (and (not $x40) $x38) (= (- 1) (- 1))))))))))) + (let (($x30 (and true (not (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x27 (= standard_metadata.ingress_port ?x26))) + (let (($x37 (ite $x27 false $x30))) + (let (($x29 (and true $x27))) + (let ((?x35 (ite $x30 ?x26 (ite $x29 (concat (_ bv0 8) (_ bv1 1)) standard_metadata.egress_spec)))) + (let (($x39 (= ?x35 (_ bv511 9)))) + (and (and (not $x39) $x37) (= (- 1) (- 1))))))))))) (check-sat) diff --git a/p4_symbolic/symbolic/expected/reflector.smt2 b/p4_symbolic/symbolic/expected/reflector.smt2 index f554d766..a563443c 100644 --- a/p4_symbolic/symbolic/expected/reflector.smt2 +++ b/p4_symbolic/symbolic/expected/reflector.smt2 @@ -3,17 +3,15 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x35 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x35)))) + (let (($x34 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x34)))) (assert - (let (($x24 (not false))) - (let ((?x26 (ite $x24 standard_metadata.ingress_port standard_metadata.egress_spec))) - (let (($x28 (= ?x26 (_ bv511 9)))) - (or $x28 (or (or false (= ?x26 (_ bv0 9))) (= ?x26 (_ bv1 9)))))))) + (let ((?x25 (ite true standard_metadata.ingress_port standard_metadata.egress_spec))) + (let (($x27 (= ?x25 (_ bv511 9)))) + (or $x27 (or (or false (= ?x25 (_ bv0 9))) (= ?x25 (_ bv1 9))))))) (assert - (let (($x24 (not false))) - (let ((?x26 (ite $x24 standard_metadata.ingress_port standard_metadata.egress_spec))) - (let (($x28 (= ?x26 (_ bv511 9)))) - (and (and (not $x28) $x24) (= (- 1) (- 1))))))) + (let ((?x25 (ite true standard_metadata.ingress_port standard_metadata.egress_spec))) + (let (($x27 (= ?x25 (_ bv511 9)))) + (and (and (not $x27) true) (= (- 1) (- 1)))))) (check-sat) diff --git a/p4_symbolic/symbolic/expected/table.smt2 b/p4_symbolic/symbolic/expected/table.smt2 index 28ce7728..a778b36b 100644 --- a/p4_symbolic/symbolic/expected/table.smt2 +++ b/p4_symbolic/symbolic/expected/table.smt2 @@ -3,31 +3,29 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x54 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x54)))) + (let (($x53 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x53)))) (assert - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x24 (not false))) - (let (($x37 (and (and $x24 (not (and true (= standard_metadata.ingress_port ?x27)))) $x33))) - (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x29 (and true (= standard_metadata.ingress_port ?x27)))) - (let (($x34 (and $x24 $x29))) - (let ((?x48 (ite $x34 ?x31 (ite $x37 ?x27 standard_metadata.egress_spec)))) - (let (($x39 (= ?x48 (_ bv511 9)))) - (or $x39 (or (or false (= ?x48 (_ bv0 9))) (= ?x48 (_ bv1 9)))))))))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x35 (and true (not (and true (= standard_metadata.ingress_port ?x26)))))) + (let ((?x30 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x28 (and true (= standard_metadata.ingress_port ?x26)))) + (let (($x33 (and true $x28))) + (let ((?x47 (ite $x33 ?x30 (ite (and $x35 $x32) ?x26 standard_metadata.egress_spec)))) + (let (($x38 (= ?x47 (_ bv511 9)))) + (or $x38 (or (or false (= ?x47 (_ bv0 9))) (= ?x47 (_ bv1 9))))))))))))) (assert - (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x24 (not false))) - (let (($x29 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) - (let (($x34 (and $x24 $x29))) - (let ((?x47 (ite $x34 0 (ite (and $x24 $x33) 1 (- 1))))) - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let ((?x45 (ite (and (and $x24 (not $x29)) $x33) ?x27 standard_metadata.egress_spec))) - (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) - (let ((?x48 (ite $x34 ?x31 ?x45))) - (let (($x39 (= ?x48 (_ bv511 9)))) - (and (and (not $x39) $x24) (= ?x47 (- 1)))))))))))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x28 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x33 (and true $x28))) + (let ((?x46 (ite $x33 0 (ite (and true $x32) 1 (- 1))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x44 (ite (and (and true (not $x28)) $x32) ?x26 standard_metadata.egress_spec))) + (let ((?x30 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x47 (ite $x33 ?x30 ?x44))) + (let (($x38 (= ?x47 (_ bv511 9)))) + (and (and (not $x38) true) (= ?x46 (- 1))))))))))))) (check-sat) ; @@ -35,32 +33,30 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x54 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x54)))) + (let (($x53 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x53)))) (assert - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x24 (not false))) - (let (($x37 (and (and $x24 (not (and true (= standard_metadata.ingress_port ?x27)))) $x33))) - (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x29 (and true (= standard_metadata.ingress_port ?x27)))) - (let (($x34 (and $x24 $x29))) - (let ((?x48 (ite $x34 ?x31 (ite $x37 ?x27 standard_metadata.egress_spec)))) - (let (($x39 (= ?x48 (_ bv511 9)))) - (or $x39 (or (or false (= ?x48 (_ bv0 9))) (= ?x48 (_ bv1 9)))))))))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x35 (and true (not (and true (= standard_metadata.ingress_port ?x26)))))) + (let ((?x30 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x28 (and true (= standard_metadata.ingress_port ?x26)))) + (let (($x33 (and true $x28))) + (let ((?x47 (ite $x33 ?x30 (ite (and $x35 $x32) ?x26 standard_metadata.egress_spec)))) + (let (($x38 (= ?x47 (_ bv511 9)))) + (or $x38 (or (or false (= ?x47 (_ bv0 9))) (= ?x47 (_ bv1 9))))))))))))) (assert - (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x24 (not false))) - (let (($x29 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) - (let (($x34 (and $x24 $x29))) - (let ((?x47 (ite $x34 0 (ite (and $x24 $x33) 1 (- 1))))) - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let ((?x45 (ite (and (and $x24 (not $x29)) $x33) ?x27 standard_metadata.egress_spec))) - (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) - (let ((?x48 (ite $x34 ?x31 ?x45))) - (let (($x39 (= ?x48 (_ bv511 9)))) - (let (($x117 (and (not $x39) $x24))) - (and $x117 (= ?x47 0)))))))))))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x28 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x33 (and true $x28))) + (let ((?x46 (ite $x33 0 (ite (and true $x32) 1 (- 1))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x44 (ite (and (and true (not $x28)) $x32) ?x26 standard_metadata.egress_spec))) + (let ((?x30 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x47 (ite $x33 ?x30 ?x44))) + (let (($x38 (= ?x47 (_ bv511 9)))) + (let (($x116 (and (not $x38) true))) + (and $x116 (= ?x46 0))))))))))))) (check-sat) ; @@ -68,30 +64,28 @@ (declare-fun standard_metadata.ingress_port () (_ BitVec 9)) (declare-fun standard_metadata.egress_spec () (_ BitVec 9)) (assert - (let (($x54 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x54)))) + (let (($x53 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x53)))) (assert - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x24 (not false))) - (let (($x37 (and (and $x24 (not (and true (= standard_metadata.ingress_port ?x27)))) $x33))) - (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) - (let (($x29 (and true (= standard_metadata.ingress_port ?x27)))) - (let (($x34 (and $x24 $x29))) - (let ((?x48 (ite $x34 ?x31 (ite $x37 ?x27 standard_metadata.egress_spec)))) - (let (($x39 (= ?x48 (_ bv511 9)))) - (or $x39 (or (or false (= ?x48 (_ bv0 9))) (= ?x48 (_ bv1 9)))))))))))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x35 (and true (not (and true (= standard_metadata.ingress_port ?x26)))))) + (let ((?x30 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x28 (and true (= standard_metadata.ingress_port ?x26)))) + (let (($x33 (and true $x28))) + (let ((?x47 (ite $x33 ?x30 (ite (and $x35 $x32) ?x26 standard_metadata.egress_spec)))) + (let (($x38 (= ?x47 (_ bv511 9)))) + (or $x38 (or (or false (= ?x47 (_ bv0 9))) (= ?x47 (_ bv1 9))))))))))))) (assert - (let (($x33 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) - (let (($x24 (not false))) - (let (($x29 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) - (let (($x34 (and $x24 $x29))) - (let ((?x47 (ite $x34 0 (ite (and $x24 $x33) 1 (- 1))))) - (let ((?x27 (concat (_ bv0 8) (_ bv0 1)))) - (let ((?x45 (ite (and (and $x24 (not $x29)) $x33) ?x27 standard_metadata.egress_spec))) - (let ((?x31 (concat (_ bv0 8) (_ bv1 1)))) - (let ((?x48 (ite $x34 ?x31 ?x45))) - (let (($x39 (= ?x48 (_ bv511 9)))) - (and (and (not $x39) $x24) (= ?x47 1))))))))))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x28 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x33 (and true $x28))) + (let ((?x46 (ite $x33 0 (ite (and true $x32) 1 (- 1))))) + (let ((?x26 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x44 (ite (and (and true (not $x28)) $x32) ?x26 standard_metadata.egress_spec))) + (let ((?x30 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x47 (ite $x33 ?x30 ?x44))) + (let (($x38 (= ?x47 (_ bv511 9)))) + (and (and (not $x38) true) (= ?x46 1)))))))))))) (check-sat) From c079897b6d52bb2b8fb5a684567f4fb4ff082faa Mon Sep 17 00:00:00 2001 From: smolkaj Date: Mon, 29 Mar 2021 11:42:55 -0700 Subject: [PATCH 05/10] [pins-infra] Update pins_infra_deps.bzl with some best practices, and apply them. --- install_dependencies.sh | 32 ++++++++++++++++------ p4_symbolic/tests/sai_p4_component_test.cc | 4 +-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/install_dependencies.sh b/install_dependencies.sh index 7e8a8657..907aba7a 100755 --- a/install_dependencies.sh +++ b/install_dependencies.sh @@ -1,17 +1,31 @@ #!/bin/bash # Copyright 2021 Google LLC # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at +# Please read carefully before adding new dependencies: +# +# System dependencies are disallowed by default, and the bar for exceptions is +# high. +# +# pins-infra strives for a hermetic build, i.e. one that is insensitive to the +# libraries and other software installed on your machine, other than Bazel and +# the compilers. This ensure the build is reproducible and portable. +# +# Before adding a new system dependency, consider the following: # -# http://www.apache.org/licenses/LICENSE-2.0 +# 1. Please read the note on dependencies in pins_infra_deps.bzl. # -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# 2. Can the dependency be avoided altogether? Consider that there is a +# non-trival cost to maintaining dependencies over time. +# +# 3. Can the dependency be built with Bazel instead? +# - For many libraries, there are existing Bazel BUILD files. Try a quick +# Google search. +# - If there is no existing BUILD file, can you write your own BUILD file? +# See the bazel/ folder for examples. Ideally, we strive to upstream such +# BUILD files so everyone can benefit and share the maintenance burden. +# - If it's too hard to write a native BUILD file, try writing a BUILD file +# using rules_foreign_cc (https://github.com/bazelbuild/rules_foreign_cc). +#. See the bazel/ folder for examples. # Please read carefully before adding new dependencies: # diff --git a/p4_symbolic/tests/sai_p4_component_test.cc b/p4_symbolic/tests/sai_p4_component_test.cc index e6cbe62f..14944e0c 100644 --- a/p4_symbolic/tests/sai_p4_component_test.cc +++ b/p4_symbolic/tests/sai_p4_component_test.cc @@ -28,7 +28,7 @@ using ::p4::config::v1::P4Info; using ::testing::Eq; using ::testing::Not; -constexpr absl::string_view kTableEntries = R"PB( +constexpr absl::string_view kTableEntries = R"pb( entries { acl_pre_ingress_table_entry { match { @@ -73,7 +73,7 @@ constexpr absl::string_view kTableEntries = R"PB( action { set_dst_mac { dst_mac: "cc:bb:aa:99:88:77" } } } } -)PB"; +)pb"; class P4SymbolicComponentTest : public testing::Test { public: From 9f047d612b2edfec73d504b91f0bd4626b436d0f Mon Sep 17 00:00:00 2001 From: smolkaj Date: Mon, 10 May 2021 16:21:22 -0700 Subject: [PATCH 06/10] [pins-infra] Fix formatting in preparation for PR #328.Remove (spurious) visibility declarations; make all targets public. --- p4_symbolic/BUILD.bazel | 19 +++-------------- p4_symbolic/bmv2/BUILD.bazel | 7 ------- p4_symbolic/ir/BUILD.bazel | 36 +++++++++++++------------------- p4_symbolic/sai/BUILD.bazel | 11 ++++------ p4_symbolic/symbolic/BUILD.bazel | 5 ----- p4_symbolic/testdata/BUILD.bazel | 6 ------ p4_symbolic/tests/BUILD.bazel | 5 ----- p4_symbolic/util/BUILD.bazel | 6 ------ 8 files changed, 21 insertions(+), 74 deletions(-) diff --git a/p4_symbolic/BUILD.bazel b/p4_symbolic/BUILD.bazel index 753fa143..2fb1ac2d 100644 --- a/p4_symbolic/BUILD.bazel +++ b/p4_symbolic/BUILD.bazel @@ -14,11 +14,6 @@ # This file contains build rules for the main binary of p4_symbolic. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") - package( default_visibility = ["//visibility:public"], licenses = ["notice"], @@ -29,8 +24,6 @@ cc_binary( srcs = [ "main.cc", ], - # linkopts = ["-lz3"], - visibility = ["//p4_symbolic/symbolic:__pkg__"], deps = [ ":parser", "//gutil:status", @@ -49,15 +42,10 @@ cc_binary( cc_library( name = "parser", - srcs = [ - "parser.cc", - ], - hdrs = [ - "parser.h", - ], - visibility = ["//visibility:public"], + srcs = ["parser.cc"], + hdrs = ["parser.h"], deps = [ - "//gutil:proto", + "//gutil:proto", "//gutil:status", "//p4_pdpi:ir_cc_proto", "//p4_symbolic/bmv2", @@ -74,7 +62,6 @@ cc_library( name = "z3_util", srcs = ["z3_util.cc"], hdrs = ["z3_util.h"], - visibility = ["//visibility:public"], deps = [ "//gutil:status", "//p4_pdpi/string_encodings:hex_string", diff --git a/p4_symbolic/bmv2/BUILD.bazel b/p4_symbolic/bmv2/BUILD.bazel index bfe70047..f80130ff 100644 --- a/p4_symbolic/bmv2/BUILD.bazel +++ b/p4_symbolic/bmv2/BUILD.bazel @@ -12,10 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_symbolic/bmv2:test.bzl", "bmv2_protobuf_parsing_test") package( @@ -25,7 +21,6 @@ package( cc_proto_library( name = "bmv2_cc_proto", - visibility = ["//p4_symbolic:__subpackages__"], deps = [":bmv2_proto"], ) @@ -34,7 +29,6 @@ proto_library( srcs = [ "bmv2.proto", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ "@com_google_protobuf//:struct_proto", ], @@ -48,7 +42,6 @@ cc_library( hdrs = [ "bmv2.h", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ ":bmv2_cc_proto", "//gutil:status", diff --git a/p4_symbolic/ir/BUILD.bazel b/p4_symbolic/ir/BUILD.bazel index 26f11de1..be4ec3e5 100644 --- a/p4_symbolic/ir/BUILD.bazel +++ b/p4_symbolic/ir/BUILD.bazel @@ -12,10 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_symbolic/ir:test.bzl", "ir_parsing_test") package( @@ -23,6 +19,20 @@ package( licenses = ["notice"], ) +cc_proto_library( + name = "ir_cc_proto", + deps = [":ir_proto"], +) + +proto_library( + name = "ir_proto", + srcs = ["ir.proto"], + deps = [ + "//p4_pdpi:ir_proto", + "//p4_symbolic/bmv2:bmv2_proto", + ], +) + cc_library( name = "pdpi_driver", srcs = [ @@ -31,7 +41,6 @@ cc_library( hdrs = [ "pdpi_driver.h", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ "//gutil:proto", "//gutil:status", @@ -40,21 +49,6 @@ cc_library( ], ) -cc_proto_library( - name = "ir_cc_proto", - visibility = ["//p4_symbolic:__subpackages__"], - deps = [":ir_proto"], -) - -proto_library( - name = "ir_proto", - srcs = ["ir.proto"], - deps = [ - "//p4_pdpi:ir_proto", - "//p4_symbolic/bmv2:bmv2_proto", - ], -) - cc_library( name = "table_entries", srcs = [ @@ -63,7 +57,6 @@ cc_library( hdrs = [ "table_entries.h", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ ":ir_cc_proto", "//gutil:status", @@ -85,7 +78,6 @@ cc_library( hdrs = [ "ir.h", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ ":ir_cc_proto", ":table_entries", diff --git a/p4_symbolic/sai/BUILD.bazel b/p4_symbolic/sai/BUILD.bazel index 93d15ead..f6bbff33 100644 --- a/p4_symbolic/sai/BUILD.bazel +++ b/p4_symbolic/sai/BUILD.bazel @@ -12,12 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") - -package(licenses = ["notice"]) +package( + default_visibility = ["//visibility:public"], + licenses = ["notice"], +) cc_library( name = "fields", @@ -36,7 +34,6 @@ cc_library( name = "parser", srcs = ["parser.cc"], hdrs = ["parser.h"], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ ":fields", "//gutil:status", diff --git a/p4_symbolic/symbolic/BUILD.bazel b/p4_symbolic/symbolic/BUILD.bazel index 7dbad4ae..ca48e2b2 100644 --- a/p4_symbolic/symbolic/BUILD.bazel +++ b/p4_symbolic/symbolic/BUILD.bazel @@ -12,10 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") load("//p4_symbolic/symbolic:test.bzl", "end_to_end_test") package( @@ -49,7 +45,6 @@ cc_library( "util.h", "values.h", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ "//gutil:status", "//p4_pdpi:ir_cc_proto", diff --git a/p4_symbolic/testdata/BUILD.bazel b/p4_symbolic/testdata/BUILD.bazel index 7ec79468..52e61f67 100644 --- a/p4_symbolic/testdata/BUILD.bazel +++ b/p4_symbolic/testdata/BUILD.bazel @@ -12,11 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") - package(default_visibility = ["//visibility:public"]) # Make sure programs under p4-samples are visible to other @@ -27,5 +22,4 @@ exports_files( "**/*.txt", ]), licenses = ["notice"], - visibility = ["//p4_symbolic:__subpackages__"], ) diff --git a/p4_symbolic/tests/BUILD.bazel b/p4_symbolic/tests/BUILD.bazel index 87daf147..013dcdcc 100644 --- a/p4_symbolic/tests/BUILD.bazel +++ b/p4_symbolic/tests/BUILD.bazel @@ -1,8 +1,3 @@ -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") - package( default_visibility = ["//visibility:public"], licenses = ["notice"], diff --git a/p4_symbolic/util/BUILD.bazel b/p4_symbolic/util/BUILD.bazel index b8070667..d9f9a016 100644 --- a/p4_symbolic/util/BUILD.bazel +++ b/p4_symbolic/util/BUILD.bazel @@ -12,11 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -load("@bazel_skylib//rules:build_test.bzl", "build_test") -load("//p4_pdpi/testing:diff_test.bzl", "cmd_diff_test", "diff_test") -load("//p4_pdpi:pdgen.bzl", "p4_pd_proto") -load("@com_github_p4lang_p4c//:bazel/p4_library.bzl", "p4_library") - package( default_visibility = ["//visibility:public"], licenses = ["notice"], @@ -33,7 +28,6 @@ cc_library( # TODO: clean up. # "status.h", ], - visibility = ["//p4_symbolic:__subpackages__"], deps = [ "//gutil:status", "@com_google_absl//absl/status", From 658a984949d3e3f4eba9cea5d839dd7111f17a7d Mon Sep 17 00:00:00 2001 From: smolkaj Date: Fri, 14 May 2021 18:48:47 -0700 Subject: [PATCH 07/10] [p4-symbolic] Interpret clone as no-op instead of drop and add pseudo field that tracks cloning. PiperOrigin-RevId: 373904870 --- p4_symbolic/symbolic/action.cc | 14 +- p4_symbolic/symbolic/expected/basic.smt2 | 172 +++++++++++------------ p4_symbolic/symbolic/guarded_map.cc | 13 +- p4_symbolic/symbolic/guarded_map.h | 6 +- p4_symbolic/symbolic/symbolic.cc | 6 + p4_symbolic/symbolic/symbolic.h | 14 +- p4_symbolic/symbolic/util.cc | 11 +- 7 files changed, 124 insertions(+), 112 deletions(-) diff --git a/p4_symbolic/symbolic/action.cc b/p4_symbolic/symbolic/action.cc index d253c933..c49aca4d 100644 --- a/p4_symbolic/symbolic/action.cc +++ b/p4_symbolic/symbolic/action.cc @@ -19,6 +19,7 @@ #include "absl/strings/str_format.h" #include "glog/logging.h" #include "p4_symbolic/symbolic/operators.h" +#include "p4_symbolic/symbolic/symbolic.h" #include "p4_symbolic/z3_util.h" namespace p4_symbolic { @@ -33,17 +34,16 @@ absl::Status EvaluateStatement(const ir::Statement &statement, return EvaluateAssignmentStatement(statement.assignment(), state, context, guard); } - case ir::Statement::kClone: // TODO: Add support for cloning. + case ir::Statement::kClone: { + // TODO: Add support for cloning. + return state->Set(std::string(kGotClonedPseudoField), + Z3Context().bool_val(true), guard); + } case ir::Statement::kDrop: { // https://github.com/p4lang/p4c/blob/7ee76d16da63883c5092ab0c28321f04c2646759/p4include/v1model.p4#L435 - const std::string &header_name = - // TODO: conditonal needed to interpret clone as drop. - statement.has_drop() ? statement.drop().header().header_name() - : "standard_metadata"; + const std::string &header_name = statement.drop().header().header_name(); RETURN_IF_ERROR(state->Set(absl::StrFormat("%s.egress_spec", header_name), EgressSpecDroppedValue(), guard)); - RETURN_IF_ERROR(state->Set(absl::StrFormat("%s.mcast_grp", header_name), - Z3Context().bv_val(0, 1), guard)); return absl::OkStatus(); } case ir::Statement::kHash: { diff --git a/p4_symbolic/symbolic/expected/basic.smt2 b/p4_symbolic/symbolic/expected/basic.smt2 index 7bb25971..f21101aa 100644 --- a/p4_symbolic/symbolic/expected/basic.smt2 +++ b/p4_symbolic/symbolic/expected/basic.smt2 @@ -5,8 +5,8 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) + (let (($x134 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x134)))) (assert (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) @@ -15,43 +15,41 @@ (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) (let (($x42 (and true ipv4.$valid$))) - (let (($x74 (and $x42 $x73))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x71 (and (and $x42 $x69) $x59))) + (let ((?x85 (ite $x71 ?x84 (ite (and $x42 $x73) (_ bv511 9) standard_metadata.egress_spec)))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) (let (($x60 (and $x42 $x46))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 ?x85))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (or $x41 (or (or false (= ?x121 (_ bv0 9))) (= ?x121 (_ bv1 9))))))))))))))))))))))) (assert (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x42 (and true ipv4.$valid$))) - (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) - (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let ((?x96 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x108 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x96))) (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) (let (($x60 (and $x42 $x46))) - (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) - (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let ((?x128 (ite ipv4.$valid$ (ite $x60 1 ?x108) (- 1)))) + (let (($x127 (ite ipv4.$valid$ $x42 false))) (let (($x61 (not $x46))) (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x42 (and $x69 (not $x59))))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x77 (ite (and $x42 (and $x69 (not $x59))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x71 (and (and $x42 $x69) $x59))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (and (and (not $x41) $x130) (= ?x131 (- 1)))))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 (ite $x71 ?x84 ?x77)))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (and (and (not $x41) $x127) (= ?x128 (- 1))))))))))))))))))))))))) (check-sat) ; @@ -61,8 +59,8 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) + (let (($x134 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x134)))) (assert (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) @@ -71,44 +69,42 @@ (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) (let (($x42 (and true ipv4.$valid$))) - (let (($x74 (and $x42 $x73))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x71 (and (and $x42 $x69) $x59))) + (let ((?x85 (ite $x71 ?x84 (ite (and $x42 $x73) (_ bv511 9) standard_metadata.egress_spec)))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) (let (($x60 (and $x42 $x46))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 ?x85))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (or $x41 (or (or false (= ?x121 (_ bv0 9))) (= ?x121 (_ bv1 9))))))))))))))))))))))) (assert (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x42 (and true ipv4.$valid$))) - (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) - (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let ((?x96 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x108 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x96))) (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) (let (($x60 (and $x42 $x46))) - (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) - (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let ((?x128 (ite ipv4.$valid$ (ite $x60 1 ?x108) (- 1)))) + (let (($x127 (ite ipv4.$valid$ $x42 false))) (let (($x61 (not $x46))) (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x42 (and $x69 (not $x59))))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x77 (ite (and $x42 (and $x69 (not $x59))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x71 (and (and $x42 $x69) $x59))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (let (($x255 (and (not $x41) $x130))) - (and $x255 (= ?x131 0)))))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 (ite $x71 ?x84 ?x77)))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (let (($x252 (and (not $x41) $x127))) + (and $x252 (= ?x128 0))))))))))))))))))))))))) (check-sat) ; @@ -118,8 +114,8 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) + (let (($x134 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x134)))) (assert (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) @@ -128,43 +124,41 @@ (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) (let (($x42 (and true ipv4.$valid$))) - (let (($x74 (and $x42 $x73))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x71 (and (and $x42 $x69) $x59))) + (let ((?x85 (ite $x71 ?x84 (ite (and $x42 $x73) (_ bv511 9) standard_metadata.egress_spec)))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) (let (($x60 (and $x42 $x46))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 ?x85))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (or $x41 (or (or false (= ?x121 (_ bv0 9))) (= ?x121 (_ bv1 9))))))))))))))))))))))) (assert (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x42 (and true ipv4.$valid$))) - (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) - (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let ((?x96 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x108 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x96))) (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) (let (($x60 (and $x42 $x46))) - (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) - (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let ((?x128 (ite ipv4.$valid$ (ite $x60 1 ?x108) (- 1)))) + (let (($x127 (ite ipv4.$valid$ $x42 false))) (let (($x61 (not $x46))) (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x42 (and $x69 (not $x59))))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x77 (ite (and $x42 (and $x69 (not $x59))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x71 (and (and $x42 $x69) $x59))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (and (and (not $x41) $x130) (= ?x131 1))))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 (ite $x71 ?x84 ?x77)))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (and (and (not $x41) $x127) (= ?x128 1)))))))))))))))))))))))) (check-sat) ; @@ -174,8 +168,8 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) + (let (($x134 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x134)))) (assert (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) @@ -184,43 +178,41 @@ (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) (let (($x42 (and true ipv4.$valid$))) - (let (($x74 (and $x42 $x73))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x71 (and (and $x42 $x69) $x59))) + (let ((?x85 (ite $x71 ?x84 (ite (and $x42 $x73) (_ bv511 9) standard_metadata.egress_spec)))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) (let (($x60 (and $x42 $x46))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 ?x85))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (or $x41 (or (or false (= ?x121 (_ bv0 9))) (= ?x121 (_ bv1 9))))))))))))))))))))))) (assert (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x42 (and true ipv4.$valid$))) - (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) - (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let ((?x96 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x108 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x96))) (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) (let (($x60 (and $x42 $x46))) - (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) - (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let ((?x128 (ite ipv4.$valid$ (ite $x60 1 ?x108) (- 1)))) + (let (($x127 (ite ipv4.$valid$ $x42 false))) (let (($x61 (not $x46))) (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x42 (and $x69 (not $x59))))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x77 (ite (and $x42 (and $x69 (not $x59))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x71 (and (and $x42 $x69) $x59))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (and (and (not $x41) $x130) (= ?x131 2))))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 (ite $x71 ?x84 ?x77)))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (and (and (not $x41) $x127) (= ?x128 2)))))))))))))))))))))))) (check-sat) ; @@ -230,8 +222,8 @@ (declare-fun ipv4.dstAddr () (_ BitVec 32)) (declare-fun ipv4.$valid$ () Bool) (assert - (let (($x137 (= standard_metadata.ingress_port (_ bv1 9)))) - (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x137)))) + (let (($x134 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x134)))) (assert (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) @@ -240,42 +232,40 @@ (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) (let (($x73 (and $x69 (not (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))))) (let (($x42 (and true ipv4.$valid$))) - (let (($x74 (and $x42 $x73))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x71 (and (and $x42 $x69) $x59))) + (let ((?x85 (ite $x71 ?x84 (ite (and $x42 $x73) (_ bv511 9) standard_metadata.egress_spec)))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) (let (($x60 (and $x42 $x46))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (or $x41 (or (or false (= ?x124 (_ bv0 9))) (= ?x124 (_ bv1 9)))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 ?x85))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (or $x41 (or (or false (= ?x121 (_ bv0 9))) (= ?x121 (_ bv1 9))))))))))))))))))))))) (assert (let (($x59 (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))))) (let (($x42 (and true ipv4.$valid$))) - (let ((?x100 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) - (let ((?x112 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x100))) + (let ((?x96 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32))))) 3 (ite (and $x42 $x59) 2 (- 1))))) + (let ((?x108 (ite (and $x42 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32))))) 0 ?x96))) (let (($x45 (= ipv4.dstAddr (_ bv168427520 32)))) (let (($x46 (and true $x45))) (let (($x60 (and $x42 $x46))) - (let ((?x131 (ite ipv4.$valid$ (ite $x60 1 ?x112) (- 1)))) - (let (($x130 (ite ipv4.$valid$ $x42 false))) + (let ((?x128 (ite ipv4.$valid$ (ite $x60 1 ?x108) (- 1)))) + (let (($x127 (ite ipv4.$valid$ $x42 false))) (let (($x61 (not $x46))) (let (($x65 (and $x61 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))))) (let (($x69 (and $x65 (not (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))))) - (let (($x74 (and $x42 (and $x69 (not $x59))))) - (let ((?x88 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x77 (ite (and $x42 (and $x69 (not $x59))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x84 (concat (_ bv0 8) (_ bv1 1)))) (let (($x71 (and (and $x42 $x69) $x59))) (let (($x54 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))))) (let (($x67 (and (and $x42 $x65) $x54))) - (let ((?x102 (ite $x67 ?x88 (ite $x71 ?x88 (ite $x74 (_ bv511 9) standard_metadata.egress_spec))))) (let (($x50 (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))))) (let (($x63 (and (and $x42 $x61) $x50))) - (let ((?x124 (ite $x60 ?x88 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) ?x102)))) - (let (($x41 (= ?x124 (_ bv511 9)))) - (and (and (not $x41) $x130) (= ?x131 3))))))))))))))))))))))))) + (let ((?x121 (ite $x60 ?x84 (ite $x63 (concat (_ bv0 8) (_ bv0 1)) (ite $x67 ?x84 (ite $x71 ?x84 ?x77)))))) + (let (($x41 (= ?x121 (_ bv511 9)))) + (and (and (not $x41) $x127) (= ?x128 3)))))))))))))))))))))))) (check-sat) diff --git a/p4_symbolic/symbolic/guarded_map.cc b/p4_symbolic/symbolic/guarded_map.cc index 24f885e4..547e2a64 100644 --- a/p4_symbolic/symbolic/guarded_map.cc +++ b/p4_symbolic/symbolic/guarded_map.cc @@ -19,6 +19,7 @@ #include "absl/container/btree_map.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/string_view.h" #include "p4_symbolic/symbolic/operators.h" #include "p4_symbolic/symbolic/util.h" @@ -31,20 +32,20 @@ absl::StatusOr SymbolicGuardedMap::CreateSymbolicGuardedMap( return SymbolicGuardedMap(map); } -bool SymbolicGuardedMap::ContainsKey(const std::string &key) const { - return this->map_.count(key) == 1; +bool SymbolicGuardedMap::ContainsKey(absl::string_view key) const { + return this->map_.contains(key); } -absl::StatusOr SymbolicGuardedMap::Get(const std::string &key) const { - if (this->ContainsKey(key)) { - return this->map_.at(key); +absl::StatusOr SymbolicGuardedMap::Get(absl::string_view key) const { + if (auto it = this->map_.find(key); it != this->map_.end()) { + return it->second; } return absl::InvalidArgumentError( absl::StrCat("Cannot find key \"", key, "\" in SymbolicGuardedMap!")); } -absl::Status SymbolicGuardedMap::Set(const std::string &key, z3::expr value, +absl::Status SymbolicGuardedMap::Set(absl::string_view key, z3::expr value, const z3::expr &guard) { if (!this->ContainsKey(key)) { return absl::InvalidArgumentError(absl::StrCat( diff --git a/p4_symbolic/symbolic/guarded_map.h b/p4_symbolic/symbolic/guarded_map.h index 7e5c4aec..b567608a 100644 --- a/p4_symbolic/symbolic/guarded_map.h +++ b/p4_symbolic/symbolic/guarded_map.h @@ -64,13 +64,13 @@ class SymbolicGuardedMap { SymbolicGuardedMap &operator=(SymbolicGuardedMap &&other) = delete; // Getters. - bool ContainsKey(const std::string &key) const; - absl::StatusOr Get(const std::string &key) const; + bool ContainsKey(absl::string_view key) const; + absl::StatusOr Get(absl::string_view key) const; // Guarded setter. // Returns an error if the assigned value has incompatible sort with the // pre-defined value. - absl::Status Set(const std::string &key, z3::expr value, + absl::Status Set(absl::string_view key, z3::expr value, const z3::expr &guard); // Constant iterators. diff --git a/p4_symbolic/symbolic/symbolic.cc b/p4_symbolic/symbolic/symbolic.cc index 026e9ded..bee51063 100644 --- a/p4_symbolic/symbolic/symbolic.cc +++ b/p4_symbolic/symbolic/symbolic.cc @@ -47,6 +47,10 @@ absl::StatusOr IsDropped(const SymbolicPerPacketState &state) { return operators::Eq(egress_spec, EgressSpecDroppedValue()); } +absl::StatusOr GotCloned(const SymbolicPerPacketState &state) { + return state.Get(std::string(kGotClonedPseudoField)); +} + absl::StatusOr> EvaluateP4Pipeline( const Dataplane &data_plane, const std::vector &physical_ports) { // Use global context to define a solver. @@ -72,6 +76,7 @@ absl::StatusOr> EvaluateP4Pipeline( // Alias the event that the packet is dropped for ease of use in assertions ASSIGN_OR_RETURN(z3::expr dropped, IsDropped(egress_headers)); + ASSIGN_OR_RETURN(z3::expr got_cloned, GotCloned(egress_headers)); // Restrict ports to the available physical ports. if (absl::c_find(physical_ports, kDropPort) != physical_ports.end()) { @@ -102,6 +107,7 @@ absl::StatusOr> EvaluateP4Pipeline( auto trace = SymbolicTrace{ .matched_entries = std::move(matched_entries), .dropped = dropped, + .got_cloned = got_cloned, }; auto context = SymbolicContext{ .ingress_port = ingress_port, diff --git a/p4_symbolic/symbolic/symbolic.h b/p4_symbolic/symbolic/symbolic.h index 0966e574..6b46f93b 100644 --- a/p4_symbolic/symbolic/symbolic.h +++ b/p4_symbolic/symbolic/symbolic.h @@ -26,6 +26,7 @@ #include "absl/container/btree_map.h" #include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" #include "gutil/status.h" #include "p4_symbolic/ir/ir.pb.h" #include "p4_symbolic/ir/table_entries.h" @@ -36,6 +37,10 @@ namespace p4_symbolic { namespace symbolic { +// Boolean pseudo header field that is set to true by p4-symbolic if the packet +// gets cloned. Not an actual header field, but convenient for analysis. +constexpr absl::string_view kGotClonedPseudoField = "$got_cloned$"; + // Maps the name of a header field in the p4 program to its concrete value. using ConcretePerPacketState = absl::btree_map; @@ -58,6 +63,7 @@ using SymbolicPerPacketState = SymbolicGuardedMap; // processing. See v1model.p4 for details. z3::expr EgressSpecDroppedValue(); absl::StatusOr IsDropped(const SymbolicPerPacketState &state); +absl::StatusOr GotCloned(const SymbolicPerPacketState &state); // Expresses a concrete match for a corresponding concrete packet with a // table in the program. @@ -97,9 +103,12 @@ struct ConcreteTrace { // Can be extended more in the future to include useful // flags about dropping the packet, taking specific code (e.g. if) // branches, vrf, other interesting events, etc. - bool dropped; // true if the packet was dropped. + bool dropped; // true if the packet was dropped. + bool got_cloned; // true if the packet got cloned. std::string to_string() const { - auto result = absl::StrCat("dropped = ", dropped); + std::string result; + absl::StrAppend(&result, "dropped = ", dropped, "\n"); + absl::StrAppend(&result, "got cloned = ", got_cloned, "\n"); for (const auto &[table, match] : matched_entries) { result = absl::StrCat(result, "\n", table, " => ", match.to_string()); } @@ -114,6 +123,7 @@ struct SymbolicTrace { // TODO: Rename to matches_by_table_name. SymbolicTableMatches matched_entries; z3::expr dropped; + z3::expr got_cloned; }; // Specifies the concrete data inside a packet. diff --git a/p4_symbolic/symbolic/util.cc b/p4_symbolic/symbolic/util.cc index a0d7adf2..cc5c1861 100644 --- a/p4_symbolic/symbolic/util.cc +++ b/p4_symbolic/symbolic/util.cc @@ -68,9 +68,11 @@ absl::StatusOr> FreeSymbolicHeaders( } } - // Finally, we have a special field marking if the packet represented by - // these headers was dropped. - symbolic_headers.insert({"$dropped$", Z3Context().bool_val(false)}); + // Initialize pseudo header fields. + symbolic_headers.insert({ + std::string(kGotClonedPseudoField), + Z3Context().bool_val(false), + }); return symbolic_headers; } @@ -104,6 +106,8 @@ absl::StatusOr ExtractFromModel( // Extract the trace (matches on every table). ASSIGN_OR_RETURN(bool dropped, EvalZ3Bool(context.trace.dropped, model)); + ASSIGN_OR_RETURN(bool got_cloned, + EvalZ3Bool(context.trace.got_cloned, model)); absl::btree_map matched_entries; for (const auto &[table, match] : context.trace.matched_entries) { ASSIGN_OR_RETURN(bool matched, EvalZ3Bool(match.matched, model)); @@ -123,6 +127,7 @@ absl::StatusOr ExtractFromModel( ConcreteTrace{ .matched_entries = matched_entries, .dropped = dropped, + .got_cloned = got_cloned, }, }; } From a7335c601ef685be9c78a66141c02370900e6b5b Mon Sep 17 00:00:00 2001 From: kheradmandG Date: Fri, 11 Feb 2022 19:39:54 -0800 Subject: [PATCH 08/10] [P4Symbolic] Add support for string formatted optional matches. PiperOrigin-RevId: 428140974 --- p4_symbolic/BUILD.bazel | 9 + p4_symbolic/main.cc | 17 +- p4_symbolic/symbolic/BUILD.bazel | 23 + .../symbolic/expected/string_optional.smt2 | 382 ++++++++++ .../symbolic/expected/string_optional.txt | 42 ++ p4_symbolic/symbolic/expected/vrf.smt2 | 696 ++++++++++++++++++ p4_symbolic/symbolic/expected/vrf.txt | 83 +++ p4_symbolic/symbolic/table.cc | 9 +- p4_symbolic/symbolic/test.bzl | 2 + p4_symbolic/symbolic/values.cc | 44 +- p4_symbolic/symbolic/values_test.cc | 41 ++ .../testdata/string-optional/entries.pb.txt | 111 +++ .../testdata/string-optional/program.p4 | 106 +++ p4_symbolic/testdata/vrf-routing/vrf.p4 | 2 +- p4_symbolic/z3_util.cc | 19 + p4_symbolic/z3_util.h | 10 + p4_symbolic/z3_util_test.cc | 31 + 17 files changed, 1580 insertions(+), 47 deletions(-) create mode 100644 p4_symbolic/symbolic/expected/string_optional.smt2 create mode 100644 p4_symbolic/symbolic/expected/string_optional.txt create mode 100644 p4_symbolic/symbolic/expected/vrf.smt2 create mode 100644 p4_symbolic/symbolic/expected/vrf.txt create mode 100644 p4_symbolic/symbolic/values_test.cc create mode 100644 p4_symbolic/testdata/string-optional/entries.pb.txt create mode 100644 p4_symbolic/testdata/string-optional/program.p4 create mode 100644 p4_symbolic/z3_util_test.cc diff --git a/p4_symbolic/BUILD.bazel b/p4_symbolic/BUILD.bazel index 2fb1ac2d..cd5432f8 100644 --- a/p4_symbolic/BUILD.bazel +++ b/p4_symbolic/BUILD.bazel @@ -72,3 +72,12 @@ cc_library( "@com_google_absl//absl/strings", ], ) + +cc_test( + name = "z3_util_test", + srcs = ["z3_util_test.cc"], + deps = [ + ":z3_util", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/p4_symbolic/main.cc b/p4_symbolic/main.cc index 434f0c53..ccf635b1 100644 --- a/p4_symbolic/main.cc +++ b/p4_symbolic/main.cc @@ -42,6 +42,7 @@ ABSL_FLAG(std::string, entries, "", "if the input p4 program contains no (explicit) tables for which " "entries are needed."); ABSL_FLAG(std::string, debug, "", "Dump the SMT program for debugging"); +ABSL_FLAG(int, port_count, 2, "Number of used ports (numbered 0 to N-1)"); ABSL_FLAG(bool, hardcoded_parser, true, "Use the hardcoded parser during symbolic evaluation"); @@ -53,6 +54,7 @@ absl::Status ParseAndEvaluate() { const std::string &bmv2_path = absl::GetFlag(FLAGS_bmv2); const std::string &entries_path = absl::GetFlag(FLAGS_entries); const std::string &debug_path = absl::GetFlag(FLAGS_debug); + const int port_count = absl::GetFlag(FLAGS_port_count); bool hardcoded_parser = absl::GetFlag(FLAGS_hardcoded_parser); RET_CHECK(!p4info_path.empty()); @@ -63,11 +65,14 @@ absl::Status ParseAndEvaluate() { p4_symbolic::symbolic::Dataplane dataplane, p4_symbolic::ParseToIr(bmv2_path, p4info_path, entries_path)); + // Generate port list. + std::vector physical_ports(port_count); + for (int i = 0; i < port_count; i++) physical_ports[i] = i; + // Evaluate program symbolically. ASSIGN_OR_RETURN( const std::unique_ptr &solver_state, - p4_symbolic::symbolic::EvaluateP4Pipeline(dataplane, - std::vector{0, 1})); + p4_symbolic::symbolic::EvaluateP4Pipeline(dataplane, physical_ports)); // Add constraints for parser. if (hardcoded_parser) { ASSIGN_OR_RETURN( @@ -151,6 +156,14 @@ absl::Status ParseAndEvaluate() { "scalars.userMetadata.vrf_is_valid") << std::endl; } + // Custom metadata field defined in testdata/string-optional/program.p4 + if (packet_option.value().egress_headers.contains( + "scalars.userMetadata.string_field")) { + std::cout << "\tscalars.userMetadata.string_field = " + << packet_option.value().egress_headers.at( + "scalars.userMetadata.string_field") + << std::endl; + } } else { std::cout << "Cannot find solution!" << std::endl; } diff --git a/p4_symbolic/symbolic/BUILD.bazel b/p4_symbolic/symbolic/BUILD.bazel index ca48e2b2..608ae6ec 100644 --- a/p4_symbolic/symbolic/BUILD.bazel +++ b/p4_symbolic/symbolic/BUILD.bazel @@ -103,3 +103,26 @@ end_to_end_test( smt_golden_file = "expected/basic.smt2", table_entries = "//p4_symbolic/testdata:ipv4-routing/entries.pb.txt", ) + +end_to_end_test( + name = "string_optional_test", + output_golden_file = "expected/string_optional.txt", + p4_program = "//p4_symbolic/testdata:string-optional/program.p4", + port_count = 3, + smt_golden_file = "expected/string_optional.smt2", + table_entries = "//p4_symbolic/testdata:string-optional/entries.pb.txt", +) + +cc_test( + name = "values_test", + srcs = ["values_test.cc"], + deps = [ + ":symbolic", + "//gutil:status_matchers", + "//gutil:testing", + "//p4_pdpi:ir_cc_proto", + "@com_google_absl//absl/container:flat_hash_map", + "@com_google_absl//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/p4_symbolic/symbolic/expected/string_optional.smt2 b/p4_symbolic/symbolic/expected/string_optional.smt2 new file mode 100644 index 00000000..af847f33 --- /dev/null +++ b/p4_symbolic/symbolic/expected/string_optional.smt2 @@ -0,0 +1,382 @@ +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let ((?x56 (ite (and (and true (and $x43 (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let (($x66 (and true $x65))) + (let ((?x76 (ite $x66 0 (ite (and true true) 1 (- 1))))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (and (and (not $x51) true) (= ?x76 (- 1)))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let ((?x56 (ite (and (and true (and $x43 (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let (($x66 (and true $x65))) + (let ((?x76 (ite $x66 0 (ite (and true true) 1 (- 1))))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (let (($x144 (and (not $x51) true))) + (and $x144 (= ?x76 0)))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let ((?x56 (ite (and (and true (and $x43 (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let (($x66 (and true $x65))) + (let ((?x76 (ite $x66 0 (ite (and true true) 1 (- 1))))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (and (and (not $x51) true) (= ?x76 1))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 7) (_ bv2 2)))))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x42 (and true $x32))) + (let ((?x62 (ite $x42 0 (ite (and true $x36) 1 (ite (and true $x41) 2 (- 1)))))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x56 (ite (and (and true (and (not $x32) (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true (not $x32)) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (and (and (not $x51) true) (= ?x62 (- 1))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 7) (_ bv2 2)))))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x42 (and true $x32))) + (let ((?x62 (ite $x42 0 (ite (and true $x36) 1 (ite (and true $x41) 2 (- 1)))))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x56 (ite (and (and true (and (not $x32) (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true (not $x32)) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (let (($x144 (and (not $x51) true))) + (and $x144 (= ?x62 0))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 7) (_ bv2 2)))))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x42 (and true $x32))) + (let ((?x62 (ite $x42 0 (ite (and true $x36) 1 (ite (and true $x41) 2 (- 1)))))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x56 (ite (and (and true (and (not $x32) (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true (not $x32)) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (and (and (not $x51) true) (= ?x62 1)))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let (($x41 (and true (= standard_metadata.ingress_port (concat (_ bv0 7) (_ bv2 2)))))) + (let (($x36 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv1 1)))))) + (let (($x32 (and true (= standard_metadata.ingress_port (concat (_ bv0 8) (_ bv0 1)))))) + (let (($x42 (and true $x32))) + (let ((?x62 (ite $x42 0 (ite (and true $x36) 1 (ite (and true $x41) 2 (- 1)))))) + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let ((?x56 (ite (and (and true (and (not $x32) (not $x36))) $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true (not $x32)) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (and (and (not $x51) true) (= ?x62 2)))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.string_field () (_ BitVec 9)) +(assert + (let (($x85 (= standard_metadata.ingress_port (_ bv2 9)))) + (let (($x80 (= standard_metadata.ingress_port (_ bv1 9)))) + (let (($x86 (or (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x80) $x85))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) $x86))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (or $x51 (or (or (or false (= ?x77 (_ bv0 9))) (= ?x77 (_ bv1 9))) (= ?x77 (_ bv2 9))))))))))))))))))))) +(assert + (let ((?x34 (concat (_ bv0 8) (_ bv1 1)))) + (let ((?x39 (concat (_ bv0 7) (_ bv2 2)))) + (let ((?x29 (concat (_ bv0 8) (_ bv0 1)))) + (let (($x41 (and true (= standard_metadata.ingress_port ?x39)))) + (let (($x32 (and true (= standard_metadata.ingress_port ?x29)))) + (let (($x43 (not $x32))) + (let (($x48 (and true (and $x43 (not (and true (= standard_metadata.ingress_port ?x34))))))) + (let ((?x56 (ite (and $x48 $x41) ?x29 (ite true ?x29 scalars.userMetadata.string_field)))) + (let (($x36 (and true (= standard_metadata.ingress_port ?x34)))) + (let (($x42 (and true $x32))) + (let ((?x63 (ite $x42 ?x39 (ite (and (and true $x43) $x36) ?x34 ?x56)))) + (let (($x65 (and true (= ?x63 ?x39)))) + (let ((?x75 (ite (and (and true (not $x65)) true) ?x34 standard_metadata.egress_spec))) + (let (($x66 (and true $x65))) + (let ((?x77 (ite $x66 ?x29 ?x75))) + (let (($x51 (= ?x77 (_ bv511 9)))) + (and (and (not $x51) true) (= (- 1) (- 1)))))))))))))))))))) +(check-sat) + diff --git a/p4_symbolic/symbolic/expected/string_optional.txt b/p4_symbolic/symbolic/expected/string_optional.txt new file mode 100644 index 00000000..72409dad --- /dev/null +++ b/p4_symbolic/symbolic/expected/string_optional.txt @@ -0,0 +1,42 @@ +Finding packet for table MyIngress.optional_match and row -1 +Cannot find solution! + +Finding packet for table MyIngress.optional_match and row 0 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000000 + scalars.userMetadata.string_field = VALUE-0 + +Finding packet for table MyIngress.optional_match and row 1 + Dropped = 0 + standard_metadata.ingress_port = #b000000010 + standard_metadata.egress_spec = #b000000001 + scalars.userMetadata.string_field = VALUE-2 + +Finding packet for table MyIngress.set_field_table and row -1 +Cannot find solution! + +Finding packet for table MyIngress.set_field_table and row 0 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000000 + scalars.userMetadata.string_field = VALUE-0 + +Finding packet for table MyIngress.set_field_table and row 1 + Dropped = 0 + standard_metadata.ingress_port = #b000000001 + standard_metadata.egress_spec = #b000000001 + scalars.userMetadata.string_field = VALUE-1 + +Finding packet for table MyIngress.set_field_table and row 2 + Dropped = 0 + standard_metadata.ingress_port = #b000000010 + standard_metadata.egress_spec = #b000000001 + scalars.userMetadata.string_field = VALUE-2 + +Finding packet for table tbl_program92 and row -1 + Dropped = 0 + standard_metadata.ingress_port = #b000000010 + standard_metadata.egress_spec = #b000000001 + scalars.userMetadata.string_field = VALUE-2 + diff --git a/p4_symbolic/symbolic/expected/vrf.smt2 b/p4_symbolic/symbolic/expected/vrf.smt2 new file mode 100644 index 00000000..5142be5e --- /dev/null +++ b/p4_symbolic/symbolic/expected/vrf.smt2 @@ -0,0 +1,696 @@ +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let ((?x153 (ite (and $x84 $x95) 0 (ite (and $x84 $x101) 3 (ite (and $x84 $x107) 2 (- 1)))))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x108 (and $x84 $x90))) + (let ((?x67 (ite ipv4.$valid$ (ite $x82 (ite $x108 1 ?x153) (- 1)) (- 1)))) + (let (($x66 (ite ipv4.$valid$ (ite $x82 $x84 false) false))) + (let (($x122 (and $x84 (and (and (and (not $x90) (not $x95)) (not $x101)) (not $x107))))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 (and (and (not $x90) (not $x95)) (not $x101))) $x107))) + (let (($x115 (and (and $x84 (and (not $x90) (not $x95))) $x101))) + (let ((?x144 (ite $x115 ?x130 (ite $x119 ?x130 (ite $x122 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x111 (and (and $x84 (not $x90)) $x95))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) ?x144)))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x66) (= ?x67 (- 1)))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let ((?x153 (ite (and $x84 $x95) 0 (ite (and $x84 $x101) 3 (ite (and $x84 $x107) 2 (- 1)))))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x108 (and $x84 $x90))) + (let ((?x67 (ite ipv4.$valid$ (ite $x82 (ite $x108 1 ?x153) (- 1)) (- 1)))) + (let (($x66 (ite ipv4.$valid$ (ite $x82 $x84 false) false))) + (let (($x122 (and $x84 (and (and (and (not $x90) (not $x95)) (not $x101)) (not $x107))))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 (and (and (not $x90) (not $x95)) (not $x101))) $x107))) + (let (($x115 (and (and $x84 (and (not $x90) (not $x95))) $x101))) + (let ((?x144 (ite $x115 ?x130 (ite $x119 ?x130 (ite $x122 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x111 (and (and $x84 (not $x90)) $x95))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) ?x144)))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (let (($x341 (and (not $x49) $x66))) + (and $x341 (= ?x67 0)))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let ((?x153 (ite (and $x84 $x95) 0 (ite (and $x84 $x101) 3 (ite (and $x84 $x107) 2 (- 1)))))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x108 (and $x84 $x90))) + (let ((?x67 (ite ipv4.$valid$ (ite $x82 (ite $x108 1 ?x153) (- 1)) (- 1)))) + (let (($x66 (ite ipv4.$valid$ (ite $x82 $x84 false) false))) + (let (($x122 (and $x84 (and (and (and (not $x90) (not $x95)) (not $x101)) (not $x107))))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 (and (and (not $x90) (not $x95)) (not $x101))) $x107))) + (let (($x115 (and (and $x84 (and (not $x90) (not $x95))) $x101))) + (let ((?x144 (ite $x115 ?x130 (ite $x119 ?x130 (ite $x122 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x111 (and (and $x84 (not $x90)) $x95))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) ?x144)))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x66) (= ?x67 1))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let ((?x153 (ite (and $x84 $x95) 0 (ite (and $x84 $x101) 3 (ite (and $x84 $x107) 2 (- 1)))))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x108 (and $x84 $x90))) + (let ((?x67 (ite ipv4.$valid$ (ite $x82 (ite $x108 1 ?x153) (- 1)) (- 1)))) + (let (($x66 (ite ipv4.$valid$ (ite $x82 $x84 false) false))) + (let (($x122 (and $x84 (and (and (and (not $x90) (not $x95)) (not $x101)) (not $x107))))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 (and (and (not $x90) (not $x95)) (not $x101))) $x107))) + (let (($x115 (and (and $x84 (and (not $x90) (not $x95))) $x101))) + (let ((?x144 (ite $x115 ?x130 (ite $x119 ?x130 (ite $x122 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x111 (and (and $x84 (not $x90)) $x95))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) ?x144)))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x66) (= ?x67 2))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let ((?x153 (ite (and $x84 $x95) 0 (ite (and $x84 $x101) 3 (ite (and $x84 $x107) 2 (- 1)))))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x108 (and $x84 $x90))) + (let ((?x67 (ite ipv4.$valid$ (ite $x82 (ite $x108 1 ?x153) (- 1)) (- 1)))) + (let (($x66 (ite ipv4.$valid$ (ite $x82 $x84 false) false))) + (let (($x122 (and $x84 (and (and (and (not $x90) (not $x95)) (not $x101)) (not $x107))))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 (and (and (not $x90) (not $x95)) (not $x101))) $x107))) + (let (($x115 (and (and $x84 (and (not $x90) (not $x95))) $x101))) + (let ((?x144 (ite $x115 ?x130 (ite $x119 ?x130 (ite $x122 (_ bv511 9) standard_metadata.egress_spec))))) + (let (($x111 (and (and $x84 (not $x90)) $x95))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) ?x144)))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x66) (= ?x67 3))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x83 (ite ipv4.$valid$ (ite $x62 0 (ite (and $x50 $x61) 1 (- 1))) (- 1)))) + (let (($x68 (ite ipv4.$valid$ $x50 false))) + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let ((?x80 (ite $x62 ?x79 (ite (and (and $x50 (not $x56)) $x61) ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let (($x65 (and (and $x50 (not $x56)) $x61))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x68) (= ?x83 (- 1))))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x83 (ite ipv4.$valid$ (ite $x62 0 (ite (and $x50 $x61) 1 (- 1))) (- 1)))) + (let (($x68 (ite ipv4.$valid$ $x50 false))) + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let ((?x80 (ite $x62 ?x79 (ite (and (and $x50 (not $x56)) $x61) ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let (($x65 (and (and $x50 (not $x56)) $x61))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x68) (= ?x83 0)))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x83 (ite ipv4.$valid$ (ite $x62 0 (ite (and $x50 $x61) 1 (- 1))) (- 1)))) + (let (($x68 (ite ipv4.$valid$ $x50 false))) + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let ((?x80 (ite $x62 ?x79 (ite (and (and $x50 (not $x56)) $x61) ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let (($x65 (and (and $x50 (not $x56)) $x61))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) $x68) (= ?x83 1)))))))))))))))))))))))))))))))))) +(check-sat) + +; +(set-info :status unknown) +(declare-fun standard_metadata.ingress_port () (_ BitVec 9)) +(declare-fun standard_metadata.egress_spec () (_ BitVec 9)) +(declare-fun scalars.userMetadata.vrf () (_ BitVec 10)) +(declare-fun ipv4.srcAddr () (_ BitVec 32)) +(declare-fun ipv4.$valid$ () Bool) +(declare-fun ipv4.dstAddr () (_ BitVec 32)) +(declare-fun scalars.userMetadata.vrf_is_valid () (_ BitVec 1)) +(assert + (let (($x175 (= standard_metadata.ingress_port (_ bv1 9)))) + (and (and (distinct standard_metadata.ingress_port (_ bv511 9)) true) (or (or false (= standard_metadata.ingress_port (_ bv0 9))) $x175)))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (or $x49 (or (or false (= ?x164 (_ bv0 9))) (= ?x164 (_ bv1 9)))))))))))))))))))))))))))))))))) +(assert + (let ((?x73 (concat (_ bv0 9) (_ bv0 1)))) + (let (($x61 (and true (= (bvand ipv4.srcAddr (_ bv555813129 32)) (_ bv555810816 32))))) + (let (($x50 (and true ipv4.$valid$))) + (let (($x65 (and (and $x50 (not (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) $x61))) + (let ((?x79 (concat (_ bv0 9) (_ bv1 1)))) + (let (($x56 (and true (= (bvand ipv4.srcAddr (_ bv153159945 32)) (_ bv2162944 32))))) + (let (($x62 (and $x50 $x56))) + (let ((?x80 (ite $x62 ?x79 (ite $x65 ?x73 scalars.userMetadata.vrf)))) + (let (($x89 (= ?x80 ?x73))) + (let (($x107 (and (and true (= ((_ extract 31 24) ipv4.dstAddr) ((_ extract 31 24) (_ bv167772160 32)))) $x89))) + (let (($x101 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv336855040 32)))) (= ?x80 ?x79)))) + (let (($x95 (and (and true (= ((_ extract 31 16) ipv4.dstAddr) ((_ extract 31 16) (_ bv168427520 32)))) $x89))) + (let (($x90 (and (and true (= ipv4.dstAddr (_ bv168427520 32))) $x89))) + (let (($x109 (not $x90))) + (let (($x113 (and $x109 (not $x95)))) + (let (($x117 (and $x113 (not $x101)))) + (let ((?x75 (ite true (_ bv1 1) (_ bv0 1)))) + (let ((?x76 (ite $x65 ?x75 (ite true (ite false (_ bv1 1) (_ bv0 1)) scalars.userMetadata.vrf_is_valid)))) + (let ((?x81 (ite $x62 ?x75 ?x76))) + (let (($x82 (bvuge ?x81 (_ bv1 1)))) + (let (($x84 (and $x50 $x82))) + (let ((?x124 (ite (and $x84 (and $x117 (not $x107))) (_ bv511 9) standard_metadata.egress_spec))) + (let ((?x130 (concat (_ bv0 8) (_ bv1 1)))) + (let (($x119 (and (and $x84 $x117) $x107))) + (let (($x115 (and (and $x84 $x113) $x101))) + (let (($x111 (and (and $x84 $x109) $x95))) + (let (($x108 (and $x84 $x90))) + (let ((?x164 (ite $x108 ?x130 (ite $x111 (concat (_ bv0 8) (_ bv0 1)) (ite $x115 ?x130 (ite $x119 ?x130 ?x124)))))) + (let (($x49 (= ?x164 (_ bv511 9)))) + (and (and (not $x49) true) (= (- 1) (- 1))))))))))))))))))))))))))))))))) +(check-sat) + diff --git a/p4_symbolic/symbolic/expected/vrf.txt b/p4_symbolic/symbolic/expected/vrf.txt new file mode 100644 index 00000000..355f0642 --- /dev/null +++ b/p4_symbolic/symbolic/expected/vrf.txt @@ -0,0 +1,83 @@ +Finding packet for table packet_ingress.ipv4_lpm_table and row -1 +Cannot find solution! + +Finding packet for table packet_ingress.ipv4_lpm_table and row 0 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000000 + ipv4.srcAddr = #x29210000 + ipv4.dstAddr = #x0a0a0002 + ethernet.dstAddr = #x000000000000 + scalars.userMetadata.vrf = VRF1 + scalars.userMetadata.vrf_is_valid = #b1 + +Finding packet for table packet_ingress.ipv4_lpm_table and row 1 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x29210000 + ipv4.dstAddr = #x0a0a0000 + ethernet.dstAddr = #x000000000000 + scalars.userMetadata.vrf = VRF1 + scalars.userMetadata.vrf_is_valid = #b1 + +Finding packet for table packet_ingress.ipv4_lpm_table and row 2 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x29210000 + ipv4.dstAddr = #x0a1a0000 + ethernet.dstAddr = #x00000000000a + scalars.userMetadata.vrf = VRF1 + scalars.userMetadata.vrf_is_valid = #b1 + +Finding packet for table packet_ingress.ipv4_lpm_table and row 3 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x00210100 + ipv4.dstAddr = #x14140000 + ethernet.dstAddr = #x160000000016 + scalars.userMetadata.vrf = VRF2 + scalars.userMetadata.vrf_is_valid = #b1 + +Finding packet for table packet_ingress.set_vrf_table and row -1 + Dropped = 0 + standard_metadata.ingress_port = #b000000000 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x00000909 + ipv4.dstAddr = #x00000000 + ethernet.dstAddr = #x000000000000 + scalars.userMetadata.vrf = VRF1 + scalars.userMetadata.vrf_is_valid = #b0 + +Finding packet for table packet_ingress.set_vrf_table and row 0 + Dropped = 0 + standard_metadata.ingress_port = #b000000001 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x00210100 + ipv4.dstAddr = #x14140000 + ethernet.dstAddr = #x160000000016 + scalars.userMetadata.vrf = VRF2 + scalars.userMetadata.vrf_is_valid = #b1 + +Finding packet for table packet_ingress.set_vrf_table and row 1 + Dropped = 0 + standard_metadata.ingress_port = #b000000001 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x21210000 + ipv4.dstAddr = #x0a0a0000 + ethernet.dstAddr = #x000000000000 + scalars.userMetadata.vrf = VRF1 + scalars.userMetadata.vrf_is_valid = #b1 + +Finding packet for table tbl_vrf133 and row -1 + Dropped = 0 + standard_metadata.ingress_port = #b000000001 + standard_metadata.egress_spec = #b000000001 + ipv4.srcAddr = #x21210000 + ipv4.dstAddr = #x0a0a0000 + ethernet.dstAddr = #x000000000000 + scalars.userMetadata.vrf = VRF1 + scalars.userMetadata.vrf_is_valid = #b1 + diff --git a/p4_symbolic/symbolic/table.cc b/p4_symbolic/symbolic/table.cc index dfbc0ee8..effe5f8d 100644 --- a/p4_symbolic/symbolic/table.cc +++ b/p4_symbolic/symbolic/table.cc @@ -205,8 +205,15 @@ absl::StatusOr EvaluateSingleMatch( case p4::config::v1::MatchField::OPTIONAL: { if (match.match_value_case() != pdpi::IrMatch::kOptional) return mismatch; + // According to the P4Runtime spec, "for don't care matches, the P4Runtime + // client must omit the field's entire FieldMatch entry when building the + // match repeated field of the TableEntry message". Therefore, if the + // match value is present for an optional match type, it must be a + // concrete value. ASSIGN_OR_RETURN(z3::expr value_expression, - values::FormatBmv2Value(match.optional().value())); + values::FormatP4RTValue( + field_name, match_definition.type_name().name(), + match.optional().value(), translator)); return operators::Eq(field_expression, value_expression); } diff --git a/p4_symbolic/symbolic/test.bzl b/p4_symbolic/symbolic/test.bzl index eeb3c13d..8ae621e1 100644 --- a/p4_symbolic/symbolic/test.bzl +++ b/p4_symbolic/symbolic/test.bzl @@ -31,6 +31,7 @@ def end_to_end_test( output_golden_file, smt_golden_file, table_entries = None, + port_count = 2, p4_deps = []): """Macro that defines our end to end tests. Given a p4 program, this macro runs our main binary @@ -103,6 +104,7 @@ def end_to_end_test( ("--p4info=$(location %s)" % p4info_file), ("--entries=$(location %s)" % table_entries if table_entries else ""), ("--debug=$(location %s)" % smt_output_file), + ("--port_count=%d" % port_count), ("&> $(location %s)" % test_output_file), ]), ) diff --git a/p4_symbolic/symbolic/values.cc b/p4_symbolic/symbolic/values.cc index 8dfbfe3c..4056e899 100644 --- a/p4_symbolic/symbolic/values.cc +++ b/p4_symbolic/symbolic/values.cc @@ -56,47 +56,6 @@ unsigned int FindBitsize(uint64_t value) { return (bitsize > 1 ? bitsize : 1); // At least 1 bit. } -// Turns the given z3 extracted value (as a string) to a uint64_t. -// Z3 returns an extracted value as either a binary, hex, or int strings -// dependening on the size of the value and the formatting flags it is -// initialized with. -uint64_t StringToInt(std::string value) { - static std::unordered_map hex_to_bin = { - {'0', "0000"}, {'1', "0001"}, {'2', "0010"}, {'3', "0011"}, - {'4', "0100"}, {'5', "0101"}, {'6', "0110"}, {'7', "0111"}, - {'8', "1000"}, {'9', "1001"}, {'a', "1010"}, {'b', "1011"}, - {'c', "1100"}, {'d', "1101"}, {'e', "1110"}, {'f', "1111"}}; - - bool value_is_hex = absl::StartsWith(value, "#x"); - bool value_is_binary = absl::StartsWith(value, "#b"); - - // Boolean or integer values. - if (!value_is_hex && !value_is_binary) { - if (value == "true") { - return 1; - } else if (value == "false") { - return 0; - } else { - return std::stoull(value); - } - } - - // Make sure value is a binary string without leading base prefix. - std::string binary; - if (value_is_hex) { - // Turn hex to binary. - absl::string_view stripped_value = absl::StripPrefix(value, "#x"); - for (char c : stripped_value) { - absl::StrAppend(&binary, hex_to_bin.at(c)); - } - } else if (value_is_binary) { - // Strip leading #b for binary strings. - binary = absl::StripPrefix(value, "#b"); - } - - return std::stoull(binary); -} - } // namespace absl::StatusOr ParseIrValue(const std::string &value) { @@ -180,7 +139,7 @@ absl::StatusOr TranslateValueToP4RT( translator.p4runtime_translation_allocators.at(field_type_name); // Turn the value from a string to an int. - uint64_t int_value = StringToInt(value); + uint64_t int_value = Z3ValueStringToInt(value); return allocator.IdToString(int_value); } @@ -191,7 +150,6 @@ uint64_t IdAllocator::AllocateId(const std::string &string_value) { if (this->string_to_id_map_.count(string_value)) { return this->string_to_id_map_.at(string_value); } - // Allocate new bitvector value and store it in mapping. uint64_t int_value = this->counter_++; this->string_to_id_map_.insert({string_value, int_value}); diff --git a/p4_symbolic/symbolic/values_test.cc b/p4_symbolic/symbolic/values_test.cc new file mode 100644 index 00000000..14d4a604 --- /dev/null +++ b/p4_symbolic/symbolic/values_test.cc @@ -0,0 +1,41 @@ +#include "p4_symbolic/symbolic/values.h" + +#include "absl/container/flat_hash_map.h" +#include "absl/strings/str_cat.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "gutil/status_matchers.h" +#include "gutil/testing.h" +#include "p4_pdpi/ir.pb.h" + +namespace p4_symbolic::symbolic::values { +namespace { + +TEST(TranslateValueToP4RT, ReverseTranslatedValuesAreEqualToTheOriginalOnes) { + constexpr int kNumIds = 256; + const std::string kFieldName = "dummy_field_name"; + const std::string kFieldType = "dummy_field_type"; + + // Prepare the translator and expected values. + P4RuntimeTranslator translator; + absl::flat_hash_map z3_value_to_id; + for (int i = 0; i < kNumIds; i++) { + const std::string id = absl::StrCat("id-", i); + pdpi::IrValue ir_value; + ir_value.set_str(id); + ASSERT_OK_AND_ASSIGN(z3::expr expr, FormatP4RTValue(kFieldName, kFieldType, + ir_value, &translator)); + z3_value_to_id[expr.to_string()] = id; + } + + // Check that the reverse translation is as expected. + for (const auto& [z3_value, expected_id] : z3_value_to_id) { + ASSERT_OK_AND_ASSIGN( + const std::string actual_id, + TranslateValueToP4RT(kFieldName, z3_value, translator)); + ASSERT_THAT(actual_id, testing::Eq(expected_id)); + } +} + +} // namespace +} // namespace p4_symbolic::symbolic::values diff --git a/p4_symbolic/testdata/string-optional/entries.pb.txt b/p4_symbolic/testdata/string-optional/entries.pb.txt new file mode 100644 index 00000000..13d1f278 --- /dev/null +++ b/p4_symbolic/testdata/string-optional/entries.pb.txt @@ -0,0 +1,111 @@ +updates { + type: INSERT + entity { + table_entry { + table_id: 44279369 + match { + field_id: 1 + exact { + value: "\00" + } + } + action { + action { + action_id: 21593668 + params { + param_id: 1 + value: "VALUE-0" + } + } + } + } + } +} +updates { + type: INSERT + entity { + table_entry { + table_id: 44279369 + match { + field_id: 1 + exact { + value: "\01" + } + } + action { + action { + action_id: 21593668 + params { + param_id: 1 + value: "VALUE-1" + } + } + } + } + } +} +updates { + type: INSERT + entity { + table_entry { + table_id: 44279369 + match { + field_id: 1 + exact { + value: "\02" + } + } + action { + action { + action_id: 21593668 + params { + param_id: 1 + value: "VALUE-2" + } + } + } + } + } +} +updates { + type: INSERT + entity { + table_entry { + table_id: 47867719 + match { + field_id: 1 + optional { + value: "VALUE-0" + } + } + action { + action { + action_id: 21735938 + params { + param_id: 1 + value: "\00" + } + } + } + priority: 2 + } + } +} +updates { + type: INSERT + entity { + table_entry { + table_id: 47867719 + action { + action { + action_id: 21735938 + params { + param_id: 1 + value: "\01" + } + } + } + priority: 1 + } + } +} diff --git a/p4_symbolic/testdata/string-optional/program.p4 b/p4_symbolic/testdata/string-optional/program.p4 new file mode 100644 index 00000000..1f7f65b0 --- /dev/null +++ b/p4_symbolic/testdata/string-optional/program.p4 @@ -0,0 +1,106 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/* -*- P4_16 -*- */ +#include +#include + +@p4runtime_translation("", string) +type bit<9> string_field_t; + +struct metadata { + string_field_t string_field; +} +struct headers {} + +parser UselessParser(packet_in packet, + out headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + state start { + transition accept; + } +} + +control UselessChecksum(inout headers hdr, inout metadata meta) { + apply { } +} + +control UselessEgress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + apply { } +} + +control UselessComputeChecksum(inout headers hdr, inout metadata meta) { + apply { } +} + +control UselessDeparser(packet_out packet, in headers hdr) { + apply { } +} + +// Forwarding Code +control MyIngress(inout headers hdr, + inout metadata meta, + inout standard_metadata_t standard_metadata) { + + action set_egress_spec(bit<9> port) { + standard_metadata.egress_spec = port; + } + + action set_field(string_field_t f) { + meta.string_field = f; + } + + table set_field_table { + key = { + standard_metadata.ingress_port : exact; + } + actions = { + @proto_id(1) set_field; + @proto_id(2) NoAction; + } + size = 1024; + default_action = NoAction; + } + + table optional_match { + key = { + meta.string_field: optional; + } + actions = { + @proto_id(1) set_egress_spec; + @proto_id(2) NoAction; + } + size = 1024; + default_action = NoAction; + } + + apply { + meta.string_field = (string_field_t)0; + set_field_table.apply(); + optional_match.apply(); + } +} + +// Switch +V1Switch( + UselessParser(), + UselessChecksum(), + MyIngress(), + UselessEgress(), + UselessComputeChecksum(), + UselessDeparser() +) main; diff --git a/p4_symbolic/testdata/vrf-routing/vrf.p4 b/p4_symbolic/testdata/vrf-routing/vrf.p4 index 10d99600..cb2770e7 100644 --- a/p4_symbolic/testdata/vrf-routing/vrf.p4 +++ b/p4_symbolic/testdata/vrf-routing/vrf.p4 @@ -22,7 +22,7 @@ typedef bit<9> egress_spec_t; typedef bit<48> mac_addr_t; typedef bit<32> ipv4_addr_t; -@p4runtime_translation("", string) +@p4runtime_translation("", string) type bit<10> vrf_t; header ethernet_t { diff --git a/p4_symbolic/z3_util.cc b/p4_symbolic/z3_util.cc index b290e893..391627a7 100644 --- a/p4_symbolic/z3_util.cc +++ b/p4_symbolic/z3_util.cc @@ -47,4 +47,23 @@ absl::StatusOr HexStringToZ3Bitvector(const std::string& hex_string, return Z3Context().bv_val(decimal.c_str(), *bitwidth); } +uint64_t Z3ValueStringToInt(const std::string& value) { + if (absl::StartsWith(value, "#x")) { + return std::stoull(value.substr(2), /*idx=*/nullptr, /*base=*/16); + } + if (absl::StartsWith(value, "#b")) { + return std::stoull(value.substr(2), /*idx=*/nullptr, /*base=*/2); + } + + // Boolean or integer values. + if (value == "true") { + return 1; + } else if (value == "false") { + return 0; + } else { + // Must be a base 10 number. + return std::stoull(value, /*idx=*/nullptr, /*base=*/10); + } +} + } // namespace p4_symbolic diff --git a/p4_symbolic/z3_util.h b/p4_symbolic/z3_util.h index f993babc..16a2179b 100644 --- a/p4_symbolic/z3_util.h +++ b/p4_symbolic/z3_util.h @@ -34,6 +34,16 @@ absl::StatusOr HexStringToZ3Bitvector( const std::string& hex_string, absl::optional bitwidth = absl::nullopt); +// -- Misc. -------------------------------------------------------------------- + +// Turns the given z3 extracted value (as a string) to a uint64_t. +// Z3 returns an extracted value as either a binary, hex, or decimal strings +// dependening on the size of the value and the formatting flags it is +// initialized with. +// Note: This function assumes that the input is well-formatted and the result +// fits in uint64_t (otherwise an exception will be thrown). +uint64_t Z3ValueStringToInt(const std::string& value); + // == END OF PUBLIC INTERFACE ================================================== template diff --git a/p4_symbolic/z3_util_test.cc b/p4_symbolic/z3_util_test.cc new file mode 100644 index 00000000..88de5194 --- /dev/null +++ b/p4_symbolic/z3_util_test.cc @@ -0,0 +1,31 @@ +#include "p4_symbolic/z3_util.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace p4_symbolic { +namespace { + +TEST(Z3ValueStringToInt, WorksForBoolStrings) { + ASSERT_EQ(Z3ValueStringToInt("true"), 1); + ASSERT_EQ(Z3ValueStringToInt("false"), 0); +} + +TEST(Z3ValueStringToInt, WorksForBinaryStrings) { + ASSERT_EQ(Z3ValueStringToInt("#b10"), 2); + ASSERT_EQ(Z3ValueStringToInt("#b01"), 1); +} + +TEST(Z3ValueStringToInt, WorksForHexStrings) { + ASSERT_EQ(Z3ValueStringToInt("#x10"), 16); + ASSERT_EQ(Z3ValueStringToInt("#xff"), 255); + ASSERT_EQ(Z3ValueStringToInt("#x9"), 9); +} + +TEST(Z3ValueStringToInt, WorksForDecimalStrings) { + ASSERT_EQ(Z3ValueStringToInt("10"), 10); + ASSERT_EQ(Z3ValueStringToInt("900"), 900); +} + +} // namespace +} // namespace p4_symbolic From c4c9631649699e85efc163ab5d157d07999c657f Mon Sep 17 00:00:00 2001 From: kishanps Date: Mon, 17 May 2021 15:49:43 -0700 Subject: [PATCH 09/10] Enable secure connection for p4rt_route_test. Migrate program to new SAI API for setting VRFs. update comments to use inclusive naming from github and p4.org Add route_metadata field and initializing logic to reflect the changes in SAI-P4 code. Remove program-specific structs mixed in with the generic API. --- gutil/io.cc | 2 +- gutil/io.h | 2 +- p4_fuzzer/fuzzer_tests.cc | 5 +- p4_symbolic/BUILD.bazel | 6 +- p4_symbolic/bmv2/BUILD.bazel | 4 +- p4_symbolic/bmv2/bmv2.cc | 4 +- p4_symbolic/bmv2/test.cc | 8 +-- p4_symbolic/ir/BUILD.bazel | 2 +- p4_symbolic/ir/ir.proto | 4 +- p4_symbolic/ir/table_entries.cc | 2 +- p4_symbolic/main.cc | 5 +- p4_symbolic/parser.cc | 4 +- p4_symbolic/sai/fields.cc | 5 ++ p4_symbolic/sai/fields.h | 10 ++- p4_symbolic/symbolic/BUILD.bazel | 5 -- p4_symbolic/symbolic/packet.cc | 76 ---------------------- p4_symbolic/symbolic/packet.h | 40 ------------ p4_symbolic/symbolic/symbolic.cc | 6 +- p4_symbolic/symbolic/symbolic.h | 70 ++------------------ p4_symbolic/tests/BUILD.bazel | 1 + p4_symbolic/tests/sai_p4_component_test.cc | 5 +- p4_symbolic/util/BUILD.bazel | 37 ----------- p4_symbolic/util/io.cc | 75 --------------------- p4_symbolic/util/io.h | 36 ---------- 24 files changed, 48 insertions(+), 366 deletions(-) delete mode 100644 p4_symbolic/symbolic/packet.cc delete mode 100644 p4_symbolic/symbolic/packet.h delete mode 100644 p4_symbolic/util/BUILD.bazel delete mode 100644 p4_symbolic/util/io.cc delete mode 100644 p4_symbolic/util/io.h diff --git a/gutil/io.cc b/gutil/io.cc index 3d1b7542..6508f4c3 100644 --- a/gutil/io.cc +++ b/gutil/io.cc @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/gutil/io.h b/gutil/io.h index 34f0f117..b14e23c6 100644 --- a/gutil/io.h +++ b/gutil/io.h @@ -1,4 +1,4 @@ -// Copyright 2020 Google LLC +// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/p4_fuzzer/fuzzer_tests.cc b/p4_fuzzer/fuzzer_tests.cc index 62254465..9defc445 100644 --- a/p4_fuzzer/fuzzer_tests.cc +++ b/p4_fuzzer/fuzzer_tests.cc @@ -151,12 +151,13 @@ TEST_P(FuzzTest, P4rtWriteAndCheckNoInternalErrors) { ASSERT_OK_AND_ASSIGN( const pdpi::IrTableDefinition& table, gutil::FindOrStatus(info.tables_by_id(), table_id)); - // TODO: acl_lookup_table has a resource limit problem. + // TODO: acl_pre_ingress_table has a resource limit + // problem. // TODO: router_interface_table, ipv4_table and // ipv6_table all have resource limit problems. // TODO: wcmp_group_table has a resource limit problem. if (!(mask_known_failures && - (table.preamble().alias() == "acl_lookup_table" || + (table.preamble().alias() == "acl_pre_ingress_table" || table.preamble().alias() == "router_interface_table" || table.preamble().alias() == "ipv4_table" || table.preamble().alias() == "ipv6_table" || diff --git a/p4_symbolic/BUILD.bazel b/p4_symbolic/BUILD.bazel index cd5432f8..6c044033 100644 --- a/p4_symbolic/BUILD.bazel +++ b/p4_symbolic/BUILD.bazel @@ -26,11 +26,11 @@ cc_binary( ], deps = [ ":parser", + "//gutil:io", "//gutil:status", "//p4_symbolic/bmv2", "//p4_symbolic/sai:parser", "//p4_symbolic/symbolic", - "//p4_symbolic/util", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/flags:parse", "@com_google_absl//absl/flags:usage", @@ -45,7 +45,8 @@ cc_library( srcs = ["parser.cc"], hdrs = ["parser.h"], deps = [ - "//gutil:proto", + "//gutil:io", + "//gutil:proto", "//gutil:status", "//p4_pdpi:ir_cc_proto", "//p4_symbolic/bmv2", @@ -53,7 +54,6 @@ cc_library( "//p4_symbolic/ir:ir_cc_proto", "//p4_symbolic/ir:pdpi_driver", "//p4_symbolic/symbolic", - "//p4_symbolic/util", "@com_google_absl//absl/types:span", ], ) diff --git a/p4_symbolic/bmv2/BUILD.bazel b/p4_symbolic/bmv2/BUILD.bazel index f80130ff..c2aaf3f0 100644 --- a/p4_symbolic/bmv2/BUILD.bazel +++ b/p4_symbolic/bmv2/BUILD.bazel @@ -44,8 +44,8 @@ cc_library( ], deps = [ ":bmv2_cc_proto", + "//gutil:io", "//gutil:status", - "//p4_symbolic/util", "@com_google_protobuf//:protobuf", ], ) @@ -55,8 +55,8 @@ cc_binary( srcs = ["test.cc"], deps = [ ":bmv2", + "//gutil:io", "//gutil:status", - "//p4_symbolic/util", "@com_google_absl//absl/flags:flag", "@com_google_absl//absl/flags:parse", "@com_google_absl//absl/flags:usage", diff --git a/p4_symbolic/bmv2/bmv2.cc b/p4_symbolic/bmv2/bmv2.cc index 0c5623da..08dec256 100644 --- a/p4_symbolic/bmv2/bmv2.cc +++ b/p4_symbolic/bmv2/bmv2.cc @@ -17,14 +17,14 @@ #include #include "google/protobuf/util/json_util.h" +#include "gutil/io.h" #include "gutil/status.h" -#include "p4_symbolic/util/io.h" namespace p4_symbolic { namespace bmv2 { absl::StatusOr ParseBmv2JsonFile(const std::string &json_path) { - ASSIGN_OR_RETURN(std::string json, util::ReadFile(json_path)); + ASSIGN_OR_RETURN(std::string json, gutil::ReadFile(json_path)); return ParseBmv2JsonString(json); } diff --git a/p4_symbolic/bmv2/test.cc b/p4_symbolic/bmv2/test.cc index 99dd4d14..0de25489 100644 --- a/p4_symbolic/bmv2/test.cc +++ b/p4_symbolic/bmv2/test.cc @@ -30,9 +30,9 @@ #include "absl/strings/str_format.h" #include "google/protobuf/text_format.h" #include "google/protobuf/util/json_util.h" +#include "gutil/io.h" #include "gutil/status.h" #include "p4_symbolic/bmv2/bmv2.h" -#include "p4_symbolic/util/io.h" ABSL_FLAG(std::string, bmv2, "", "The path to the bmv2 json file (required)"); ABSL_FLAG(std::string, protobuf, "", @@ -55,8 +55,7 @@ absl::Status Test() { p4_symbolic::bmv2::ParseBmv2JsonFile(bmv2_path.c_str())); // Dumping protobuf. - RETURN_IF_ERROR( - p4_symbolic::util::WriteFile(bmv2.DebugString(), protobuf_path.c_str())); + RETURN_IF_ERROR(gutil::WriteFile(bmv2.DebugString(), protobuf_path.c_str())); // Dumping JSON. google::protobuf::util::JsonPrintOptions dumping_options; @@ -68,8 +67,7 @@ absl::Status Test() { RETURN_IF_ERROR( gutil::ToAbslStatus(google::protobuf::util::MessageToJsonString( bmv2, &json_output_str, dumping_options))); - RETURN_IF_ERROR( - p4_symbolic::util::WriteFile(json_output_str, json_path.c_str())); + RETURN_IF_ERROR(gutil::WriteFile(json_output_str, json_path.c_str())); return absl::OkStatus(); } diff --git a/p4_symbolic/ir/BUILD.bazel b/p4_symbolic/ir/BUILD.bazel index be4ec3e5..14674ca3 100644 --- a/p4_symbolic/ir/BUILD.bazel +++ b/p4_symbolic/ir/BUILD.bazel @@ -59,10 +59,10 @@ cc_library( ], deps = [ ":ir_cc_proto", + "//gutil:io", "//gutil:status", "//p4_pdpi:ir", "//p4_pdpi:ir_cc_proto", - "//p4_symbolic/util", "@com_github_p4lang_p4runtime//:p4runtime_cc_proto", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", diff --git a/p4_symbolic/ir/ir.proto b/p4_symbolic/ir/ir.proto index 72d6ce15..590bd0b7 100644 --- a/p4_symbolic/ir/ir.proto +++ b/p4_symbolic/ir/ir.proto @@ -25,7 +25,7 @@ // Additionally, some types of expressions and statements are unsupported, these // are described in the relevant sections of this file. // See the bmv2 JSON format reference for more information: -// https://github.com/p4lang/behavioral-model/blob/master/docs/JSON_format.md +// https://github.com/p4lang/behavioral-model/blob/main/docs/JSON_format.md syntax = "proto3"; @@ -51,7 +51,7 @@ message P4Program { // TODO: If needed in the future, action calls can be added here, for // action calls that are not wrapped in other control constructs. - // https://github.com/p4lang/behavioral-model/blob/master/docs/JSON_format.md#pipelines + // https://github.com/p4lang/behavioral-model/blob/main/docs/JSON_format.md#pipelines } // A header type definition. diff --git a/p4_symbolic/ir/table_entries.cc b/p4_symbolic/ir/table_entries.cc index 714b9266..331ecfb5 100644 --- a/p4_symbolic/ir/table_entries.cc +++ b/p4_symbolic/ir/table_entries.cc @@ -18,11 +18,11 @@ #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_split.h" +#include "gutil/io.h" #include "gutil/status.h" #include "p4/v1/p4runtime.pb.h" #include "p4_pdpi/ir.h" #include "p4_pdpi/ir.pb.h" -#include "p4_symbolic/util/io.h" namespace p4_symbolic { namespace ir { diff --git a/p4_symbolic/main.cc b/p4_symbolic/main.cc index ccf635b1..8451f0ec 100644 --- a/p4_symbolic/main.cc +++ b/p4_symbolic/main.cc @@ -27,12 +27,12 @@ #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "gutil/io.h" #include "gutil/status.h" #include "p4_symbolic/bmv2/bmv2.h" #include "p4_symbolic/parser.h" #include "p4_symbolic/sai/parser.h" #include "p4_symbolic/symbolic/symbolic.h" -#include "p4_symbolic/util/io.h" ABSL_FLAG(std::string, p4info, "", "The path to the p4info protobuf file (required)"); @@ -173,8 +173,7 @@ absl::Status ParseAndEvaluate() { // Debugging. if (!debug_path.empty()) { - RETURN_IF_ERROR( - p4_symbolic::util::WriteFile(debug_smt_formula, debug_path)); + RETURN_IF_ERROR(gutil::WriteFile(debug_smt_formula, debug_path)); } return absl::OkStatus(); diff --git a/p4_symbolic/parser.cc b/p4_symbolic/parser.cc index 6d58d91b..bf167715 100644 --- a/p4_symbolic/parser.cc +++ b/p4_symbolic/parser.cc @@ -14,11 +14,11 @@ #include "p4_symbolic/parser.h" +#include "gutil/io.h" #include "gutil/proto.h" #include "p4_symbolic/bmv2/bmv2.h" #include "p4_symbolic/ir/ir.h" #include "p4_symbolic/ir/pdpi_driver.h" -#include "p4_symbolic/util/io.h" namespace p4_symbolic { @@ -58,7 +58,7 @@ absl::StatusOr ParseToIr( const std::string &bmv2_json_path, const std::string &p4info_path, absl::Span table_entries) { // Parse bmv2 json file into our initial bmv2 protobuf. - ASSIGN_OR_RETURN(std::string bmv2_json, util::ReadFile(bmv2_json_path)); + ASSIGN_OR_RETURN(std::string bmv2_json, gutil::ReadFile(bmv2_json_path)); // Parse p4info file into pdpi format. ASSIGN_OR_RETURN(pdpi::IrP4Info p4info, diff --git a/p4_symbolic/sai/fields.cc b/p4_symbolic/sai/fields.cc index 02145369..99f20165 100644 --- a/p4_symbolic/sai/fields.cc +++ b/p4_symbolic/sai/fields.cc @@ -100,6 +100,11 @@ absl::StatusOr GetSaiFields(const SymbolicPerPacketState& state) { .admit_to_l3 = get_metadata_field("admit_to_l3"), .vrf_id = get_metadata_field("vrf_id"), .mirror_session_id_valid = get_metadata_field("mirror_session_id_valid"), + .ingress_port = get_metadata_field("ingress_port"), + .route_metadata = get_metadata_field("route_metadata"), + }; + auto standard_metadata = V1ModelStandardMetadata{ + .ingress_port = get_field("standard_metadata.ingress_port"), }; if (!errors.empty()) { diff --git a/p4_symbolic/sai/fields.h b/p4_symbolic/sai/fields.h index 103c2982..25dd70ef 100644 --- a/p4_symbolic/sai/fields.h +++ b/p4_symbolic/sai/fields.h @@ -63,8 +63,14 @@ struct SaiLocalMetadata { z3::expr vrf_id; // TODO: add `packet_rewrites` fields. z3::expr mirror_session_id_valid; - // TODO: add `mirror*` fields. - // TODO: Add `color` field. + z3::expr ingress_port; + z3::expr route_metadata; +}; + +// Symbolic version of `struct standard_metadata_t` in v1model.p4 +// TODO: Add missing fields, as needed. +struct V1ModelStandardMetadata { + z3::expr ingress_port; }; struct SaiFields { diff --git a/p4_symbolic/symbolic/BUILD.bazel b/p4_symbolic/symbolic/BUILD.bazel index 608ae6ec..b601b1f2 100644 --- a/p4_symbolic/symbolic/BUILD.bazel +++ b/p4_symbolic/symbolic/BUILD.bazel @@ -27,7 +27,6 @@ cc_library( "control.cc", "guarded_map.cc", "operators.cc", - "packet.cc", "symbolic.cc", "table.cc", "util.cc", @@ -39,7 +38,6 @@ cc_library( "control.h", "guarded_map.h", "operators.h", - "packet.h", "symbolic.h", "table.h", "util.h", @@ -59,10 +57,7 @@ cc_library( "@com_github_p4lang_p4runtime//:p4info_cc_proto", "@com_github_z3prover_z3//:api", "@com_gnu_gmp//:gmp", - "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/cleanup", - "@com_google_absl//absl/container:btree", - "@com_google_absl//absl/memory", "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", diff --git a/p4_symbolic/symbolic/packet.cc b/p4_symbolic/symbolic/packet.cc deleted file mode 100644 index 12c75a74..00000000 --- a/p4_symbolic/symbolic/packet.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Contains helpers for creating, extracting, and managing concerete and -// symbolic packet structs. - -#include "p4_symbolic/symbolic/packet.h" - -#include - -namespace p4_symbolic { -namespace symbolic { -namespace packet { - -namespace { - -// Get the symbolic field value from state or return a default value -// of the given size. -z3::expr GetOrDefault(SymbolicPerPacketState state, const std::string &field, - unsigned int default_value_bit_size) { - if (state.ContainsKey(field)) { - return state.Get(field).value(); - } -} - -} // namespace - -SymbolicPacket ExtractSymbolicPacket(SymbolicPerPacketState state) { - z3::expr ipv6_src = GetOrDefault(state, "ipv6.src_addr", 128); - z3::expr ipv6_dst = GetOrDefault(state, "ipv6.dst_addr", 128); - - return SymbolicPacket{GetOrDefault(state, "ethernet.src_addr", 48), - GetOrDefault(state, "ethernet.dst_addr", 48), - GetOrDefault(state, "ethernet.ether_type", 16), - - GetOrDefault(state, "ipv4.src_addr", 32), - GetOrDefault(state, "ipv4.dst_addr", 32), - ipv6_dst.extract(127, 64), - ipv6_dst.extract(63, 0), - GetOrDefault(state, "ipv4.protocol", 8), - GetOrDefault(state, "ipv4.dscp", 6), - GetOrDefault(state, "ipv4.ttl", 8), - - GetOrDefault(state, "icmp.type", 8)}; -} - -ConcretePacket ExtractConcretePacket(SymbolicPacket packet, z3::model model) { - return {model.eval(packet.eth_src, true).to_string(), - model.eval(packet.eth_dst, true).to_string(), - model.eval(packet.eth_type, true).to_string(), - - model.eval(packet.ipv4_src, true).to_string(), - model.eval(packet.ipv4_dst, true).to_string(), - model.eval(packet.ipv6_dst_upper, true).to_string(), - model.eval(packet.ipv6_dst_lower, true).to_string(), - model.eval(packet.protocol, true).to_string(), - model.eval(packet.dscp, true).to_string(), - model.eval(packet.ttl, true).to_string(), - - model.eval(packet.icmp_type, true).to_string()}; -} - -} // namespace packet -} // namespace symbolic -} // namespace p4_symbolic diff --git a/p4_symbolic/symbolic/packet.h b/p4_symbolic/symbolic/packet.h deleted file mode 100644 index bd18674a..00000000 --- a/p4_symbolic/symbolic/packet.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Contains helpers for creating, extracting, and managing concerete and -// symbolic packet structs. - -#ifndef P4_SYMBOLIC_SYMBOLIC_PACKET_H_ -#define P4_SYMBOLIC_SYMBOLIC_PACKET_H_ - -#include "gutil/status.h" -#include "p4_symbolic/symbolic/symbolic.h" -#include "z3++.h" - -namespace p4_symbolic { -namespace symbolic { -namespace packet { - -// Extract the packet fields from their p4 program counterparts. -SymbolicPacket ExtractSymbolicPacket(SymbolicPerPacketState state); - -// Extract a concrete packet by evaluating every field's corresponding -// expression in the model. -ConcretePacket ExtractConcretePacket(SymbolicPacket packet, z3::model model); - -} // namespace packet -} // namespace symbolic -} // namespace p4_symbolic - -#endif // P4_SYMBOLIC_SYMBOLIC_PACKET_H_ diff --git a/p4_symbolic/symbolic/symbolic.cc b/p4_symbolic/symbolic/symbolic.cc index bee51063..03df3933 100644 --- a/p4_symbolic/symbolic/symbolic.cc +++ b/p4_symbolic/symbolic/symbolic.cc @@ -16,15 +16,12 @@ #include -#include "absl/algorithm/container.h" #include "absl/cleanup/cleanup.h" -#include "absl/memory/memory.h" #include "absl/types/optional.h" #include "glog/logging.h" #include "gutil/status.h" #include "p4_symbolic/symbolic/control.h" #include "p4_symbolic/symbolic/operators.h" -#include "p4_symbolic/symbolic/packet.h" #include "p4_symbolic/symbolic/util.h" #include "p4_symbolic/z3_util.h" @@ -132,11 +129,11 @@ absl::StatusOr> Solve( solver_state->solver->push(); solver_state->solver->add(constraint); + auto pop = absl::Cleanup([&] { solver_state->solver->pop(); }); z3::check_result check_result = solver_state->solver->check(); switch (check_result) { case z3::unsat: case z3::unknown: - solver_state->solver->pop(); return absl::nullopt; case z3::sat: @@ -145,7 +142,6 @@ absl::StatusOr> Solve( ConcreteContext result, util::ExtractFromModel(solver_state->context, packet_model, solver_state->translator)); - solver_state->solver->pop(); return result; } LOG(DFATAL) << "invalid Z3 check() result: " diff --git a/p4_symbolic/symbolic/symbolic.h b/p4_symbolic/symbolic/symbolic.h index 6b46f93b..2ecf3b72 100644 --- a/p4_symbolic/symbolic/symbolic.h +++ b/p4_symbolic/symbolic/symbolic.h @@ -110,7 +110,7 @@ struct ConcreteTrace { absl::StrAppend(&result, "dropped = ", dropped, "\n"); absl::StrAppend(&result, "got cloned = ", got_cloned, "\n"); for (const auto &[table, match] : matched_entries) { - result = absl::StrCat(result, "\n", table, " => ", match.to_string()); + absl::StrAppend(&result, "\n", table, " => ", match.to_string()); } return result; } @@ -126,87 +126,31 @@ struct SymbolicTrace { z3::expr got_cloned; }; -// Specifies the concrete data inside a packet. -// This is a friendly helper struct, all information in this struct -// is extracted from ConcretePerPacketState. -struct ConcretePacket { - std::string eth_src; - std::string eth_dst; - std::string eth_type; - - std::string ipv4_src; - std::string ipv4_dst; - std::string ipv6_dst_upper; - std::string ipv6_dst_lower; - std::string protocol; - std::string dscp; - std::string ttl; - - std::string icmp_type; - - std::string to_string() const { - return absl::StrCat("eth_src = ", eth_src, "\n", "eth_dst = ", eth_dst, - "\n", "eth_type = ", eth_type, "\n", - "ipv4_src = ", ipv4_src, "\n", "ipv4_dst = ", ipv4_dst, - "\n", "ipv6_dst_upper = ", ipv6_dst_upper, "\n", - "ipv6_dst_lower = ", ipv6_dst_lower, "\n", - "protocol = ", protocol, "\n", "dscp = ", dscp, "\n", - "ttl = ", ttl, "\n", "icmp_type = ", icmp_type); - } -}; - -// A helper struct containing symbolic expressions for every field in a packet. -// All expressions in this struct are extracted from SymbolicPerPacketState. -// We explicitly give these fields name in this struct to simplify how the -// client code can impose constraints on them in assertions. -struct SymbolicPacket { - z3::expr eth_src; // 48 bit. - z3::expr eth_dst; // 48 bit. - z3::expr eth_type; // 16 bit. - - z3::expr ipv4_src; // 32 bit, valid if eth_type = 0x0800 - z3::expr ipv4_dst; // 32 bit, valid if eth_type = 0x0800 - z3::expr ipv6_dst_upper; // 64 bit, valid if eth_type = 0x86dd - z3::expr ipv6_dst_lower; // 64 bit, valid if eth_type = 0x86dd - z3::expr protocol; // 8 bit, valid if eth_type is ip - z3::expr dscp; // 6 bit, valid if eth_type is ip - z3::expr ttl; // 8 bit, valid if eth_type is ip - - z3::expr icmp_type; // 8 bit, valid if eth_type is ip -}; - // The result of solving with some assertion. // This contains an input test packet with its predicted flow in the program, // and the predicted output. struct ConcreteContext { std::string ingress_port; std::string egress_port; - ConcretePacket ingress_packet; // Input packet into the program/switch. - ConcretePacket egress_packet; // Expected output packet. ConcretePerPacketState ingress_headers; ConcretePerPacketState egress_headers; ConcreteTrace trace; // Expected trace in the program. std::string to_string() const { return to_string(false); } std::string to_string(bool verbose) const { - auto result = absl::StrCat( - "ingress_port = ", ingress_port, "\n", "egress_port = ", egress_port, - "\n\n", "ingress_packet:\n", ingress_packet.to_string(), "\n\n", - "egress_packet:\n", egress_packet.to_string(), "\n\n", "trace:\n", - trace.to_string()); + auto result = absl::StrCat("ingress_port = ", ingress_port, "\n", + "egress_port = ", egress_port, "\n", "trace:\n", + trace.to_string()); if (verbose) { auto ingress_string = absl::StrCat("ingress_headers", ":"); auto egress_string = absl::StrCat("egress_headers", ":"); for (const auto &[name, ingress_value] : ingress_headers) { - ingress_string = - absl::StrCat(ingress_string, "\n", name, " = ", ingress_value); + absl::StrAppend(&ingress_string, "\n", name, " = ", ingress_value); } for (const auto &[name, egress_value] : egress_headers) { - egress_string = - absl::StrCat(egress_string, "\n", name, " = ", egress_value); + absl::StrAppend(&egress_string, "\n", name, " = ", egress_value); } - result = - absl::StrCat(result, "\n\n", ingress_string, "\n\n", egress_string); + absl::StrAppend(&result, "\n\n", ingress_string, "\n\n", egress_string); } return result; } diff --git a/p4_symbolic/tests/BUILD.bazel b/p4_symbolic/tests/BUILD.bazel index 013dcdcc..9bf1f6c3 100644 --- a/p4_symbolic/tests/BUILD.bazel +++ b/p4_symbolic/tests/BUILD.bazel @@ -13,6 +13,7 @@ cc_test( "//p4_pdpi:ir_cc_proto", "//p4_pdpi:pd", "//p4_symbolic:parser", + "//p4_symbolic:z3_util", "//p4_symbolic/sai:parser", "//p4_symbolic/symbolic", "//sai_p4/instantiations/google:sai_nonstandard_platforms_cc", diff --git a/p4_symbolic/tests/sai_p4_component_test.cc b/p4_symbolic/tests/sai_p4_component_test.cc index 14944e0c..4e973433 100644 --- a/p4_symbolic/tests/sai_p4_component_test.cc +++ b/p4_symbolic/tests/sai_p4_component_test.cc @@ -15,9 +15,10 @@ #include "p4_symbolic/parser.h" #include "p4_symbolic/sai/parser.h" #include "p4_symbolic/symbolic/symbolic.h" +#include "p4_symbolic/z3_util.h" +#include "sai_p4/instantiations/google/instantiations.h" #include "sai_p4/instantiations/google/sai_nonstandard_platforms.h" #include "sai_p4/instantiations/google/sai_pd.pb.h" -#include "sai_p4/instantiations/google/instantiations.h" #include "thinkit/bazel_test_environment.h" namespace p4_symbolic { @@ -30,7 +31,7 @@ using ::testing::Not; constexpr absl::string_view kTableEntries = R"pb( entries { - acl_pre_ingress_table_entry { + acl_pre_ingress_table_entry { match { src_mac { value: "22:22:22:11:11:11" mask: "ff:ff:ff:ff:ff:ff" } dst_ip { value: "10.0.10.0" mask: "255.255.255.255" } diff --git a/p4_symbolic/util/BUILD.bazel b/p4_symbolic/util/BUILD.bazel deleted file mode 100644 index d9f9a016..00000000 --- a/p4_symbolic/util/BUILD.bazel +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright 2024 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -package( - default_visibility = ["//visibility:public"], - licenses = ["notice"], -) - -cc_library( - name = "util", - srcs = [ - "io.cc", - # "status.cc", - ], - hdrs = [ - "io.h", - # TODO: clean up. - # "status.h", - ], - deps = [ - "//gutil:status", - "@com_google_absl//absl/status", - "@com_google_absl//absl/strings", - "@com_google_absl//absl/strings:str_format", - ], -) diff --git a/p4_symbolic/util/io.cc b/p4_symbolic/util/io.cc deleted file mode 100644 index 000b8a7c..00000000 --- a/p4_symbolic/util/io.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "p4_symbolic/util/io.h" - -#include -#include -#include -#include - -#include "absl/strings/str_format.h" -#include "gutil/status.h" - -namespace p4_symbolic { -namespace util { - -namespace { - -absl::Status ErrorNoToAbsl(const char *operation, const std::string &path) { - switch (errno) { - case EACCES: - case ENOENT: - return absl::NotFoundError( - absl::StrFormat("%s: %s", strerror(errno), path)); - default: - return absl::UnknownError(absl::StrFormat("Cannot %s file %s, errno = %d", - operation, path, errno)); - } -} - -} // namespace - -absl::StatusOr ReadFile(const std::string &path) { - std::ifstream f; - f.open(path.c_str()); - if (f.fail()) { - return ErrorNoToAbsl("open", path); - } - f >> std::noskipws; // Read whitespaces. - std::string result(std::istreambuf_iterator(f), - (std::istreambuf_iterator())); - if (f.bad()) { - return ErrorNoToAbsl("read", path); - } - f.close(); - return result; -} - -absl::Status WriteFile(const std::string &content, const std::string &path) { - std::ofstream f; - f.open(path.c_str()); - if (f.fail()) { - return ErrorNoToAbsl("open", path); - } - f << content; - f.close(); - if (f.bad()) { - return ErrorNoToAbsl("write", path); - } - return absl::OkStatus(); -} - -} // namespace util -} // namespace p4_symbolic diff --git a/p4_symbolic/util/io.h b/p4_symbolic/util/io.h deleted file mode 100644 index a105b072..00000000 --- a/p4_symbolic/util/io.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2024 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef P4_SYMBOLIC_UTIL_IO_H_ -#define P4_SYMBOLIC_UTIL_IO_H_ - -#include - -#include "absl/status/status.h" -#include "absl/strings/string_view.h" -#include "gutil/status.h" - -namespace p4_symbolic { -namespace util { - -// Reads the entire content of the file and returns it (or an error status). -absl::StatusOr ReadFile(const std::string &path); - -// Writes the content of the string to the file. -absl::Status WriteFile(const std::string &content, const std::string &path); - -} // namespace util -} // namespace p4_symbolic - -#endif // P4_SYMBOLIC_UTIL_IO_H_ From 8bb7b076afd98e25a44831da40e62b718dc33d46 Mon Sep 17 00:00:00 2001 From: smolkaj Date: Tue, 20 Jul 2021 10:00:49 -0700 Subject: [PATCH 10/10] [p4-symbolic] Eliminate extremely long variable names for action selector variables. Eliminate bug in detecting unsupported scenario (conditional on table match result) Eliminate non-determinism in EvaluateTableEntryCondition. Add test for output determinism.Update hard-coded SAI parser constraint to reflect the updated P4 code.Decrease the number of runs for determinism check. Define kDefaultActionEntryIndex. Fix typo. --- p4_symbolic/symbolic/BUILD.bazel | 3 +- p4_symbolic/symbolic/table.cc | 60 ++++++++++++++++++-------------- p4_symbolic/symbolic/table.h | 3 ++ p4_symbolic/z3_util.cc | 8 ++++- p4_symbolic/z3_util.h | 8 +++-- 5 files changed, 50 insertions(+), 32 deletions(-) diff --git a/p4_symbolic/symbolic/BUILD.bazel b/p4_symbolic/symbolic/BUILD.bazel index b601b1f2..81fa9701 100644 --- a/p4_symbolic/symbolic/BUILD.bazel +++ b/p4_symbolic/symbolic/BUILD.bazel @@ -46,7 +46,8 @@ cc_library( deps = [ "//gutil:status", "//p4_pdpi:ir_cc_proto", - "//p4_pdpi/netaddr:ipv4_address", + "//p4_pdpi/internal:ordered_map", + "//p4_pdpi/netaddr:ipv4_address", "//p4_pdpi/netaddr:ipv6_address", "//p4_pdpi/netaddr:mac_address", "//p4_pdpi/utils:ir", diff --git a/p4_symbolic/symbolic/table.cc b/p4_symbolic/symbolic/table.cc index effe5f8d..66e36000 100644 --- a/p4_symbolic/symbolic/table.cc +++ b/p4_symbolic/symbolic/table.cc @@ -30,6 +30,7 @@ #include "absl/types/span.h" #include "gutil/status.h" #include "p4/config/v1/p4info.pb.h" +#include "p4_pdpi/internal/ordered_map.h" #include "p4_pdpi/ir.pb.h" #include "p4_symbolic/symbolic/action.h" #include "p4_symbolic/symbolic/operators.h" @@ -77,7 +78,7 @@ int FindMatchWithName(const pdpi::IrTableEntry &entry, // We return the old index so that Symbolic and Concrete TableMatches are // set up against the indices as they appear in the input table entries array, // and not the sorted array. -std::vector> SortEntries( +std::vector> SortEntries( const ir::Table &table, const std::vector &entries) { if (entries.empty()) return {}; // Find which *definition* of priority we should use by looking at the @@ -106,27 +107,26 @@ std::vector> SortEntries( } // The output array. - std::vector> sorted_entries; - for (size_t i = 0; i < entries.size(); i++) { + std::vector> sorted_entries; + for (int i = 0; i < entries.size(); i++) { const pdpi::IrTableEntry &entry = entries.at(i); sorted_entries.push_back(std::make_pair(i, entry)); } // The sort comparator depends on the match types. - std::function &, - const std::pair &)> + std::function &, + const std::pair &)> comparator; if (has_ternary) { // Sort by explicit priority. - comparator = [](const std::pair &entry1, - const std::pair &entry2) { + comparator = [](const std::pair &entry1, + const std::pair &entry2) { return entry1.second.priority() > entry2.second.priority(); }; } else if (lpm_key.has_value()) { // Sort by prefix length. - comparator = [lpm_key]( - const std::pair &entry1, - const std::pair &entry2) { + comparator = [lpm_key](const std::pair &entry1, + const std::pair &entry2) { auto is_lpm_match = [=](const pdpi::IrMatch &match) -> bool { return match.name() == *lpm_key; }; @@ -235,8 +235,13 @@ absl::StatusOr EvaluateTableEntryCondition( z3::expr condition_expression = Z3Context().bool_val(true); const google::protobuf::Map &match_to_fields = table.table_implementation().match_name_to_field(); - for (const auto &[name, match_fields] : - table.table_definition().match_fields_by_name()) { + + // It is desirable for P4Symbolic to produce deterministic outputs. Therefore, + // all containers need to be traversed in a deterministic order. + const auto sorted_match_fields_by_name = + Ordered(table.table_definition().match_fields_by_name()); + + for (const auto &[name, match_fields] : sorted_match_fields_by_name) { p4::config::v1::MatchField match_definition = match_fields.match_field(); int match_field_index = FindMatchWithName(entry, name); @@ -295,7 +300,7 @@ absl::Status EvaluateSingeTableEntryAction( // Constructs a symbolic expressions that represents the action invocation // corresponding to this entry. absl::Status EvaluateTableEntryAction( - const ir::Table &table, const pdpi::IrTableEntry &entry, + const ir::Table &table, const pdpi::IrTableEntry &entry, int entry_index, const google::protobuf::Map &actions, SymbolicPerPacketState *state, values::P4RuntimeTranslator *translator, const z3::expr &guard) { @@ -312,7 +317,8 @@ absl::Status EvaluateTableEntryAction( // whose value determines which action is executed: to a first // approximation, action i is executed iff `selector == i`. std::string selector_name = - absl::StrCat("action selector for ", entry.DebugString()); + absl::StrFormat("action selector for entry #%d of table '%s'", + entry_index, entry.table_name()); z3::expr selector = Z3Context().int_const(selector_name.c_str()); z3::expr unselected = Z3Context().bool_val(true); for (int i = 0; i < action_set.size(); ++i) { @@ -345,7 +351,7 @@ absl::StatusOr EvaluateTable( const z3::expr &guard) { const std::string &table_name = table.table_definition().preamble().name(); // Sort entries by priority deduced from match types. - std::vector> sorted_entries = + std::vector> sorted_entries = SortEntries(table, entries); // The table semantically is just a bunch of if conditions, one per // table entry, we construct this big if-elseif-...-else symbolically. @@ -431,16 +437,17 @@ absl::StatusOr EvaluateTable( } // Start with the default entry - z3::expr match_index = Z3Context().int_val(-1); - RETURN_IF_ERROR(EvaluateTableEntryAction( - table, default_entry, data_plane.program.actions(), state, translator, - default_entry_assignment_guard)); + z3::expr match_index = Z3Context().int_val(kDefaultActionEntryIndex); + RETURN_IF_ERROR( + EvaluateTableEntryAction(table, default_entry, kDefaultActionEntryIndex, + data_plane.program.actions(), state, translator, + default_entry_assignment_guard)); // Continue evaluating each table entry in reverse priority for (int row = sorted_entries.size() - 1; row >= 0; row--) { - size_t old_index = sorted_entries.at(row).first; + int old_index = sorted_entries.at(row).first; const pdpi::IrTableEntry &entry = sorted_entries.at(row).second; - z3::expr row_symbol = Z3Context().int_val(static_cast(old_index)); + z3::expr row_symbol = Z3Context().int_val(old_index); // The condition used in the big if_else_then construct. ASSIGN_OR_RETURN(z3::expr entry_match, @@ -450,9 +457,9 @@ absl::StatusOr EvaluateTable( // Evaluate the entry's action guarded by its complete assignment guard. z3::expr entry_assignment_guard = assignment_guards.at(row); - RETURN_IF_ERROR( - EvaluateTableEntryAction(table, entry, data_plane.program.actions(), - state, translator, entry_assignment_guard)); + RETURN_IF_ERROR(EvaluateTableEntryAction( + table, entry, old_index, data_plane.program.actions(), state, + translator, entry_assignment_guard)); } // This table has been completely evaluated, the result of the evaluation @@ -476,9 +483,8 @@ absl::StatusOr EvaluateTable( table.table_implementation().action_to_next_control()) { if (first) { next_control = control; - continue; - } - if (next_control != control) { + first = false; + } else if (next_control != control) { return absl::UnimplementedError(absl::StrCat( "Table \"", table_name, "\" invokes different control constructs based on matched actions.")); diff --git a/p4_symbolic/symbolic/table.h b/p4_symbolic/symbolic/table.h index 94b27423..09def04b 100644 --- a/p4_symbolic/symbolic/table.h +++ b/p4_symbolic/symbolic/table.h @@ -36,6 +36,9 @@ namespace p4_symbolic { namespace symbolic { namespace table { +// P4-Symbolic models the default action as an entry with index -1. +constexpr int kDefaultActionEntryIndex = -1; + absl::StatusOr EvaluateTable( const Dataplane &data_plane, const ir::Table &table, const std::vector &entries, diff --git a/p4_symbolic/z3_util.cc b/p4_symbolic/z3_util.cc index 391627a7..cccb0174 100644 --- a/p4_symbolic/z3_util.cc +++ b/p4_symbolic/z3_util.cc @@ -8,8 +8,14 @@ namespace p4_symbolic { -z3::context& Z3Context() { +z3::context& Z3Context(bool renew) { static z3::context* z3_context = new z3::context(); + + if (renew) { + delete z3_context; + z3_context = new z3::context(); + } + return *z3_context; } diff --git a/p4_symbolic/z3_util.h b/p4_symbolic/z3_util.h index 16a2179b..59a8d1c9 100644 --- a/p4_symbolic/z3_util.h +++ b/p4_symbolic/z3_util.h @@ -11,9 +11,11 @@ namespace p4_symbolic { -// Global z3::context used for creating symbolic expressions during symbolic -// evaluation. -z3::context& Z3Context(); +// Returns the global z3::context used for creating symbolic expressions during +// symbolic evaluation. If parameter `renew` is set to true, it deletes the +// older context and returns a new one. +// TODO: `renew` is a workaround for using a global context. +z3::context& Z3Context(bool renew = false); // -- Evaluation ---------------------------------------------------------------