Theory First_Order_Clause.Ground_Critical_Pairs

theory Ground_Critical_Pairs
  imports Ground_Term_Rewrite_System
begin

context ground_term_rewrite_system
begin

definition ground_critical_pairs :: "'t rel  't rel" where
  "ground_critical_pairs R = {(cr2, r1) | c l r1 r2. (cl, r1)  R  (l, r2)  R}"

abbreviation ground_critical_pair_theorem where
  "ground_critical_pair_theorem R  
    WCR (rewrite_in_context R)  ground_critical_pairs R  (rewrite_in_context R)"

lemma ground_critical_pairs_fork:
  fixes R :: "'t rel"
  assumes ground_critical_pairs: "(l, r)  ground_critical_pairs R"
  shows "(r, l)  (rewrite_in_context R)¯ O rewrite_in_context R"
proof -

  obtain c t t' where "l = ct'" and "(ct, r)  R" and "(t, t')  R" 
    using ground_critical_pairs
    unfolding ground_critical_pairs_def
    by auto

  have "(r, ct)  (rewrite_in_context R)¯"
    using (ct, r)  R subset_rewrite_in_context 
    by blast

  moreover have "(ct, l)  rewrite_in_context R"
    using (t, t')  R l = ct' rewrite_in_context_def
    by fast

  ultimately show ?thesis 
    by auto
qed

lemma ground_critical_pairs_complete:
  fixes R :: "'t rel"
  assumes 
    ground_critical_pairs: "(l, r)  ground_critical_pairs R" and
    no_join: "(l, r)  (rewrite_in_context R)"
  shows "¬ WCR (rewrite_in_context R)"
  using ground_critical_pairs_fork[OF ground_critical_pairs] no_join
  by auto

end

locale ground_critical_pairs = ground_term_rewrite_system +
  assumes ground_critical_pairs_main: 
    "R s t1 t2.
      (s, t1)  rewrite_in_context R 
      (s, t2)  rewrite_in_context R 
      (t1, t2)  (rewrite_in_context R) 
       (c l r. t1 = cl  t2 = cr 
         ((l, r)  ground_critical_pairs R  (r, l)  ground_critical_pairs R))"
begin

lemma ground_critical_pairs:
  assumes ground_critical_pairs:
    "l r. (l, r)  ground_critical_pairs R  l  r 
      s. (l, s)  (rewrite_in_context R)*  (r, s)  (rewrite_in_context R)*"
  shows "WCR (rewrite_in_context R)"
proof (intro WCR_onI)

  let ?R = "rewrite_in_context R"
  let ?CP = "ground_critical_pairs R"

  fix s t1 t2

  assume steps: "(s, t1)  ?R" "(s, t2)  ?R"

  let ?p = "λs'. (t1, s')  ?R*  (t2, s')  ?R*"

  from ground_critical_pairs_main [OF steps]
  have "s'. ?p s'"
    using ground_critical_pairs rewrite_in_context_trancl_add_context
    by (metis joinE rtrancl.rtrancl_refl)
 
  then show "(t1, t2)  ?R"
    by auto
qed

theorem ground_critical_pair_theorem: "ground_critical_pair_theorem R" (is "?l = ?r")
proof (rule iffI)
  assume ?l

  with ground_critical_pairs_complete show ?r 
    by auto
next
  assume ?r

  with ground_critical_pairs show ?l
    by auto
qed

end

end