Theory HM_Logic_Infinitary

section ‹Infinitary Hennessy--Milner Logic›

theory HM_Logic_Infinitary
  imports 
    Weak_Relations
begin

datatype ('a,'x)HML_formula =
  HML_true 
| HML_conj 'x set 'x  ('a,'x)HML_formula  (AND _ _›)
| HML_neg ('a,'x)HML_formula                  (~_› [20] 60)
| HML_poss 'a ('a,'x)HML_formula            (__› [60] 60)

―‹The HML formulation is derived from that by Max Pohlmann @{cite pohlmann2021reactivebisim}.›

subsection ‹Satisfaction Relation›

context lts_tau
begin

function satisfies :: 's  ('a, 's) HML_formula  bool 
  (‹_  _› [50, 50] 50)
  where
    (p  HML_true) = True 
  | (p  HML_conj I F) = ( i  I. p  (F i)) 
  | (p  HML_neg φ) = (¬ p  φ)
  | (p  HML_poss α φ) =
      ( p'. ((tau α  p ⟼* tau p')  (¬ tau α  p α p'))  p'  φ)
  using HML_formula.exhaust by (auto, blast)

inductive_set HML_wf_rel :: ('s × ('a, 's) HML_formula) rel 
  where
    φ = F i  i  I  ((p, φ), (p, HML_conj I F))  HML_wf_rel 
  | ((p, φ), (p, HML_neg φ))  HML_wf_rel 
  | ((p, φ), (p', HML_poss α φ))  HML_wf_rel

lemma HML_wf_rel_is_wf: wf HML_wf_rel 
  unfolding wf_def
proof (safe)
  fix P::'s × ('a, 's) HML_formula  bool and t::'s × ('a, 's) HML_formula
  obtain p φ where t = (p, φ) by force
  assume x. (y. (y, x)  HML_wf_rel  P y)  P x
  hence P (p, φ)
  proof (induct φ arbitrary: p)
    case HML_true
    then show ?case
      by (metis HML_formula.distinct(1,3,5) HML_wf_rel.cases old.prod.exhaust)
  next
    case (HML_conj I F)
    thus ?case
      by (smt (verit) HML_formula.distinct(7,9) HML_formula.inject(1) HML_wf_rel.cases
         case_prodD case_prodE' lts_tau.HML_wf_rel_def mem_Collect_eq range_eqI)
  next
    case (HML_neg φ)
    thus ?case
      by (metis HML_formula.distinct(11,7) HML_formula.inject(2) HML_wf_rel.cases surj_pair)
  next
    case (HML_poss a φ)
    thus ?case
      by (smt (verit, del_insts) HML_formula.distinct(3,5,9,11)  HML_formula.inject(3)
        HML_wf_rel.cases case_prodD case_prodE' HML_wf_rel_def mem_Collect_eq)
  qed
  thus P t using t = (p, φ) by simp
qed

termination satisfies using HML_wf_rel_is_wf 
  by (standard, (simp add: HML_wf_rel.intros)+)

inductive_set HML_direct_subformulas :: (('a, 's) HML_formula) rel
  where
    φ = F i  i  I  (φ, HML_conj I F)  HML_direct_subformulas 
  | (φ, HML_neg φ)  HML_direct_subformulas 
  | (φ, HML_poss α φ)  HML_direct_subformulas

lemma HML_direct_subformulas_wf: wf HML_direct_subformulas 
  unfolding wf_def
proof (safe)
  fix P x
  assume x. (y. (y, x)  HML_direct_subformulas  P y)  P x
  thus P x
  proof induct
    case HML_true
    then show ?case using HML_direct_subformulas.simps by blast
  next
    case (HML_conj I F)
    then show ?case
      by (metis HML_direct_subformulas.cases HML_formula.distinct(7,9)
          HML_formula.inject(1) range_eqI)
  next
    case (HML_neg φ)
    then show ?case
      by (metis HML_direct_subformulas.simps HML_formula.distinct(11,7) HML_formula.inject(2))
  next
    case (HML_poss a φ)
    then show ?case
      by (metis HML_direct_subformulas.simps HML_formula.distinct(11,9) HML_formula.inject(3))
  qed
qed

definition HML_subformulas where HML_subformulas  (HML_direct_subformulas)+

lemma HML_subformulas_wf: wf HML_subformulas
  using HML_direct_subformulas_wf HML_subformulas_def wf_trancl
  by fastforce

lemma conj_only_depends_on_indexset:
  assumes iI. f1 i = f2 i
  shows (p  HML_conj I f1) = (p  HML_conj I f2)
  using assms by auto

subsection ‹Distinguishing Formulas›

definition HML_equivalent :: 's  's  bool
  where HML_equivalent p q 
     ( φ::('a, 's) HML_formula. (p  φ)  (q  φ))

fun distinguishes ::  ('a,'s) HML_formula  's  's  bool
  where
   distinguishes φ p q = (p  φ  ¬ q  φ)

fun distinguishes_from_set ::  ('a,'s) HML_formula  's  's set  bool
  where
   distinguishes_from_set φ p Q = (p  φ  (q. q  Q  ¬ q  φ))

lemma distinguishing_formula:
  assumes ¬ HML_equivalent p q
  shows  φ. p  φ  ¬ q  φ
  using assms  satisfies.simps(3) unfolding HML_equivalent_def 
  by blast

lemma HML_equivalent_symm:
  assumes HML_equivalent p q
  shows HML_equivalent q p
  using HML_equivalent_def assms by presburger

subsection ‹Weak-NOR Hennessy--Milner Logic›

definition HML_weaknor ::
  'x set  ('x  ('a,'x)HML_formula)  ('a,'x)HML_formula
  where HML_weaknor I F = HML_poss τ (HML_conj I (λf. HML_neg (F f)))

definition HML_weaknot ::
  ('a,'x)HML_formula  ('a,'x)HML_formula
  where HML_weaknot φ = HML_weaknor {undefined} (λi. φ)

inductive_set HML_weak_formulas :: ('a,'x)HML_formula set where
  Base: HML_true  HML_weak_formulas |
  Obs: φ  HML_weak_formulas  (τaφ)  HML_weak_formulas |
  Conj: (i. i  I  F i  HML_weak_formulas)  HML_weaknor I F  HML_weak_formulas

lemma weak_backwards_truth:
  assumes
    φ  HML_weak_formulas
    p ⟼* tau  p'
    p'  φ
  shows
    p  φ
  using assms
proof cases
  case Base
  then show ?thesis by force
next
  case (Obs φ a)
  then show ?thesis
    using assms(2,3) satisfies.simps(4) steps_concat tau_tau by blast
next
  case (Conj I F)
  then show ?thesis
    unfolding HML_weaknor_def tau_def
    using tau_tau assms steps_concat
    by force
qed

lemma tau_a_obs_implies_delay_step: 
  assumes p   τaφ
  shows p'. p =⊳a p'  p'  φ
proof - 
  obtain p'' where p ⇒^τ p''  p''  aφ using assms by auto
  thus ?thesis using satisfies.simps(4) steps_concat tau_tau by blast
qed

lemma delay_step_implies_tau_a_obs: 
  assumes 
    p =⊳a p'
    p'  φ
  shows p   τaφ
proof - 
  obtain p'' where p ⇒^τ p'' and p'' ⇒^a p'
    using assms steps.refl tau_tau by blast
  thus ?thesis
    by (metis assms(1,2) lts_tau.satisfies.simps(4) lts_tau.tau_tau)
qed

end
end