Theory FOR_Semantics

theory FOR_Semantics
  imports FOR_Certificate
    Lift_Root_Step
    "FOL-Fitting.FOL_Fitting"
begin

section ‹Semantics of Relations›

definition is_to_trs :: "('f, 'v) trs list  ftrs list  ('f, 'v) trs" where
  "is_to_trs Rs is = (set (map (case_ftrs ((!) Rs) ((`) prod.swap  (!) Rs)) is))"

primrec eval_gtt_rel :: "('f × nat) set  ('f, 'v) trs list  ftrs gtt_rel  'f gterm rel" where
  "eval_gtt_rel  Rs (ARoot is) = Restr (grrstep (is_to_trs Rs is)) (𝒯G )"
| "eval_gtt_rel  Rs (GInv g) = prod.swap ` (eval_gtt_rel  Rs g)"
| "eval_gtt_rel  Rs (AUnion g1 g2) = (eval_gtt_rel  Rs g1)  (eval_gtt_rel  Rs g2)"
| "eval_gtt_rel  Rs (ATrancl g) = (eval_gtt_rel  Rs g)+"
| "eval_gtt_rel  Rs (AComp g1 g2) = (eval_gtt_rel  Rs g1) O (eval_gtt_rel  Rs g2)"
| "eval_gtt_rel  Rs (GTrancl g) = gtrancl_rel  (eval_gtt_rel  Rs g)"
| "eval_gtt_rel  Rs (GComp g1 g2) =  gcomp_rel  (eval_gtt_rel  Rs g1) (eval_gtt_rel  Rs g2)"

primrec eval_rr1_rel :: "('f × nat) set  ('f, 'v) trs list  ftrs rr1_rel  'f gterm set"
  and eval_rr2_rel :: "('f × nat) set  ('f, 'v) trs list  ftrs rr2_rel  'f gterm rel" where
  "eval_rr1_rel  Rs R1Terms = (𝒯G )"
| "eval_rr1_rel  Rs (R1Union R S) = (eval_rr1_rel  Rs R)  (eval_rr1_rel  Rs S)"
| "eval_rr1_rel  Rs (R1Inter R S) = (eval_rr1_rel  Rs R)  (eval_rr1_rel  Rs S)"
| "eval_rr1_rel  Rs (R1Diff R S) = (eval_rr1_rel  Rs R) - (eval_rr1_rel  Rs S)"
| "eval_rr1_rel  Rs (R1Proj n R) = (case n of 0  fst ` (eval_rr2_rel  Rs R)
                                             | _  snd ` (eval_rr2_rel  Rs R))"
| "eval_rr1_rel  Rs (R1NF is) = NF (Restr (grstep (is_to_trs Rs is)) (𝒯G ))  (𝒯G )"
| "eval_rr1_rel  Rs (R1Inf R) = {s. infinite (eval_rr2_rel  Rs R `` {s})}"
| "eval_rr2_rel  Rs (R2GTT_Rel A W X) = lift_root_step  W X (eval_gtt_rel  Rs A)"
| "eval_rr2_rel  Rs (R2Inv R) = prod.swap ` (eval_rr2_rel  Rs R)"
| "eval_rr2_rel  Rs (R2Union R S) = (eval_rr2_rel  Rs R)  (eval_rr2_rel  Rs S)"
| "eval_rr2_rel  Rs (R2Inter R S) = (eval_rr2_rel  Rs R)  (eval_rr2_rel  Rs S)"
| "eval_rr2_rel  Rs (R2Diff R S) = (eval_rr2_rel  Rs R) - (eval_rr2_rel  Rs S)"
| "eval_rr2_rel  Rs (R2Comp R S) = (eval_rr2_rel  Rs R) O (eval_rr2_rel  Rs S)"
| "eval_rr2_rel  Rs (R2Diag R) = Id_on (eval_rr1_rel  Rs R)"
| "eval_rr2_rel  Rs (R2Prod R S) = (eval_rr1_rel  Rs R) × (eval_rr1_rel  Rs S)"


subsection ‹Semantics of Formulas›

fun eval_formula ::  "('f × nat) set  ('f, 'v) trs list  (nat  'f gterm) 
  ftrs formula  bool" where
  "eval_formula  Rs α (FRR1 r1 x)  α x  eval_rr1_rel  Rs r1"
| "eval_formula  Rs α (FRR2 r2 x y)  (α x, α y)  eval_rr2_rel  Rs r2"
| "eval_formula  Rs α (FAnd fs)  (f  set fs. eval_formula  Rs α f)"
| "eval_formula  Rs α (FOr fs)  (f  set fs. eval_formula  Rs α f)"
| "eval_formula  Rs α (FNot f)  ¬ eval_formula  Rs α f"
| "eval_formula  Rs α (FExists f)  (z  𝒯G . eval_formula  Rs (α0 : z) f)"
| "eval_formula  Rs α (FForall f)  (z  𝒯G . eval_formula  Rs (α0 : z) f)"

fun formula_arity :: "'trs formula  nat" where
  "formula_arity (FRR1 r1 x) = Suc x"
| "formula_arity (FRR2 r2 x y) = max (Suc x) (Suc y)"
| "formula_arity (FAnd fs) = max_list (map formula_arity fs)"
| "formula_arity (FOr fs) = max_list (map formula_arity fs)"
| "formula_arity (FNot f) = formula_arity f"
| "formula_arity (FExists f) = formula_arity f - 1"
| "formula_arity (FForall f) = formula_arity f - 1"



lemma R1NF_reps:
  assumes "funas_trs R  " " t. (term_of_gterm s, term_of_gterm t)  rstep R  ¬funas_gterm t  "
    and "funas_gterm s  " "(l, r)  R" "term_of_gterm s = Cl  (σ  :: 'b  ('a, 'b) Term.term)"
  shows False
proof -
  obtain c where w: "funas_term (c :: ('a, 'b) Term.term)  " "ground c"
    using assms(3) funas_term_of_gterm_conv ground_term_of_gterm by blast
  define τ where "τ x = (if x  vars_term l then σ x else c)" for x
  from assms(4-) have terms: "term_of_gterm s = Cl  τ" "(Cl  τ, Cr  τ)  rstep R"
    using τ_def by auto (metis term_subst_eq)
  from this(1) have [simp]: "funas_gterm s = funas_term Cl  τ" by (metis funas_term_of_gterm_conv)
  from w assms(1, 3, 4) have [simp]: "funas_term Cr  τ  " using τ_def
    by (auto simp: funas_trs_def funas_term_subst)
  moreover have "ground Cr  τ" using terms(1) w τ_def
    by (auto intro!: ground_substI) (metis term_of_gterm_ctxt_subst_apply_ground)
  ultimately show ?thesis using assms(2) terms(2)
    by (metis funas_term_of_gterm_conv ground_term_to_gtermD terms(1))
qed


text ‹The central property we are interested in is satisfiability›

definition formula_satisfiable where
  "formula_satisfiable  Rs f  (α. range α  𝒯G   eval_formula  Rs α f)"

subsection ‹Validation›

subsection ‹Defining properties of @{const gcomp_rel} and @{const gtrancl_rel}

lemma gcomp_rel_sig:
  assumes "R  𝒯G  × 𝒯G " and "S  𝒯G  × 𝒯G "
  shows "gcomp_rel  R S  𝒯G  × 𝒯G "
  using assms subsetD[OF signature_pres_funas_cl(2)[OF assms(1)]]
  by (auto simp: gcomp_rel_def lift_root_step.simps gmctxt_cl_gmctxtex_onp_conv) (metis refl_onD2 relf_on_gmctxtcl_funas)

lemma gtrancl_rel_sig:
  assumes "R  𝒯G  × 𝒯G "
  shows "gtrancl_rel  R  𝒯G  × 𝒯G "
  using gtrancl_rel_sound[OF assms] by simp

lemma gtrancl_rel:
  assumes "R  𝒯G  × 𝒯G "
  shows "lift_root_step  PAny EStrictParallel (gtrancl_rel  R) = (lift_root_step  PAny ESingle R)+"
  unfolding lift_root_step.simps using gmctxtcl_funas_strict_gtrancl_rel[OF assms] .

lemma gtrancl_rel':
  assumes "R  𝒯G  × 𝒯G "
  shows "lift_root_step  PAny EParallel (gtrancl_rel  R) = Restr ((lift_root_step  PAny ESingle R)*) (𝒯G )"
  using assms gtrancl_rel[OF assms]
  by (auto simp: lift_root_step_Parallel_conv
      simp flip: reflcl_trancl dest: Restr_simps(5)[OF lift_root_step_sig, THEN subsetD])

text ‹GTT relation semantics respects the signature›

lemma eval_gtt_rel_sig:
  "eval_gtt_rel  Rs g  𝒯G  × 𝒯G "
proof -
  show ?thesis by (induct g) (auto 0 3 simp: gtrancl_rel_sig gcomp_rel_sig dest: tranclD tranclD2)
qed

text ‹RR1 and RR2 relation semantics respect the signature›

lemma eval_rr12_rel_sig:
  "eval_rr1_rel  Rs r1  𝒯G "
  "eval_rr2_rel  Rs r2  𝒯G  × 𝒯G "
proof (induct r1 and r2)
  case (R1Inf r2) then show ?case by (auto dest!: infinite_imp_nonempty)
next
  case (R1Proj i r2) then show ?case by (fastforce split: nat.splits)
next
  case (R2GTT_Rel g W X) then show ?case by (simp add: lift_root_step_sig eval_gtt_rel_sig)
qed auto


subsection ‹Correctness of derived constructions›

lemma R1Fin:
  "eval_rr1_rel  Rs (R1Fin r) = {t  𝒯G . finite {s. (t, s)  eval_rr2_rel  Rs r}}"
  by (auto simp: R1Fin_def Image_def)

lemma R2Eq:
  "eval_rr2_rel  Rs R2Eq = Id_on (𝒯G )"
  by (auto simp: 𝒯G_funas_gterm_conv R2Eq_def)

lemma R2Reflc:
  "eval_rr2_rel  Rs (R2Reflc r) = eval_rr2_rel  Rs r  Id_on (𝒯G )"
  "eval_rr2_rel  Rs (R2Reflc r) = Restr ((eval_rr2_rel  Rs r)=) (𝒯G )"
  using eval_rr12_rel_sig(2)[of  Rs "R2Reflc r"]
  by (auto simp: R2Reflc_def R2Eq)

lemma R2Step:
  "eval_rr2_rel  Rs (R2Step ts) = Restr (grstep (is_to_trs Rs ts)) (𝒯G )"
  by (auto simp: lift_root_step.simps R2Step_def grstep_lift_root_step grrstep_subst_cl_conv grstepD_grstep_conv grstepD_def)

lemma R2StepEq:
  "eval_rr2_rel  Rs (R2StepEq ts) = Restr ((grstep (is_to_trs Rs ts))=) (𝒯G )"
  by (auto simp: R2StepEq_def R2Step R2Reflc(2))

lemma R2Steps:
  fixes  Rs ts defines "R  Restr (grstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2Steps ts) = R+"
  by (simp add: R2Steps_def GSteps_def R_def gtrancl_rel grstep_lift_root_step)
     (metis FOR_Semantics.gtrancl_rel Sigma_cong grstep_lift_root_step inf.cobounded2 lift_root_Any_EStrict_eq)

lemma R2StepsEq:
  fixes  Rs ts defines "R  Restr (grstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2StepsEq ts) = Restr (R*) (𝒯G )"
  using R2Steps[of  Rs ts]
  by (simp add: R2StepsEq_def R2Steps_def lift_root_step_Parallel_conv Int_Un_distrib2 R_def Restr_simps flip: reflcl_trancl)

lemma R2StepsNF:
  fixes  Rs ts defines "R  Restr (grstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2StepsNF ts) = Restr (R*  UNIV × NF R) (𝒯G )"
  using R2StepsEq[of  Rs ts]
  by (auto simp: R2StepsNF_def R2StepsEq_def R_def)

lemma R2ParStep:
  "eval_rr2_rel  Rs (R2ParStep ts) = Restr (gpar_rstep (is_to_trs Rs ts)) (𝒯G )"
  by (simp add: R2ParStep_def gar_rstep_lift_root_step)

lemma R2RootStep:
  "eval_rr2_rel  Rs (R2RootStep ts) = Restr (grrstep (is_to_trs Rs ts)) (𝒯G )"
  by (simp add: R2RootStep_def lift_root_step.simps)

lemma R2RootStepEq:
  "eval_rr2_rel  Rs (R2RootStepEq ts) = Restr ((grrstep (is_to_trs Rs ts))=) (𝒯G )"
  by (auto simp: R2RootStepEq_def R2RootStep R2Reflc(2))

lemma R2RootSteps:
  fixes  Rs ts defines "R  Restr (grrstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2RootSteps ts) = R+"
  by (simp add: R2RootSteps_def R_def lift_root_step.simps)

lemma R2RootStepsEq:
  fixes  Rs ts defines "R  Restr (grrstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2RootStepsEq ts) = Restr (R*) (𝒯G )"
  by (auto simp: R2RootStepsEq_def R2Reflc_def R2RootSteps R_def R2Eq_def Int_Un_distrib2 Restr_simps simp flip: reflcl_trancl)

lemma R2NonRootStep:
  "eval_rr2_rel  Rs (R2NonRootStep ts) = Restr (gnrrstep (is_to_trs Rs ts)) (𝒯G )"
  by (simp add: R2NonRootStep_def grrstep_lift_root_gnrrstep)

lemma R2NonRootStepEq:
  "eval_rr2_rel  Rs (R2NonRootStepEq ts) = Restr ((gnrrstep (is_to_trs Rs ts))=) (𝒯G )"
  by (auto simp: R2NonRootStepEq_def R2Reflc_def R2Eq_def R2NonRootStep Int_Un_distrib2)

lemma R2NonRootSteps:
  fixes  Rs ts defines "R  Restr (gnrrstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2NonRootSteps ts) = R+"
  apply (simp add: lift_root_step.simps gnrrstepD_gnrrstep_conv gnrrstepD_def
    grrstep_subst_cl_conv R2NonRootSteps_def R_def GSteps_def lift_root_step_Parallel_conv)
  apply (intro gmctxtex_funas_nroot_strict_gtrancl_rel)
  by simp

lemma R2NonRootStepsEq:
  fixes  Rs ts defines "R  Restr (gnrrstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2NonRootStepsEq ts) = Restr (R*) (𝒯G )"
  using R2NonRootSteps[of  Rs ts]
  by (simp add: R2NonRootSteps_def R2NonRootStepsEq_def lift_root_step_Parallel_conv
    R_def Int_Un_distrib2 Restr_simps flip: reflcl_trancl)

lemma converse_to_prod_swap:
  "R¯ = prod.swap ` R"
  by auto

lemma R2Meet:
  fixes  Rs ts defines "R  Restr (grstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2Meet ts) = Restr ((R¯)* O R*) (𝒯G )"
  apply (simp add: R2Meet_def R_def GSteps_def converse_to_prod_swap gcomp_rel[folded lift_root_step.simps] gtrancl_rel' swap_lift_root_step grstep_lift_root_step)
  apply (simp add: Restr_simps converse_Int converse_Un converse_Times Int_Un_distrib2 flip: reflcl_trancl trancl_converse converse_to_prod_swap)
  done

lemma R2Join:
  fixes  Rs ts defines "R  Restr (grstep (is_to_trs Rs ts)) (𝒯G )"
  shows "eval_rr2_rel  Rs (R2Join ts) = Restr (R* O (R¯)*) (𝒯G )"
  apply (simp add: R2Join_def R_def GSteps_def converse_to_prod_swap  gcomp_rel[folded lift_root_step.simps] gtrancl_rel' swap_lift_root_step grstep_lift_root_step)
  apply (simp add: Restr_simps converse_to_prod_swap[symmetric] converse_Int converse_Un converse_Times Int_Un_distrib2 flip: reflcl_trancl trancl_converse)
  done

end