Theory Matching_Embeddings

theory Matching_Embeddings
imports "Semantics_Ternary/Matching_Ternary" Matching "Semantics_Ternary/Unknown_Match_Tacs"
begin

section‹Boolean Matching vs. Ternary Matching›

term Semantics.matches
term Matching_Ternary.matches
(*'a is the primitive match condition, e.g. IpSrc …*)


text‹The two matching semantics are related. However, due to the ternary logic, we cannot directly translate one to the other.
The problem are @{const MatchNot} expressions which evaluate to @{const TernaryUnknown} because MatchNot TernaryUnknown› and
TernaryUnknown› are semantically equal!›
lemma "m β α a. Matching_Ternary.matches (β, α) m a p  
  Semantics.matches (λ atm p. case β atm p of TernaryTrue  True | TernaryFalse  False | TernaryUnknown  α a p) m p"
apply(rule_tac x="MatchNot (Match X)" in exI) ― ‹any @{term "X::'a"}
by (auto split: ternaryvalue.split ternaryvalue.split_asm simp add: matches_case_ternaryvalue_tuple)

text‹the @{const the} in the next definition is always defined›
lemma "m  {m. approx m p  TernaryUnknown}. ternary_to_bool (approx m p)  None"
  by(simp add: ternary_to_bool_None)


text‹
The Boolean and the ternary matcher agree (where the ternary matcher is defined)
›
definition matcher_agree_on_exact_matches :: "('a, 'p) matcher  ('a  'p  ternaryvalue)  bool" where
  "matcher_agree_on_exact_matches exact approx  p m. approx m p  TernaryUnknown  exact m p = the (ternary_to_bool (approx m p))"

text‹We say the Boolean and ternary matchers agree iff they return the same result or the ternary matcher returns @{const TernaryUnknown}.›
lemma "matcher_agree_on_exact_matches exact approx  (p m. exact m p = the (ternary_to_bool (approx m p))  approx m p = TernaryUnknown)"
  unfolding matcher_agree_on_exact_matches_def by blast
lemma matcher_agree_on_exact_matches_alt: (*no `the`*)
  "matcher_agree_on_exact_matches exact approx  (p m. approx m p  TernaryUnknown  bool_to_ternary (exact m p) = approx m p)"
  unfolding matcher_agree_on_exact_matches_def
  by (metis (full_types) bool_to_ternary.simps(1) bool_to_ternary.simps(2) option.sel ternary_to_bool.simps(1)
                         ternary_to_bool.simps(2) ternaryvalue.exhaust)

lemma eval_ternary_Not_TrueD: "eval_ternary_Not m = TernaryTrue  m = TernaryFalse"
  by (metis eval_ternary_Not.simps(1) eval_ternary_idempotence_Not)


lemma matches_comply_exact: "ternary_ternary_eval (map_match_tac β p m)  TernaryUnknown 
       matcher_agree_on_exact_matches γ β 
        Semantics.matches γ m p = Matching_Ternary.matches (β, α) m a p"
  proof(unfold matches_case_ternaryvalue_tuple,induction m)
  case Match thus ?case
       by(simp split: ternaryvalue.split add: matcher_agree_on_exact_matches_def)
  next
  case (MatchNot m) thus ?case
      apply(simp split: ternaryvalue.split add: matcher_agree_on_exact_matches_def)
      apply(case_tac "ternary_ternary_eval (map_match_tac β p m)")
        by(simp_all)
  next
  case (MatchAnd m1 m2)
    thus ?case
     apply(case_tac "ternary_ternary_eval (map_match_tac β p m1)")
       apply(case_tac [!] "ternary_ternary_eval (map_match_tac β p m2)")
                by(simp_all)
  next
  case MatchAny thus ?case by simp
  qed


lemma matcher_agree_on_exact_matches_gammaE:
  "matcher_agree_on_exact_matches γ β  β X p = TernaryTrue  γ X p"
  apply(simp add: matcher_agree_on_exact_matches_alt)
  apply(erule_tac x=p in allE)
  apply(erule_tac x=X in allE)
  apply(simp add: bool_to_ternary_simps)
  done




lemma in_doubt_allow_allows_Accept: "a = Accept  matcher_agree_on_exact_matches γ β 
        Semantics.matches γ m p  Matching_Ternary.matches (β, in_doubt_allow) m a p"
  apply(case_tac "ternary_ternary_eval (map_match_tac β p m)  TernaryUnknown")
   using matches_comply_exact apply fast
  apply(simp add: matches_case_ternaryvalue_tuple)
  done

lemma not_exact_match_in_doubt_allow_approx_match: "matcher_agree_on_exact_matches γ β  a = Accept  a = Reject  a = Drop 
  ¬ Semantics.matches γ m p  
  (a = Accept  Matching_Ternary.matches (β, in_doubt_allow) m a p)  ¬ Matching_Ternary.matches (β, in_doubt_allow) m a p"
  apply(case_tac "ternary_ternary_eval (map_match_tac β p m)  TernaryUnknown")
   apply(drule(1) matches_comply_exact[where α=in_doubt_allow and a=a])
   apply(rule disjI2)
   apply fast
  apply(simp)
  apply(clarify)
  apply(simp add: matches_case_ternaryvalue_tuple)
  apply(cases a)
         apply(simp_all)
  done




lemma in_doubt_deny_denies_DropReject: "a = Drop  a = Reject  matcher_agree_on_exact_matches γ β 
        Semantics.matches γ m p  Matching_Ternary.matches (β, in_doubt_deny) m a p"
  apply(case_tac "ternary_ternary_eval (map_match_tac β p m)  TernaryUnknown")
   using matches_comply_exact apply fast
   apply(simp)
  apply(auto simp add: matches_case_ternaryvalue_tuple)
  done

lemma not_exact_match_in_doubt_deny_approx_match: "matcher_agree_on_exact_matches γ β  a = Accept  a = Reject  a = Drop 
  ¬ Semantics.matches γ m p  
  ((a = Drop  a = Reject)  Matching_Ternary.matches (β, in_doubt_deny) m a p)  ¬ Matching_Ternary.matches (β, in_doubt_deny) m a p"
  apply(case_tac "ternary_ternary_eval (map_match_tac β p m)  TernaryUnknown")
   apply(drule(1) matches_comply_exact[where α=in_doubt_deny and a=a])
   apply(rule disjI2)
   apply fast
  apply(simp)
  apply(clarify)
  apply(simp add: matches_case_ternaryvalue_tuple)
  apply(cases a)
         apply(simp_all)
  done

text‹The ternary primitive matcher can return exactly the result of the Boolean primitive matcher›
definition βmagic :: "('a, 'p) matcher  ('a  'p  ternaryvalue)" where
  "βmagic γ  (λ a p. if γ a p then TernaryTrue else TernaryFalse)"

lemma "matcher_agree_on_exact_matches γ (βmagic γ)"
  by(simp add: matcher_agree_on_exact_matches_def βmagic_def)

lemma βmagic_not_Unknown: "ternary_ternary_eval (map_match_tac (βmagic γ) p m)  TernaryUnknown"
  proof(induction m)
  case MatchNot thus ?case using eval_ternary_Not_UnknownD βmagic_def
     by (simp) blast
  case (MatchAnd m1 m2) thus ?case
    apply(case_tac "ternary_ternary_eval (map_match_tac (βmagic γ) p m1)")
      apply(case_tac [!] "ternary_ternary_eval (map_match_tac (βmagic γ) p m2)")
            by(simp_all add: βmagic_def)
  qed (simp_all add: βmagic_def)

lemma βmagic_matching: "Matching_Ternary.matches ((βmagic γ), α) m a p  Semantics.matches γ m p"
  proof(induction m)
  case Match thus ?case 
    by(simp add: βmagic_def matches_case_ternaryvalue_tuple)
  case MatchNot thus ?case
    by(simp add: matches_case_ternaryvalue_tuple βmagic_not_Unknown split: ternaryvalue.split_asm)
  qed (simp_all add: matches_case_ternaryvalue_tuple split: ternaryvalue.split ternaryvalue.split_asm)
  


end